C Space 侵略者敌人移动
C Space Invaders enemy movement
我必须使用 SDL 库用 C 语言为大学编写 space 入侵者游戏的克隆,因为 graphics.I 我对 C 和一般编程还很陌生,所以我很费力。现在我有一排敌人,我正在努力让它正确移动。这是外星人移动的功能,它检查与 right/left 墙(在 window 边缘附近的 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 是一个结构体。
LEFT/RIGHT 代表移动方向(很明显)[enum Direction {LEFT, RIGHT};]。我在我的 alien1 结构枚举方向目录和 load_game 函数中我将它设置为 RIGHT.
typedef struct
{
Player player;
Rightwall rightwall;
Leftwall leftwall;
Alien1 alien1[HMALIENS];
SDL_Texture *bulet;
SDL_Texture *ship;
SDL_Texture *Alien1;
SDL_Renderer *renderer;
} GameState;
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);
}
}
可能是这样的:
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
。当你开始消灭外星人时,
你必须追踪第一个(最左边)和最后一个(最右边)活着的外星人,并将它们用于碰撞测试。
您的缩进和格式有点不对,这使得代码更难阅读。格式化很重要,当您的代码变得更复杂时,格式化会更加重要。
没有重写你的代码,问题是你已经把第一个外星人([0])移到了左边,
if (game->alien1[i].dir==LEFT)
game->alien1[i].x -= 10;
and then 你正在做碰撞测试并标记它们都向右移动,但是循环继续 [1..10],而 [0] 已经感动了。
我必须使用 SDL 库用 C 语言为大学编写 space 入侵者游戏的克隆,因为 graphics.I 我对 C 和一般编程还很陌生,所以我很费力。现在我有一排敌人,我正在努力让它正确移动。这是外星人移动的功能,它检查与 right/left 墙(在 window 边缘附近的 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 是一个结构体。 LEFT/RIGHT 代表移动方向(很明显)[enum Direction {LEFT, RIGHT};]。我在我的 alien1 结构枚举方向目录和 load_game 函数中我将它设置为 RIGHT.
typedef struct
{
Player player;
Rightwall rightwall;
Leftwall leftwall;
Alien1 alien1[HMALIENS];
SDL_Texture *bulet;
SDL_Texture *ship;
SDL_Texture *Alien1;
SDL_Renderer *renderer;
} GameState;
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);
}
}
可能是这样的:
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
。当你开始消灭外星人时,
你必须追踪第一个(最左边)和最后一个(最右边)活着的外星人,并将它们用于碰撞测试。
您的缩进和格式有点不对,这使得代码更难阅读。格式化很重要,当您的代码变得更复杂时,格式化会更加重要。
没有重写你的代码,问题是你已经把第一个外星人([0])移到了左边,
if (game->alien1[i].dir==LEFT)
game->alien1[i].x -= 10;
and then 你正在做碰撞测试并标记它们都向右移动,但是循环继续 [1..10],而 [0] 已经感动了。