我正在尝试在触摸时绘制线条精灵,然后在触摸时操纵这些线条。画线参考论坛链接:cocos2d forum
操作包括拖动和旋转线条。仅在触摸中心区域时才可以拖动,并且可以正常工作。
关于旋转,我需要做的是当触摸在任何端点区域时,我需要旋转线(不改变其长度)保持另一端随着触摸移动而固定。
以下是我到目前为止所做的..
#import <GameKit/GameKit.h>
// When you import this file, you import all the cocos2d classes
#import "cocos2d.h"
// HelloWorldLayer
@interface HelloWorldLayer : CCLayer <GKAchievementViewControllerDelegate, GKLeaderboardViewControllerDelegate>
{
CGPoint lastTouchPoint;
CCSprite *line;
CCSprite *selectedSprite;
CGFloat rotation;
NSMutableArray *pointLoader;
NSMutableArray *startPointLoader;
BOOL moved;
BOOL doubleTap;
BOOL touchedTop;
BOOL touchedBottom;
}
// returns a CCScene that contains the HelloWorldLayer as the only child
+(CCScene *) scene;
@end
实现文件如下:
#import "HelloWorldLayer.h"
#import "CCTouchDispatcher.h"
// Needed to obtain the Navigation Controller
#import "AppDelegate.h"
#pragma mark - HelloWorldLayer
// HelloWorldLayer implementation
@implementation HelloWorldLayer
// Helper class method that creates a Scene with the HelloWorldLayer as the only child.
+(CCScene *) scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];
// 'layer' is an autorelease object.
HelloWorldLayer *layer = [HelloWorldLayer node];
// add layer as a child to scene
[scene addChild: layer];
// return the scene
return scene;
}
-(id) init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super's" return value
if( (self=[super init]) ) {
// create and initialize our seeker sprite, and add it to this layer
lastTouchPoint = ccp(-1.0f,-1.0f);
pointLoader = [[NSMutableArray alloc]init];
startPointLoader = [[NSMutableArray alloc]init];
self.isTouchEnabled = YES;
[[CCDirector sharedDirector] setDisplayStats:NO];
}
return self;
}
-(void) registerWithTouchDispatcher{
[[[CCDirector sharedDirector] touchDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
}
-(BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event{
line = [CCSprite spriteWithFile:@"list.png"];
if( touch ) {
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
if ([pointLoader count] != 0) {
[self selectSpriteOnTouch:location];
}
//
if( CGPointEqualToPoint(lastTouchPoint, ccp(-1.0f,-1.0f) ) ){
lastTouchPoint = ccp(location.x, location.y);
[startPointLoader addObject:NSStringFromCGPoint(lastTouchPoint)];
}
}
return YES;
}
-(void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event{
if (selectedSprite) {
CGRect firstRect = CGRectMake(selectedSprite.boundingBox.origin.x, selectedSprite.boundingBox.origin.y, selectedSprite.boundingBox.size.width/3, selectedSprite.boundingBox.size.height);
CGRect secondRect = CGRectMake(selectedSprite.boundingBox.origin.x+(2*selectedSprite.boundingBox.size.width/3), selectedSprite.boundingBox.origin.y, selectedSprite.boundingBox.size.width/3, selectedSprite.boundingBox.size.height);
CGPoint touchLocation = [touch locationInView:[touch view]];
touchLocation = [[CCDirector sharedDirector] convertToGL:touchLocation];
touchLocation = [self convertTouchToNodeSpace:touch];
CGPoint oldTouchLocation = [touch previousLocationInView:touch.view];
oldTouchLocation = [[CCDirector sharedDirector] convertToGL:oldTouchLocation];
oldTouchLocation = [self convertToNodeSpace:oldTouchLocation];
if (CGRectContainsPoint(firstRect, touchLocation)) {
NSLog(@"Touched top");
//Code to rotate when clicking on top region of line
touchedTop = YES;
lastTouchPoint = ccp(-1.0f,-1.0f);
}
else if (CGRectContainsPoint(secondRect, touchLocation)){
NSLog(@"Touched bottom");
touchedBottom = YES;
//Code to rotate when clicking on bottom region of line
lastTouchPoint = ccp(-1.0f,-1.0f);
}
else{
CGPoint translation = ccpSub(touchLocation, oldTouchLocation);
[self Translation:translation];
lastTouchPoint = ccp(-1.0f,-1.0f);
}
}
else{
moved = YES;
}
}
-(void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event{
//If there was a touch move..
if (moved==YES) {
line = [CCSprite spriteWithFile:@"list.png"];
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
CGPoint endPoint = ccp(location.x, location.y);
CGPoint diff = ccpSub(lastTouchPoint, endPoint);
float rads = atan2f( diff.y, diff.x);
float degs = -CC_RADIANS_TO_DEGREES(rads);
float dist = ccpDistance(lastTouchPoint, endPoint);
[line setAnchorPoint:ccp(0.0f, 0.5f)];
[line setPosition:endPoint];
[line setScaleX:dist/line.boundingBox.size.width];
[line setRotation: degs];
[pointLoader addObject:line];
[self addChild:line z:0];
moved = NO;
lastTouchPoint = ccp(-1.0f,-1.0f);
CCLOG(@" line location is (%f,%f)",line.position.x, line.position.y);
CCLOG(@"lastTouchPoint is now(%f,%f), location is (%f,%f)", lastTouchPoint.x, lastTouchPoint.y, location.x, location.y);
}
else if (touchedTop ==YES) {
[selectedSprite.parent removeChild:selectedSprite cleanup:YES];
line = [CCSprite spriteWithFile:@"list.png"];
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
CGPoint endPoint = ccp(location.x, location.y);
CGPoint diff = ccpSub(selectedSprite.position, endPoint);
float rads = atan2f( diff.y, diff.x);
float degs = -CC_RADIANS_TO_DEGREES(rads);
float dist = ccpDistance(selectedSprite.position, endPoint);
[line setAnchorPoint:ccp(0.0f, 0.5f)];
[line setPosition:endPoint];
[line setScaleX:dist/line.boundingBox.size.width];
[line setRotation: degs];
[pointLoader addObject:line];
[self addChild:line z:0];
touchedTop = NO;
lastTouchPoint = ccp(-1.0f,-1.0f);
}
else if (touchedBottom ==YES) {
[selectedSprite.parent removeChild:selectedSprite cleanup:YES];
line = [CCSprite spriteWithFile:@"list.png"];
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
CGPoint endPoint = ccp(location.x, location.y);
CGPoint diff = ccpSub(selectedSprite.position, endPoint);
float rads = atan2f( diff.y, diff.x);
float degs = -CC_RADIANS_TO_DEGREES(rads);
float dist = ccpDistance(selectedSprite.position, endPoint);
[line setAnchorPoint:ccp(0.0f, 0.5f)];
[line setPosition:endPoint];
[line setScaleX:dist/line.boundingBox.size.width];
[line setRotation: degs];
[pointLoader addObject:line];
[self addChild:line z:0];
touchedBottom = NO;
lastTouchPoint = ccp(-1.0f,-1.0f);
}
//
else if ([touch tapCount]==3){ //code to clear all screen
[self removeAllChildrenWithCleanup:YES];
rotatorSprite = nil;
selectedSprite = nil;
[pointLoader removeAllObjects];
NSLog(@"Screen Cleared");
lastTouchPoint = ccp(-1.0f,-1.0f);
}
}
- (void)selectSpriteOnTouch:(CGPoint)touchLocation {
// for (CCSprite *sprite in pointLoader) {
// if (CGRectContainsPoint(sprite.boundingBox, touchLocation)) {
// NSLog(@"sprite was touched");
//// [self removeChild:sprite cleanup:YES];
// [sprite.parent removeChild:sprite cleanup:YES];
//// break; // putting break does not solve the multiple deletion problem... it only disables the deletion
// NSLog(@"sprite moving");
//
//
// }
// }
// lastTouchPoint = ccp(-1.0f,-1.0f);
if (doubleTap == YES) {
id rotate = [CCRotateBy actionWithDuration:10 angle:360];
for(CCSprite *sprite in pointLoader){
if(CGRectContainsPoint(sprite.boundingBox, touchLocation)){
rotatorSprite = sprite;
[rotatorSprite setAnchorPoint:ccp(0.0f, 0.5f)];
[rotatorSprite runAction:rotate];
break;
}
}
doubleTap = NO;
lastTouchPoint = ccp(-1.0f,-1.0f);
}
else{
CCSprite * newSprite = nil;
for (CCSprite *sprite in pointLoader) {
// CGRect rect = CGRectMake(sprite.position.x-(sprite.contentSize.width/2), sprite.position.y-(sprite.contentSize.height/2),
// sprite.contentSize.width, sprite.contentSize.height);
// if (CGRectContainsPoint(rect, touchLocation)) {
if (CGRectContainsPoint(sprite.boundingBox, touchLocation)) {
newSprite = sprite;
NSLog(@"Sprite was Touched");
CCLOG(@" newSprite location is (%f,%f)",newSprite.position.x, newSprite.position.y);
break;
}
}
if (newSprite != selectedSprite) {
selectedSprite = newSprite;
}
}
}
- (void)Translation:(CGPoint)translation {
if (selectedSprite) {
CGPoint newPos = ccpAdd(selectedSprite.position, translation);
selectedSprite.position = newPos;
CCLOG(@" selectedSprite location is (%f,%f)",selectedSprite.position.x, selectedSprite.position.y);
}
lastTouchPoint = ccp(-1.0f,-1.0f);
}
// on "dealloc" you need to release all your retained objects
- (void) dealloc
{
// in case you have something to dealloc, do it in this method
// in this particular example nothing needs to be released.
// cocos2d will automatically release all the children (Label)
// don't forget to call "super dealloc"
[super dealloc];
}
#pragma mark GameKit delegate
-(void) achievementViewControllerDidFinish:(GKAchievementViewController *)viewController
{
AppController *app = (AppController*) [[UIApplication sharedApplication] delegate];
[[app navController] dismissModalViewControllerAnimated:YES];
}
-(void) leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController
{
AppController *app = (AppController*) [[UIApplication sharedApplication] delegate];
[[app navController] dismissModalViewControllerAnimated:YES];
}
@end
旋转正在发生,但不是按需要发生的,并且在平行于 x 和 y 轴时也会停止。
请帮我解决旋转问题....
谢谢