Issue with lists

BlitzMax Forums/BlitzMax Beginners Area/Issue with lists

altitudems(Posted 2005) [#1]
I'm trying to figure out why my list of entities is only updating two object at a time and not all of them.

Below is the code for tEntity:
Strict 

Global EntityList:TList = CreateList()

Type tEntity
	Field X:Float, Y:Float
	Field VX:Float, VY:Float
	Field Width:Int
	Field Height:Int
	Field Pushable:Int

	Method New()
		EntityList.AddLast(Self)
		X = Rnd(0,640)
		Y = Rnd(0,480)
		Width = 32
		Height = 16
		Pushable = True
	End Method

	Method Compare(_O:Object)
		Return Y - tEntity(_O).Y
	End Method
	
	Method Delete ()
		EntityList.Remove(Self)
	End Method
	
	Method Render ()
		SetColor 0,0,0
		DrawRect X-1, Y-Height-1, Width+2, Height+Height+2
		SetColor 200,200,200
		DrawRect X, Y, Width, Height
		SetColor 125,125,125
		DrawRect X, Y-Height, Width, Height
	End Method
	
	Method Update ()
		MoveIfNotCollided(VX, VY)
	End Method
	
	Method MoveIfNotCollided(_VX:Float, _VY:Float)
		Local e:tEntity
		
		X :+ _VX	
		e = CollideWithEntity()

		If (e <> Null)
			If e.Pushable
				X :- (_VX * .5)
				e.X :+ (_VX * .5)
			Else
				X :- _VX
			End If
		End If
		
		Y :+ _VY		
		e = CollideWithEntity()
		If (e <> Null)
			If e.Pushable
				Y :- (_VY * .5)
				e.Y :+ (_VY * .5)
			Else
				Y :- _VY
			End If
		End If

	End Method
	
	Method CollideWithEntity:tEntity ()
		Local e:tEntity
		For e = EachIn EntityList
			If e <> Self
				If (e.X > X + Width) Return Null
				If (e.X + e.Width < X) Return Null
				If (e.Y > Y + Height) Return Null
				If (e.Y + e.Height < Y) Return Null
				Return e
			End If
		Next
	End Method
End Type


Here is the game loop:
Graphics 640,480
SetClsColor 0,150,0

Local p1:tEntity = New tEntity
Local p2:tEntity = New tEntity
Local p3:tEntity = New tEntity

Local Controls:Int [] = [KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT]

While Not KeyHit(KEY_ESCAPE)
	Cls
	
	p1.VX = 0; p1.VY = 0
	If (KeyDown(Controls[0])) p1.VY :+ -2 'UP
	If (KeyDown(Controls[1])) p1.VY :+ 2 'DOWN
	If (KeyDown(Controls[2])) p1.VX :+ -2 'LEFT
	If (KeyDown(Controls[3])) p1.VX :+ 2 'RIGHT
	
	EntityList.Sort
	For Local e:tEntity = EachIn EntityList
		e.Update()
		e.Render()
	Next

	Flip
	FlushMem
Wend


When you run the code Sometimes your box will collide with the others and sometimes not. Why? If you only create two enities, everything is fine. This is driving me up a wall. Any help is greatly appreciated.


Perturbatio(Posted 2005) [#2]
it alternates between them when the Y value of each is the same.


altitudems(Posted 2005) [#3]
Ok yeah I see that, hmm. I wonder whats causing that.
My first guess was that list sorting was causing the problem, but I don't its the main problem. Comment out the sort command and there is still an issue. Man, what is going on here


altitudems(Posted 2005) [#4]
Jeez! I still can't figure it out. Somebody please help me? Someone? I can't do anything until this is finished. I've debuged and printed every single variable I can think of. Either I'm a huge idiot or there is a major flaw with the list system. HELP


skidracer(Posted 2005) [#5]
	Method CollideWithEntity:tEntity ()
		Local e:tEntity
		For e = EachIn EntityList
			If e <> Self
				If e.X > X + Width Continue 
				If e.X + e.Width < X Continue
				If e.Y > Y + Height Continue
				If e.Y + e.Height < Y Continue
				Return e
			End If
		Next
	End Method



Perturbatio(Posted 2005) [#6]


*EDIT*
I really should refresh before posting if I've spent a while on these things :)


altitudems(Posted 2005) [#7]
@skidracer
Your slight modification to the CollideWithEntity method doesen't really make any difference that I can see. But thanks for the effort.

@Perturbatio
Ok your changes make the difference, but I'm still not sure why. The only thing you realy did was make it so the it tests both axis at the same time. Instead of testing for collision on x and y seperately. So essentialy youve removed sliding collision. This led to the solution though. It seem that I was swapping entities back and forth.

Here is the fixed version if your interested:


Thanks again guys for all your help. Now I just have to figure out why the other boxes don't collide when when your pushing one.


skidracer(Posted 2005) [#8]
If it didn't collide with the first non self entity in the list it would return instead of checking the next in the list (hence the use of Continue instead of return null).


Perturbatio(Posted 2005) [#9]
Now I just have to figure out why the other boxes don't collide when when your pushing one.


solved:


You need to set and reset their VX and VY values as well.


altitudems(Posted 2005) [#10]
@skidracer
Oops, your right. Thanks for pointing that out. I guess that does make a difference. :)

@Perturbatio
Thanks for that quick response :) It works a treat.