如何发射激光?
How to Shoot a Laser?
我一直在学习 C,并且正在尝试使用 SDL 来稍微改变一下。我想制作一个简单的 space 射击游戏,其中 space 条会导致玩家的小船发射激光。
我目前关于这将如何工作的想法是会有一个 "Laser" 结构,它包含精灵表面和精灵矩形。
struct Laser {
SDL_Surface *sprite;
SDL_Rect rcSprite;
};
现在我需要一个函数来创建我的 "Laser" 结构。它将分配内存、加载 .BMP 精灵图像并设置激光的起始位置。然后它将 return 指向新创建的结构的指针。
struct Laser *fireLaser(char *sprite, int x, int y) {
struct Laser *l = malloc(sizeof(struct Laser));
assert(l != NULL);
l->sprite = loadImage(sprite);
l->rcSprite.x = x;
l->rcSprite.y = y;
return l;
}
现在的想法是在按下 space 条时让激光发射。按照我 认为 这会起作用的方式,这意味着需要为每个激光发射调用 "fireLaser" 函数。
if(keystate[SDLK_SPACE]) {
lasers[i] = fireLaser("laser.bmp", player->rcSprite.x, player->rcSprite.y);
drawLaser(lasers[i]);
i += 1;
}
上面的代码会调用 "drawLaser" 函数,将新创建的 Laser 结构传递给它。
void drawLaser(struct Laser *laser) {
while(laser->rcSprite.y > 0) {
SDL_BlitSurface(laser->sprite, NULL, screen, &laser->rcSprite);
laser->rcSprite.y -= 1;
}
}
当我 运行 这是我期望发生的事情是我会按住 space 条,因为没有 开火频率 , 就会从上升的船中汲取源源不断的水流
代码可以编译,但是当我 运行 它并按下 space 栏时,会绘制出预期的直白,但程序崩溃(分段错误)!我发现(主要是偶然地)如果我重新编写代码以在创建结构后将索引变量“i”设置回 0(如下所示),程序将不会崩溃。
if(keystate[SDLK_SPACE]) {
i = 0;
lasers[i] = fireLaser("laser.bmp", player->rcSprite.x, player->rcSprite.y);
drawLaser(lasers[i]);
i += 1;
}
现在我在屏幕上垂直绘制了一条长白线。
我敢肯定这可能不是一个很好的方法,但我开始沿着这条路走下去,我正在努力坚持下去!我现在的问题是,为什么我需要重置“i”变量,否则程序会崩溃?我还必须问,这是否是完成发射激光的有效方法。我是在正确的道路上,还是应该停下来重新评估?
虽然我不能给你一个准确的答案,因为我不知道整个代码,但我可以解释它应该如何工作以及你的方法与正常方法有何不同。
正常的游戏循环是这样工作的:
while (!exiting) {
render();
logic();
events();
}
现在,render()
应该绘制东西,logic()
应该移动东西,events()
应该轮询外部输入(例如键盘)并相应地修改东西。
在您的代码中,您在代码的 events()
部分绘制激光。这是不正确的,你在混合东西。一个好的设计应该是这样的:
static size_t MAX_LASERS = 50;
static size_t laserCount;
static laser* lasers;
void setup()
{
lasers = calloc(MAX_LASERS, sizeof(laser));
laserCount = 0;
}
void draw()
{
for (int i = 0; i < laserCount; ++i)
drawLaser(lasers[i]);
}
void logic()
{
for (int i = 0; i < laserCount; ++i)
{
moveLaser(lasers[i]);
}
for (int i = 0; i < laserCount; ++i)
{
if (outsideScreen(lasers[i])
removeLaser(lasers[i])
}
}
void events()
{
...
if(keystate[SDLK_SPACE]) {
if (laserCount < MAX_LASERS)
laser[laserCount++] = generateLaser(...);
}
}
我一直在学习 C,并且正在尝试使用 SDL 来稍微改变一下。我想制作一个简单的 space 射击游戏,其中 space 条会导致玩家的小船发射激光。
我目前关于这将如何工作的想法是会有一个 "Laser" 结构,它包含精灵表面和精灵矩形。
struct Laser {
SDL_Surface *sprite;
SDL_Rect rcSprite;
};
现在我需要一个函数来创建我的 "Laser" 结构。它将分配内存、加载 .BMP 精灵图像并设置激光的起始位置。然后它将 return 指向新创建的结构的指针。
struct Laser *fireLaser(char *sprite, int x, int y) {
struct Laser *l = malloc(sizeof(struct Laser));
assert(l != NULL);
l->sprite = loadImage(sprite);
l->rcSprite.x = x;
l->rcSprite.y = y;
return l;
}
现在的想法是在按下 space 条时让激光发射。按照我 认为 这会起作用的方式,这意味着需要为每个激光发射调用 "fireLaser" 函数。
if(keystate[SDLK_SPACE]) {
lasers[i] = fireLaser("laser.bmp", player->rcSprite.x, player->rcSprite.y);
drawLaser(lasers[i]);
i += 1;
}
上面的代码会调用 "drawLaser" 函数,将新创建的 Laser 结构传递给它。
void drawLaser(struct Laser *laser) {
while(laser->rcSprite.y > 0) {
SDL_BlitSurface(laser->sprite, NULL, screen, &laser->rcSprite);
laser->rcSprite.y -= 1;
}
}
当我 运行 这是我期望发生的事情是我会按住 space 条,因为没有 开火频率 , 就会从上升的船中汲取源源不断的水流
代码可以编译,但是当我 运行 它并按下 space 栏时,会绘制出预期的直白,但程序崩溃(分段错误)!我发现(主要是偶然地)如果我重新编写代码以在创建结构后将索引变量“i”设置回 0(如下所示),程序将不会崩溃。
if(keystate[SDLK_SPACE]) {
i = 0;
lasers[i] = fireLaser("laser.bmp", player->rcSprite.x, player->rcSprite.y);
drawLaser(lasers[i]);
i += 1;
}
现在我在屏幕上垂直绘制了一条长白线。
我敢肯定这可能不是一个很好的方法,但我开始沿着这条路走下去,我正在努力坚持下去!我现在的问题是,为什么我需要重置“i”变量,否则程序会崩溃?我还必须问,这是否是完成发射激光的有效方法。我是在正确的道路上,还是应该停下来重新评估?
虽然我不能给你一个准确的答案,因为我不知道整个代码,但我可以解释它应该如何工作以及你的方法与正常方法有何不同。
正常的游戏循环是这样工作的:
while (!exiting) {
render();
logic();
events();
}
现在,render()
应该绘制东西,logic()
应该移动东西,events()
应该轮询外部输入(例如键盘)并相应地修改东西。
在您的代码中,您在代码的 events()
部分绘制激光。这是不正确的,你在混合东西。一个好的设计应该是这样的:
static size_t MAX_LASERS = 50;
static size_t laserCount;
static laser* lasers;
void setup()
{
lasers = calloc(MAX_LASERS, sizeof(laser));
laserCount = 0;
}
void draw()
{
for (int i = 0; i < laserCount; ++i)
drawLaser(lasers[i]);
}
void logic()
{
for (int i = 0; i < laserCount; ++i)
{
moveLaser(lasers[i]);
}
for (int i = 0; i < laserCount; ++i)
{
if (outsideScreen(lasers[i])
removeLaser(lasers[i])
}
}
void events()
{
...
if(keystate[SDLK_SPACE]) {
if (laserCount < MAX_LASERS)
laser[laserCount++] = generateLaser(...);
}
}