目前,我正在使用这个player.cpp
类用于我的精灵动画。我正在使用计数器来更新每一帧。它动画,但它飞过动画。
我想放慢速度。我找到了可以用来减慢精灵动画的代码,但我不确定如何将它实现到我当前的程序中。
下面是我的player.cpp
文件,然后是我发现的可以减慢精灵动画速度的代码。当我试图向counterWalking++
添加一个时钟时它根本没有动画,我尝试实现这个代码以达到同样的效果。
player::player()
{
rect.setSize(sf::Vector2f(32, 32));
rect.setFillColor(sf::Color::White);
rect.setPosition(300, 300);
sprite.setTextureRect(sf::IntRect(0, 0, 32, 32));
}
void player::update()
{
sprite.setPosition(rect.getPosition());
}
void player::updateMovement()
{
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {
if (canMoveRight == true) {
rect.move(movementSpeed, 0);
sprite.setTextureRect(sf::IntRect(counterWalking * 32, 64, 32, 32));
direction = 4;
canMoveUp = true;
canMoveDown = true;
canMoveLeft = true;
canMoveRight = true;
}
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
if (canMoveLeft == true) {
rect.move(-movementSpeed, 0);
sprite.setTextureRect(sf::IntRect(counterWalking * 32, 32, 32, 32));
direction = 3;
canMoveUp = true;
canMoveDown = true;
canMoveLeft = true;
canMoveRight = true;
}
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
if (canMoveUp == true) {
rect.move(0, -movementSpeed);
sprite.setTextureRect(sf::IntRect(counterWalking * 32, 96, 32, 32));
direction = 1;
canMoveUp = true;
canMoveDown = true;
canMoveLeft = true;
canMoveRight = true;
}
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) {
if (canMoveDown == true) {
rect.move(0, movementSpeed);
sprite.setTextureRect(sf::IntRect(counterWalking * 32, 0, 32, 32));
direction = 2;
canMoveUp = true;
canMoveDown = true;
canMoveLeft = true;
canMoveRight = true;
}
}
else {
//Player not moving
}
counterWalking++;
if (counterWalking == 3)
counterWalking = 0;
}
以下是我发现的显示慢动画的代码:
int main()
{
sf::RenderWindow renderWindow(sf::VideoMode(640, 480), "Demo Game");
sf::Event event;
sf::Texture texture;
texture.loadFromFile("images/player.png");
sf::IntRect rectSourceSprite(0, 0, 32, 32);
sf::Sprite sprite(texture, rectSourceSprite);
sf::Clock clock;
while (renderWindow.isOpen()) {
while (renderWindow.pollEvent(event)) {
if (event.type == sf::Event::EventType::Closed)
renderWindow.close();
}
if (clock.getElapsedTime().asSeconds() > 1.0f) {
if (rectSourceSprite.left == 96)
rectSourceSprite.left = 0;
else
rectSourceSprite.left += 32;
sprite.setTextureRect(rectSourceSprite);
clock.restart();
}
renderWindow.clear();
renderWindow.draw(sprite);
renderWindow.display();
}
}
答案 0 :(得分:0)
由于解决方案已在评论中给出但未在答案中实施,因此这里有某种代码审核"
这段代码实际上是在每个循环中使用sf::Keyboard::isKeyPressed
和sf::Keyboard::isKeyReleased
,而按下/释放键时切换的简单布尔值可以使用事件进行工作。
while (renderWindow.pollEvent(event)) {
if (event.type == sf::Event::EventType::Closed)
renderWindow.close();
}
主循环中使用的事件也包含有关KeyEvents的信息,但不是以这种方式使用的。我建议在关键事件发生时将evet发送给玩家:
while (renderWindow.pollEvent(event)) {
switch(event.type){
case sf::Event::EventType::Closed:
renderWindow.close();
break;
case sf::Event::KeyPressed: case sf::Event::KeyReleased:
myPlayer.keyEvent(event);
break;
}
}
播放器中的keyEvent
功能应如下所示:
void player::keyEvent(sf::Event event){
//Keycode of your keyboard's arrows goes from 71 to 74
if (event.key.code >= 71 && event.key.code <= 74){
//Gets the array ID from the enumeration value
int ID = event.key.code - 71;
//Stores false if the key is release, and true if it's pressed
keys[ID] = (event.type == sf::Event::KeyPressed);
}
}
在Player.h中更改数组的每个值:
private:
bool keys[4];
现在你所要做的就是每秒在游戏循环中调用播放器update()函数:
if (clock.getElapsedTime().asSeconds() > 1.0f) {
if (rectSourceSprite.left == 96)
rectSourceSprite.left = 0;
else
rectSourceSprite.left += 32;
sprite.setTextureRect(rectSourceSprite);
myPlayer.update();
clock.restart();
}
在update()
函数中,您将根据按下的键建立运动矢量:
void player::update()
{
sf::Vector2f movementVector(0,0);
//Left
if (keys[0]){
movementVector.x -= movementSpeed;
//Sends the sprite Rectangle position based on the movement type
move(32);
}
//Right
if (keys[1]){
movementVector.x += movementSpeed;
move(64);
}
//Up
if (keys[2]){
movementVector.y -= movementSpeed;
move(96);
}
//Down
if (keys[3]){
movementVector.y += movementSpeed;
move(0);
}
}
移动功能将根据运动矢量和计数器移动精灵位置,然后设置精灵。
您的移动计数器将增加到30,并且您的玩家只有在此计数器等于0,10或20时才会移动:
void move(int spritePos){
//Here, the check() function should tell if the player isn't going outside of the screen / in a wall
if (check(sprite.getPosition() + movementVector)){
sprite.move(movementVector);
++counterWalking %= 30;
if(!counterWalking % 10)
sprite.setTextureRect(sf::IntRect(counterWalking / 10 * 32, spritePos, 32, 32));
}
}
有多种方法可以做到这一点,这只是我这样做的方式
答案 1 :(得分:0)
像您这样的声音可能需要学习有关控制时间步长的知识。本质上,只有在经过所需时间后才执行某些代码。
您通常会看到此站点被引用,因此可以查看一下: https://gafferongames.com/post/fix_your_timestep/