因此,我一直在为我的2D Platformer开发一个游戏系统/引擎,当我按下w、a、s或d键时,它在主循环事件中调用时不会移动。
这里是我所有的项目文件和我写的一切:main.cpp:
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <iostream>
#include <vector>
#include "RenderWindow.hpp"
#include "Entity.hpp"
#include "Utils.hpp"
int main(int argc, char const *argv[])
{
if (SDL_Init(SDL_INIT_VIDEO) > 0)
std::cout << "ERROR: SDL_Init() HAS FAILED: SDL_ERROR => " << SDL_GetError() << std::endl;
if (!(IMG_Init(IMG_INIT_PNG)))
std::cout << "ERROR: IMG_Init() HAS FAILED: SDL_ERROR => " << SDL_GetError() << std::endl;
RenderWindow window("GAME v1.0", 1280, 720);
SDL_Texture* grassTexture = window.loadTexture("res/gfx/ground_grass.png");
SDL_Texture* playerTexture = window.loadTexture("res/gfx/ghost.png");
std::vector<Entity> platforms = {Entity(Vector2f(0, 30), grassTexture),
Entity(Vector2f(30, 30), grassTexture),
Entity(Vector2f(30, 30), grassTexture),
Entity(Vector2f(60, 30), grassTexture)};
Entity player(Vector2f(30, 8), playerTexture);
bool gameRunning = true;
SDL_Event event;
const float timeStep = 0.01f;
float accumulator = 0.0f;
float currentTime = utils::hireTimeInSeconds();
while(gameRunning)
{
int startTicks = SDL_GetTicks();
float newTime = utils::hireTimeInSeconds();
float frameTime = newTime - currentTime;
currentTime = newTime;
accumulator += frameTime;
while(accumulator >= timeStep)
{
// Get out controls and events
while(SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
{
gameRunning = false;
break;
// window.freeTexture(grassTexture);
// window.freeTexture(playerTexture);
}
// Add code to move the player texture
const Uint8* currentKeyStates = SDL_GetKeyboardState(NULL);
Vector2f& playerPos = player.getPos();
if(currentKeyStates[SDL_SCANCODE_W]) {
playerPos.y -= 1;
break;
}
if(currentKeyStates[SDL_SCANCODE_S]) {
playerPos.y += 1;
break;
}
if(currentKeyStates[SDL_SCANCODE_A]) {
playerPos.x -= 1;
break;
}
if(currentKeyStates[SDL_SCANCODE_D]) {
playerPos.x += 1;
break;
}
}
window.clear();
for (Entity& e : platforms)
{
window.render(e);
window.render(player);
}
window.display();
// // Add code to move the player texture
// const Uint8* currentKeyStates = SDL_GetKeyboardState(NULL);
// Vector2f& playerPos = player.getPos();
// if(currentKeyStates[SDL_SCANCODE_W]) {
// playerPos.y -= 1;
// }
// if(currentKeyStates[SDL_SCANCODE_S]) {
// playerPos.y += 1;
// }
// if(currentKeyStates[SDL_SCANCODE_A]) {
// playerPos.x -= 1;
// }
// if(currentKeyStates[SDL_SCANCODE_D]) {
// playerPos.x += 1;
// }
//playerPos.print();
accumulator -= timeStep;
// std::cout << accumulator << std::endl;
}
// const float alpha = accumulator / timeStep; // 50%?
// window.freeTexture(grassTexture);
// window.freeTexture(playerTexture);
int frameTicks = SDL_GetTicks() - startTicks;
if (frameTicks < 1000 / window.getRefreshRate())
SDL_Delay(100 / window.getRefreshRate() - frameTicks);
}
window.cleanUp();
SDL_Quit();
return 0;
}
renderwindow.hpp:
#pragma once
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include "Entity.hpp"
class RenderWindow
{
public:
RenderWindow(const char* p_title, int p_w, int p_h);
SDL_Texture* loadTexture(const char* p_filePath);
int getRefreshRate();
void cleanUp();
void clear();
void render(Entity& p_entity);
//void freeTexture(SDL_Texture* p_tex);
void display();
private:
SDL_Window* window;
SDL_Renderer* renderer;
};
renderwindow.cpp:
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <iostream>
#include "RenderWindow.hpp"
#include "Entity.hpp"
RenderWindow::RenderWindow(const char* p_title, int p_w, int p_h)
:window(NULL), renderer(NULL)
{
window = SDL_CreateWindow(p_title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, p_w, p_h, SDL_WINDOW_SHOWN);
if (window == NULL)
{
std::cout << "ERROR: Window has failed to init! SDL_Error: " << SDL_GetError() << std::endl;
}
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
}
SDL_Texture* RenderWindow::loadTexture(const char* p_filePath)
{
SDL_Texture* texture = NULL;
texture = IMG_LoadTexture(renderer, p_filePath);
if (texture == NULL)
std::cout << "ERROR: Failed to load texture! SDL_Error: " << SDL_GetError() << std::endl;
return texture;
}
int RenderWindow::getRefreshRate()
{
int displayIndex = SDL_GetWindowDisplayIndex(window);
SDL_DisplayMode mode;
SDL_GetDisplayMode(displayIndex, 0, &mode);
return mode.refresh_rate;
}
void RenderWindow::cleanUp()
{
SDL_DestroyWindow(window);
}
void RenderWindow::clear()
{
SDL_RenderClear(renderer);
}
void RenderWindow::render(Entity& p_entity)
{
SDL_Rect src;
src.x = p_entity.getCurrentFrame().x;
src.y = p_entity.getCurrentFrame().y;
src.w = p_entity.getCurrentFrame().w;
src.h = p_entity.getCurrentFrame().h;
SDL_Rect dst;
dst.x = p_entity.getPos().x * 4;
dst.y = p_entity.getPos().y * 4;
dst.w = p_entity.getCurrentFrame().w * 4;
dst.h = p_entity.getCurrentFrame().h * 4;
SDL_RenderCopy(renderer, p_entity.getTex(), &src, &dst);
}
// void RenderWindow::freeTexture(SDL_Texture* p_tex) {
// SDL_DestroyTexture(p_tex);
// }
void RenderWindow::display()
{
SDL_RenderPresent(renderer);
}
Entity.hpp:
#pragma once
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include "Math.hpp"
class Entity
{
public:
Entity(Vector2f p_pos, SDL_Texture* p_tex);
Vector2f& getPos()
{
return pos;
}
void setPos(Vector2f p_pos)
{
pos = p_pos;
}
SDL_Texture* getTex();
SDL_Rect getCurrentFrame();
private:
Vector2f pos;
SDL_Rect currentFrame;
SDL_Texture* tex;
};
entity.cpp:
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include "Entity.hpp"
#include "Math.hpp"
Entity::Entity(Vector2f p_pos, SDL_Texture* p_tex)
:pos(p_pos), tex(p_tex)
{
currentFrame.x = 0;
currentFrame.y = 0;
currentFrame.w = 32;
currentFrame.h = 32;
}
SDL_Texture* Entity::getTex()
{
return tex;
}
SDL_Rect Entity::getCurrentFrame()
{
return currentFrame;
}
math.hpp:
#pragma once
#include <iostream>
struct Vector2f
{
Vector2f()
:x(0.0f), y(0.0f)
{}
Vector2f(float p_x, float p_y)
:x(p_x), y(p_y)
{}
void print()
{
std::cout << x << ", " << y << std::endl;
}
float x, y;
};
Utils.hpp:
#pragma once
#include <SDL2/SDL.h>
namespace utils
{
inline float hireTimeInSeconds()
{
float t = SDL_GetTicks();
t *= 0.001f;
return t;
}
}
谢谢!
1条答案
按热度按时间qkf9rpyu1#
这是我的代码的更新版本,我已经弄明白了。
结果发现问题是:
实际上是推迟了100年而不是1000年