The collisions aren't working right. Essentially I have an array of cubes layed out like a table. I have a sphere I created. I scaled down the cubes and the sphere to 1,1,1 (.5 meaning half). The gameToken is the sphere the cubes are the playfield. I also have a gravity field in the TGameObject type, so it will start moving down if another field is set to allow gravity. If I place the sphere (gameToken) 6 units above the cubes (playfield) the sphere will move down towards the board resting on top of it like it should. However, if I place the sphere one unit closer then the collision goes haywire.
Also a thing to note is I use y for z, that is, the playfield is 2d x and y, I'll put in the playfield y coordinate into the z position, because up corresponds to into the screen, and down corresponds to out of the screen. For instance PositionEntity( gameToken, x, 0, y ) - even though y is in the z coordinate it represents y on the game board.
Consider this source code -
; 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, 2, -16 )
temppivot = CreatePivot()
PositionEntity( temppivot, 6, 0, -6 )
;RotateEntity( camera, 60, -20, 0 )
PointEntity( camera, temppivot )
FreeEntity( temppivot )
; light
AmbientLight 32, 32, 32
light=CreateLight()
RotateEntity light, 60, 0, 0
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 )
Collisions( 1, 2, 3, 1 )
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 ), 2 )
EntityBox( Playfield( x, y ), x, 0, adj_y, 0.5, 0.5, 0.5 )
; 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, 1 )
EntityRadius( gameToken\m_entity, 0.90 )
PositionEntity( gameToken\m_entity, 5.5, 6.00, -5.5 )
gameToken\m_xSpeed# = 0.0
gameToken\m_ySpeed# = 0.0
gameToken\m_zSpeed# = 0.0
gameToken\m_xVelocity# = 0.0
gameToken\m_yVelocity# = 0.0
gameToken\m_zVelocity# = 0.0
gameToken\mb_useGravity = True
gameToken\m_gravity# = -0.002
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
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()
fn_OpenLogFile()
fn_CreateWorld()
While Not KeyDown( 1 )
fn_MoveGameToken()
fn_ManageCollisions()
UpdateWorld
RenderWorld
fn_ShowDebugTxt( debugTxt )
Flip
Wend
fn_DestroyWorld()
fn_CloseLogFile()
End
If anyone can tell me what i'm doing wrong, i'd appreaciate it.
|