More on collisions

Blitz3D Forums/Blitz3D Beginners Area/More on collisions

Uhfood , you were never resetting the yvelocity so it was a huge value the token was trying to move downwards ...

See your manage collisions function for what I changed.

Also, trust me on this .. using constants for your collision types is much easier to follow .. I included some in your main program.

; m = member, b = boolean

Const b_DebugMode = False

; This won't have positional information
; as blitz will do that for me.  It will
; have velocity, speed, and gravity parameters
; probably some blitz collision information as well
Type TGameObject

	Field m_entity
	Field m_xVelocity#
	Field m_yVelocity#
	Field m_zVelocity#
	Field m_xSpeed#
	Field m_ySpeed#
	Field m_zSpeed#	
	Field mb_useGravity
	Field m_gravity#
	
End Type

Global debugtxt$ = ""

; most of the game entities
; to copy all the playfield 'cells'
; from; Gametoken is the piece that 
; moves around the board.

Global camera, light, gameToken.TGameObject
Dim Playfield( 12, 12 )

Global logfile

;;; General Functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Function fn_AddDebugTxt( txt$ )

	debugTxt = debugTxt + txt$ + "|"
 
End Function

Function fn_ShowDebugTxt( txt$ )

	If( Right( txt, 1 ) <> "|" ) Then txt = txt + "|"

	ty = 0
	Repeat
		tx = Instr( txt, "|" )
		If( tx > 0 )
			Text( 0, ty, Left( txt, tx - 1 ) )
			txt = Right( txt, Len( txt ) - tx )
			ty = ty + 10
		End If
	Until tx = 0
	
	debugTxt$ = ""
	
End Function

Function fn_OpenLogFile()

	If( b_DebugMode = True )
	
		Cdate$ = CurrentDate$()
		Ctime$ = CurrentTime$()
		Cdir$ = CurrentDir$()
		logdir$ = Cdir$ + "log"
		
		If( FileType( logdir$ ) = 0 )
			CreateDir( logdir$ )
		End If
		
		LogFileName$ = logdir$ + "" + Cdate$ + "log.txt"
		
		If( FileType( logdir$ ) = 2 )
			
			If( FileType( LogFileName$ ) = 1 )
				logfile = OpenFile( LogFileName$ )
				Repeat
					SeekFile( logfile, i )
					i = i + 1
				Until Eof( logfile )	
			Else
				logfile = WriteFile( LogFileName$ )
		
			End If
			
			If( logfile <> 0 )
			
				WriteLine( logfile, "" )
				WriteLine( logfile, LogFileName$ + " opened successfully." )
				WriteLine( logfile, "" )
				WriteLine( logfile, "log file opened on " + Cdate$ + " at " + Ctime$ + "." )
		
			Else
				DebugLog( "Could not create or open log file." )	
			End If
			
		End If
	
	End If
	
End Function ; fn_OpenLogFile()

;--------------------------------------;

Function fn_CloseLogFile()

	If( b_DebugMode = True )
	
		If( logfile <> 0 )
		
			WriteLine( logfile, "Logging successful, closing log file." )
			WriteLine( logfile, "" )
			WriteLine( logfile, "---" )
			CloseFile( logfile )
		
		End If
	
	End If

End Function ; fn_CloseLogFile()

;--------------------------------------;

; This function generally creates everything in 
; the game.  First the camera, then the light, then
; playfield and finally the game token.
Function fn_CreateWorld()

	; camera 
	camera=CreateCamera() 
	PositionEntity( camera, 6, 4, -12.5 )
	temppivot = CreatePivot()
	PositionEntity( temppivot, 6, 0, -6 )
	PointEntity( camera, temppivot )
	FreeEntity( temppivot )
	
	; light
	AmbientLight 32, 32, 32
	light=CreateLight() 
	RotateEntity light, 60, 0, 0

	; playfield boundry walls
	wallone = CreateCube()
	ScaleEntity( wallone, .5, 1, 7 )
	PositionEntity( wallone, -1, .5, -5.5 )
	EntityAlpha( wallone, .25 )
	EntityType( wallone, WALLS )
		
	walltwo = CreateCube()
	ScaleEntity( walltwo, .5, 1, 7 )
	PositionEntity( walltwo, 12, .5, -5.5 )
	EntityAlpha( walltwo, .25 )
	EntityType( walltwo, WALLS )
		
	wallthree = CreateCube()
	ScaleEntity( wallthree, 6, 1, .5 )
	PositionEntity( wallthree, 5.5, .5, -12 )
	EntityAlpha( wallthree, .25 )
	EntityType( wallthree, WALLS )
		
	wallfour = CreateCube()
	ScaleEntity( wallfour, 6, 1, .5 )
	PositionEntity( wallfour, 5.5, .5, 1 )
	EntityAlpha( wallfour, .25 )	
	EntityType( wallfour, WALLS )
	
	fn_CreatePlayfield()
	fn_CreateGameToken()

	
	
End Function ; fn_CreateWorld()

;--------------------------------------;

; free everything
Function fn_DestroyWorld()

	fn_DestroyGameToken()
	fn_DestroyPlayfield()

	FreeEntity( light )	
	FreeEntity( camera )
	
End Function ; fn_DestroyWorld

Function fn_ManageCollisions()

	; cell y is as you're looking from the top down, essentially the 2d
	; version used the y coordinates, but as y literally goes up and down
	; i have to worry about the z position (in and out of the screen)
	
	readjusted_z# = -EntityZ( gameToken\m_entity )
	
	fn_AddDebugTxt( "x = " + EntityX( gameToken\m_entity ) + " y = " + EntityZ( gameToken\m_entity ) )
	ul_x = ( EntityX( gameToken\m_entity ) - 0.45 )
	ul_y = ( readjusted_z# - 0.45 )
	fn_AddDebugTxt( "upperleft x = " + ul_x + " upperleft y = " + ul_y )
	ur_x = ( EntityX( gameToken\m_entity ) + 0.45 )
	ur_y = ( readjusted_z# - 0.45 )
	fn_AddDebugTxt( "upperright x = " + ur_x + " upperright y = " + ur_y )
	ll_x = ( EntityX( gameToken\m_entity ) - 0.45 )
	ll_y = ( readjusted_z# + 0.45 )
	fn_AddDebugTxt( "lowerleft x = " + ll_x + " lowerleft y = " + ll_y )
	lr_x = ( EntityX( gameToken\m_entity ) + 0.45 )
	lr_y = ( readjusted_z# + 0.45 )
	fn_AddDebugTxt( "lowerright x = " + lr_x + " lowerright y = " + lr_y )
	
	
	If CountCollisions( gameToken\m_entity ) > 0 
		gameToken\m_yVelocity# = 0
	EndIf
	
	If( EntityCollided( gameToken\m_entity, 2 ) = Playfield( ul_x, ul_y ) )
		EntityColor( Playfield( ul_x, ul_y ), 32, 32, 32 )
	End If
	If( EntityCollided( gameToken\m_entity, 2 ) = Playfield( ur_x, ur_y ) )
		EntityColor( Playfield( ur_x, ur_y ), 32, 32, 32 )
	End If
	If( EntityCollided( gameToken\m_entity, 2 ) = Playfield( ll_x, ll_y ) )
		EntityColor( Playfield( ll_x, ll_y ), 32, 32, 32 )
	End If
	If( EntityCollided( gameToken\m_entity, 2 ) = Playfield( lr_x, lr_y ) )
		EntityColor( Playfield( lr_x, lr_y ), 32, 32, 32 )
	End If
	
End Function

;;; Playfield related functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Create the playfield, which at the moment
; is nothing more than an array of cubes.
Function fn_CreatePlayfield()

	; initial cube as a starting point
	Local cube = CreateCube() 
	ScaleEntity( cube, 0.5, 0.5, 0.5 )
	; 12 x 12 game board ( 0 - 11 = 12 positions )
	; note using y for z, swapping axes as the 2d
	; gameboard is being layed out flat like a table
	For y = 0 To 11
		For x = 0 To 11
			If( y > 0 ) Then adj_y = -y
			; create each "cell"
			Playfield( x, y ) = CopyEntity( cube )
			; position it relative to the other cells
			PositionEntity( Playfield( x, y ), x, 0, adj_y )
			EntityType( Playfield( x, y ), BLOCKS )
			; give it a random color for indentity
			EntityColor( Playfield( x, y ), Rand( 63, 192 ), Rand( 63, 192 ), Rand( 63, 192 ) )
		Next
	Next
	
	; no more need for the cube
	FreeEntity( cube )
	
End Function ; fn_CreatePlayfield

;--------------------------------------;

; free up all the cells essentially
Function fn_DestroyPlayfield()

	For y = 0 To 11
		For x = 0 To 11
			FreeEntity( Playfield( x, y ) )
		Next
	Next

End Function ; fn_DestroyPlayfield

;;; Game Token Related Functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; The piece the player directs
Function fn_CreateGameToken()

	gameToken = fn_CreateGameObject()
	
	; Make sure it created correctly
	If( gameToken <> Null )

		; now create the mesh/model etc
		gameToken\m_entity = CreateSphere()
		ScaleEntity( gameToken\m_entity, 0.45, 0.45, 0.45 )
		EntityType( gameToken\m_entity, TOKEN )
		PositionEntity( gameToken\m_entity, 5.5, 2, -5.5 )
		EntityRadius( gameToken\m_entity, .45 )
		ResetEntity( gameToken\m_entity )
		gameToken\m_xSpeed# = 0.02
		gameToken\m_ySpeed# = 0.0
		gameToken\m_zSpeed# = 0.02
		gameToken\m_xVelocity# = 0.0
		gameToken\m_yVelocity# = 0.0
		gameToken\m_zVelocity# = 0.0
		gameToken\mb_useGravity = True
		gameToken\m_gravity# = -.01
	Else
		RuntimeError( "Could not create game token." )
	End If
		
End Function ; fn_CreateGameToken()

;--------------------------------------;

; get rid of the game piece
Function fn_DestroyGameToken()

	fn_DestroyGameObject( gameToken )
	
End Function ; fn_DestroyGameToken()

;--------------------------------------;

Function fn_MoveGameToken()

	If( gameToken\mb_useGravity = True )
		gameToken\m_yVelocity# = gameToken\m_yVelocity# + gameToken\m_gravity#
	End If
	
	If( KeyDown( 200 ) )
		gameToken\m_zVelocity# = gameToken\m_zSpeed#
	Else If( KeyDown( 208 ) )
		gameToken\m_zVelocity# = -gameToken\m_zSpeed#
	Else
		gameToken\m_zVelocity# = 0
	End If

	If( KeyDown( 203 ) )
		gameToken\m_xVelocity# = -gameToken\m_xSpeed#
	Else If( KeyDown( 205 ) )
		gameToken\m_xVelocity# = gameToken\m_xSpeed#
	Else
		gameToken\m_xVelocity# = 0
	End If
	
	dx# = gameToken\m_xVelocity#
	dy# = gameToken\m_yVelocity#
	dz# = gameToken\m_zVelocity#
	
	TranslateEntity( gameToken\m_entity, dx#, dy#, dz# )
	
End Function

;;; TGameObject Functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; A quick note about game object functions.  It's not always
; good to create super long function names, so most of the
; game object functions shortend TGameObject as TGOb For instance
; fn_TGObXXX() - where XXX is the rest of the function name.

;--------------------------------------;

; create and return a game object (game entity,
; but since this is blitz i called it an object)
Function fn_CreateGameObject.TGameObject()

	; 'o' is temporary
	Local o.TGameObject
	
	; create it make sure everything went well
	o.TGameObject = New TGameObject
	If( o <> Null )
		Return( o )
	Else
		RuntimeError( "Could not create game object." )
	End If
	
End Function ; fn_CreateGameObject.TGameObject()

;--------------------------------------;

; Get rid of it
Function fn_DestroyGameObject( o.TGameObject )

	; if there's an entity created free it first
	If( o\m_entity <> 0 )
		FreeEntity( o\m_entity )
	End If
	
	Delete( o )
	
End Function ; fn_DestroyGameObject( o.TGameObject )

;--------------------------------------;

Function fn_TGObSetXVelocity( o.TGameObject, value# )

	o\m_xVelocity# = value#
	
End Function

;--------------------------------------;

Function fn_TGObGetXVelocity#( o.TGameObject )

	Return( o\m_xVelocity# )
	
End Function

;--------------------------------------;

Function fn_TGObSetYVelocity( o.TGameObject, value# )

	o\m_yVelocity# = value#
	
End Function

;--------------------------------------;

Function fn_TGObGetYVelocity#( o.TGameObject )

	Return( o\m_yVelocity# )
	
End Function

;--------------------------------------;

Function fn_TGObSetZVelocity( o.TGameObject, value# )

	o\m_zVelocity# = value#
	
End Function

;--------------------------------------;

Function fn_TGObGetZVelocity#( o.TGameObject )

	Return( o\m_zVelocity# )
	
End Function

;--------------------------------------;

Function fn_TGObSetXSpeed( o.TGameObject, value# )

	o\m_xSpeed# = value#
	
End Function

;--------------------------------------;

Function fn_TGObGetXSpeed#( o.TGameObject )

	Return( o\m_xSpeed# )
	
End Function

;--------------------------------------;

Function fn_TGObSetYSpeed( o.TGameObject, value# )

	o\m_ySpeed# = value#
	
End Function

;--------------------------------------;

Function fn_TGObGetYSpeed#( o.TGameObject )

	Return( o\m_ySpeed# )
	
End Function

;--------------------------------------;

Function fn_TGObSetZSpeed( o.TGameObject, value# )

	o\m_zSpeed# = value#
	
End Function

;--------------------------------------;

Function fn_TGObGetZSpeed#( o.TGameObject )

	Return( o\m_zSpeed# )
	
End Function

;--------------------------------------;

Function fn_TGObSetGravityFlag( o.TGameObject, b_flag )

	o\mb_useGravity = b_flag

End Function

;--------------------------------------;

Function fn_TGObGetGravityFlag( o.TGameObject )

	Return( o\mb_useGravity )
	
End Function

;--------------------------------------;

Function fn_TGObSetGravity( o.TGameObject, value# )

	o\m_gravity = value

End Function

;--------------------------------------;

Function fn_TGObGetGravity#( o.TGameObject )

	Return( o\m_gravity# )
	
End Function

;--------------------------------------;

.main

Graphics3D 640,480 
SetBuffer BackBuffer() 

Const TOKEN = 1
Const BLOCKS = 2
Const WALLS = 3
Collisions TOKEN, BLOCKS, 2 , 3
Collisions TOKEN, WALLS , 2, 3


fn_OpenLogFile()

fn_CreateWorld()

While Not KeyDown( 1 ) 
	fn_MoveGameToken()
	fn_AddDebugTxt( "Count collisions = " + CountCollisions( gameToken\m_entity ) )
	
	fn_ManageCollisions()
	UpdateWorld
	RenderWorld 
	fn_ShowDebugTxt( debugTxt )
	Flip 
Wend 

fn_DestroyWorld()

fn_CloseLogFile()

End 



Oh .. and now you have an array out of bounds when you hit the outer walls ... can't be arsed looking at that right now .. sorry.

Stevie