0
\$\begingroup\$

I need to make a simple object (like a turtle) move on a 2D scene. The keys w, s, a and d, respectively, make a positive and negative translate on x-axis (move to forward and backward), and rotate 1 degree (a and d).

The problem is the simple object, will initially rotate and translate correctly (because initially the object is at the origin). But after that the commands don't work like I intend them to.

Which are the best practices to make this?

Anyone can help me?

To compile (assuming this code is saved in a file named movement2D.cpp):
g++ movement2D.cpp -o movement2D -lGL -lglut

To execute, use : ./movement2D 500 500

Here's the code:

#include <GL/glut.h>

struct point {
    int x;
    int y;
};
typedef struct point t_point;

struct object {
    int width;
    int height;
    t_point pose;
    float angle;
};
typedef struct object t_object;

void display(void);
void keyPress(unsigned char, int, int);
void initialize(int, int);
void exit(void);
void draw(void);

t_object *head, *body;

int
main(int argc, char** argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(atoi(argv[1]), atoi(argv[2]));
    glutInitWindowPosition(10, 10);
    glutCreateWindow("Movement");
    initialize(atoi(argv[1]), atoi(argv[2]));
    glutDisplayFunc(display);
    glutKeyboardFunc(keyPress);
    atexit(exit);
    glutMainLoop();
}

void
display(void) {
    glClear(GL_COLOR_BUFFER_BIT);
    
    glPushMatrix(); {
        glLoadIdentity();
        glRotatef(body->angle, 0.0f, 0.0f, 1.0f);
        glTranslatef(body->pose.x, body->pose.y, 0.0f);
        draw();
    }
    glPopMatrix();
    
    glutSwapBuffers();
}

void
keyPress(unsigned char key, int x, int y) {
    switch (key) {
    case 'a':
    case 'A':
        body->angle += 1;
        break;
    case 'd':
    case 'D':
        body->angle -= 1;
        break;
    case 'w':
    case 'W':
        body->pose.x += 5;
        break;
    case 's':
    case 'S':
        body->pose.x -= 5;
        break;
    case 27:
        exit(1);
    }
    glutPostRedisplay();
}

void
initialize(int width, int height) {
    head = (t_object*) calloc(1, sizeof(t_object));
    body = (t_object*) calloc(1, sizeof(t_object));

    body->width = body->height = 100;
    head->width = head->height = 20;
    body->pose.x = body->pose.y = 0;

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glMatrixMode(GL_PROJECTION);
    glOrtho(-width / 2, width / 2, -height / 2, height / 2, -100, 100);
    glMatrixMode(GL_MODELVIEW);
}

void
exit(void) {
    free(head);
    free(body);
}

void
draw(void) {
    glColor3f(1.0f, 0.0f, 0.0f);
    glBegin(GL_QUADS);
        glVertex2i(-body->width / 2, -body->height / 2);
        glVertex2i(-body->width / 2, body->height / 2);
        glVertex2i(body->width / 2, body->height / 2);
        glVertex2i(body->width / 2, -body->height / 2);               
    glEnd();
    glTranslatef(body->width / 2 + head->width / 2, 0.0f, 0.0f);
    glColor3f(0.0f, 0.0f, 1.0f);
    glBegin(GL_QUADS);
        glVertex2i(-head->width / 2, -head->height / 2);
        glVertex2i(-head->width / 2, head->height / 2);
        glVertex2i(head->width / 2, head->height / 2);
        glVertex2i(head->width / 2, -head->height / 2);               
    glEnd();
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.