Strange problem with movement code

BlitzMax Forums/BlitzMax Programming/Strange problem with movement code

BugZilla(Posted 2008) [#1]
I tried this code, which I cribbed from an old BlitzBasic project and it worked fine there. In BlitzMax, it works, but the ship moves slowly when going to the right but superfast when it goes to the upper left. Any idea why? Here's the code:


'ANGLE MOVE TEST
'right click to set the destination x,y coordinates and start moving

Graphics 800,600

Global ship:TImage=LoadImage("ship1.png")
Global angle#=0
Global speed#=0
Global x,y,dx,dy=0

While Not KeyHit(key_escape)
moveShip()
DrawImage ship,x,y
DrawOval dx,dy,5,5
If MouseDown(1)
speed=2
dx=MouseX()
dy=MouseY()
End If

Flip
Cls
Wend


Function moveShip()
angle=ATan2(dy-y,dx-x)
x=x+Cos(angle)*speed
y=y+Sin(angle)*speed
End Function


GfK(Posted 2008) [#2]
Both X and Y are integers by default. Since you're using Sin/Cos on them, they most likely should be floats.


Floyd(Posted 2008) [#3]
Exactly right. The variables x,y,dx,dy should all be floats. This is the natural approach for BlitzMax and Blitz3D.

The reason for the different behavior is the default "float to integer" conversion. BlitzMax chops while Blitz3D rounds.

For example, suppose integer x=5 is changed by +1.7 or -1.7.

In Biltz3D this will produce 6.7 or 3.3, which are rounded to 7 or 3. So x changes by 2.

But in BlitzMax 6.7 is chopped to 6 and 3.3 is chopped to 3.
So x increases by 1 ( speed to the right ) or decreases by 2 ( speed to the left ).


GfK(Posted 2008) [#4]
Well, in this case, dx and dy only represent the mouse position, so Ints will do fine for that.


Floyd(Posted 2008) [#5]
Okay, I guess dx,dy can be ints. But then they are used like this:

x=x+Cos(angle)*speed

This has the form Int = Int + Float and results in the behavior I described, i.e. faster movement to the left.

As a matter of personal style I would still make them floats because of the way they are interact with other variables.


BugZilla(Posted 2008) [#6]
You have all described this topic very well. I have tried to put what you have said into practice but I am still having the same problems. I have set all the variables to Float type, but I still get the weird movement problems. The problem is that I cannot convert the int to float and the only method I know to do this type of movement is the code:

x=x+Cos(angle)*speed

Any ideas how I can convert these things in BlitzMax? Here's the new code. I set the speed to 1 and now it won't move to the right at all:

'ANGLE MOVE TEST
'right click to set the destination x,y coordinates and start moving
Graphics 800, 600

Global ship:TImage=LoadImage("ship1.png")
Global angle:Float = 0.0
Global speed:Float = 0.0
Global x, y, dx, dy:Float
x = 300.0
y = 300.0

While Not KeyHit(key_escape)
moveShip()
DrawImage ship,x,y
DrawOval dx,dy,5,5
If MouseDown(1)
speed = 1.0
dx=MouseX()
dy=MouseY()
End If

Flip
Cls
Wend

Function moveShip()
angle=ATan2(dy-y,dx-x)
x = x + Cos(angle) * speed
y=y+Sin(angle)*speed
End Function


Jesse(Posted 2008) [#7]
Hint: Use Superstrict:
SuperStrict
'ANGLE MOVE TEST
'right click to set the destination x,y coordinates and start moving
Graphics 800, 600

Global ship:TImage=LoadImage("ship1.png")
Global angle:Float = 0.0
Global speed:Float = 0.0
Global x:Float, y:Float, dx:Float, dy:Float
x = 300.0
y = 300.0

While Not KeyHit(key_escape)
	moveShip()
	DrawRect x,y,20,20
	DrawOval dx,dy,5,5
	If MouseDown(1)
		speed = 1.0
		dx=MouseX()
		dy=MouseY()
	End If

	Flip
	Cls
Wend

Function moveShip()
	angle=ATan2(dy-y,dx-x)
	x = x + Cos(angle) * speed
	y=y+Sin(angle)*speed
End Function



Floyd(Posted 2008) [#8]
The variable declaration

Global x, y, dx, dy:Float

says dy is a Float. But x,y,dx are still type default Int type.

It would be nice if you could declare the types of several variables like this, but you can't.
I also wish we could initialize Float arrays without specifying the type of each element.