C++ 无法更改船舶位置,函数调用不起作用
这是调用函数setLocation的源文件,其中包含的图形头文件应该有尖括号,但它消失了,所以我使用了引号C++ 无法更改船舶位置,函数调用不起作用,c++,draw,sfml,C++,Draw,Sfml,这是调用函数setLocation的源文件,其中包含的图形头文件应该有尖括号,但它消失了,所以我使用了引号 #include "SFML/Graphics.hpp" #include "ship.h" const int WINDOW_WIDTH = 500; const int WINDOW_HEIGHT = 500; //============================================================================== int
#include "SFML/Graphics.hpp"
#include "ship.h"
const int WINDOW_WIDTH = 500;
const int WINDOW_HEIGHT = 500;
//==============================================================================
int main()
{
sf::RenderWindow window( sf::VideoMode(WINDOW_WIDTH, WINDOW_HEIGHT),
"Delta Quadrant", sf::Style::Titlebar | sf::Style::Close);
window.setFramerateLimit(120);
// this causes loop to execute 120 times a second at most.
// (a delay is automatically added after screen is drawn)
Ship obj;
//ADD Code to set limits on ships location (call setMaxLocation);
//sets position of the ship in the middle of the screen
obj.setLocation(250, 250);
while (window.isOpen())
{
//----------------------------------------------------------
//handle user input (events and keyboard keys being pressed)
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed)
window.close();
}
//turn left with press of left button
while (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
obj.rotateLeft();
//turn right with press of right button
while (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
obj.rotateRight();
//apply thrust with press of up button
while (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
obj.applyThrust();
//----------------------------------------------------------
//draw new frame
window.clear();
//draw ship
obj.updateLocation();
obj.draw(window);
//redisplay window
window.display();
}
return 0;
}
这是setLocation的定义,在ship源文件中,同样的问题用尖括号表示,再次使用引号
#include"cmath"
#include "SFML/Window.hpp"
#include "SFML/Graphics.hpp"
#include "vector.h"
#include "ship.h"
//Constants
const double PI = 3.14159;
const double THRUST = 0.005;
const double TURN_SPEED = 1;
//constructor
Ship::Ship(){
maxLocations.x = 500;
maxLocations.y = 500;
radius = 5;
location.x = 0;
location.y = 0;
velocity.x = 0;
velocity.y = 0;
angleDeg = 5;
}
void Ship::setLocation(double x, double y){
//Check and correct for the ship going out of bounds.
if (x < 0)
location.x = 0;
else if (x > maxLocations.x)
location.x -= maxLocations.x;
else
location.x = x;
if (y < 0)
location.y = 0;
else if (y > maxLocations.y)
location.y -= maxLocations.y;
else
location.y = y;
}
void Ship::updateLocation(){
location.x += velocity.x;
location.y -= velocity.y;
//Check and correct for the ship going out of bounds.
if (location.x < 0)
location.x = 0;
else if (location.x > maxLocations.x)
location.x -= maxLocations.x;
if (location.y < 0)
location.y = 0;
else if (location.y > maxLocations.y)
location.y -= maxLocations.y;
}
void Ship::draw(sf::RenderWindow& win) {
//Initializes the Ship class to an object
Ship obj;
// draw ship
sf::ConvexShape ship;
ship.setPointCount(3);
ship.setPoint(0, sf::Vector2f(10, 0));
ship.setPoint(1, sf::Vector2f(0, 25));
ship.setPoint(2, sf::Vector2f(20, 25));
sf::Vector2f midpoint(10,15);
ship.setOrigin(midpoint);
ship.setFillColor(sf::Color(0, 0, 0));
ship.setOutlineThickness(1);
ship.setOutlineColor(sf::Color(255, 255, 255));
ship.setPosition(obj.getLocation().x, obj.getLocation().y);
obj.setAngle(obj.getAngle());
win.draw(ship);
}
}
我的问题是,当我调用setLocation时,它不会将第二个源文件中定义的位置向量从0更改为0。编译时,船舶保持在0,0。我想发生的是当我调用StAt定位时,船需要从0, 0变到250, 250,所以编译的船从屏幕中部开始,而不是一个角落。 当前的问题是您没有使用您认为正在使用的Ship对象。我的意思是,您没有在主函数中绘制ship对象,而是在ship::draw方法中创建一个临时ship对象,然后使用该ships位置绘制形状。因此,位置将始终为0,0,因为temp ship对象在每一帧都使用位置0,0进行初始化,然后使用临时ship的位置绘制形状 为了更清楚地说明这一点,让我们看看您的代码
void Ship::draw(sf::RenderWindow& win) {
// This is a temporary object and is not the same as the one you defined in your
// main.cpp file. When this object is constructed it's location is (0, 0) by
// default.
Ship obj;
// draw ship
sf::ConvexShape ship;
ship.setPointCount(3);
ship.setPoint(0, sf::Vector2f(10, 0));
ship.setPoint(1, sf::Vector2f(0, 25));
ship.setPoint(2, sf::Vector2f(20, 25));
sf::Vector2f midpoint(10,15);
ship.setOrigin(midpoint);
ship.setFillColor(sf::Color(0, 0, 0));
ship.setOutlineThickness(1);
ship.setOutlineColor(sf::Color(255, 255, 255));
// Here we are setting the shapes position to the position of the temporary
// Ship object that you defined above. Remember that it's default location is
// (0, 0) when constructed and you never changed it's location in the draw
// method.
ship.setPosition(obj.getLocation().x, obj.getLocation().y);
obj.setAngle(obj.getAngle());
win.draw(ship);
}
现在你怎么解决这个问题?这很容易。您所需要做的就是在绘制方法中去掉临时的ship对象,而是使用位置向量来设置形状的位置。像这样
ship.setPosition(location.x, location.y);
<> P>对你继续研究对象和类如何在C++中工作可能是有益的。您可能不太清楚它们是如何工作的,以及不同的代码范围是如何工作的。但我会让你决定怎么做
尽管我想为你们指出一些其他的建议
1-在绘制方法中,您正在更新对象的位置。这通常是一件坏事,你应该避免。所有更新代码(如更改对象位置时)都应在更新函数/方法中进行。实体的绘图方法中应仅包含绘图代码。这是因为在主游戏循环中,绘制和更新通常发生在不同的时间步
2-你的updateLocation方法不会像你想象的那样工作。原因是您正在执行location.y-=velocity.y;实际上,你应该把y的速度加到位置上,就像你对x做的那样
3-我建议不要使用sfml的setFrameRateLimit方法,而是使用您自己的timestep,这将更加准确。sfml的版本使用sf::Sleep,它以不准确而臭名昭著,可以让您更好地控制时间步长。如果你不知道时间步,我强烈建议你阅读这篇关于时间步的文章。它会帮你省去几个小时的头痛
4——让我们看看这条线。
else if (x > maxLocations.x)
location.x -= maxLocations.x;
现在让我们假设maxLocations.x=500与您的示例类似,并且让我们也假设location.x=550。您真的希望位置为x=50吗?将x设置为x=maxLocations.x不是更合理的步骤吗?不确定这是否是你想要的,但我想我会指出这一点
希望这会对你有所帮助,我会一直很高兴回答你可能有的任何其他问题。祝您的项目好运。我以前使用过SFML,很乐意为您提供帮助,但您需要整理您的问题;一团糟。顺便说一句,欢迎来到SO!抱歉弄得一团糟。我希望这更清楚,如果不是,我不介意再试一次!谢谢好一些,但还是很乱。我能看到的关键问题是你的缩进。另外,你能发布updateLocation的代码吗?希望看起来更好一点?我添加了updateLocation。这更好,我最不需要的是draw函数,然后我应该能够提供帮助。还有,你的飞船里有sf::Sprite或者类似的东西吗?哇,这真的很深入。除了继续编码的有用提示之外,我还感谢您的回答,我特别感谢这些提示。说真的,加分,你抓住了一切。谢谢
else if (x > maxLocations.x)
location.x -= maxLocations.x;