Public Group

# Moving Player Using Sine/Cos

This topic is 4917 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hello everybody, I'm currently facing a mathematical problem. I don't think it's very intense though, that's why I posted here and not in the "Maths & Physics"-Area. I am working on the movement system of a GTA2-clone project at the moment. I have a player struct pretty much defined like this for now:  struct player { int x; int y; int angle; int velocity; };  I also coded that pushing UP arrow key increases player.velocity and DOWN decreases it (or makes it negative) and that LEFT decreases the player.angle and RIGHT increases the angle. That works fine. Now I think my mistake is when I calculate the new position of the player. I do it this way at the moment:  player.x = player.x + FloatToInt ( IntToFloat ( player.velocity ) * Maths.Sin ( Maths.DegreesToRadians ( IntToFloat ( player.angle ) ) ) ); player.y = player.y + FloatToInt ( IntToFloat ( player.velocity ) * Maths.Cos ( Maths.DegreesToRadians ( IntToFloat ( player.angle ) ) ) );  That results that I can move in only 8 directions. LEFT, RIGHT, UP, DOWN and inbetween those directions. My guess that this is because of a rounding error with FloatToInt, but what should I change in order to be able to walk in 360 degrees (pretty much like it is in GTA2)? Thanks for your help, Jan.

##### Share on other sites
Try changing your variables to doubles or floats:

struct player{double x;double y;double angle;double velocity;};

then in order to move the player

player.x += sin(player.angle/57.3)*player.velocity
player.y += cos(player.angle/57.3)*player.velocity

then, whenever you are drawing him on screen and you need to have the variables as an int just cast them:

DrawThing((int)player.x , (int)player.y);

I'm sure there's better ways to do this, but thats how I do it and it works.

##### Share on other sites
You might also want to multiply the velocity change (acceleration) by the time delta, and the velocity itself by the time delta again, if you're not doing fixed time steps. Also, do not use integer variables to represent vectors; the precision problems will be horrendous. Unless your target platform has some very weird requirements I would at least revise an object's position tracking structure to:

struct vector_2d{    float x;    float y;};struct physics_object{    vector_2d position;    vector_2d velocity;    float angle;};

Keep your angle separated from your velocity as how the car is turned should be independent from its velocity. Consider to also add a z vector component even if your game is in 2D as you might want to track heights nontheless: Cars that can leave the ground driving off high edges, for bullets, and similar stuff.

EDIT: As Sir Sapo said, using floats (or doubles if you need more precision), will not influence your drawing negatively. Just convert each float to an integer like he showed, though you may or may not want to round the floats by making it int(float_number + 0.5f) instead.

EDIT2: When updating any object, you can do this (assuming 2D):

//dt is delta time, or time since last frame//acceleration is a scalar quantity, you can make this by summing forces and using the formula a = F / mplayer.velocity.x += cos(angle) * acceleration * dt;player.velocity.y += sin(angle) * acceleration * dt;player.position.x += player.velocity.x * dt;player.position.y += player.velocity.y * dt;

##### Share on other sites
Hmm... I changed it, but it now placed the player object somewhere offscreen.

This is what I have:

struct player{ float x; // the x-coordinate of the player float y; // the y-coordinate of the player float angle; // the angle of the player float velocity; // the velocity ( thrust ) of the player};[\CODE]player.x += Maths.Sin ( player.angle / 57.3 ) * player.velocity;player.y += Maths.Cos ( player.angle / 57.3 ) * player.velocity;[\CODE]And then I use those player.x and player.y values, cast them to ints and draw the player.What's wrong?Oh, and player.velocity is 0 when no key is pressed. Those values work and are correct (so it's not that I wouldn't initialize the angle or especially velocity properly)... 
 0 
 Share this post Link to post Share on other sites 
 
 
 Unwise owl    158 Unwise owl Member 158 Posted August 1, 2005 One reason why the player is placed offscren may be the following:Your function which modifies positions and or velocities triggers way too many times each second. Either multiply by delta time like I showed or limit the possible number of updates.Either that, or your drawing function does not convert to ints properly.Do you see the player before you move him or not? I mean, if he has zero velocity, do you still see him at screen?EDIT: Just to remember, make velocity a vector and separate from the car's angle. It's very nice to have a car that's able to move in another direction than it's currently facing. :) 0 Share this post Link to post Share on other sites d h k    439 d h k Member 439 Posted August 1, 2005 But how can updating this function often displace the player? Shouldn't it just become more accurate?I am sorry for being a little newbie here, thanks for your patience.Also, I am rather sure the cast is working.I can't store vectors how you supposed since the platform does not support structs in structs at the moment.EDIT: Sorry, saw your edits just by now. I don't see him at all moving around. My frame rate is at max fixed value 40... Thanks for your answers though. Keep em comming if there's any ideas out there to fix this. 0 Share this post Link to post Share on other sites Unwise owl    158 Unwise owl Member 158 Posted August 1, 2005 The function becomes more accurate if you have an accurate time measurement function. Also, if you don't multiply by the time since the last update, consider what happens:CASE 1:UpdatePlayer() moves player at 10 velocity units.It triggers 100 times each second.The total displacement is 100 * 10 = 1000 velocity units!If you multiply by the delta time which is 1 / number of updates per second you get the following:CASE 2:Delta_time = 1 / 100 = 0.01.UpdatePlayer(Delta_time) moves the player 10 * 0.01 = 0.1 velocity units.It triggers 100 times each second.The total displacement is 100 * 0.1 = 10 velocity units! (As you probably intended.)EDIT: Saw your frame limit to be 40, then use 40 instead of 100 in example... However, it may still be a good idea to measure time since limiting frame rate does not always work perfectly... If you don't however you can just adjust your velocities by a factor of (1 / 40) to get it working provided it really triggers not much from 40 times a second. 0 Share this post Link to post Share on other sites d h k    439 d h k Member 439 Posted August 1, 2005 Ah, I see.Now I just need a good way to calcualte that delta_t using my platform...I will post once I have it included.Thanks though. 0 Share this post Link to post Share on other sites Unwise owl    158 Unwise owl Member 158 Posted August 1, 2005 If you have any sort of time function with high precision it's enough to take the time of the current frame minus that of the last. If it doesn't have as high precision you can measure across several frames and divide by the number of them to get the average frame time. 0 Share this post Link to post Share on other sites d h k    439 d h k Member 439 Posted August 1, 2005 Hmm... I can get the current framerate. And that's pretty much about it, I believe. I mean I have a timer system, which I could use. But how exactly?EDIT: Nevermind, got it to work. Works accurately and fine even without delta time. 0 Share this post Link to post Share on other sites 
 Sign in to follow this   Followers 0 
 Go To Topic Listing Forum 
 Advertisement 
 Advertisement What is your GameDev Story? In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us. (You must login to your GameDev.net account.) Share My Story Popular Tags 2D 3D Advice C# C++ Character Concept DX11 DX12 GameMaker Gameplay General Graphics Java Learning Mobile Music OpenGL Optimization PC Pixel Unity Unreal VR Vulkan Popular Now 13 Unity Updates Terms of Service in Response to Developer Backlash By khawkStarted Yesterday at 04:25 PM 9 2D [DX9] Displaying font loaded by FreeType By datboiStarted Yesterday at 06:41 AM 9 DX11 Weird depth buffer values By jakovoStarted Monday at 04:50 PM 15 DX11 Texture repeat question By DividedByZeroStarted Monday at 03:07 AM 14 3D How to get the 3D position for the point with (0,0) UV coordinates? By Stackmann0Started January 11 Advertisement Forum Statistics Total Topics 634070 Total Posts 3015330 GameDev.net GameDev.net Articles GameDev.net Event Coverage GameDev.net Forums GameDev.net Blogs GameDev.net Gallery GameDev.net News GameDev.net Projects GDNet Chat All Activity Search In Everywhere This Forum This Topic More options... Find results that contain... All of my search term words Any of my search term words Find results in... Content titles and body Content titles only Home Groups For Beginners Forum Moving Player Using Sine/Cos 
 
 
 × Existing user? Sign In Sign Up Browse Back Articles & Tutorials Back All Categories Audio Business Game Design Industry Programming Visual Arts Columns Back GameDev Unboxed Event Coverage Back All Events Game Developers Conference Power Up Digital Games Conference GameDev.Market Links News Podcasts Back All Podcasts Game Dev Loadout Archive Community Back Beginners Back Beginners Group Beginners Forum Beginners Resources Blogs Calendar Chat Forums Back All Forums Audio Business Game Design Programming Visual Arts Community GameDev Challenges Affiliates Topical Workshops Gallery Groups Back For Beginners GameDev Challenges All Groups Projects Back All Projects Games Game Assets Game Mods Developer Tools Store Forums Back All Forums For Beginners Audio Back Music and Sound FX Games Career Development Business Back Games Career Development Production and Management Games Business and Law Game Design Back Game Design and Theory Writing for Games Programming Back Artificial Intelligence Engines and Middleware General and Gameplay Programming Graphics and GPU Programming Math and Physics Networking and Multiplayer Visual Arts Back 2D and 3D Art Critique and Feedback Community Back GameDev Challenges GDNet Lounge GDNet Comments, Suggestions, and Ideas Coding Horrors Your Announcements Hobby Project Classifieds Indie Showcase Affiliates Back NeHe Productions AngelCode Topical Workshops Careers Back Contractors Hobby Projects Game Jobs Back Browse on GameDev.Jobs Post a Job Members Back Subscriptions Chat Guidelines Leaderboard Online Users Awards Search Back All Activity My Activity Streams Back Latest Topics Featured Blogs Search Important Information By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.   I accept GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry. Sign me up! 
 $('body').click(function (e) { var container =$("#pagecontainer"); if (($(e.target).parent().prop('nodeName') == 'BODY') && (container.has(e.target).length === 0) && (e.button == 0) && (!$(e.target).hasClass('ipsDialog'))) { window.open('https://ad.doubleclick.net/ddm/trackclk/N129002.1825GAMEDEV.NET/B11085475.236262913;dc_trk_aid=433791501;dc_trk_cid=90245747;dc_lat=;dc_rdid=;tag_for_child_directed_treatment=;tfua='); ga('send','event','Advertisement','Click','3q_fb_gamedev_skin_2019_1'); } }); $(document).ready(function() { setInterval(function() { window.googletag.pubads().refresh(); }, 30000); });$(document).ready(function() { if (ipsSettings.memberID > 0) { ga('send','event','User','View','Member'); } else { ga('send','event','User','View','Guest'); } });