类管理,以区分玩家密钥



制作pong克隆,在运动和类方面遇到一些问题。因此,我有一个类Game,它管理类Paddle的两个实例,并且在Game类的构造函数中启动两个不同桨类中的变量,并将变量player设置为12,基于该类将对哪些键进行运动响应。然后,在Paddle类事件函数中,我使用if(player == 1)if(player == 2)来判断何时要检查按键以更改桨板的y速度。我遇到的问题是,因为Game类的事件函数看起来像这样:

void Game::events()
{
PlayerOne.events();
PlayerTwo.events();
Game_Ball.events();
}

Paddle类的事件函数和类定义如下:

class Paddle
{
public:
int player;
SDL_Surface *sprite = NULL;
float x, y, w, h;
float yVel;
SDL_Rect *clip;
void events();
void logic(Uint32 deltaTicks);
void render();
Paddle();
~Paddle();
};
void Paddle::events()
{
while (SDL_PollEvent(&event))
{
Uint8 *keystates = SDL_GetKeyState(NULL);
if (player == 1)
{
if (keystates[SDLK_o] == 1)
{
yVel -= 100;
}
if (keystates[SDLK_k] == 1)
{
yVel += 100;
}
}
else
{
if (keystates[SDLK_o] == 0)
{
yVel += 100;
}
if (keystates[SDLK_k] == 0)
{
yVel -= 100;
}
}
if (player == 2)
{
if (keystates[SDLK_w] == 1)
{
yVel -= 100;
}
if (keystates[SDLK_s] == 1)
{
yVel += 100;
}
}
else
{
if (keystates[SDLK_w] == 0)
{
yVel += 100;
}
if (keystates[SDLK_s] == 0)
{
yVel -= 100;
}
}
}
}

发生了一些事情,把钥匙弄混了。通常PlayerOne使用"O/K"移动,PlayerTwo使用"W/S"移动,但有时我按下任一键,对面的类就会移动。这似乎没有道理。以下是Game类构造函数和定义

class Game : public GameState
{
private:
int server;
TTF_Font *score = NULL;
Paddle PlayerOne;
Paddle PlayerTwo;
Ball Game_Ball;
public:
SDL_Rect clip[2];
void events();
void logic();
void render();
Game();
~Game();
};
Game::Game()
{
//RESOURSES
PlayerOne.sprite = load_image("Game_sprite.png");
PlayerTwo.sprite = load_image("Game_sprite.png");
clip[0].x = 0;
clip[0].y = 0;
clip[0].w = 20;
clip[0].h = 20;
clip[1].x = 0;
clip[1].y = 20;
clip[1].w = 20;
clip[1].h = 100;
//PLAYER ONE
PlayerOne.x = 420;
PlayerOne.y = 100;
PlayerOne.w = 60;
PlayerOne.h = 100;
PlayerOne.clip = &clip[1];
PlayerOne.yVel = 0;
PlayerOne.player = 1;
//PLAYER TWO
PlayerTwo.x = 60;
PlayerTwo.y = 100;
PlayerTwo.w = 60;
PlayerTwo.h = 100;
PlayerTwo.clip = &clip[1];
PlayerTwo.yVel = 0;
PlayerTwo.player = 2;
//BALL
Game_Ball.Ball_Bound.x = 190;
Game_Ball.Ball_Bound.y = 190;
Game_Ball.Ball_Bound.w = 60;
Game_Ball.Ball_Bound.h = 60;
Game_Ball.clip = &clip[0];
}

player在两个对象中都有明确的设置,Paddle类的events部分清楚地区分了它们,那么,为什么键会混淆呢?我可以很容易地为第二个玩家编写另一个类,但这将是低效的,我宁愿使用同一个类的两个副本,除了键状态之外,其他都做相同的事情。所以,我不太确定发生了什么。

乍一看,您似乎只需要使用:

if (player == 1)
{
if (keystates[SDLK_o] == 1)
{
yVel -= 100;
}
if (keystates[SDLK_k] == 1)
{
yVel += 100;
}
}
else // player == 2
{
if (keystates[SDLK_w] == 1)
{
yVel -= 100;
}
if (keystates[SDLK_s] == 1)
{
yVel += 100;
}
}

我猜测当错误的光标移动时,O会向下移动错误的光标,这是正确的吗?

问题似乎是您有

if (player == 1) {
check keys O K pressed
}
else {
check keys O K released
} 

这是没有意义的,因为这修改了与在播放器2上发布的密钥O K相关的值。

在任何情况下,你都不应该让任何游戏对象轮询事件。主游戏循环应该将它们汇集一次,并将它们发送到相应的游戏元素,例如:

void gameLoop() {
while (true) {
draw();
updatePositions();
handleEvents();
}
}
void handleEvents() {
while (SDL_PollEvent(&event)) {
Uint8 *keystates = SDL_GetKeyState(NULL);
if (keystates[SDLK_o]) paddle1->startMovingUp();
else if (keystates[SDLK_k]) paddle1->startMovingDown();
else paddle1->stopMoving();
// same thing for player2
}
}
Paddle::startMovingUp() {
uvelY = -100;
}
Paddle::startMovingDown() {
uvelY = 100;
}
Paddle::stopMoving() {
uvelY = 0;
}
Paddle::updatePosition() {  // called on each frame
positionY += uvelY;
}

您可以简化设计,只更新handleEvents()功能中的位置,但将位置更新与事件管理分开是一件好事

相关内容

  • 没有找到相关文章

最新更新