Why Am I Being Ejected From My Maze?

Monkey Forums/Monkey Programming/Why Am I Being Ejected From My Maze?

donicamm(Posted 2013) [#1]
I have this code for a silly maze game, based on one of the minib3d tutorials:

Strict
Import mojo
Import minib3d

Global player:Int = 1
Global wall:Int = 2

Class Game Extends App
	
	Field Camera:TCamera
	Field Light:TLight, Light2:TLight
	Field Floor:TEntity
	Field Started:Bool
	Field Tiles:Int[][]
	Field mapData:String
	
	
	Method OnCreate%()
		Tiles = AllocateArray(10,10)
		mapData = ""
		mapData += "1111111111"
		mapData += "1010000031"
		mapData += "1011011111"
		mapData += "1000000001"
		mapData += "1111101111"
		mapData += "1200101001"
		mapData += "1000101001"
		mapData += "1011101101"
		mapData += "1000000001"
		mapData += "1111111111"

		
		SetUpdateRate 30
		Return 0
	End


	Method OnUpdate%()
		If Not Started Then Return 0

		If KeyDown(KEY_UP)	
			Camera.MoveEntity 0,0,1
		Elseif KeyDown(KEY_DOWN)
			Camera.MoveEntity 0,0,-1
		Endif
		If KeyDown(KEY_LEFT)
			Camera.TurnEntity 0,2.5,0
		Elseif KeyDown(KEY_RIGHT)
			Camera.TurnEntity 0,-2.5,0
		Endif
		
		Collisions(player, wall, COLLISION_METHOD_BOX, COLLISION_RESPONSE_SLIDE)
		UpdateWorld()
		Return 0
	End

	
	Method Init:Void()		
		If Started Then Return
		Started = True		
		SetRender()		
		Camera = CreateCamera()
		Camera.CameraClsColor(180,210,220)
		'Camera.MoveEntity 0,1.5,-10
		Floor=CreateGrid(15,15)
		Floor.ScaleEntity 10,1,10 
		Floor.PositionEntity -2,0,8
		Floor.EntityColor 55,95,0
		EntityType(Camera,player)
		EntityRadius (Camera, 1.5)
		
	'	For Local i%=0 To 11
	'		Local C:TEntity=CreateCube()
	'		C.MoveEntity 6*i, 3 ,50
	'		C.EntityColor Rnd(255),Rnd(255),Rnd(255)
	'		C.ScaleEntity 3,3,3
	'		C.EntityBox()  ''EntityBox() will auto-setup if there are no arguments
	'		EntityType(C, wall)

	'	Next
	
		Local levelPosition:Int
		levelPosition = 0
		For Local i:Int = 1 To 10
			
			For Local j:Int = 1 To 10
			
				If String.FromChar(mapData[levelPosition]) = "0"
					Print ("EMPTY SPACE at " + 6*i + " " + 6*j)
				Elseif String.FromChar(mapData[levelPosition]) = "1"
					Local C:TEntity=CreateCube()
					C.MoveEntity 6*i, 3 ,6*j
					C.EntityColor Rnd(255),Rnd(255),Rnd(255)
					C.ScaleEntity 3,3,3
					C.EntityBox()  ''EntityBox() will auto-setup if there are no arguments
					EntityType(C, wall)
					Print ("BLOCK at " + 6*i + " " + 6*j)
				Elseif String.FromChar(mapData[levelPosition]) = "2"
					Camera.MoveEntity 6*i, 1.5, 6*j
					Print ("CAMERA at " + 6*i + " " + 6*j)
				Elseif String.FromChar(mapData[levelPosition]) = "3"
					Print ("BANANA")
				End
				levelPosition += 1
			End
		End
	

		Light=CreateLight(1)
		Light.TurnEntity 35,-40,0
		Light.LightColor 222,222,111
		Light.AmbientLight 111,99,111
	End


	Method OnRender%()
		Init()
		RenderWorld()
		Return 0
	End
	

	Method AllocateArray:Int[][]( i:Int, j:Int)
	    Local arr:Int[][] = New Int[i][]
	    For Local ind% = 0 Until i
	        arr[ind] = New Int[j]
	    Next
	    Return arr		
	End
		
End

Function Main%()
	New Game
	Return 0
End


Which prints this output, implying that the camera is being placed at 36, 1.5, 12. However, when the game starts, I am quickly thrown outside the maze.

BLOCK at 6 6
BLOCK at 6 12
BLOCK at 6 18
BLOCK at 6 24
BLOCK at 6 30
BLOCK at 6 36
BLOCK at 6 42
BLOCK at 6 48
BLOCK at 6 54
BLOCK at 6 60
BLOCK at 12 6
EMPTY SPACE at 12 12
BLOCK at 12 18
EMPTY SPACE at 12 24
EMPTY SPACE at 12 30
EMPTY SPACE at 12 36
EMPTY SPACE at 12 42
EMPTY SPACE at 12 48
BANANA
BLOCK at 12 60
BLOCK at 18 6
EMPTY SPACE at 18 12
BLOCK at 18 18
BLOCK at 18 24
EMPTY SPACE at 18 30
BLOCK at 18 36
BLOCK at 18 42
BLOCK at 18 48
BLOCK at 18 54
BLOCK at 18 60
BLOCK at 24 6
EMPTY SPACE at 24 12
EMPTY SPACE at 24 18
EMPTY SPACE at 24 24
EMPTY SPACE at 24 30
EMPTY SPACE at 24 36
EMPTY SPACE at 24 42
EMPTY SPACE at 24 48
EMPTY SPACE at 24 54
BLOCK at 24 60
BLOCK at 30 6
BLOCK at 30 12
BLOCK at 30 18
BLOCK at 30 24
BLOCK at 30 30
EMPTY SPACE at 30 36
BLOCK at 30 42
BLOCK at 30 48
BLOCK at 30 54
BLOCK at 30 60
BLOCK at 36 6
CAMERA at 36 12
EMPTY SPACE at 36 18
EMPTY SPACE at 36 24
BLOCK at 36 30
EMPTY SPACE at 36 36
BLOCK at 36 42
EMPTY SPACE at 36 48
EMPTY SPACE at 36 54
BLOCK at 36 60
BLOCK at 42 6
EMPTY SPACE at 42 12
EMPTY SPACE at 42 18
EMPTY SPACE at 42 24
BLOCK at 42 30
EMPTY SPACE at 42 36
BLOCK at 42 42
EMPTY SPACE at 42 48
EMPTY SPACE at 42 54
BLOCK at 42 60
BLOCK at 48 6
EMPTY SPACE at 48 12
BLOCK at 48 18
BLOCK at 48 24
BLOCK at 48 30
EMPTY SPACE at 48 36
BLOCK at 48 42
BLOCK at 48 48
EMPTY SPACE at 48 54
BLOCK at 48 60
BLOCK at 54 6
EMPTY SPACE at 54 12
EMPTY SPACE at 54 18
EMPTY SPACE at 54 24
EMPTY SPACE at 54 30
EMPTY SPACE at 54 36
EMPTY SPACE at 54 42
EMPTY SPACE at 54 48
EMPTY SPACE at 54 54
BLOCK at 54 60
BLOCK at 60 6
BLOCK at 60 12
BLOCK at 60 18
BLOCK at 60 24
BLOCK at 60 30
BLOCK at 60 36
BLOCK at 60 42
BLOCK at 60 48
BLOCK at 60 54
BLOCK at 60 60


Initially, I though there might be something wrong with the way I made the maze. I thought that maybe I had put my camera too close to walls and it was causing some sort of collision so I changed my "mapData" to this:

		mapData = ""
		mapData += "1111111111"
		mapData += "1010000001"
		mapData += "1000000001"
		mapData += "1000000001"
		mapData += "1000020001"
		mapData += "1000000001"
		mapData += "1000000001"
		mapData += "1000000001"
		mapData += "1000000001"
		mapData += "1111111111"


Which should have my camera at least 18 units from anything else. However, I still get ejected from the maze.

This is my output with second mapData:

BLOCK at 6 6
BLOCK at 6 12
BLOCK at 6 18
BLOCK at 6 24
BLOCK at 6 30
BLOCK at 6 36
BLOCK at 6 42
BLOCK at 6 48
BLOCK at 6 54
BLOCK at 6 60
BLOCK at 12 6
EMPTY SPACE at 12 12
BLOCK at 12 18
EMPTY SPACE at 12 24
EMPTY SPACE at 12 30
EMPTY SPACE at 12 36
EMPTY SPACE at 12 42
EMPTY SPACE at 12 48
EMPTY SPACE at 12 54
BLOCK at 12 60
BLOCK at 18 6
EMPTY SPACE at 18 12
EMPTY SPACE at 18 18
EMPTY SPACE at 18 24
EMPTY SPACE at 18 30
EMPTY SPACE at 18 36
EMPTY SPACE at 18 42
EMPTY SPACE at 18 48
EMPTY SPACE at 18 54
BLOCK at 18 60
BLOCK at 24 6
EMPTY SPACE at 24 12
EMPTY SPACE at 24 18
EMPTY SPACE at 24 24
EMPTY SPACE at 24 30
EMPTY SPACE at 24 36
EMPTY SPACE at 24 42
EMPTY SPACE at 24 48
EMPTY SPACE at 24 54
BLOCK at 24 60
BLOCK at 30 6
EMPTY SPACE at 30 12
EMPTY SPACE at 30 18
EMPTY SPACE at 30 24
EMPTY SPACE at 30 30
CAMERA at 30 36
EMPTY SPACE at 30 42
EMPTY SPACE at 30 48
EMPTY SPACE at 30 54
BLOCK at 30 60
BLOCK at 36 6
EMPTY SPACE at 36 12
EMPTY SPACE at 36 18
EMPTY SPACE at 36 24
EMPTY SPACE at 36 30
EMPTY SPACE at 36 36
EMPTY SPACE at 36 42
EMPTY SPACE at 36 48
EMPTY SPACE at 36 54
BLOCK at 36 60
BLOCK at 42 6
EMPTY SPACE at 42 12
EMPTY SPACE at 42 18
EMPTY SPACE at 42 24
EMPTY SPACE at 42 30
EMPTY SPACE at 42 36
EMPTY SPACE at 42 42
EMPTY SPACE at 42 48
EMPTY SPACE at 42 54
BLOCK at 42 60
BLOCK at 48 6
EMPTY SPACE at 48 12
EMPTY SPACE at 48 18
EMPTY SPACE at 48 24
EMPTY SPACE at 48 30
EMPTY SPACE at 48 36
EMPTY SPACE at 48 42
EMPTY SPACE at 48 48
EMPTY SPACE at 48 54
BLOCK at 48 60
BLOCK at 54 6
EMPTY SPACE at 54 12
EMPTY SPACE at 54 18
EMPTY SPACE at 54 24
EMPTY SPACE at 54 30
EMPTY SPACE at 54 36
EMPTY SPACE at 54 42
EMPTY SPACE at 54 48
EMPTY SPACE at 54 54
BLOCK at 54 60
BLOCK at 60 6
BLOCK at 60 12
BLOCK at 60 18
BLOCK at 60 24
BLOCK at 60 30
BLOCK at 60 36
BLOCK at 60 42
BLOCK at 60 48
BLOCK at 60 54
BLOCK at 60 60


Thanks you for taking the time to view my post.


Midimaster(Posted 2013) [#2]
1.
The Collisions() command has to be placed in the Init() method, not the OnUpdate().

2.
The Collisions() command is not working proper. If you comment it out for a moment you will see your maze.

3.
The camera position is too deep and the collision radius too big for the small corridors. Change...
Camera.MoveEntity 0,1,0
Camera.EntityType player
Camera.EntityRadius 0.3


4.
The camera is too fast. With a step of 1 you jump more than you move. Reduce the speed:
Camera.MoveEntity 0,0,.1


5.
You forgot to also add a collision with the floor. Because of your selected "Slide"-Algo the camera slips under the floor, when colliding with a wall. You used the wrong collision respond algo. Better use COLLISION_RESPONSE_SLIDEXZ or COLLISION_RESPONSE_STOP:
Collisions(player, wall, COLLISION_METHOD_SPHERE, COLLISION_RESPONSE_SLIDEXZ)


6.
You forgot to add a collision room definition of the walls:
C.CollisionSetup wall,COLLISION_METHOD_BOX


7.
Your maze is too compact for testing purposes. Open the walls:
		mapData += "1100000011"
		mapData += "1010000031"
		mapData += "0011011110"
		mapData += "0000000000"
		mapData += "0111101110"
		mapData += "1200101001"
		mapData += "1000101001"
		mapData += "1011101101"
		mapData += "1000000001"
		mapData += "1110000111"



For testing games it is often not very helpful to test it in a final setup. Better you setup special test conditions, like "only one wall" instead of a complete maze. In such test sourroundings you will be able to test only one aspect of your code. If you do not, you will have a lot of "side effects" and you will not discover the bugs.


You should re-think about your wall concept. The collision algos only work perfect if the whole wall is really one object and not a row of cubes. Every time when the player reaches an angle of such an cube. the algo let "him through", because the 90° side of the cube is nearer than the way back


        |   
       o|
______o_|_____
     o 

test your modified code at the end of this post to understand...



Isn't it better to post your MiniB3D questions to this thread?
http://www.monkeycoder.co.nz/Community/posts.php?topic=5016


use this to better understand, what's happening in your code: