#define NUMBER_OF_ANIMATIONS 4
using namespace std;
extern Texture texture[3];
extern int mapdata[28][25];
double playerx = -15.0;
double playery = 11.0;
int playerposx = 1;
int playerposy = 1;
float plyx = 0;
float plyy = 0;
double current_anim = 1;
int DrawMap()
{
//glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
glDisable(GL_ALPHA_TEST);
for (int x=0;x < 28;x++)
{
for (int y=0;y<25;y++)
{
glLoadIdentity();
glTranslatef(-16.0f+x,12.0f-y,-30.0f);
glBindTexture(GL_TEXTURE_2D, texture[(mapdata[x][y])].texID);
glBegin(GL_QUADS);
glTexCoord2d(0.0,1.0);
glVertex3f(-0.5f, 0.5f, 0.0f);
glTexCoord2d(1.0,1.0);
glVertex3f(0.5f, 0.5f, 0.0f);
glTexCoord2d(1.0,0.0);
glVertex3f(0.5f, -0.5f, 0.0f);
glTexCoord2d(0.0,0.0);
glVertex3f(-0.5f, -0.5f, 0.0f);
glEnd();
}
}
glEnable(GL_ALPHA_TEST);
return true;
}
int DrawPlayer(double anim)
{
// need to add player x and y pos to translatef command
// also need to incorporate the anim in the function header
// aswell as the timer.
// angle += (float)(milliseconds) / 5.0f; // Update angle Based On The Clock
glLoadIdentity();
glTranslatef(playerx,playery,-30.0f);
glBindTexture(GL_TEXTURE_2D,texture[2].texID);
float sprite = (anim/NUMBER_OF_ANIMATIONS);
float sprite2 = sprite-(0.25);
glBegin(GL_QUADS);
glTexCoord2d(0.0,1.0-sprite2);
glVertex3f(-0.5f, 0.5f, 0.0f);
glTexCoord2d(1.0,1.0-sprite2);
glVertex3f(0.5f, 0.5f, 0.0f);
glTexCoord2d(1.0,1.0-sprite);
glVertex3f(0.5f, -0.5f, 0.0f);
glTexCoord2d(0.0,1.0-sprite);
glVertex3f(-0.5f, -0.5f, 0.0f);
glEnd();
return true;
}
int DrawGLScene(GLvoid) // Here''s Where We Do All The Drawing
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The Current Modelview Matrix
DrawMap();
DrawPlayer(current_anim);
return true; // Everything Went OK
}
int MoveAi()
{
return true;
}
int CheckKeyboardInput(DWORD milliseconds)
{
double werd = (milliseconds*0.001);
if (keys[VK_ESCAPE]) // Was ESC Pressed?
{
done=TRUE; // ESC Signalled A Quit
}
if (keys[VK_F1]) // Is F1 Being Pressed?
{
keys[VK_F1]=FALSE; // If So Make Key FALSE
KillGLWindow(); // Kill Our Current Window
fullscreen=!fullscreen; // Toggle Fullscreen / Windowed Mode
// Recreate Our OpenGL Window
if (!CreateGLWindow("Opengl Basecode v0.25",SCREENWIDTH,SCREENHEIGHT,BITSPERPIXEL,fullscreen))
{
return 0; // Quit If Window Was Not Created
}
}
if (keys[VK_LEFT])
{
// keys[VK_LEFT] = false;
//playerx -= (float) (milliseconds) / 200.0f;
playerx -= (float) (werd) *5;
current_anim = 4;
}
if (keys[VK_RIGHT])
{
// keys[VK_RIGHT] = false;
//playerx += (float) (milliseconds) / 200.0f;
playerx += (werd) *5;
current_anim = 3;
plyx += (werd) *5;
if (mapdata[playerposx][playerposy] == 0)
{
playerx -= (werd) *5;
current_anim = 3;
plyx -= (werd) *5;
}
if (plyx >=1.0f)
{
plyx = 0.0f;
playerposx++;
}
}
if (keys[VK_UP])
{
//keys[VK_UP] = false;
//playerx -= (float) (milliseconds) / 200.0f;
playery += (float) (werd) *5;
current_anim = 4;
}
if (keys[VK_DOWN])
{
// keys[VK_DOWN] = false;
//playerx += (float) (milliseconds) / 200.0f;
playery -= (float) (werd) *5;
current_anim = 3;
}
return true;
}
void Update (DWORD milliseconds) // Perform Motion Updates Here
{
CheckKeyboardInput(milliseconds);
MoveAi();
DrawGLScene();
// angle += (float)(milliseconds) / 5.0f; // Update angle Based On The Clock
}
collision detection with a 2d tile map?
hi.
i am trying to implement some sort of collision detection for my little tile map using opengl. However it doesn''t want to work for me! at the moment i am just testing the right movement of a quad and it goes over to the right off my map by 2 or 3 tiles before stopping.
Here is my rendering and keyboard checking stuff. Maybe someone could help me out ??
ok i have managed to get some sort of collision detection happenning but its not perfect. sometimes i can move left and i walk right through the wall if i am not right in line with it, and i can''t fit through some small gaps!
here is my revised drawing and keyboard input functions
And if u would like the complete program go here http://werdy666.20megsfree.com
here is my revised drawing and keyboard input functions
#define NUMBER_OF_ANIMATIONS 4using namespace std;extern Texture texture[3];extern int mapdata[28][25];double playerx = -15.0;double playery = 11.0;double county = 1;double countx = 1;double current_anim = 1;int DrawMap(){ glDisable(GL_ALPHA_TEST); for (int x=0;x < 28;x++) { for (int y=0;y<25;y++) { glLoadIdentity(); glTranslatef(-16.0f+x,12.0f-y,-30.0f); glBindTexture(GL_TEXTURE_2D, texture[(mapdata[x][y])].texID); glBegin(GL_QUADS); glTexCoord2d(0.0,1.0); glVertex3f(-0.5f, 0.5f, 0.0f); glTexCoord2d(1.0,1.0); glVertex3f(0.5f, 0.5f, 0.0f); glTexCoord2d(1.0,0.0); glVertex3f(0.5f, -0.5f, 0.0f); glTexCoord2d(0.0,0.0); glVertex3f(-0.5f, -0.5f, 0.0f); glEnd(); } } glEnable(GL_ALPHA_TEST);return true;}int DrawPlayer(double anim){ glLoadIdentity(); glTranslatef(playerx,playery,-30.0f); glBindTexture(GL_TEXTURE_2D,texture[2].texID); float sprite = (anim/NUMBER_OF_ANIMATIONS); float sprite2 = sprite-(0.25); glBegin(GL_QUADS); glTexCoord2d(0.0,1.0-sprite2); glVertex3f(-0.5f, 0.5f, 0.0f); glTexCoord2d(1.0,1.0-sprite2); glVertex3f(0.5f, 0.5f, 0.0f); glTexCoord2d(1.0,1.0-sprite); glVertex3f(0.5f, -0.5f, 0.0f); glTexCoord2d(0.0,1.0-sprite); glVertex3f(-0.5f, -0.5f, 0.0f); glEnd();return true;}int DrawGLScene(GLvoid) // Here''s Where We Do All The Drawing{ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer glLoadIdentity(); // Reset The Current Modelview Matrix DrawMap(); DrawPlayer(current_anim); return true; // Everything Went OK}int MoveAi(){return true;}int CheckKeyboardInput(DWORD milliseconds){ double werd = (milliseconds*0.001); if (keys[VK_ESCAPE]) // Was ESC Pressed? { done=TRUE; // ESC Signalled A Quit } if (keys[VK_F1]) // Is F1 Being Pressed? { keys[VK_F1]=FALSE; // If So Make Key FALSE KillGLWindow(); // Kill Our Current Window fullscreen=!fullscreen; // Toggle Fullscreen / Windowed Mode // Recreate Our OpenGL Window if (!CreateGLWindow("Opengl Basecode v0.25",SCREENWIDTH,SCREENHEIGHT,BITSPERPIXEL,fullscreen)) { return 0; // Quit If Window Was Not Created } } if (keys[VK_LEFT]) { playerx -= .1; current_anim = 4; countx-=.1; if ( (mapdata[(int)countx][(int)county] == 0) ) { playerx += 0.1; countx+=.1; } } if (keys[VK_RIGHT]) { playerx += 0.1; current_anim = 3; countx+=0.1; if ( (mapdata[(int)countx][(int)county] == 0) || (mapdata[(int)countx+1][(int)county] == 0)) { playerx -= 0.1; countx-=.1; } } if (keys[VK_UP]) { playery += .1; current_anim = 2; county-=.1; if ( mapdata[(int)countx][(int)county] == 0) { playery -= .1; county+=.1; } } if (keys[VK_DOWN]) { playery -= .1; current_anim = 1; county+=.1; if ( (mapdata[(int)countx][(int)county] == 0) || (mapdata[(int)countx][(int)county+1] == 0)) { playery += .1; county-=.1; } }return true;}void Update (DWORD milliseconds) // Perform Motion Updates Here{ CheckKeyboardInput(milliseconds); MoveAi(); DrawGLScene();}
And if u would like the complete program go here http://werdy666.20megsfree.com
Im, not exactly sure about this sort of game, never spent too much time thinking tile based, but I had a similar broblem with a tetris clone i was making.
Firstly are u sure u need to be using an OR clause in the collision check? I assume the code says, "if the tile im on is clear OR the next tile is clear, then walk...". I would have thought that you would only want to move if the tile your on AND the next tile were clear.
The way I managed to get round this was, to slice the space up into squares (your tiles) and then decide which square the player co-ords were in. Looking at ur code I think u shouldn''t rely on the conversion of float to int to convert from point to square... calculate it ur self. Id be more help but I can''t look at my own code now, and that was years ago...
Firstly are u sure u need to be using an OR clause in the collision check? I assume the code says, "if the tile im on is clear OR the next tile is clear, then walk...". I would have thought that you would only want to move if the tile your on AND the next tile were clear.
The way I managed to get round this was, to slice the space up into squares (your tiles) and then decide which square the player co-ords were in. Looking at ur code I think u shouldn''t rely on the conversion of float to int to convert from point to square... calculate it ur self. Id be more help but I can''t look at my own code now, and that was years ago...
Thanks for your input TheSyan.
The main reason for the OR instead of AND is that cause i only move my player 0.1 at a time, if i was moving left and had just moved into the last tile before a wall, wouldn''t it stop me straight away without allowing me to move right up against the wall? But it is something i will put more thought into.
I am a beginner, so could you maybe give me some hints or point me to a website that will help me understand converting a float such as 1.245 to an int?
again thanks for your input!
Werdy666
My Homepage : http://werdy666.20megsfree.com/
The main reason for the OR instead of AND is that cause i only move my player 0.1 at a time, if i was moving left and had just moved into the last tile before a wall, wouldn''t it stop me straight away without allowing me to move right up against the wall? But it is something i will put more thought into.
I am a beginner, so could you maybe give me some hints or point me to a website that will help me understand converting a float such as 1.245 to an int?
again thanks for your input!
Werdy666
My Homepage : http://werdy666.20megsfree.com/
Ok... the conversion method... there''s no garentee this is correct, its all from memory...
U know the size of your tile grid, say 100.0f gl co-ordinates square, and your player co-ords, say for example ( 20.3f, 10.2f ). Oh and your tile size, Ill say 10.0f by 10.0f.
So you start by finding the player co-ords relative to the grid, say the grids 0,0 cell starts at gl(10.0f,0.0f,0.0f). The player co-ords relative would be ( 10.3f, 10.2f ).
Then you round up/down the player co-ords to the nearest integer. Theres a function somewhere in the C++ math libs, look in the help files for that. It goes something like,
U know the size of your tile grid, say 100.0f gl co-ordinates square, and your player co-ords, say for example ( 20.3f, 10.2f ). Oh and your tile size, Ill say 10.0f by 10.0f.
So you start by finding the player co-ords relative to the grid, say the grids 0,0 cell starts at gl(10.0f,0.0f,0.0f). The player co-ords relative would be ( 10.3f, 10.2f ).
Then you round up/down the player co-ords to the nearest integer. Theres a function somewhere in the C++ math libs, look in the help files for that. It goes something like,
int player_tile_x = rounddown( player_x );int player_tile_y = rounddown( player_y );This gives you a player tile of (10, 10) if u round down. Whether you round up or down, I think changes whether the player_tile_ values start from 0 or 1...Example: |0 | 1 | 2 | 3 | ... -----|---|---|---| ...0 | | | | | ...-----|---|---|---| ...1 | | | | | ...-----|---|---|---| ...2 | | | | | ...-----|---|---|---| ...3 | | | P | | ...-----|---|---|---| ...Now u can use these co-ords to check against your tile grid (but get the start point right or u end up going off the grid''n''stuff).That was a bit messy and I confused my self halfway throught writing, when I get home, If you still have problems ill look at my code and post some of my solutions...
I havn''t been able to find the rounding down method in the msdn for c++. So any extra info u can provide would be great!
My only other idea was to increase the size of my map array. So like if i move 10 points to go from 1 tile to the next, then increase the array 10x to [280][250] and basically fill in the first tile by filling the array 10 times instead of 1. so like when i have my original array of [28][25] the first array would be [0][0] would say equal 1, where as with the new [280][250] from [0][0] to [9][0] would all equal 1. Would this work too? but it does take quite a bit of extra memory!
Thanks for helping me TheSyan!
Werdy666
My Homepage : http://werdy666.20megsfree.com/
My only other idea was to increase the size of my map array. So like if i move 10 points to go from 1 tile to the next, then increase the array 10x to [280][250] and basically fill in the first tile by filling the array 10 times instead of 1. so like when i have my original array of [28][25] the first array would be [0][0] would say equal 1, where as with the new [280][250] from [0][0] to [9][0] would all equal 1. Would this work too? but it does take quite a bit of extra memory!
Thanks for helping me TheSyan!
Werdy666
My Homepage : http://werdy666.20megsfree.com/
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement