我正在使用SFML编写棋盘游戏,我希望我的玩家的数字在这个棋盘上移动,但我希望这是一个平滑的动画移动,从场X到场Y.不幸的是,它没有发生,我的玩家的数字只是改变位置,它从让我们说场4跳到场8,而我想从4移动到5,然后到6,然后到7和最终到8。希望它足够清楚。现在让我们看一些代码。
首先是Field类。
class Field {
int m_position_id;
int m_position_x;
int m_position_y;
std::string m_name;
public:
Field() {}
Field(int, int, int);
virtual ~Field() = default;
int getPosID() { return m_position_id; }
int getPosX() { return m_position_x; }
int getPosY() { return m_position_y; }
};
然后我们得到了Board,它基本上只是一个Fields数组
constexpr int BOARD_SIZE = 40;
class Board {
std::array<Field, BOARD_SIZE> m_board;
public:
Board();
Field& getBoard(int index) { return m_board[index]; }
};
球员班
class Player {
int m_position_id = 0; //starting position
float m_position_x = 600;
float m_position_y = 600;
sf::CircleShape m_shape;
public:
Player(std::string, sf::Color, float);
sf::CircleShape& getShape() { return m_shape; }
int getPositionID() { return m_position_id; }
float getPositionX() { return m_position_x; }
float getPositionY() { return m_position_y; }
void setPositionID(int p_position_id) { m_position_id = p_position_id; }
void setPositionX(int p_position_x) { m_position_x = p_position_x; }
void setPositionY(int p_position_y) { m_position_y = p_position_y; }
};
最后,方法不能像我期望的那样工作oo
void GameEngine::movePlayer(Player &p_player, int p_distance) {
int l_current_pos_id = p_player.getPositionID();
p_player.setPositionID(p_player.getPositionID() + p_distance);
p_player.setPositionX(m_game_board.getBoard(p_player.getPositionID()).getPosX());
p_player.setPositionY(m_game_board.getBoard(p_player.getPositionID()).getPosY());
if (p_player.getPositionID() > 39) {
p_player.setPositionID(p_player.getPositionID() - 40);
p_player.setPositionX(m_game_board.getBoard(p_player.getPositionID()).getPosX());
p_player.setPositionY(m_game_board.getBoard(p_player.getPositionID()).getPosY());
}
//going out of array range here probably
for (int i = l_current_pos_id; i < p_player.getPositionID(); i++) {
int x = m_game_board.getBoard(i + 1).getPosX() - m_game_board.getBoard(i).getPosX();
int y = m_game_board.getBoard(i + 1).getPosY() - m_game_board.getBoard(i).getPosY();
p_player.getShape().move(x, y);
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
}
最后,处理视图的类
bool m_draw = false;
while (window.isOpen()) {
if (m_evnt.type == sf::Event::KeyReleased && m_evnt.key.code == sf::Keyboard::R) {
//Roll dice
m_game_engine.rollDice(m_game_status); //this just updates some text, result of rollDice is passed as p_distance to movePlayer
m_draw = true;
}
}
window.clear();
for (int i = 0; i < m_game_engine.getNumberOfPlayers(); i++) {
window.draw(m_game_engine.getPlayer(i).getShape());
}
if (m_draw) {
for (int i = 0; i < m_game_engine.getNumberOfPlayers(); i++) {
window.draw(m_game_engine.getPlayer(i).getShape());
}
window.display();
}
啊,来自GameEngine类
class GameEngine {
std::vector<Player> m_players;
Player& getPlayer(int index) { return m_players[index]; }
};
所以你可以看到,它存储在局部变量当前玩家位置,然后分配新的位置,然后通过Field位置ID获得该位置的X和Y坐标。下一步是检查这个位置是否在阵列内(为了在板周围移动我的图形必须做同样的事情,因为它在板周围的第一个电路后崩溃。但是,这不是重点。对于循环结束,应该从字段i到(i + 1),然后它应该等待0.5秒,再次移动到下一个字段,等等。虽然,我运行我的程序后,它睡在开始然后不移动,但改变我的形状的位置它结束了,根本没有动画。
你有一个循环,你有等待。这不是游戏的运作方式。你可以阅读基础知识here。
你的游戏循环必须运行。这是绘图发生的地方。如果您移动令牌并且在它到达之前不绘制它,它将看起来像一个传送。你需要在你的迷你动作之间画画。
您的令牌需要目标位置以及当前位置和速度。每个循环都需要将适当的数字添加到当前位置,直到它最终到达目标位置。但是你不能在闭环中做到这一点,这需要在你的游戏循环中发生,作为其中的一部分。您可能还需要一个表示令牌确实正在移动的变量,因此在未完成时不会发生任何其他情况。