iPhone射击游戏的子弹物理!

3

我正在制作一款新的射击游戏,类似于我小时候最喜欢的《Galaga》。

这是我用于子弹物理的代码:

-(IBAction)shootBullet:(id)sender{
imgBullet.hidden = NO;
timer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(fireBullet) userInfo:Nil repeats:YES];
}

-(void)fireBullet{
imgBullet.center = CGPointMake(imgBullet.center.x + bulletVelocity.x , imgBullet.center.y + bulletVelocity.y);
if(imgBullet.center.y <= 0){
 imgBullet.hidden = YES;
 imgBullet.center = self.view.center;
 [timer invalidate];
}
}

无论如何,显而易见的问题是一旦子弹离开屏幕,它的中心就会被重置,因此我正在为每次“射击”按钮按下重复使用同一个子弹对象。

理想情况下,我希望用户可以在不导致程序崩溃的情况下连续按下“射击”按钮。如何修改现有代码以便在每次按下按钮时生成一个新的子弹对象,并在其离开屏幕或与敌人碰撞后消失?

感谢您提供的任何帮助!

1个回答

3
您肯定不希望计时器为每个子弹、陨石、爆炸动画等触发,这会非常糟糕。
大多数游戏都基于所谓的有限状态机。本质上,这是一种跟踪游戏状态(例如PLAYING、END_GAME、WAITING_FOR_OTHERPLAYERS)并根据其做出决策的方法。通过一个计时器反复调用此方法,就像您为子弹所做的那样。我建议您设置游戏就像这样。现在关于这些子弹,当玩家按下开火按钮时,将另一个子弹添加到需要随时间调整自身的事物数组中。然后,每次通过游戏循环时,当状态指示时,迭代它们并告诉它们“updateYourself”。这也是您将执行碰撞检测并启动爆炸动画、删除已离开屏幕的对象等的位置。
希望这可以帮助您,
Kenny
更新:一些伪代码(即无法编译),应该更好地解释了事情。请注意,我总是喜欢传递游戏时间,以便对象不知道实际时间,这是很好的实践,因为它不仅允许重新动画游戏会话(对于调试非常有用,有时可以成为一个很棒的功能),而且意味着所有对象都获得相同的时间,不会因为它在数组中的位置而与第一个对象相差毫秒。今天的热门提示!!太好了!!
// implementation in MainGame class

  // After application has had its lunch....
- (void) applicationDidFinishLunching {
    gameTimer = [NSTimer scheduledTimerWithTimeInterval:GAMETIME_INTERVAL target:self selector:@selector(myGameLoop)    userInfo:nil repeats:TRUE];
}

- (void) startGame {
    gameState = PLAYING;
// And most likely a whole bunch of other stuff
}

NSMutableArray * mTransientObjects;

- (void) fireButtonPressed:(float) atY andTime:(NSTimeInterval) fireTime {
    // I will assume only a "Y" variable for this game, Galaga style.
    Bullet * aBullet = [[Bullet alloc] initWithY:atY atTime:fireTime];
    [mTransientObjects addObject:aBullet];

    [aBullet release];
}

// myGameLoop is called via the timer above firing at whatever interval makes sense for your game
- (void) myGameLoop {

switch (gameState) {
    case PLAYING:
        for (nextObject in mTransientObjects)
            [nextObject updateYourself:gameTime];

        // Now check for dead object, add explosions to mTransientObjects
        // Remove dead things, add anything new etc.
            etc.
}

// implementation in Bullet subclass
// Bullet is SubClass of your overall Sprite class
- (void) updateYourself:(NSTimerInterval) timeInterval  {
// Do any movement, change of animation frame, start sound....etc. etc.
}

我明白游戏状态的问题,这不应该是个问题。然而,当用户按下“射击”按钮时,你所描述的情况仍让我有些困惑。你能不能详细解释一下?非常感谢你迄今为止提供的帮助! - user298261
还有问题...能否再给我一点解释,拜托? :P - user298261
还是有点困惑。:(我正在尝试弄清楚为什么要实现数组以及它应该做什么。能否提供更多细节?我对伪代码的其余部分非常了解。此外,“fire button pressed”方法是否代表IBAction?谢谢! - user298261
第一个问题:为什么要实现数组,它的作用是什么。- 我想提问可能是实现理解的最好方式。您有许多相同类别的未知对象,并且需要随时间对每个对象执行特定操作。哪种数据结构或设计模式可以解决此问题?如果您想使用Interface Builder连接UI,则Fire按钮按下可以是IBAction。但更多的是展示创建子弹并将其放置在精灵数组中的想法。 - gnasher

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接