Just a simple rectangle
Hello everyone, Im just starting to program and have absolutely no programming experience so I'm taking it really slow to get started. So I was just wondering if someone would help me make a very simple thing.
I just want to make a rectangle appear on the screen and that each time I press the arrow keys it moves in that direction. How can I go about this. I was just reading a Open Gl guide to making a triangle in objective c but I didnt understand much of it.
I just want to make a rectangle appear on the screen and that each time I press the arrow keys it moves in that direction. How can I go about this. I was just reading a Open Gl guide to making a triangle in objective c but I didnt understand much of it.
Personally, I would stay away from open gl until you are pretty good at a language (c for example).
So what would you suggest I do in the meantime, while I get better at C?
This has come up a few times recently.
http://www.idevgames.com/forum/showthread.php?t=11896
http://www.idevgames.com/forum/showthread.php?t=15520
http://www.idevgames.com/forum/showthread.php?t=10561
http://www.idevgames.com/forum/showthread.php?t=11896
http://www.idevgames.com/forum/showthread.php?t=15520
http://www.idevgames.com/forum/showthread.php?t=10561
Thank you. I actually started a tutorial I found and made a small rectangle. So thanks again.
I Just did exactly that. What I did was this:
Here's my source code for main.c:
(The project's OneSadCookie's GLUT tutorial)
- Learn the fundamentals of C at http://www.physics.drexel.edu/courses/Co.../C_basics/
- Using OneSadCookie's GLUT/Xcode Tutorial make a rectangle
- Use this thread, add keyboard input to your loop.
Here's my source code for main.c:
(The project's OneSadCookie's GLUT tutorial)
Code:
#include <stdlib.h>
#include <GLUT/glut.h>
int dir;
int shipPosX;
int shipPosY;
void keyboard(int key, int x, int y)
{
//printf("key %d\n", key);
switch (key)
{
case 100:
//lefty
shipPosX=shipPosX-20;
dir=-90;
break;
case 101:
//uppy
shipPosY=shipPosY+20;
dir=0;
break;
case 102:
//righty
shipPosX=shipPosX+20;
dir=90;
break;
case 103:
//downy
shipPosY=shipPosY-20;
dir=180;
break;
}
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// This code is where you put all drawing code. v
// draw the ship @ the position
glBegin(GL_LINE_LOOP);
glVertex3f(shipPosX-40,shipPosY-40, 0.0f);
glVertex3f(shipPosX+40,shipPosY-40, 0.0f);
glVertex3f(shipPosX+40, shipPosY+40, 0.0f);
glVertex3f(shipPosX-40,shipPosY+40,0.0f);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex3f(shipPosX-30,shipPosY-30, 0.0f);
glVertex3f(shipPosX+30,shipPosY-30, 0.0f);
glVertex3f(shipPosX+30, shipPosY+30, 0.0f);
glVertex3f(shipPosX-30,shipPosY+30,0.0f);
glEnd();
// That's the ship drawn
// drawframe
glutSwapBuffers();
}
void reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, width, 0, height);
glMatrixMode(GL_MODELVIEW);
}
void idle(void)
{
glutPostRedisplay();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(1680,1050);
glutCreateWindow("GLUT Program");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(idle);
glutSpecialFunc(keyboard); // <-- add this for keyboard
glutFullScreen();
glutMainLoop();
return EXIT_SUCCESS;
}
// Keyboard Routines\\~ Bring a Pen ~
You only need a minimal of the language to start with OpenGL. Once you start loading textures or processing meshes in your own code, you need more.
A few comments:
- It is more valuable for future serious applications to learn to draw the polygons from a vertex array. And slightly less code.
- You want to process both keydowns and keyups, so you don't move at keydown but every frame between keydown and keyup.
A few comments:
- It is more valuable for future serious applications to learn to draw the polygons from a vertex array. And slightly less code.
- You want to process both keydowns and keyups, so you don't move at keydown but every frame between keydown and keyup.
Ingemar Wrote:- You want to process both keydowns and keyups, so you don't move at keydown but every frame between keydown and keyup.
Yes. Here is an improved version which demonstrates smooth movement and how to cache keyboard events so you can more easily utilize them anywhere in your code, not just in the GLUT callbacks.
Use arrow keys for the smooth movement and wasd to demonstrate the discrete keyDowns.
Code:
#include <stdlib.h>
#include <GLUT/glut.h>
enum
{
false,
true
};
typedef unsigned char Bool;
typedef enum
{
ENTER = 3,
TAB = 9,
RETURN = 13,
ESC = 27,
SPACE = 32,
DEL = 127,
UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW,
NUM_KEY_CODES
} KeyCode;
Bool key[NUM_KEY_CODES], keyDown[NUM_KEY_CODES], keyUp[NUM_KEY_CODES];
int lastFrameTime = 0;
float dt; // delta time (how much time in between frames, used for all movement calculations)
float shipPosX;
float shipPosY;
void resetKeyboardInput(void)
{
int i;
for (i = 0; i < NUM_KEY_CODES; i++)
{
keyDown[i] = false;
keyUp[i] = false;
}
}
void keyboard(unsigned char rawKeyCode, int x, int y)
{
if (rawKeyCode < NUM_KEY_CODES)
{
key[rawKeyCode] = true;
keyDown[rawKeyCode] = true;
}
}
void keyboardUp(unsigned char rawKeyCode, int x, int y)
{
if (rawKeyCode < NUM_KEY_CODES)
{
key[rawKeyCode] = false;
keyUp[rawKeyCode] = false;
}
}
void keyboardSpecial(int rawKeyCode, int x, int y)
{
switch (rawKeyCode)
{
case GLUT_KEY_LEFT:
key[LEFT_ARROW] = true;
keyDown[LEFT_ARROW] = true;
break;
case GLUT_KEY_UP:
key[UP_ARROW] = true;
keyDown[UP_ARROW] = true;
break;
case GLUT_KEY_RIGHT:
key[RIGHT_ARROW] = true;
keyDown[RIGHT_ARROW] = true;
break;
case GLUT_KEY_DOWN:
key[DOWN_ARROW] = true;
keyDown[DOWN_ARROW] = true;
break;
}
}
void keyboardSpecialUp(int rawKeyCode, int x, int y)
{
switch (rawKeyCode)
{
case GLUT_KEY_LEFT:
key[LEFT_ARROW] = false;
keyUp[LEFT_ARROW] = true;
break;
case GLUT_KEY_UP:
key[UP_ARROW] = false;
keyUp[UP_ARROW] = true;
break;
case GLUT_KEY_RIGHT:
key[RIGHT_ARROW] = false;
keyUp[RIGHT_ARROW] = true;
break;
case GLUT_KEY_DOWN:
key[DOWN_ARROW] = false;
keyUp[DOWN_ARROW] = true;
break;
}
}
void display(void)
{
if (lastFrameTime == 0)
{
lastFrameTime = glutGet(GLUT_ELAPSED_TIME);
}
int now = glutGet(GLUT_ELAPSED_TIME);
int elapsedMilliseconds = now - lastFrameTime;
float dt = elapsedMilliseconds / 1000.0f;
lastFrameTime = now;
// "key" is cached locally so that it stays down until the next key up event
if (key[LEFT_ARROW])
shipPosX -= 200.0f * dt;
if (key[RIGHT_ARROW])
shipPosX += 200.0f * dt;
if (key[UP_ARROW])
shipPosY += 200.0f * dt;
if (key[DOWN_ARROW])
shipPosY -= 200.0f * dt;
// also do wasd to demonstrate discrete "keyDown" events
if (keyDown['a'])
shipPosX -= 20.0f;
if (keyDown['d'])
shipPosX += 20.0f;
if (keyDown['w'])
shipPosY += 20.0f;
if (keyDown['s'])
shipPosY -= 20.0f;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// This code is where you put all drawing code. v
// draw the ship @ the position
glBegin(GL_LINE_LOOP);
glVertex3f(shipPosX-40,shipPosY-40, 0.0f);
glVertex3f(shipPosX+40,shipPosY-40, 0.0f);
glVertex3f(shipPosX+40, shipPosY+40, 0.0f);
glVertex3f(shipPosX-40,shipPosY+40,0.0f);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex3f(shipPosX-30,shipPosY-30, 0.0f);
glVertex3f(shipPosX+30,shipPosY-30, 0.0f);
glVertex3f(shipPosX+30, shipPosY+30, 0.0f);
glVertex3f(shipPosX-30,shipPosY+30,0.0f);
glEnd();
// That's the ship drawn
// drawframe
glutSwapBuffers();
// do this to clear the key ups and key downs for each frame
resetKeyboardInput();
}
void reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, width, 0, height);
glMatrixMode(GL_MODELVIEW);
}
void idle(void)
{
glutPostRedisplay();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
//glutInitWindowSize(1680,1050);
glutInitWindowSize(640, 480);
glutCreateWindow("GLUT Program");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(idle);
glutKeyboardFunc(keyboard);
glutKeyboardUpFunc(keyboardUp);
glutSpecialFunc(keyboardSpecial);
glutSpecialUpFunc(keyboardSpecialUp);
//glutFullScreen();
glutMainLoop();
return EXIT_SUCCESS;
}
Thanks, I know understand It. I see you've implemented the arrow keys, but not Space. When your switch section chooses keys (GLUT_KEY_LEFT) I tried adding (Since there's no GLUT, or is there, space key name) case 32:, but that fails too. How can I implement a space bar?
~ Bring a Pen ~
If you look carefully you'll notice that I did implement space already. The constants are near the top:
What's not obvious is that the constants for regular characters and numbers don't need to be listed since they can be accessed using simple character constants like 'a', 'b', '1', 'H', etc.
You can find out if space is pressed by doing something like:
There are four GLUT keyboard functions here: keyboard(), keyboardUp(), keyboardSpecial(), and keyboardSpecialUp(); Don't put any code in those functions. What they do is cache the values sent from GLUT so you can use them elsewhere in your program, like in display(). They're "cached" by setting a Boolean flag in the three arrays: key[], keyDown[], keyUp[]
So here's how you would detect a key being held down:
Here's how you would detect a key being pressed for just one frame. In this example we're checking to see if the "a" key was pressed:
You can also see if a key was let up:
Code:
typedef enum
{
ENTER = 3,
TAB = 9,
RETURN = 13,
ESC = 27,
SPACE = 32,
DEL = 127,
UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW,
NUM_KEY_CODES
} KeyCode;What's not obvious is that the constants for regular characters and numbers don't need to be listed since they can be accessed using simple character constants like 'a', 'b', '1', 'H', etc.
You can find out if space is pressed by doing something like:
Code:
if (key[SPACE])
shipPosX -= 5.0f * dt;There are four GLUT keyboard functions here: keyboard(), keyboardUp(), keyboardSpecial(), and keyboardSpecialUp(); Don't put any code in those functions. What they do is cache the values sent from GLUT so you can use them elsewhere in your program, like in display(). They're "cached" by setting a Boolean flag in the three arrays: key[], keyDown[], keyUp[]
So here's how you would detect a key being held down:
Code:
if (key[LEFT_ARROW])
shipPosX -= 200.0f * dt;Here's how you would detect a key being pressed for just one frame. In this example we're checking to see if the "a" key was pressed:
Code:
if (keyDown['a'])
shipPosX -= 20.0f;You can also see if a key was let up:
Code:
if (keyUp['a'])
shipPosX -= 20.0f;
Ahh. Thanks loads. What I did try was right, it's the firing sequence that's broke:
It's still not working. I've tried moving the contents of fire() to inside the if block, but still no results. I've also tried putting a rudimentary drawing operation in fire(), but even that won't work.






It's still not working. I've tried moving the contents of fire() to inside the if block, but still no results. I've also tried putting a rudimentary drawing operation in fire(), but even that won't work.







Code:
#include <stdlib.h>
#include <GLUT/glut.h>
enum
{
false,
true
};
typedef unsigned char Bool;
typedef enum
{
ENTER = 3,
TAB = 9,
RETURN = 13,
ESC = 27,
SPACE = 32,
DEL = 127,
UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW,
NUM_KEY_CODES
} KeyCode;
Bool key[NUM_KEY_CODES], keyDown[NUM_KEY_CODES], keyUp[NUM_KEY_CODES];
int lastFrameTime = 0;
float dt; // delta time (how much time in between frames, used for all movement calculations)
float shipPosX;
float shipPosY;
int dir;
void fire()
{
if (dir==0)
{
glBegin(GL_LINE_STRIP);
glVertex3f(shipPosX,shipPosY,0.0f);
glVertex3f(shipPosX,shipPosY+500,0.0f);
glEnd();
}
else if (dir==90)
{
glBegin(GL_LINE_STRIP);
glVertex3f(shipPosX,shipPosY,0.0f);
glVertex3f(shipPosX+500,shipPosY,0.0f);
glEnd();
}
else if (dir==180)
{
glBegin(GL_LINE_STRIP);
glVertex3f(shipPosX,shipPosY,0.0f);
glVertex3f(shipPosX,shipPosY-500,0.0f);
glEnd();
}
else if (dir==-90)
{
glBegin(GL_LINE_STRIP);
glVertex3f(shipPosX,shipPosY,0.0f);
glVertex3f(shipPosX-500,shipPosY,0.0f);
glEnd();
}
}
void resetKeyboardInput(void)
{
int i;
for (i = 0; i < NUM_KEY_CODES; i++)
{
keyDown[i] = false;
keyUp[i] = false;
}
}
void keyboard(unsigned char rawKeyCode, int x, int y)
{
if (rawKeyCode < NUM_KEY_CODES)
{
key[rawKeyCode] = true;
keyDown[rawKeyCode] = true;
}
}
void keyboardUp(unsigned char rawKeyCode, int x, int y)
{
if (rawKeyCode < NUM_KEY_CODES)
{
key[rawKeyCode] = false;
keyUp[rawKeyCode] = false;
}
}
void keyboardSpecial(int rawKeyCode, int x, int y)
{
switch (rawKeyCode)
{
case GLUT_KEY_LEFT:
key[LEFT_ARROW] = true;
keyDown[LEFT_ARROW] = true;
break;
case GLUT_KEY_UP:
key[UP_ARROW] = true;
keyDown[UP_ARROW] = true;
break;
case GLUT_KEY_RIGHT:
key[RIGHT_ARROW] = true;
keyDown[RIGHT_ARROW] = true;
break;
case GLUT_KEY_DOWN:
key[DOWN_ARROW] = true;
keyDown[DOWN_ARROW] = true;
break;
}
}
void keyboardSpecialUp(int rawKeyCode, int x, int y)
{
switch (rawKeyCode)
{
case GLUT_KEY_LEFT:
key[LEFT_ARROW] = false;
keyUp[LEFT_ARROW] = true;
break;
case GLUT_KEY_UP:
key[UP_ARROW] = false;
keyUp[UP_ARROW] = true;
break;
case GLUT_KEY_RIGHT:
key[RIGHT_ARROW] = false;
keyUp[RIGHT_ARROW] = true;
break;
case GLUT_KEY_DOWN:
key[DOWN_ARROW] = false;
keyUp[DOWN_ARROW] = true;
break;
}
}
void display(void)
{
if (lastFrameTime == 0)
{
lastFrameTime = glutGet(GLUT_ELAPSED_TIME);
}
int now = glutGet(GLUT_ELAPSED_TIME);
int elapsedMilliseconds = now - lastFrameTime;
float dt = elapsedMilliseconds / 1000.0f;
lastFrameTime = now;
// "key" is cached locally so that it stays down until the next key up event
if (key[LEFT_ARROW])
{
shipPosX -= 200.0f * dt;
dir = -90;
}
if (key[RIGHT_ARROW])
{
shipPosX += 200.0f * dt;
dir = 90;
}
if (key[UP_ARROW])
{
shipPosY += 200.0f * dt;
dir = 0;
}
if (key[DOWN_ARROW])
{
shipPosY -= 200.0f * dt;
dir =180;
}
if (key[SPACE])
{
fire();
}
// also do wasd to demonstrate discrete "keyDown" events
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// This code is where you put all drawing code. v
// draw the ship @ the position
glBegin(GL_LINE_LOOP);
glVertex3f(shipPosX-40,shipPosY-40, 0.0f);
glVertex3f(shipPosX+40,shipPosY-40, 0.0f);
glVertex3f(shipPosX+40, shipPosY+40, 0.0f);
glVertex3f(shipPosX-40,shipPosY+40,0.0f);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex3f(shipPosX-30,shipPosY-30, 0.0f);
glVertex3f(shipPosX+30,shipPosY-30, 0.0f);
glVertex3f(shipPosX+30, shipPosY+30, 0.0f);
glVertex3f(shipPosX-30,shipPosY+30,0.0f);
glEnd();
if (dir==0)
{
glBegin(GL_LINES);
glVertex3f(shipPosX,shipPosY,0.0f);
glVertex3f(shipPosX,shipPosY+40,0.0f);
glEnd();
}
else if (dir==90)
{
glBegin(GL_LINES);
glVertex3f(shipPosX,shipPosY,0.0f);
glVertex3f(shipPosX+40,shipPosY,0.0f);
glEnd();
}
else if (dir==180)
{
glBegin(GL_LINES);
glVertex3f(shipPosX,shipPosY,0.0f);
glVertex3f(shipPosX,shipPosY-40,0.0f);
glEnd();
}
else if (dir==-90)
{
glBegin(GL_LINES);
glVertex3f(shipPosX,shipPosY,0.0f);
glVertex3f(shipPosX-40,shipPosY,0.0f);
glEnd();
}
// That's the ship drawn
// drawframe
glutSwapBuffers();
// do this to clear the key ups and key downs for each frame
resetKeyboardInput();
}
void reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, width, 0, height);
glMatrixMode(GL_MODELVIEW);
}
void idle(void)
{
glutPostRedisplay();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
//glutInitWindowSize(1680,1050);
glutInitWindowSize(640, 480);
glutCreateWindow("GLUT Program");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(idle);
glutFullScreen();
glutKeyboardFunc(keyboard);
glutKeyboardUpFunc(keyboardUp);
glutSpecialFunc(keyboardSpecial);
glutSpecialUpFunc(keyboardSpecialUp);
//glutFullScreen();
glutMainLoop();
return EXIT_SUCCESS;
}~ Bring a Pen ~
Possibly Related Threads...
| Thread: | Author | Replies: | Views: | Last Post | |
| Sphere/Rectangle collision detection | sinclair44 | 5 | 7,372 |
Dec 12, 2007 02:44 PM Last Post: scgames |
|

