Closed. This question is off-topic。它当前不接受答案。
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            想改善这个问题吗? Update the question,所以它是on-topic,用于堆栈溢出。
                        
                        3年前关闭。
                                                                                            
                
        
我一直在学习C,并且尝试使用SDL进行一些改动。我想做一个简单的太空射击游戏,其中空格键使玩家的小飞船发射激光。

我目前关于如何工作的思考过程是有一个“激光”结构,其中包含精灵表面和精灵矩形。

struct Laser {
    SDL_Surface *sprite;
    SDL_Rect rcSprite;
};


现在,我需要一个函数来创建我的“激光”结构。它将分配内存,加载.BMP精灵图像并设置激光器的起始位置。然后它将返回一个指向新创建的结构的指针。

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;
}


现在的想法是在按下空格键时让激光发射。按照我认为的工作原理,这意味着需要为每个发射的激光调用“ 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;
    }
}


我希望在执行此操作时会发生的事情是将空格键保持向下,并且由于没有开火频率,因此会从上升的船上汲取稳定的水流。

代码可以编译,但是当我运行它并按空格键时,会绘制出预期的白色,但是程序崩溃了(分段错误)!我发现(大部分是偶然的),如果在构造该结构后重新编写代码以将索引变量“ 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 - 如何发射激光? ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35191257/

10-10 13:33