C++ 如何处理所有可能的玩家移动输入?
C++ How do I Handle all possible Player Movement inputs?
我正在尝试清理我从从未完成的视频教程系列中遵循的运动代码。我的目的是让角色在任何给定时间只能在 X 或 Y 上移动(所以没有对角线(。角色有方向要记住。
我的问题是玩家仍然可以按他们想要的任何键,或者不小心同时按下两个键。
例如,如果您向上移动并右转,请在放开向上之前不小心按右键。
或者,如果按向上,按下并向右松开以在继续按向上的同时向右移动轻微,则玩家在向右松开后应继续向上移动,而不必重新按向上等。
只是为了确保直观地处理所有可能的输入情况。
编辑:这是到目前为止的代码,我遇到了奇怪的错误,我不知道出了什么问题
#pragma once
#include "../game.h"
#include "ECS.h"
#include "Components.h"
#include <list>
using namespace std;
class KeyboardController : public Component
{
public:
TransformComponent *transform;
SpriteComponent *sprite;
std::list<SDL_Event> keyDownList;
SDL_Event lastDirection;
void updateKeyState()
{
if (Game::event.type == SDLK_ESCAPE) {
Game::isRunning = false;
}
else if (Game::event.type == SDL_KEYDOWN) {
keyDownList.push_back(Game::event.key.keysym.sym);
}
else if (Game::event.type == SDL_KEYUP) {
keyDownList.remove(Game::event.key.keysym.sym);
}
}
void init() override
{
transform = &entity->getComponent<TransformComponent>();
sprite = &entity->getComponent<SpriteComponent>();
}
void update() override
{
void updateKeyState();
void updateMovement();
}
};
严重性代码说明项目文件行抑制状态 错误(活动(E0304 没有重载函数"std::list<_Ty、_Alloc>::p ush_back [with _Ty=SDL_Event, _Alloc=std::allocator]"的实例与参数列表 Sandbox C:\file_path\KeyboardController.h 31
严重性代码说明项目文件行抑制状态 错误(活动(E0415 不存在合适的构造函数来从"SDL_Keycode"转换为"SDL_Event"沙箱 C:\file_path\键盘控制器.h 34
基本上,您应该通过分离关键事件和玩家移动之间的逻辑来清理代码。因此,您的update()
方法可能如下所示:
void update() override
{
updateKeyState();
updateMovement();
}
由于您希望播放器仅垂直或水平移动(从不对角线(,因此必须将按键顺序存储在易于访问的数据结构中。我认为您可以使用双向链表:
std::list<SDL_Event> keyDownList;
我们还应该存储最后按下的键,以恢复播放器的空闲动画:
SDL_Event lastDirection;
updateKeyState()
方法应在链表中添加或删除键。我们还应该通过按ESC
来检查玩家是否想离开游戏:
void updateKeyState() {
if (Game::event.type == SDLK_ESCAPE) {
Game::isRunning = false;
} else if (Game::event.type == SDL_KEYDOWN) {
keyDownList.push_back(Game::event.key.keysym.sym);
} else if (Game::event.type == SDL_KEYUP) {
keyDownList.remove(Game::event.key.keysym.sym);
}
}
updatePlayerMovement()
方法是魔术发生的地方。我们基本上应该检查先按下了哪个键,并相应地更新玩家位置。我们还将向下键保存在lastDirection
字段中,以便在不按键时使用它。
void updateMovement() {
// if any key is down
if (keyDownList.size() > 0) {
const SDL_Event downKey = keyDownList.front();
switch (downKey) {
case SDLK_w:
transform->velocity.y = -1;
transform->velocity.x = 0;
sprite->Play("BackWalk");
lastDirection = downKey;
break;
case SDLK_a:
transform->velocity.x = -1;
transform->velocity.y = 0;
sprite->Play("SideWalk");
sprite->spriteFlip = SDL_FLIP_HORIZONTAL;
lastDirection = downKey;
break;
case SDLK_s:
transform->velocity.y = 1;
transform->velocity.x = 0;
sprite->Play("FrontWalk");
lastDirection = downKey;
break;
case SDLK_d:
transform->velocity.x = 1;
transform->velocity.y = 0;
sprite->Play("SideWalk");
sprite->spriteFlip = SDL_FLIP_NONE;
lastDirection = downKey;
break;
}
} else {
// no key is down, handle idle situations
transform->velocity.x= 0;
transform->velocity.y = 0;
switch (lastDirection) {
case SDLK_w:
sprite->Play("BackIdle");
break;
case SDLK_a:
sprite->Play("SideIdle");
break;
case SDLK_s:
sprite->Play("FrontIdle");
break;
case SDLK_d:
sprite->Play("SideIdle");
break;
}
}
}
注意:我还没有测试过这段代码,因为我没有你们游戏中的代码和结构。因此,您可能需要在这里和那里编辑一个片段才能使其为您工作。
- 有可能在Armadillo中复制MATLAB circshift方法吗
- 在他自己的方法中,有可能将一个对象取消引用到另一个对象吗
- 有可能使shared_ptr协变吗
- 有可能在信号处理程序中设置promise吗
- 是否有可能实现O(N)时间和O(1)空间解决方案,以实现C++中的字符串循环移位
- 是否有可能构建面向Linux和Windows的.Net Core C++ / CLI应用程序?
- 是否有可能使用debug_info获取ELF文件的源代码?
- C++,是否有可能/如何定义在.h和.cpp源文件中调用函数的类构造函数
- 有可能在C++中有类的查找表吗
- 是否有可能让 c++ dll 在后台运行 python 程序并让它填充向量图?如果是这样,如何?
- 向量的大小是否有可能为 1 但其中的元素数量为零?
- 是否有可能编写新的叮当声现代化规则?
- 是否有可能通过指向另一个未关联的子对象的指针来获取指向一个子对象的指针?
- 是否有可能通过演绎指南实现整个 std::make_tuple 功能?
- 是否有可能在没有复制的情况下传递 std::vector<int> 作为参数来获得 std::vector<std::array<int, 3>>?
- 是否有可能具有放入容器的移动操作的类型?
- 是否有可能通过溢出 C 中的第一个元素来写入数组第二个元素
- 声明是否有可能逃脱其封闭的名称空间
- git-是否有互联网上某处所有可能错误的列表
- 是否有可能有一个派生类继承最终函数但创建相同的函数(而不是重写)