我正在使用 SDL 开发一款游戏,目前正在致力于实现角色移动和重力。但是,我遇到了一个问题,即我的代码的特定部分未按预期运行。
我面临的问题围绕着向我的玩家角色施加重力。我已经实现了一个PhysicsEngine 类,负责管理重力和角色运动。在此类的更新方法中,我增加了 yVelocity 来模拟重力。然而,尽管观察到 yVelocity 正确增加,但限制速度的后续代码块并未按预期执行。
采取的调试措施: 我已采取以下步骤来调试该问题:
添加了调试输出语句(std::cout)来跟踪关键变量的值,包括 yVelocity。 观察到 yVelocity 在调试输出中正确增加,但更新角色位置的后续代码块(yVelocityAFTER 部分)未按预期执行。 分析了条件 if (yVelocity > MAX_FALL_SPEED) 并发现在游戏过程中的某个时刻应该满足该条件,但该块中的代码并未运行。
player_character 类:(我在其中绘制玩家)
void PlayerCharacter::draw(SDL_Renderer* renderer)
{
// Define an array of colors corresponding to each body part
std::vector<SDL_Color> bodyPartColors = {
COLOR_DEEP_ORANGE, COLOR_DEEP_ORANGE,
COLOR_ROYAL_BLUE, COLOR_ROYAL_BLUE,
COLOR_WHITE, COLOR_DEEP_FOREST_GREEN,
COLOR_SALMON, COLOR_CRIMSON,
COLOR_DARK_PURPLE, COLOR_DARK_PURPLE
};
color.setRenderDrawColor(renderer, COLOR_ALPHA);
SDL_RenderFillRect(renderer, &boundingBox);
color.setRenderDrawColor(renderer, bodyPartColors[0]);
for (int i = 0; i < bodyPartColors.size() && i <bodyPartColors.size(); i++)
{
color.setRenderDrawColor(renderer, bodyPartColors[i]);
const auto& part = bodyParts[i];
SDL_Rect partRect = {boundingBox.x + part.x, boundingBox.y + part.y, part.w, part.h};
SDL_RenderFillRect(renderer, &partRect);
}
}
physical_engine 类:(我更新游戏的地方)
void PhysicsEngine::update(const int WINDOW_WIDTH, const int WINDOW_HEIGHT)
{
checkCollisionWithGround(WINDOW_HEIGHT);
checkCollisionWithWalls(WINDOW_WIDTH, WINDOW_HEIGHT);
playercharacter.boundingBox.x += xVelocity;
std::cout << "BoundingBoxY BEFORE: " << playercharacter.boundingBox.y << std::endl;
playercharacter.boundingBox.y += yVelocity;
std::cout << "BoundingBoxY AFTER: " << playercharacter.boundingBox.y << std::endl;
//movePlayerLeft(100, false);
//movePlayerRight(100, false);
//move(0, 10);
这就是我上面提到的问题发生的地方:
// Gravity conts
const double GRAVITY = 0.5;
const double MAX_FALL_SPEED = 10;
yVelocity += GRAVITY;
std::cout << "yVelocityBEFORE: " << yVelocity << std::endl;
if (yVelocity > MAX_FALL_SPEED)
{
yVelocity = MAX_FALL_SPEED;
std::cout << "yVelocityAFTER: " << yVelocity << std::endl;
}
for (auto& part : playercharacter.bodyParts)
{
part.x += xVelocity;
part.y += yVelocity;
}
}
边界框语句的控制台输出:
BoundingBoxY BEFORE: 720
BoundingBoxY AFTER: 720
BoundingBoxY BEFORE: 720
BoundingBoxY AFTER: 720
Velocity 语句的控制台输出:(如您所见,yVelocityAFTER 不输出)
yVelocityBEFORE: 0.5
yVelocityBEFORE: 0.5
yVelocityBEFORE: 0.5
yVelocityBEFORE: 0.5
类输入处理:
void InputHandler::eventHandling(bool& isLeftKeyPressed, bool& isRightKeyPressed)
{
bool quit = false;
SDL_Event e;
// Event handling
while (SDL_PollEvent(&e) != 0)
{
if (e.type == SDL_QUIT)
{
quit = true;
std::cout << "Quit detected";
}
else if (e.type == SDL_KEYDOWN)
{
switch (e.key.keysym.sym)
{
case SDLK_UP:
physicsengine.playerJump();
break;
case SDLK_LEFT:
isLeftKeyPressed = true;
std::cout << "LEFT KEY PRESSED";
break;
case SDLK_RIGHT:
isRightKeyPressed = true;
std::cout << "RIGHT KEY PRESSED";
break;
default:
break;
}
}
else if (e.type == SDL_KEYUP)
{
switch (e.key.keysym.sym)
{
case SDLK_LEFT:
isLeftKeyPressed = false;
break;
case SDLK_RIGHT:
isRightKeyPressed = false;
break;
default:
break;
}
}
}
}
run_game 类:
void Game::runGame(SDL_Renderer* renderer, int WINDOW_WIDTH, int WINDOW_HEIGHT)
{
while (!quit)
{
inputhandler.eventHandling(isLeftKeyPressed, isRightKeyPressed);
physicsengine->update(WINDOW_WIDTH, WINDOW_HEIGHT);
if (inputhandler.isLeftKeyPressed)
{
playercharacter->move(-1, 0); // Adjust the amount as needed
}
color.setRenderDrawColor(renderer, COLOR_PERIWINKLE_BLUE);
SDL_RenderClear(renderer);
// Draw game objects here
// Drawing
playercharacter->draw(renderer);
enemy->drawEnemy(renderer, WINDOW_HEIGHT);
enemy->enemyMovment(renderer, WINDOW_WIDTH);
hairline.drawHair(renderer);
SDL_RenderPresent(renderer);
}
}
任何帮助将不胜感激。
从代码中我可以看到,yVelocity 似乎在再次递增之前不断重置。我看不到它是在哪里声明的,但是如果它是在函数内部声明的,那么该变量将被重置,然后在每次调用该函数时重新声明。
void SomeFunction() {
double yVelocity = 0.0;
//some code
yVelocity += 0.5;
std::cout << yVelocity << std::endl;
//more code
}
int main() {
//some code
while(true) {
SomeFunction();
}
return 0;
}
这将继续打印 0.5,因为 yVelocity 将被声明、递增,然后超出范围、重置,然后重新声明。