Sonntag, 6. Dezember 2015

Programming rectangle with C++

Goal

I just wanted to create a simple triangle and moving it around with the arrow keys on keyboard.
The boarders are set around the rectangle and stops moving if boarders are close to the rectangle frame.
Curious about the input issues I got. Imagine a word document and keep holding a key. As result you get the pressed key immadiately a short break and a series of elements pretty fast till the key is released. The same effect was here with the recommenden key_callback() function from GLFW here Receiving input events while moving the rectangle around. It stopped always a while while holding an arrow key pressed.
A good solution for this issue was to poll the events with glfwPollEvents() but is less convinient (the hard way) to check the current state of the defined keys.

Requirements

Codeblocks 13.12 + Mingw
GLFW 3.1.2
OpenGL 2.1 (old fashion OpenGL, some functions are already deprecated but working on most plattforms)

Sourcecodes

#ifndef GAME2D_H_INCLUDED
#define GAME2D_H_INCLUDED

#include
#include
#include

// SETUP DATE ------------------
const float citDelta       = 0.0125f;
const float citRectLength  = 1.0f / 3.0f;
const float citRectHeight  = 0.04;
// ------------------ SETUP DATE

//void character_callback(GLFWwindow* window, unsigned int codepoint);
void citX(float& x);
void citY(float& y);
int  citRun();

/*************************************************************************************************************
* diffclock() (c) Satbir Oct 4 '09 at 15:40                                                                  *
* http://stackoverflow.com/questions/1516659/how-do-i-count-how-many-milliseconds-it-takes-my-program-to-run *
*************************************************************************************************************/
double diffclock(clock_t clock1,clock_t clock2);

#endif // GAME2D_H_INCLUDED

Listing: Game2d.hpp
_____________________
#include "Game2d.hpp"

int main()
{
    return citRun();
}

Listing: main.cpp
_____________________
#include "Game2d.hpp"

#include "Game2d.hpp"

using namespace std;

static void error_callback(int error, const char* description)
{
    cerr << "ERROR DESCRIPTION [" << description << "]";
}

int citRun()
{
    GLFWwindow* window;

    float       ratio;
    int         height;
    int         width;

    float       x               = 0;
    float       y               = 0;

    int         cit_KEY_DOWN;
    int         cit_KEY_LEFT;
    int         cit_KEY_RIGHT;
    int         cit_KEY_UP;
    int         cit_LAST_LEFT_RIGHT = 0;
    int         cit_LAST_UP_DOWN    = 0;

    // init ---------------------------------------------
    glfwSetErrorCallback(error_callback);

    if (!glfwInit())
        return -1;

    window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL);

    if (!window)
    {
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(window);
    glfwSwapInterval(1);
    //glfwSetCharCallback(window, character_callback);
    glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
    // --------------------------------------------- init

    // main loop ----------------------------------------
    while (!glfwWindowShouldClose(window))
    {
        glfwGetFramebufferSize(window, &width, &height);
        ratio = (float) width / (float) height;
        glViewport(0, 0, width, height);
        glClear(GL_COLOR_BUFFER_BIT);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(-ratio, ratio, -1.f, 1.f, 1.f, -1.f);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        // --- handle key input -----------------------------
        glfwPollEvents();

        cit_KEY_LEFT    = glfwGetKey(window, GLFW_KEY_LEFT);
        cit_KEY_RIGHT   = glfwGetKey(window, GLFW_KEY_RIGHT);
        cit_KEY_UP      = glfwGetKey(window, GLFW_KEY_UP);
        cit_KEY_DOWN    = glfwGetKey(window, GLFW_KEY_DOWN);

        if (cit_KEY_LEFT == GLFW_PRESS && cit_KEY_RIGHT != GLFW_PRESS)
            cit_LAST_LEFT_RIGHT = GLFW_KEY_LEFT;

        if (cit_KEY_LEFT != GLFW_PRESS && cit_KEY_RIGHT == GLFW_PRESS)
            cit_LAST_LEFT_RIGHT = GLFW_KEY_RIGHT;

        if (cit_KEY_LEFT != GLFW_PRESS && cit_KEY_RIGHT != GLFW_PRESS)
            cit_LAST_LEFT_RIGHT = 0;

        if (cit_KEY_UP == GLFW_PRESS && cit_KEY_DOWN != GLFW_PRESS)
            cit_LAST_UP_DOWN = GLFW_KEY_UP;

        if (cit_KEY_UP != GLFW_PRESS && cit_KEY_DOWN == GLFW_PRESS)
            cit_LAST_UP_DOWN = GLFW_KEY_DOWN;

        if (cit_KEY_UP != GLFW_PRESS && cit_KEY_DOWN != GLFW_PRESS)
            cit_LAST_UP_DOWN = 0;

        // --- debug code --------------------------------------
        //if (cit_KEY_LEFT  == GLFW_PRESS
        //||  cit_KEY_RIGHT == GLFW_PRESS
        //||  cit_KEY_UP    == GLFW_PRESS
        //||  cit_KEY_DOWN  == GLFW_PRESS)
        //{
        //    cout << "["  << x << "|" << y << "]" << endl;
        //    cout << "cit_KEY_LEFT  =["  << (cit_KEY_LEFT  == GLFW_PRESS ? "true" : "false") << "]" << endl;
        //    cout << "cit_KEY_RIGHT =["  << (cit_KEY_RIGHT == GLFW_PRESS ? "true" : "false") << "]" << endl;
        //    cout << "cit_KEY_UP    =["  << (cit_KEY_UP    == GLFW_PRESS ? "true" : "false") << "]" << endl;
        //    cout << "cit_KEY_DOWN  =["  << (cit_KEY_DOWN  == GLFW_PRESS ? "true" : "false") << "]" << endl;
        //}
        // --- debug code -----------------------------------

        if (cit_LAST_LEFT_RIGHT == GLFW_KEY_LEFT)
        {
            x -= citDelta;
        }

        if (cit_LAST_LEFT_RIGHT == GLFW_KEY_RIGHT)
        {
            x += citDelta;
        }

        if (cit_LAST_UP_DOWN == GLFW_KEY_UP)
        {
            y += citDelta;
        }

        if (cit_LAST_UP_DOWN == GLFW_KEY_DOWN)
        {
            y -= citDelta;
        }

        if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
            glfwSetWindowShouldClose(window, GL_TRUE);

        citX(x);
        citY(y);
        // --- handle key input -----------------------------

        // --- handle graphic output ------------------------
        glBegin(GL_LINE_STRIP);
          glVertex3f(x - citRectLength/2, y - citRectHeight/2, 0.0f);
          glVertex3f(x - citRectLength/2, y + citRectHeight/2, 0.0f);
          glVertex3f(x + citRectLength/2, y + citRectHeight/2, 0.0f);
          glVertex3f(x + citRectLength/2, y - citRectHeight/2, 0.0f);
          glVertex3f(x - citRectLength/2, y - citRectHeight/2, 0.0f);
        glEnd();
        // --- handle graphic output ------------------------

        glfwSwapBuffers(window);
    }
    // ---------------------------------------- main loop

    // close app ----------------------------------------
    glfwDestroyWindow(window);
    glfwTerminate();

    return 0;
    // ---------------------------------------- close app
}

void citX(float &x)
{
    if (x >  1 + citRectLength/2)
        x =  1 + citRectLength/2;
    else
    if (x < -1 - citRectLength/2)
        x = -1 - citRectLength/2;
}

void citY(float &y)
{
    if (y >  1 - citRectHeight/2)
        y =  1 - citRectHeight/2;
    else
    if (y < -1 + citRectHeight/2)
        y = -1 + citRectHeight/2;
}

/*************************************************************************************************************
* diffclock() (C) Satbir Oct 4 '09 at 15:40                                                                  *
* http://stackoverflow.com/questions/1516659/how-do-i-count-how-many-milliseconds-it-takes-my-program-to-run *
*************************************************************************************************************/
double diffclock(clock_t clock1,clock_t clock2)
{
    double diffticks=clock1-clock2;
    double diffms=(diffticks)/(CLOCKS_PER_SEC/1000);
    return diffms;

}

Listing: Game2d.cpp

Download project

Keine Kommentare:

Kommentar veröffentlichen