在 Cocos2d 中以正确的方式实现多个 CCSprite 的触摸?

发布于 2024-11-27 01:54:09 字数 2157 浏览 1 评论 0原文

我正在使用 cocos2d 开发我的第一个游戏,我遇到了一个问题,我似乎无法找到正确的解决方案。我每秒从屏幕顶部到底部添加一个 CCSprite 并为其设置动画,并且需要在玩家触摸其中任何一个精灵时隐藏这些精灵。所以我想到给我添加的每个精灵赋予标签,然后使用该特定标签访问该精灵。我是否需要将标签号放入某个数组中,因为它们每秒都会递增,甚至在我在触摸方法中访问它们之前?

- (void)addStraightBugs 
{
currentAntTag++;

[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"smallAunt.plist"];        

spriteSheetmedAnt = [CCSpriteBatchNode batchNodeWithFile:@"smallAunt.png"];
[self addChild:spriteSheetmedAnt z:0 tag:kSpriteManager];

CCSprite *ant= [CCSprite spriteWithSpriteFrameName:@"small-aunt1.png"];
[spriteSheetmedAnt addChild:ant z:1 tag:currentAntTag];

NSMutableArray *walkAnimFrames = [NSMutableArray array];
for(int i = 1; i <= 2; ++i) {
    [walkAnimFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:@"small-ant%d.png", i]]];
}

CCAnimation *walkAnim = [CCAnimation animationWithFrames:walkAnimFrames delay:0.15f];
CCAction *action=[CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:walkAnim restoreOriginalFrame:NO]];


ant.position = ccp(100,500);
[ant runAction:action];

CGPoint realDest = ccp(60,140);

int minDuration = 2.0;
int maxDuration = 5.0;
int rangeDuration = maxDuration - minDuration;
int actualDuration = (arc4random() % rangeDuration) + minDuration;

[ant runAction:[CCSequence actions:
                       [CCMoveTo actionWithDuration:actualDuration position:realDest],
                       [CCCallFuncN actionWithTarget:self selector:@selector(moveFinished:)],
                       nil]];

}

-(void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event  
{
CGPoint touchLocation = [self convertTouchToNodeSpace:touch];

CCSpriteBatchNode *spriteManager;
spriteManager = (CCSpriteBatchNode*)[self getChildByTag:kSpriteManager];
CCSprite *ant = (CCSprite*)[spriteManager getChildByTag:currentAntTag];

CGRect abc= CGRectInset([ant boundingBox],30, 85);

if(CGRectContainsPoint(abc,touchLocation))  
{

    ant.visible=NO;
}
}

我还有 3 个方法,每隔几秒调用一次,在这些方法中我创建这些 CCSpriteFrameCache 和 CCSpriteBatchNode 对象,以使我的角色在动画时运行。像这样每秒创建缓存会太重吗?还是我应该在 init 方法中创建它们,然后在此处的 CCSprite 上运行操作?

I am developing my first game with cocos2d and i have run into a problem of which i cant seem to find a right solution. i am adding and animating a CCSprite every second from top of the screen to the bottom and need to hide these sprites when the player touches on any one of them. So i thought of giving tags to every sprite i add and later on access that sprite with that particular tag. Do i need to put the tag number in some array as they get incremented every second even before i access them in the touch method??

- (void)addStraightBugs 
{
currentAntTag++;

[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"smallAunt.plist"];        

spriteSheetmedAnt = [CCSpriteBatchNode batchNodeWithFile:@"smallAunt.png"];
[self addChild:spriteSheetmedAnt z:0 tag:kSpriteManager];

CCSprite *ant= [CCSprite spriteWithSpriteFrameName:@"small-aunt1.png"];
[spriteSheetmedAnt addChild:ant z:1 tag:currentAntTag];

NSMutableArray *walkAnimFrames = [NSMutableArray array];
for(int i = 1; i <= 2; ++i) {
    [walkAnimFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:@"small-ant%d.png", i]]];
}

CCAnimation *walkAnim = [CCAnimation animationWithFrames:walkAnimFrames delay:0.15f];
CCAction *action=[CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:walkAnim restoreOriginalFrame:NO]];


ant.position = ccp(100,500);
[ant runAction:action];

CGPoint realDest = ccp(60,140);

int minDuration = 2.0;
int maxDuration = 5.0;
int rangeDuration = maxDuration - minDuration;
int actualDuration = (arc4random() % rangeDuration) + minDuration;

[ant runAction:[CCSequence actions:
                       [CCMoveTo actionWithDuration:actualDuration position:realDest],
                       [CCCallFuncN actionWithTarget:self selector:@selector(moveFinished:)],
                       nil]];

}

-(void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event  
{
CGPoint touchLocation = [self convertTouchToNodeSpace:touch];

CCSpriteBatchNode *spriteManager;
spriteManager = (CCSpriteBatchNode*)[self getChildByTag:kSpriteManager];
CCSprite *ant = (CCSprite*)[spriteManager getChildByTag:currentAntTag];

CGRect abc= CGRectInset([ant boundingBox],30, 85);

if(CGRectContainsPoint(abc,touchLocation))  
{

    ant.visible=NO;
}
}

also i have 3 methods which are called every few seconds in which i create these CCSpriteFrameCache and CCSpriteBatchNode object to make my character run while it animates. will it be too heavey to crate caches every second like this or should i create them in init method and just run the action on CCSprite here??

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

吹梦到西洲 2024-12-04 01:54:09

CCSprite 的子类。然后在它的 init 中:

[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:NO];

实现 ccTouch 方法:

- (BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event;
- (void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event;
- (void) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event;
- (void) ccTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

现在您有两个选择。您可以使用委托变量来回调或使用 NSNotifications。在这里使用回调,速度更快。

// in your @interface
id touchDelegate; // between the {}'s

@property (nonatomic, assign) id touchDelegate;

在你的游戏类中,当你创建坏人时:

NewCCSprite = newSprite = [NewCCSprite init];
newSprite.touchDelegate = self;

当你触摸一个坏人时:

- (void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event {
    if (self.touchDelegate == nil) return;
    [self.touchDelegate performSelector:@selector(touched:) withDelay:0.0f];
}

最后,你的 touch: 方法:

- (void) touch:(id)sender {
    NewCCSprite* sprite = (NewCCSprite*)sender;
    // hide/kill off/etc
}

Subclass CCSprite. Then in it's init:

[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:NO];

Implement the ccTouch methods:

- (BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event;
- (void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event;
- (void) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event;
- (void) ccTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

Now you have two options. You can have a delegate variable to callback or use NSNotifications. Go with the callback here, it's faster.

// in your @interface
id touchDelegate; // between the {}'s

@property (nonatomic, assign) id touchDelegate;

Inside your game class, when you're creating your bad guys:

NewCCSprite = newSprite = [NewCCSprite init];
newSprite.touchDelegate = self;

And when you touch one:

- (void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event {
    if (self.touchDelegate == nil) return;
    [self.touchDelegate performSelector:@selector(touched:) withDelay:0.0f];
}

Finally, your touch: method:

- (void) touch:(id)sender {
    NewCCSprite* sprite = (NewCCSprite*)sender;
    // hide/kill off/etc
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文