这是我的代码:
#include <SFML/Graphics.hpp>
#include <iostream>
#include <Windows.h>
int main()
{
sf::RenderWindow window(sf::VideoMode(800, 600), "SFML Game");
window.setFramerateLimit(200);
//Variable that keeps the game loop running
bool play = true;
//Event object holding all events
sf::Event event;
//States for button/events
bool Left = false;
bool Right = false;
bool space = false;
//Variables
int rectXPosition = 375; //Rectangles X position
int rectYPosition = 400; //Rectangles Y position
//Images
sf::Texture image1;
if (image1.loadFromFile("Images/GreekSoldier.png") == -1)
{
std::cout << "FAILED!!!" << "\n";
return 1;
}
//Render shapes
sf::RectangleShape rect;
rect.setSize(sf::Vector2f(77, 150)); //Width and height
rect.setPosition(375, 400); //Position
rect.setFillColor(sf::Color::White); //Color
rect.setTexture(&image1);
//Game loop
while (play == true)
{
//EVENTS
while (window.pollEvent(event))
{
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Left)
{
//Set the state to true
Left = true;
}
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Right)
{
Right = true;
}
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Space)
{
space = true;
}
//Event type is window closed
if (event.type == sf::Event::Closed)
{
//Set play to false in order to stop the game loop
play = false;
}
}
//LOGIC
if (Left == true)
{
int x = 0;
for (x = 1; x < 2; x++)
{
rectXPosition-=5; //X position variable of the rectangle
rect.setPosition(rectXPosition, rectYPosition);
window.clear();
window.draw(rect);
window.display();
Sleep(5);
}
Left = false;
}
if (Right == true)
{
int x = 0;
for (x = 1; x < 2; x++)
{
rectXPosition+= 5; //X position variable of the rectangle
rect.setPosition(rectXPosition, rectYPosition);
window.clear();
window.draw(rect);
window.display();
Sleep(5);
}
Right = false;
}
if (space == true)
{
int x = 0;
for (x = 1; x < 15; x++)
{
rectYPosition-= 3; //X position variable of the rectangle
rect.setPosition(rectXPosition, rectYPosition);
window.clear();
window.draw(rect);
window.display();
Sleep(10);
}
for (x = 1; x < 15; x++)
{
rectYPosition+= 3; //X position variable of the rectangle
rect.setPosition(rectXPosition, rectYPosition);
window.clear();
window.draw(rect);
window.display();
Sleep(10);
}
space = false;
}
//RENDERING
window.clear();
//Draw the rectangle shape
window.draw(rect);
window.display();
}
//Clean up and close the window
window.close();
return 0;
}
如何让运动更顺畅?如何制作矩形(士兵)可以同时跳跃和移动?我如何阻止它,当向左按住它不需要3秒才能实际移动?
我已经添加了一个youtube视频,如果你们不能为编译它而烦恼,只是想看看我在谈论什么。 https://www.youtube.com/watch?v=g_JLwGh1Wgo
答案 0 :(得分:2)
当有人按下某个键然后经常重复(但不是每一帧,这使得它不平滑)时,会生成KeyPressed
个事件。例如,它们旨在用于文本输入。
按下另一个键也会中断前一个键的重复事件,因此您的其他问题也有同样的原因。
您应该仅针对某些即时操作处理KeyPressed
事件,例如按菜单按钮。在这个特定的例子中,你应该完全摆脱这一点,只使用sf::Keyboard
替换行:
if (Left == true)
使用:
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
依旧......
我会解释为什么sf::Keyboard
在这里是正确的,但文档做得很好。
另一个大问题是你有多个循环不会在游戏中发生任何其他事情。你应该熟悉事件循环,速度和重力的概念(并制作相应的变量)。
当玩家按下 Space 时,你不应硬编码角色向上移动N像素,向下移动N像素同时停止游戏中的其他所有可能动作,而是改变角色的垂直速度并用它来改变角色在每一帧中的位置(并且还可以通过重力降低速度)。
最重要的一点是,您必须只有一个调用window.display
的主要事件循环。