不能改变船舶的位置,功能调用不工作

时间:2014-02-08 20:05:48

标签: c++ draw sfml

这是调用函数setLocation()的源文件(包括图形头文件应包含尖括号,但它消失了,所以我使用了引号)

#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()的定义,在船舶源文件中(与尖括号相同,再次使用引号)。

  #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()原型所在的头文件

    #ifndef SHIP_H
    #define SHIP_H

    #include "vector.h"

    class Ship {
    private: 
        Vector maxLocations;    //maximum allowable values for location
        Vector location;        //current location (x,y)
        Vector velocity;        //current velocity (in pixels/frame)
        double angleDeg;        //angle ship is facing, in degrees
        double radius;          //gross radius of ship (for collision detection)

    public:
        //constructor
        Ship();
        //=============================================
        //mutators
        void setLocation(double x, double y);
        void updateLocation();
        void draw(sf::RenderWindow& win);
        ...
        };
    #endif

我的问题是,当我调用setLocation()时,它不会从(0,0)更改位置向量(如第二个源文件中所定义)。编译时,船舶保持在(0,0)。我想要发生的是当我调用setLocation()时,船需要从(0,0)更改为(250,250),因此编译时的船在屏幕中间开始,而不是在角落。

1 个答案:

答案 0 :(得分:0)

您手边的问题是您没有使用您认为正在使用的Ship对象。我的意思是你没有在主函数中绘制船舶对象,而是在Ship :: draw()方法中创建临时船舶对象,然后使用该船舶位置绘制您的形状。因此,位置将始终为(0,0),因为您的临时船舶对象在每个框架的位置(0,0)初始化,然后您使用该临时船舶的位置来绘制您的形状。

为了更清楚,让我们看看你的代码。

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.setPosition(location.x, location.y);

在继续之前,研究对象和类如何在C ++中工作可能是有益的。您似乎可能无法准确理解它们的工作原理以及不同的代码范围如何工作。但是我会留下那个让你决定做什么。

虽然我想为你指出一些其他的指示。

1 - 在绘制方法中,您正在更新对象的位置。这通常是一件坏事,你应该避免它。更改对象位置时的所有更新代码都应该在更新函数/方法中进行。实体的绘制方法应该只包含绘图代码。这是因为通常在主游戏循环中的不同时间步进行绘制和更新。

2 - 您的updateLocation方法将无法像您认为的那样工作。原因是因为你在做location.y - = velocity.y;实际上,您应该像使用x一样将y的速度添加到位置。

3 - 我建议不要使用sfml的setFrameRateLimit()方法,而是使用你自己的时间步骤,这将更准确(SFML的版本使用sf :: Sleep,这是因为不准确而臭名昭着)并且让你对你的更多控制权时间步。如果您不知道时间步骤,我强烈建议您阅读这篇精彩的文章。它可以为您节省数小时的头痛。 http://gafferongames.com/game-physics/fix-your-timestep/

4 - 让我们来看看这一行。

else if (x > maxLocations.x)
    location.x -= maxLocations.x;

现在让我们说maxLocations.x = 500,就像你的例子一样,让我们​​也说location.x = 550.你真的希望这个位置是x = 50吗?将x设置为x = maxLocations.x是不是更合乎逻辑的步骤?不确定这是否是你想要的,但我想我会指出它。

希望这会对你有所帮助,我会很乐意回答你可能遇到的任何其他问题。祝你在项目中好运。