C Space Invaders敌人的运动

时间:2016-01-05 22:49:37

标签: c sdl

我必须使用SDL库为图形编写C语言大学的太空入侵者游戏的克隆。我对C和编程很新,所以我很努力。现在我有一排敌人,我正试图让它正确移动。这是外星人移动的功能,它检查与右/左墙的碰撞(窗口边缘附近的SDL_Rects),如果发生这种情况,敌人会向相反方向移动一条线。问题是它对除了第一个以外的所有十个敌人都可以。每当与左墙发生碰撞时,第一个外星人会从其他人身上移开一点而不是像我想要的那样在一个街区中移动。我注意到如果我将move_aliens函数中的第一个for循环更改为从i = 11和i--开始,那么最后一列中的敌人也会发生同样的事情。但我还是不知道如何解决它。 如果有人能告诉我我做错了什么,给我一个想法或解决,我将不胜感激:)。 我上传了一段发生http://sendvid.com/dt1reizc

的视频
void move_down (GameState *game)
{
    int i=0; 
    for(; i < HMALIENS; i++)
        game->alien1[i].y += 25;
}

int collided(int a1, int b1, int a2, int b2, int width1, 
             int height1, int width2, int height2)
 {
     return (!((a1 > (a2+width2)) || (a2 > (a1+width1)) || 
            (b1 > (b2+height2)) || (b2 > (b1+height1))));
 }


void move_aliens(GameState *game)
{
    int i=0;
    for(; i < HMALIENS; i++)
    {
    if (game->alien1[i].dir==LEFT)
       game->alien1[i].x -= 10;
    if (game->alien1[i].dir==RIGHT)
       game->alien1[i].x += 10;

    if (collided(game->alien1[i].x, game->alien1[i].y, 
        game->leftwall.x, game->leftwall.y, 50, 50, 1, 600))
     {
         int i = 0;

         for(; i < HMALIENS; i++)
            game->alien1[i].dir=RIGHT;
         move_down(game);
     }
  }

if(collided(game->alien1[i].x, game->alien1[i].y, game->rightwall.x, 
   game->rightwall.y, 50, 50, 1, 600))
{
    int i = 0;
    for(; i < HMALIENS; i++)
        game->alien1[i].dir=LEFT;

     move_down(game);
 }
}
}

//编辑 HMALIENS只是一个常数(11),一开始是活生生的敌人 GameState是一个结构。 左/右代表运动方向(非常明显)[enum Direction {LEFT,RIGHT};]。我有我的alien1结构枚举方向目录和load_game函数我设置为右的函数。

typedef struct
{
    Player player;
    Rightwall rightwall;
    Leftwall leftwall;
    Alien1 alien1[HMALIENS];
    SDL_Texture *bulet;
    SDL_Texture *ship;
    SDL_Texture *Alien1;
    SDL_Renderer *renderer;
 } GameState;

3 个答案:

答案 0 :(得分:1)

typedef enum{
    LEFT,
    RIGHT
}GAME_DIRECTION;

int dir=LEFT;

#define SPRITE_WIDTH    50
#define SPRITE_HEIGHT   50
#define BOTTOM_LINE     600


void move_down (GameState *game)
{
    int i; 
    for(i=0; i < HMALIENS; i++)
        game->alien1[i].y += 25;

}

void do_slide(GameState *game)
{
    int i; 
    for(i=0; i < HMALIENS; i++)
        game->alien1[i].x += dir?10:-10;

}


int collided(GameState *game)
 {
    int i;

    for(i=0; i < HMALIENS; i++){
        if(
            game->alien1[i].x <= game->leftwall.x                 || 
            game->alien1[i].x >= game->rightwall.x +SPRITE_WIDTH  || 
            game->alien1[i].y >= BOTTOM_LINE - SPRITE_HEIGHT
        )
        return true;
    } 
    return false;
 }


void move_aliens(GameState *game)
{
    if(collided(game)){
        move_down (game);
        dir=!dir;         // update direction; 
    }else{
        do_slide (game);
    }
}

答案 1 :(得分:1)

如果不重写代码,问题是你已经移动了第一个外星人([0]),

if (game->alien1[i].dir==LEFT)
       game->alien1[i].x -= 10;

然后你正在进行碰撞测试并标记所有这些以向右移动,但循环继续[1..10],而[0]已经移动。

答案 2 :(得分:0)

可能是这样的:

void move_aliens(GameState *game)
{
    int i=0;
    for(; i < HMALIENS; i++)
    {
        if (game->alien1[i].dir==LEFT)
            game->alien1[i].x -= 10;
        if (game->alien1[i].dir==RIGHT)
            game->alien1[i].x += 10;
    }

    if (collided(
        game->alien1[0].x, game->alien1[0].y,
        game->leftwall.x, game->leftwall.y,
        50, 50, 1, 600))
    {
        int i = 0;

        for(; i < HMALIENS; i++)
            game->alien1[i].dir=RIGHT;

         move_down(game);
    }

    if(collided(
        game->alien1[HMALIENS-1].x, game->alien1[HMALIENS-1].y,
        game->rightwall.x, game->rightwall.y,
        50, 50, 1, 600))
    {
        int i = 0;
        for(; i < HMALIENS; i++)
            game->alien1[i].dir=LEFT;

        move_down(game);
    }
}

我试图做出最小的改动。但@ milevyo更广泛的重写看起来也不错。

问题,我认为(仅仅是从外观上看),你是否在循环中进行了左碰撞测试,所以当它碰到时,运动就会失去同步。

同样非常微妙的是,正确的碰撞测试使用了前一个循环中的i,它恰好索引了最后一个元素(最右边的外星人)。我改为明确使用HMALIENS - 1。当你开始摧毁外星人时 你必须追踪第一个(最左边)和最后一个(最右边)的外星人,并用它们进行碰撞测试。

你的缩进和格式有点偏差,这使代码更难阅读。格式化很重要,当代码变得更复杂时,格式化也会更加复杂。