0

タッチで線のスプライトを描画し、それらの線をタッチで操作しようとしています。線画はフォーラム リンク: cocos2d フォーラムに基づいています。

操作には、線のドラッグと回転が含まれます。ドラッグは中央領域に触れたときだけで、うまく機能しています。

回転について、私がする必要があるのは、タッチが終点領域のいずれかにある場合、タッチの移動に合わせてもう一方の端を固定したまま、(長さを変更せずに) 線を回転させる必要があることです。

以下は、私がこれまでに行ったことです..

#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 軸に平行になると停止します。

回転の問題を解決するのを手伝ってください....

ありがとう

4

1 に答える 1