Skip to main content
GameDev.net gamedev.net
🔒 Locked

Utterly confusing problem

Started by JordyD Sep 1, 2009 at 5:08 AM 1 replies 850+ views
Original Post
JordyD
JordyD
This issue utterly confuses me. I wasn't sure how to explain it well in the title, thus the nondescript thread name. Anyways, my problem is that I have a class called Ship, which inherits from Shape, which contains all sorts of abstraction goodies. It has several setters and getters, and my problem is that it doesn't seem to show up on the screen unless I've called two of its getters... which is what's so utterly confusing. I don't understand how that works out. But I've posted my code in case you do. As you can see, I have some commented getters in the main loop. When I uncomment those, all is well; but when I don't, bad JuJu. main.cpp:
#include "ship.h"
#include <GL/glfw.h>
#include <iostream>

using namespace std;

int main()
{
    const int width = 640,
                      height = 480;
    double time = 0;
    bool running = true;

    glfwInit();

    if (!glfwOpenWindow(width, height, 0, 0, 0, 0, 0, 0, GLFW_WINDOW))
    {
        glfwTerminate();
        return 0;
    }

    glfwSetWindowTitle("NetTroids");
    glfwSwapInterval(1);

    Ship ship;

    while (running)
    {
        time = glfwGetTime();

        // Events
        if (glfwGetKey('Q') == GLFW_PRESS
                || !glfwGetWindowParam(GLFW_OPENED))
            running = false;

        // Movement, rotation, etc.
        ship.Update(time, true);

        //ship.GetPosition().x;
        //ship.GetPosition().y;

        // Draw
        glClear(GL_COLOR_BUFFER_BIT);
        glLoadIdentity();
        ship.Draw();
        glfwSetTime(0);
        glfwSwapBuffers();
    }

    glfwTerminate();

    return 0;
}

shape.h:
#ifndef SHAPE_H
#define SHAPE_H

#include <GL/gl.h>
#include <vector>
#include <iostream>

typedef struct
{
    float x;
    float y;
    float z;
} coord;

class Shape
{
public:
    Shape();
    Shape(int Type);
    ~Shape();

    void SetType(int Type);

    void AddPoint(float x, float y, float z = 0.0);

    void SetPosition(float x, float y, float z = 0.0);
    coord GetPosition();
    void SetRotation(float degrees, bool x = false, bool y = false, bool z = true);
    float GetRotation();

    void Move(float x, float y, float z = 0.0);
    void Rotate(float degrees, bool x = false, bool y = false, bool z = true);

    void SetSpeed(float x, float y, float z = 0.0);
    coord GetSpeed();
    void SetRotateSpeed(float degrees, bool x = false, bool y = false,
                        bool z = true);
    float GetRotateSpeed();

    void Update(double frameTime = 1);

    void Draw();

private:
    int type;

    std::vector<coord> points;

    coord offset;
    float rotation;
    bool rotateX, rotateY, rotateZ;

    coord speed;
    float rotationSpeed;
};

#endif // SHAPE_H
shape.cpp:
#include "shape.h"

Shape::Shape()
{
}

Shape::Shape(int Type)
{
    SetType(Type);
}

Shape::~Shape()
{
}

void Shape::SetType(int Type)
{
    type = Type;
}

void Shape::AddPoint(float x, float y, float z)
{
    coord point;
    point.x = x;
    point.y = y;
    point.z = z;

    points.push_back(point);
}

void Shape::SetPosition(float x, float y, float z)
{
    offset.x = x;
    offset.y = y;
    offset.z = z;
}

coord Shape::GetPosition()
{
    return offset;
}

void Shape::SetRotation(float degrees, bool x, bool y, bool z)
{
    rotation = degrees;
    rotateX = x;
    rotateY = y;
    rotateZ = z;
}

float Shape::GetRotation()
{
    return rotation;
}

void Shape::Move(float x, float y, float z)
{
    SetPosition(GetPosition().x + x,
                GetPosition().y + y,
                GetPosition().z + z);
}

void Shape::Rotate(float degrees, bool x, bool y, bool z)
{
    float currentRotation = GetRotation();
    SetRotation(currentRotation + degrees, x, y, z);
}

void Shape::SetSpeed(float x, float y, float z)
{
    speed.x = x;
    speed.y = y;
    speed.z = z;
}

coord Shape::GetSpeed()
{
    return speed;
}

void Shape::SetRotateSpeed(float degrees, bool x, bool y, bool z)
{
    rotationSpeed = degrees;
    rotateX = x;
    rotateY = y;
    rotateZ = z;
}

float Shape::GetRotateSpeed()
{
    return rotationSpeed;
}

void Shape::Update(double frameTime)
{
    Move(GetSpeed().x * frameTime,
         GetSpeed().y * frameTime,
         GetSpeed().z * frameTime);
    Rotate(GetRotateSpeed() * frameTime, rotateX, rotateY, rotateZ);
}

void Shape::Draw()
{
    glPushMatrix();
    glTranslatef(GetPosition().x, GetPosition().y, GetPosition().z);
    glRotatef(GetRotation(),
              rotateX ? 1.0 : 0.0,
              rotateY ? 1.0 : 0.0,
              rotateZ ? 1.0 : 0.0);
    glBegin(type);
    for (unsigned int i = 0; i < points.size(); i++)
        glVertex3f(points.x, points.y, points.z);
    glEnd();
    glPopMatrix();
}
ship.h:
#ifndef SHIP_H
#define SHIP_H

#include "shape.h"
#include <cmath> // For sin() and cos()
#include <GL/glfw.h> // For event handling

#define PI 3.1415926

float deg2rad(float deg);

class Ship : public Shape
{
public:
    Ship();
    virtual ~Ship();

    void SetThrustSpeed(float thrust);

    virtual void HandleEvents();
    virtual void Update(double frameTime = 1.0, bool HandleEvents = false);

private:
    float direction, thrustSpeed;
};

#endif // SHIP_H
ship.cpp:
#include "ship.h"

float deg2rad(float deg)
{
    return (deg * (PI/180));
}

Ship::Ship()
{
    SetType(GL_LINE_LOOP);
    AddPoint(-0.05, -0.1);
    AddPoint(0.0, -0.05);
    AddPoint(0.05, -0.1);
    AddPoint(0.0, 0.1);
}

Ship::~Ship()
{
}

void Ship::SetThrustSpeed(float thrust)
{
    thrustSpeed = thrust;
}

void Ship::HandleEvents()
{
    const float rotatespeed = 100;
    const float thrustspeed = 0.5;

    // Rotations: 'A' and 'D' keys
    if (glfwGetKey('D') == GLFW_PRESS)
        SetRotateSpeed(-rotatespeed);
    else if (glfwGetKey('A') == GLFW_PRESS)
        SetRotateSpeed(rotatespeed);
    else
        SetRotateSpeed(0);

    // Movements: 'W' and 'S' keys
    if (glfwGetKey('W') == GLFW_PRESS)
        SetThrustSpeed(thrustspeed);
    else if (glfwGetKey('W') == GLFW_RELEASE)
        SetThrustSpeed(0);
    else if (glfwGetKey('S') == GLFW_PRESS)
        SetThrustSpeed(-thrustspeed);
    else if (glfwGetKey('S') == GLFW_RELEASE)
        SetThrustSpeed(0);
}

void Ship::Update(double frameTime, bool handleEvents)
{
    /*
     * Given a polar vector of angle alpha and speed v, its equivalent
     * rectangular vector is:
     * xv: cos(alpha)*v
     * yv: sin(alpha)*v
     */

    if (handleEvents)
        HandleEvents();

    SetSpeed(-std::sin(deg2rad(GetRotation())) * thrustSpeed,
            std::cos(deg2rad(GetRotation())) * thrustSpeed);

    Shape::Update(frameTime);
}
Tell me if I'm missing something. Thanks, Jordy
Perost
Perost
Both Shape and Ship has several member variables that you don't set in the constructor for these classes, and therefore they are undefined until you call the appropriate setter. So the ships position is completely undefined, it could be anywhere. When you call GetPosition the position might get set to (0, 0, 0) for some reason, but that is just luck (and programmers don't rely on luck). So either you need to make sure to pass the relevant data to the constructor for each class, or provide appropriate default values.
JordyD
JordyD
Quote:
Original post by Perost
Both Shape and Ship has several member variables that you don't set in the constructor for these classes, and therefore they are undefined until you call the appropriate setter. So the ships position is completely undefined, it could be anywhere. When you call GetPosition the position might get set to (0, 0, 0) for some reason, but that is just luck (and programmers don't rely on luck). So either you need to make sure to pass the relevant data to the constructor for each class, or provide appropriate default values.


Thanks! I'll try to look for that next time. My problem is solved, and now I won't go mad from confusion.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.