Forum Thread
  Posts  
Open GL: Move in direction facing (Forums : 2D Graphics : Open GL: Move in direction facing) Locked
Thread Options
Kamikazi[Uk]
Kamikazi[Uk] Mobile Game Coder
Jun 19 2011 Anchor

Hi,

I'm currently working on my own game engine and i have it so i can now rotate images/sprites. The issue i'm currently having is how would i move around in the direction i'm facing. I spent ages looking through google etc but can't seem to find anything. I have an X and a Y coordinate and i can get the angle that it's facing but not sure how to move it that way as i can make it go along x and y axes just not sure how to move it on angle so i can make AI stuff :D. Currently i have a x and y velocity and set it to 5 etc when i press left key etc.

This diagram should explain what i mean. I want to move on the red axis but atm i only know how to go on blue axis.

Code:

//Update pos
sampleimage.setX(sampleimage.getX() + (cos(sampleimage.getAngle() * (3.142/180) ) * xvelocity) );

sampleimage.setY(sampleimage.getY() + (sin(sampleimage.getAngle() * (3.142/180) ) * yvelocity) );
//This gets called every frame.

So i want to try move around in 360 degrees such as games like astroids etc but not sure how to go about doing it, trying to read up more on trigonometry as need to get better at maths. I have half decent knowledge of vectors and matrices so if you could give me an equation that would be great.

Thanks Alot.

Edited by: Kamikazi[Uk]

Jun 19 2011 Anchor

I think what you missing is directional velocity. When you express movement in terms of an angle, you also need a length of movement at that angle. This, in trig, is the equivalent of the hypotenuse of a right triangle. What your doing wrong is you are using the xvelocity and yvelocity when multiplying, which be equivalent to the legs of a right triangle.

You would get your X and Y values like something like this so (guessing on how your code is):

samepleimage.setX(sampleimage.getX() + ( (cos(sampleimage.getAngle() * (3.14/180.0)) * velocity) );

samepleimage.setY(sampleimage.getY() + ( (sin(sampleimage.getAngle() * (3.14/180.0)) * velocity) );

Alternatively, you can use transform matrices. You would first create a vector, apply a transformation along the X axis the length of the velocity, then apply a rotatation matrix around the Z axis at the angle. Then just add that vector and your sampleimage's vector. (I think that'll work).

Edited by: x3nu

Kamikazi[Uk]
Kamikazi[Uk] Mobile Game Coder
Jun 19 2011 Anchor

Ah ok, i added that bit of code and added the velocity variable. This seems to be kinda working if you moev around in angles of 15 degrees etc it don't work but every 45 degrees it goes in the correct direction.

Would i have to set the velocity to 1 when to move and 0 to stop or am i missing something.

Thanks.

--


Portfolio 
Blog | Full-Time Mobile Games Programmer

Jun 19 2011 Anchor

Dang, forgot something. Ok, I'm guessing you are using the left and right keys for rotating right? so you would set the velocity with your up and down keys, like you said. Tell me if that works.

Kamikazi[Uk]
Kamikazi[Uk] Mobile Game Coder
Jun 19 2011 Anchor

I tryed setting the velocity as 1, 2, 3, 4 and 5. It seems to kinda work but if you rotate it don't go in that direction unless it's on the x and y axis and then diagonals so not any other angle inbetween.

This gets called every frame after the key presses:

   sampleimage.setX(sampleimage.getX() + (cos(sampleimage.getAngle() * (3.14159265/180.0)) * velocity) );
   sampleimage.setY(sampleimage.getY() + (sin(sampleimage.getAngle() * (3.14159265/180.0)) * velocity) );

Then i just call velocity = 1 when you press the left key.

Edited by: Kamikazi[Uk]

--


Portfolio 
Blog | Full-Time Mobile Games Programmer

Jun 19 2011 Anchor

How are you rotating the object?

Kamikazi[Uk]
Kamikazi[Uk] Mobile Game Coder
Jun 19 2011 Anchor

I just call translate the object so i can rotate it then i jut have a function called set angle.

 //Rotate image
   glTranslatef(tempx + (w/2), tempy + (h/2),0);
   glRotatef(angle-90, 0, 0, 1);
   glTranslatef(-tempx - (w/2), -tempy - (h/2),0);

Edited by: Kamikazi[Uk]

--


Portfolio 
Blog | Full-Time Mobile Games Programmer

Jun 19 2011 Anchor

I can't see the problem without seeing your code...

Edited by: x3nu

Jun 19 2011 Anchor

I wrote up a little some code for what your trying to do. This works, I tested it, so see if you can find your problem:

#include "SDL.h"
#include "SDL_opengl.h"
#include <cmath>
#pragma comment(lib, "SDL.lib")
#pragma comment(lib, "SDLmain.lib")
#pragma comment(lib, "OpenGL32.lib")


bool quit = false;
float velocity = 0;
float rotation = 0;


struct texture
{
	GLuint tex;
	int h;
	int w;
};

class object
{

public:

	object( texture &amp; tex ) : x(0), y(0), angle(0), image(tex) {}

	~object() {}

	void setX( float newx ) { x = newx; }

	float getX() { return x; }

	void setY( float newy ) { y = newy; }

	float getY() { return y; }

	void setAngle( float newangle ) { angle = newangle; }

	float getAngle() { return angle; }

	texture * getImage() { return ℑ }

protected:

	float x, y;
	float angle;
	texture image;

};


void InitGL()
{
	glMatrixMode( GL_PROJECTION );
	glLoadIdentity();
	glOrtho(-320.0, 320.0, -240.0, 240.0, 0.0, 1024.0);
	glViewport( 0.0, 0.0, 640, 480 );
	glClearColor( 0.0, 0.0, 0.0, 0.0 );
}


void RenderObject( object * obj )
{
	glMatrixMode( GL_MODELVIEW );
	glLoadIdentity();

	glTranslatef( obj->getX(), obj->getY(), 0 );
	glRotatef( obj->getAngle(), 0.0, 0.0, 1.0 );
	glTranslatef( (float)obj->getImage()->w / -2.0, (float)obj->getImage()->h / -2.0, 0 );


	glEnable( GL_TEXTURE_2D );
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_CLAMP);
	glBindTexture( GL_TEXTURE_2D, obj->getImage()->tex );

	glBegin( GL_POLYGON );

	glTexCoord2f( 0.0, 0.0 );
	glVertex2f( 0.0, 0.0 );

	glTexCoord2f( 1.0, 0.0 );
	glVertex2f( obj->getImage()->w, 0.0 );
	
	glTexCoord2f( 1.0, 1.0 );
	glVertex2f( obj->getImage()->w, obj->getImage()->h );

	glTexCoord2f( 0.0, 1.0 );
	glVertex2f( 0.0, obj->getImage()->h );

	glEnd();
}


void CaptureKeys()
{
	SDL_Event evt;

	while ( SDL_PollEvent(&amp;evt) )
	{
		if ( evt.type == SDL_KEYDOWN)
		{
			switch ( evt.key.keysym.sym )
			{
			case SDLK_ESCAPE:
				quit = true;
				break;

			case SDLK_LEFT:
				rotation += 60.0;
				break;

			case SDLK_RIGHT:
				rotation -= 60.0;
				break;

			case SDLK_UP:
				velocity += 150.0;
				break;

			case SDLK_DOWN:
				velocity -= 150.0;
				break;
			}
		}

		if ( evt.type == SDL_KEYUP )
		{
			switch ( evt.key.keysym.sym )
			{

			case SDLK_LEFT:
				rotation -= 60.0;
				break;

			case SDLK_RIGHT:
				rotation += 60.0;
				break;

			case SDLK_UP:
				velocity -= 150.0;
				break;

			case SDLK_DOWN:
				velocity += 150.0;
				break;
			}
		}
	}
}


object * CreateObject()
{
	GLuint pixels[128][128][4];
	int i, j, c;
	for (i = 0; i < 128; i++) 
	{
		for (j = 0; j < 128; j++) 
		{
			c = (((i&amp;0x4)==0)^((j&amp;0x4))==0)*255;
			pixels[i][j][0] = (GLubyte) c;
			pixels[i][j][1] = (GLubyte) c;
			pixels[i][j][2] = (GLubyte) c;
			pixels[i][j][3] = (GLubyte) 255;
		}
	}

	texture tex;
	tex.h = 128;
	tex.w = 128;

	glGenTextures( 1, &amp;tex.tex );

	glBindTexture(GL_TEXTURE_2D, tex.tex );

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.w, tex.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels );

	return  new object(tex);
}


void ModifyObject( object * obj )
{
	obj->setAngle( obj->getAngle() + (rotation * (1.0/60.0)) );
	obj->setX( obj->getX() + ( cosf(obj->getAngle() * (3.141592/180.0)) * (velocity * (1.0/60.0)) ) );
	obj->setY( obj->getY() + ( sinf(obj->getAngle() * (3.141592/180.0)) * (velocity * (1.0/60.0)) ) );
}


int main( int argc, char * argv[] )
{
	SDL_Init( SDL_INIT_VIDEO );

	SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 );
	SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 );
	SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 );
	SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8 );
	SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 32 );
	SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

	SDL_SetVideoMode( 640, 480, 32, SDL_OPENGL | SDL_HWSURFACE );

	InitGL();

	object * pObj = CreateObject();

	while ( !quit )
	{
		CaptureKeys();
		ModifyObject( pObj );
		glClear( GL_COLOR_BUFFER_BIT );
		RenderObject( pObj );
		SDL_GL_SwapBuffers();
	}

	SDL_Quit();

	return 0;
}

Edited by: x3nu

Kamikazi[Uk]
Kamikazi[Uk] Mobile Game Coder
Jun 20 2011 Anchor

Ok thanks for that. I think i have got this working now. I owe you a big one :D. Moci all the rotation code is still very wip that is why it was so messy i havn't gotten around to optimizing i like to make sure feature works before optimizing it etc.

Also i said on the thread that i was going to be running benchmarks abit later as want to get other stuff done first the rest of engine is very optimized.

P.S is it currently in radians as when i try 45 it hardly moves it.

Edited by: Kamikazi[Uk]

--


Portfolio 
Blog | Full-Time Mobile Games Programmer

Jun 20 2011 Anchor

Just curious, what type of game are you wanting to make with the engine?

Kamikazi[Uk]
Kamikazi[Uk] Mobile Game Coder
Jun 21 2011 Anchor

Currently it's just a practise engine as i'm doing programming at university so practising making a 2D game engine. I wanted to do this rotation thing because i'm actaully planning on making some AI demos with my engine as currently learning it and finding it intresting and doing a module on it next year.

I will be releasing the engine open source once i get it to a good enough state :D.

--


Portfolio 
Blog | Full-Time Mobile Games Programmer

Jok3r098
Jok3r098 “A computer is like air conditioning – it becomes useless when you open Windows” - Linus Torvals
Jun 21 2011 Anchor

*snip* never mind i was stating the obvious

Edited by: Jok3r098

Kamikazi[Uk]
Kamikazi[Uk] Mobile Game Coder
Jun 21 2011 Anchor

Ok :P. I get this all sorted now i have just added arc tangents successfully and i have made a fun little example were there is a enemy and he will find out the angle to the other destination and then he will go there once he spots it :D.

l0rdx3nu what does this do:
(rotation * (1.0/60.0)) Why does it get multiplyed by that is 60.0 just a random number or someting.

Edited by: Kamikazi[Uk]

--


Portfolio 
Blog | Full-Time Mobile Games Programmer

Jun 22 2011 Anchor

I find it easier to express any kind of movement in terms of distance per second. So instead of moving, say 1 unit every frame, I'll move something at 60 units per second. To get the movement per frame you have to multiply the movement per second by the time since the last frame. The (1.0/60.0) gives me the time for one frame at 60 frames per second. I get the 60 from my monitor's refresh rate, because the SDL's GL driver is vsynced.

Edited by: x3nu

Gibberstein
Gibberstein Generic Coder Type Thing
Jun 22 2011 Anchor

What happens if the game gets too busy and you're not hitting 60 frames a second? ;)

--

"lets say Portal is a puzzle game, so its a rehash of Tetris"
- Wraiyth points out the craziness of stereotyping games by their genre

Jun 22 2011 Anchor

You would see a slow down of objects on screen, since your computing movement with a time less than the time that really passed.

You would have to capture the actual system time every frame, find the difference between the previous time and the new time, and take that divided by one second in system time to get the time since the last frame to battle that problem.

Edited by: x3nu

Gibberstein
Gibberstein Generic Coder Type Thing
Jun 22 2011 Anchor

Bingo! Why not just do it properly the first time? ;)

--

"lets say Portal is a puzzle game, so its a rehash of Tetris"
- Wraiyth points out the craziness of stereotyping games by their genre

Jun 23 2011 Anchor

I wasn't really thinking about it when I wrote that quick test up above. I just wanted to get the type of movement right to show Kamikazi.

Kamikazi[Uk]
Kamikazi[Uk] Mobile Game Coder
Jun 23 2011 Anchor

Ah ok that is why you added that there :D. Yah i plan on trying to get all that sorted abit later so that it works at any frame-rate with same game speed as when i add in networking (next year sometime) i will need both systems to run at same speeds.

I just uploaded a little video of the AI Pathfinding i been working on past few days with some of the code from here :D.
Youtube.com

Edited by: Kamikazi[Uk]

--


Portfolio 
Blog | Full-Time Mobile Games Programmer

Jun 25 2011 Anchor

Your making better progress than I am :nervous:. I'm finding it hard to design a 2d engine... I really don't know where to start or what I want it to be capable of.

Kamikazi[Uk]
Kamikazi[Uk] Mobile Game Coder
Jun 26 2011 Anchor

Yah i was the same, i chose SDL for the windows management and input and using Open GL for the graphics (GPU based). The best thing to do first is to get images displaying properly and make sure they are really optimized. Next just build up the features with what you think would be fun to do. I'm not building my engine for a specific genre it's more of a generic engine for any game possible really. Then it means i can use it for all types of little games i make with it.

--


Portfolio 
Blog | Full-Time Mobile Games Programmer

Reply to thread
click to sign in and post

Only registered members can share their thoughts. So come on! Join the community today (totally free - or sign in with your social account on the right) and join in the conversation.