c - 检测到我的角色与物体发生碰撞后,角色无法再移动?

标签 c sdl game-physics sdl-2

我正在创建一个游戏,您可以在屏幕中间沿 x 轴移动一个点,并且会有一些元素从顶部掉落,您需要尝试躲避,显然为此我需要某种形式我已经实现了碰撞检测,并且它似乎工作正常。

我的问题是,当角色(点)移向对象并发生碰撞时,您无法再移动角色,它只是停留在固定位置。当角色与窗口边缘碰撞时,这种情况不会发生,但是正如您将在下面看到的,窗口碰撞和对象碰撞都有相同的代码运行。

主游戏循环:

  while(running) {

    // Queue of the events happening
    while(SDL_PollEvent(&event)) {
      if(event.type == SDL_QUIT) {
        running = false;
      }
      else if(event.type == SDL_KEYDOWN && event.key.repeat == 0) {
        switch(event.key.keysym.sym) {
          case SDLK_UP:
            //sprite->yVel -= VELOCITY;
            break;
          case SDLK_DOWN:
            //sprite->yVel += VELOCITY;
            break;
          case SDLK_LEFT:
            sprite->xVel -= VELOCITY;
            break;
          case SDLK_RIGHT:
            sprite->xVel += VELOCITY;
            break;
        }
     }
     else if(event.type == SDL_KEYUP && event.key.repeat == 0) {
       switch(event.key.keysym.sym) {
         case SDLK_UP:
           //sprite->yVel += VELOCITY;
           break;
         case SDLK_DOWN:
           //sprite->yVel -= VELOCITY;
           break;
         case SDLK_LEFT:
           sprite->xVel += VELOCITY;
           break;
         case SDLK_RIGHT:
           sprite->xVel -= VELOCITY;
           break;
       }
     }
   } // Poll event loop

   float timeStep = getTicks(ticks) / (float) 1000;
   move(sprite, timeStep, WINDOW_WIDTH, WINDOW_HEIGHT, head);

   startTimer(ticks);

   // Clear window then draw image
   SDL_RenderClear(rend);
   SDL_RenderCopy(rend, background->element, NULL, NULL);
   SDL_RenderCopy(rend, sofa->element, NULL, &sofa->dest);

   setPosition(sprite, sprite->xPos, sprite->yPos);
   SDL_RenderCopy(rend, sprite->element, NULL, &sprite->dest);

   SDL_RenderPresent(rend);
   capFrameRate(timeStep);
} // Main game loop

移动和碰撞功能:

void move(Character *c, float timeStep, const int WIDTH, const int HEIGHT, Scene *scene) {
  c->xPos += c->xVel * timeStep;

  // Collision check for the walls
  if(((c->xPos < 0) || (c->xPos + c->dest.w > WIDTH)) || (collision(c, scene))) {
    c->xPos -= c->xVel * timeStep;
  }
}

bool collision(Character *character, Scene *scene) {
  if(SDL_HasIntersection(&character->dest, &scene->element->dest)) {
    return true;
  }
  else {
    if(scene->nextElement == NULL) {
      return false;
    }
    else {
      collision(character, scene->nextElement);
    }
  }
  return false;
}

由于会有一些元素从屏幕顶部落下,我已经为这些元素实现了一个链接列表,因此为什么要在碰撞函数上进行递归。如果有人知道为什么角色在碰撞后不移动,我将非常感激。

最佳答案

我的猜测:您的 collision(c, scene) 方法查看当前时间步长的碰撞。在这种情况下,move 函数中的 if 语句

                                                      //  \/ This here is the problem -- if you're currently colliding with an object you don't allow any movement, even if you're moving out of the object  
if(((c->xPos < 0) || (c->xPos + c->dest.w > WIDTH)) || (collision(c, scene))) {
    c->xPos -= c->xVel * timeStep;
}

玩家在与物体碰撞后将无法移动。解决方案是在采取步骤之前检查是否存在碰撞:

float newX = c->xPos + c->xVel*timeStep;
float newY = ...;
if (!collision(newX, newY, scene)) {
    c->xPos = newX;
    ...
}

关于c - 检测到我的角色与物体发生碰撞后,角色无法再移动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43365730/

相关文章:

c - 如何在C中获取数组的长度? "sizeof"是解决方案吗?

c - 为什么我们需要递归?

c - 声明任何标准变量时 SDL 崩溃

c++ - SDL 插件库未正确链接

swift - Swift 中的 SpriteKit 物理 - 球在墙上滑动而不是反射

ios - 如何加载内存中的文件以获得更好的场景转换?

ios - 未调用 Swift func didBeginContact

c - 用 C 语言编写 TicTacToe 程序很困难

c++ - 分配给 char* 的内存

C++/SDL 'void*' 不是点对对象类型