player movement

i’m working on my first project(street football) and, of course, i got a problem with player movement…
first i did only 8 directions (up, down, left, right and diagonal) and it was working great, but now i decided i wanna go with some more realistic player movement so what i wanna do is make player move relative to its current direction

so, forward should always move player in his current direction, backward should move in oposite direction( but player is still faced forward). left and right should turn the player a bit by bit from his current direction (eg. buttons up and right would just make player go in circles).
i remember seing that kind of player movement in “chrimsonland” if anyone knows what im talking about.
any help is appreciated!

omg… good thing i asked this, last night i lost like 1,5 hours on this and another half today, but i got it now :
sorry for the spam!

Well I would use:
float direction
which handles the facing of your char
float velocity
which handles the current speed

and to help you
float xvel
float yvel
which handle the per frame position change for the given direction and velocity

With a given dir and vel, you compute the change in the x and y dimension using sin and cos. Each time, either vel or dir changes, you
need to recompute the xvel and yvel.

So something like direction 0 and speed 10 would give you 10 pixels up and 0 pixels to the side, while direction 45 (degrees) would give you around 6 xvel and 6 yvel.

I dont know, if this helps or what your solution is like, I dont know if you can even understand what I mean, I just dont get the right english words :slight_smile:

-JAW

actually your solution was better, thanks!

for the lazy cats…

public void moveForward(){
x_position = x_position - ship_speedTimer.getTimer().getElapsedTime()(float)Math.sin((double)ship_turn*(Math.PI/180));//move the ship in the correct direction (amount for x)
y_position = y_position + ship_speedTimer.getTimer().getElapsedTime()(float)Math.cos((double)ship_turn*(Math.PI/180));//move the ship in the correct direction (amount for y)
}

public void moveBackward(){
	x_position = x_position + ship_speed*0.5f*Timer.getTimer().getElapsedTime()*(float)Math.sin((double)ship_turn*(Math.PI/180));//move the ship in the correct direction (amount for x)
	y_position = y_position - ship_speed*0.5f*Timer.getTimer().getElapsedTime()*(float)Math.cos((double)ship_turn*(Math.PI/180));//move the ship in the correct direction (amount for y)
}

If you use the built in sin() and cos() calls make sure you profile your app and take a good lookat their cost.

Many modern desktop processords have intrinsic trig functions but when you get into embedded processors this is generally not true and they can be very expensive to calculate. The standard game solution to this has traditionally been a trig look-up table with linear interpolation between the data points. You can get away with as little as a single table that goes from 0 -45 degrees and get all of your sin and cos out of it for a full 360 degrees if your a teensy bit clever.

even for todays computers?
What’s an embedded processor?
How do you profile your application?
What is meant by linear “interpolation” in the context used here?
When you say a trig-lookup table do you mean some sort of an array of the values of sin, cos precalculated?

embedded processor I assume is referring to those on devices such as phones, PDAs, and consoles.

You profile your application with a profiler. :slight_smile: Google for it.

Linear interpolation means what it always means, the context here isn’t strange. You need to find the sine of 3.5 degrees but your table only has values for 3 degrees and 4 degrees, so you look up both the sine of 3 degrees and the sine of 4 degrees and then pick a value that is half way between the two as your estimate for the sine of 3.5 degrees.

Yes the trig lookup table would be an array of floats or doubles. A lookup table can be used for any expensive function and should be in your aresnal of optimization techniques.

All great questions! Lets start at the top…

Most of today’s general purpose computers (laptops and desktops) have intrinsic trigonometry in their processors. Having said that, there are some issues with x86’s trig and Java which I’ll hold til the end 'cause it complciates the picture slightly.

However today’s computers are in more then just desktops and laptops, they are everywhere. In game consoles, in cell phones, in your pocket, in your set top box, your NAT gateway, and so on. Which leads nciely to the next question…

An embedded processor is one that is intended for use in an embedded application. That doesn’t help much as a definition, I know, but ist a starting point. Embedded applications are all those devices that aren’t desktops and laptops. They have very differnt needs. A desktop, and to a lesser degree a laptop, is almost all about processing speed. These other areas though have other over-riding needs such as low power consumption or low processor cost. As a result, embedded processors are generally not as fast or as capable as the general purpose processors.

Most processors intended for embedded work do not have intrinsic trig and do it all in software.

With a profiler! A profiler is a program that watches your program run and gives you a detailed report on what parts are using what percentage of the processing time, what parts are generating what memory usage, etc. A good profiler is an essential Java performance coding tool. Both Eclipse and Netbeans now have free Profilers you can download that plug right into the IDE. The Netbeans one is quite good, almost as good as some very expensive commercial tools I’ve used in the past. I haven’t tried the Eclipse one yet so I can’t comment on it…

You can find a whole chapter on profilign in Steve and my performacne book. The book is a bit old and some of the “tactical” stuff is a bit outdated but the “strategy” section is still quite appropriate to today’s VMs. (As are msot of the tctics. The biggestchnage is that we no longer have to be as afraid of creating garbage collection runs as we used to be.)

It’s all on line here:

http://java.sun.com/docs/books/performance

The profiler chapter is here:

http://java.sun.com/docs/books/performance/1st_edition/html/JPMeasurement.fm.html#30000

I strongly recommend yo uread the entire measurmeent section though, not just the Profiler section. People new to Java often get themselves in trouble trying to write “microbenchmarks” and the section talks about that, too.

Okay, Il lanswer these together and yes, yo uare on the right tarck here, you create an array of precaculated sin values (or cos, either will work.)
You only need one because Sin and Cos are the same with a phase shift (+/- 90 degrees).

On top of that, they repeat every 180 degrees, so you can do a mod(180) and only have 180 dgrees in your table.
You can actually get fancier then that by rcognizing that the table refelcts around 90 degrees so IF180>=N>=90, sin(n) == sin(180-n), tha reduces your table size to 90 degrees. Finally, it reflects again around 45, so IF 90>=N>=45, sin(n) == sin (90-n)

These tables can be a useful aid in gorkking all this: http://www.math2.org/math/trig/tables.htm

The end result of all this, though, is all you need is a 45 degree table, some IFs and some addition or subtraction (and one mod) to get the Sin of any number.

SO lets say you build a table with 45 entries, one for each degree. How do you get the values inj betweem, say sin (1.75). The answer is interpolation. In general a simple linear interpolation will suffice for the accuracy required for most games. A linear interpolation betwene two points is just a weighted average,

So lets say our SIn array is called “sinarray”, sin(1.75) == ((2-1.75)*sinarray[2])+((1.75-1)*sinarray[1]))

or in the general case, assuming a 45 degree table with 45 entries and 45>=n>=0

long highval = Math.ceiling(n);
long lowval = Math.floor(n);
long result = (((highval-n)*sinarray[highval)+((n-lowval)*sinarray[lowval]))

Note that I am an old guy and think in “degrees”. Java’s trig is actually in radians so if you want to mimic it you will have to do conversions
or arrange your table in radians rather then degrees.

NOW I said Java compilcates things. The long explaination is here:

http://blogs.sun.com/roller/page/jag?entry=transcendental_meditation

But the short hand is that, for angles under -45 or over 45 degrees, at the accuracy that Java by definition must calculate flaoting point math, the intrinsic trig in the x86 processor is broken. For that reason Java defaults to a software implementastion outside of that range BUT using the reflection tricks I just showed you, you should never have to leave that range :slight_smile:

beautiful explanation :wink:

Calling cos/sin 2-3 times for your single player’s movement is no big deal. It’s when you have 100 characters all moving with 2-3 sin/cos calls that you really start to care about that.

all help much appreciated… i do plan to have only 7 players in this game, but the next one… who knows :slight_smile:
thanks!

Thats cool as long as the players are the only thinsg moving on screen.

But keep in mind that if you have other animated objects on the screen they too will need to do trig. (Imagine Robotron for a minute. One player, LOTS of moving objects.)