Working with Collisions and Meshes

Blitz3D Forums/Blitz3D Beginners Area/Working with Collisions and Meshes

StOrM3(Posted 2004) [#1]
When you use functions like nameentity and collisions etc.. and pass them the handle of the actual mesh inside the type you are using, that you loaded out of a b3d file, should I be using the overall entity instance, or do I use the mesh handle just like any other entity, the reason I ask, is I have a wierd Memory Violation error, after using collision stuff, and setting like collision radius, and fitmesh etc.. I think it is the functions I am using on the mesh to name it, and obtain info about it, like the collision type etc.. may need to be used on the actual entity itself instead of the mesh handle.

Can someone please help me, I am down to writing debug info out to a debug.txt file, and have limited the crash to one function which is rather large, but if need be I can paste it for review. Please help, as I don't really want to do a complete rewrite of this function, but I will if necessary, it may actually come out better the 2nd time.

Ken


_PJ_(Posted 2004) [#2]
Hmmmm....

I got a bit lost reading that, but I hope this helps:

If in a type, you have a field which coresponds to a mesh handle i.e. MyType\mesh=LoadMesh("Mesh.B3D") or MyType\mesh=CopyEntity (Master_Mesh) then MyType\mesh acts like any ordinary mesh handle. Are you sure you have copied or loaded the mesh as a type instance? Have you deleted the instance? Also, some collision commands work with handles, others work with occurrences of collisions or entity 'types' so check you've got the syntax of these right too. Perhaps sticking DebugMode on and checking the actual error line may be helpful.


StOrM3(Posted 2004) [#3]
You have helped more than you know, so I can put in my main sourcefile Debugmode on or is it Debugmode=on or what, and this will break execution on the error and point to the line with the problem ? That is great.. here I was trying to use writestring to track the bug down, and write values out to a text file. Thank you very very much.

Ken


Ross C(Posted 2004) [#4]
Could try and see if the mesh handle your using is Global. I know are Global, but type pointers,

p.pointer=new pointer


are not unless you

Global p.pointer=new pointer


Maybe this is your problem? Maybe your freeing the handle in the function or main program and using the other handle to try and access the entity, which doesn't work :)


Zethrax(Posted 2004) [#5]
To use debug mode, run your program using the standard Blitz editor and make sure the 'Debug enabled?' item is ticked in the 'Program' menubar menu.


_PJ_(Posted 2004) [#6]

To use debug mode, run your program using the standard Blitz editor and make sure the 'Debug enabled?' item is ticked in the 'Program' menubar menu.


So when an error occurs, it will give you more detailed info about what the error is (i.e. 'Object Muyst Be A Type') and as this exits back to the IDE, the cursor will be at the line containing the error ;)


StOrM3(Posted 2004) [#7]
Got the memory bug fixed. Now the collisions won't work when I took out the fitmesh line though, the scaling is not working as expected and as such some of the fruit items are falling through the level, but it was working using fitmesh, but then I had an extra ghost item that was displayed in the middle of the level, but after that item it correctly placed all the other fruit in rows and columns offset correctly and everything. I don't know the collision stuff is too tough to get working correctly under blitz, and the scaling stuff doesn't work right either, either with entity or mesh, but fitmesh somewhat works. I may need someone to look at it.

Ken


StOrM3(Posted 2004) [#8]
does anyone have a simple example showing how to load two models out of B3D files, scale them larger, and demonstrate checking for collisions etc.. ? I think this would greatly help me understand which functions to use, and help to drive the way blitz handles scaling and collision home.

Thanks for all your help guys.

Ken


_PJ_(Posted 2004) [#9]
Some points to remember:

Collision source/destination - don't forget the MOVING entity must be the Source (*hope that's the right way round!)

Scaling and collisions - ScaleEntity won't affect 'EntityRadius', Either use ScaleMesh (I think) or set the radii AFTER scaling.

Sorry, StOrM3, but I don't have much experience with the Collisions and scaling to help much more...

Why not post the relevant sections of your code regarding the meshes/collisions? ;)


StOrM3(Posted 2004) [#10]
If count% = 1 Then
fruitarray(count%)\fmodel% = LoadMesh("../media/cherry.b3d") ;Load initial model from b3d file.
meshx# = EntityX(fruitarray(count%)\fmodel%,True) ;get initial x,y,z coords for model.
meshy# = EntityY(fruitarray(count%)\fmodel%,True)
meshz# = EntityZ(fruitarray(count%)\fmodel%,True)
RotateMesh(fruitarray(count%)\fmodel%,60,30,0) ; Rotate the mesh after loading it.
FitMesh(fruitarray(count%)\fmodel%, meshx#, meshy#, meshz#, 20.0, 20.0, 20.0, True) ;stuff it in a box
EntityRadius(fruitarray(count%)\fmodel%,20.0) ; setting the entities collision radius to 20.
fruitarray(count%)\number% = count%
fruitarray(count%)\name$ = "cherry"
NameEntity fruitarray(count%)\fmodel%, "cherry" ;entityname for use in collision and points etc..
EndIf

Here is how one of the fruit models is setup.. with the fitmesh it works... though I still get a ghost fruit item.. for some reason.. I have 7 models in total setup inside a for loop.


StOrM3(Posted 2004) [#11]
I post some code, and ask for help, and this is when I get no replies... Can someone please help, I will post the full source code level I am working with right now.. I am seriously considering starting over from scratch on a couple of the functions, because something is clearly not doing what I think it should be, meaning it is a logic error and those are the hardest ones to find. On the next post I am posting the source code, there are three files, tstlvl.bb which is the main game test file containing all the setup, main loop. Then there is the types.bb which contains all of my custom types I am using. Finally there is the functions.bb which contains the meat and potatoes functions for all of it, the random fruit generation positions x,z coords, and the Y dropping routine to set the y coord when the current fruit item in the loop collides with the level. I will email them as well as any media including textures, models so you can test it fully and see what I am seeing, and then you can help to figure out where the ghost item is coming from, and why the collision is not working.

I don't mean to sound mean, but I am very tired, and have looked through and changed this source code like over 200 times now, and still am unable to get the affects I need. Can someone please, please help me. My head is hurting, if I had not tried rewriting it and changing it so many times already, and if the functions didn't seem logical to me, I would not be begging for help, but I am at my ropes end. I need someone to throw me a life preserver or life saver which ever you have available. heeheh that is about as much joking as I can make about this. Sorry, but I am starting to lose faith in Blitz3D and my own coding ability even though I have written 5 full games previously in the past, but am unable to make this simple game work as envisioned or designed.

my email for anyone interested in getting the full source and models email me at storm3@..., also I am posting just the source files here for review as well.

Ken


StOrM3(Posted 2004) [#12]
;************************************************
;FILENAME:types.bb
;PURPOSE:define all my custom types used in game.
;************************************************
Type player
Field pmodel% ; Player Model starts off as a bubble, when we hit an item, we copymesh that fruit model to this one changing player to new fruit items.
Field controller% ; What are we controlled by ? 1=Keyboard, 2=Mouse, 3=Joystick. This will be one value setup from options menu.
Field locx# ; These are the locations that we are currently located at x,y,z values...
Field locy#
Field locz#
Field roty# ; Current direction we are facing! NOTE: 90degree increments, 0, 90, 180, 270
Field direction%
Field speed# ; speed controls how far we move with each move, how fast we get from point a to point b.
Field special% ; special = 0 = none = 1 = speedup = 2 = acid = 3 = bomb = 4 = dynamite
Field fruit% ; number of fruit we currently are... 1=cherry 2=strawberry 3=orange 4=pear 5=apple 6=pineapple 7=banana
Field points% ; Current score for player!
Field lives% ; How many lives do we have left ? Start off with 3 lives only! May add a point value 1up goal to reach. 50000 points = 1up
Field dead% ; 1=yes we are dead, so sit and watch the main bubble bounce up and down
End Type

Type fruit
Field fModel%
Field number%
Field name$
End Type

Type level
Field levfloor% ; floor model of level
Field levtwall% ; top wall model of level
Field levbwall% ; botton wall model of level
Field levlwall% ; left wall model of level
Field levrwall% ; right wall model of level
Field timelimit% ; how long do we have before losing a life or the game on this level ?
Field number% ; what level are we on ?
Field name$ ; what is the name of this level called ?
End Type

Type fruititems
Field points%
Field number%
Field Model%
Field name$
Field locx#
Field locy#
Field locz#
Field dead%
Field special% ; 1 if special or 0 if just fruit.
Field specnum% ; used to track what kind of special item it is, 0 if just fruit.
Field visible% ; are we gonna draw it or not ?
End Type

Type special
Field points%
Field number%
Field name$
Field special%
Field timelimit%
Field dead%
Field lives%
Field area% ; how big of area will be affected by this object ? 1 = just player bubble, more=other fruit or boxes etc.. also take into account direction
End Type

;************************************************
; lvltest.bb - written by: Ken Cornett (ceo) Pain Killa Entertainment(tm)
; Copyright(c) 2004 - All rights reserved.
; Purpose: Load in and test simple level display and cameras and lighting.
; for useage of variables listed below see types.bb file as these variables are used in the types.bb file and functions are in functions.bb

Dim fruitarray.fruit(7) ;used to hold loaded fruit items models..
;Dim specialarray.special(5) ;used to hold loaded specialty items models..
Dim fruitlevel.fruititems(6,6) ; used to hold randomly placed fruit or special items...
Dim testlevel.level(1) ; used to test engine out merely, later it will be an array of all levels loaded one after the other stored in array for later use...
Dim playerone.player(1) ; used to setup the player we control in the game!

Global cntfruit%
Global cntx%
Global cntz%
Global dispmouse$
Global flagme%
Global colflag%
Global xspeed#
Global yspeed#
Global x#
Global y#
Global debugfile%

flagme% = 1
colflag% = 0

debugfile% = OpenFile("../debug/debug.txt")

For cntfruit% = 1 To 7
fruitarray.fruit(cntfruit%) = New fruit
Next
;specialarray.special(5) = New special
For cntz% = 1 To 6
For cntx% = 1 To 6
fruitlevel.fruititems(cntx%,cntz%) = New fruititems
Next
Next

testlevel.level(1) = New level
playerone.player(1) = New player

Include "types.bb"
Include "functions.bb"

Graphics3D 800,600,16,0

GameSetup() ; lets setup the various stuff needed like a camera, light, backbuffer!

loadlevel("../media/floor.b3d","../media/twall.b3d","../media/bwall.b3d","../media/lwall.b3d","../media/rwall.b3d") ; loading in 5 parts of level layout separetly for collide stuff.

positionlevel() ; Offset the loaded level to 0,0,0 so we have a starting place for the camera.

If setupfruit() = -1 ; Load the initial fruit models from the b3d files stored in media folder...
WriteString(debugfile%,"Setup Fruit Return = -1")
Else
WriteString(debugfile%,"Setup Fruit Return = 0")
EndIf

setupfruitarray(6) ; Create a 6x6 array of randomized fruit items for the level to be displayed...

setupplayer(2,175.0,2.0,75.0,3,0,50.0) ; cntrlr, x, y, z, lives, direction, speed.

;*******************************************************************************************************************************************************************************************
; ; no more memory leak. Now have To figure out where the fruit are positioned on the screen And why I can't see them, maybe turn off EntityAlpha Function use.
; fruit are positioned perfecto now, and rotated to make them easy to see, scaled as well. !! MILESTONE REACHED !!
; ** NEXT MILESTONE **
; Mouse routines are in, displaying mouse coords to help setup fruit positioning and the player position as you move the mouse...
; Now I need to get the fruit centered in the level again.
; Memory allocation error. Adding general purpose debug routines, which write out results to debug.txt file for further study.
;*******************************************************************************************************************************************************************************************


; the previous two includes allow us the types and functions we need to load in a test level for our game!
While Not KeyDown (1) ; now entering main loop

RenderWorld ; setup everything that is to be displayed render it fully with textures and lights...
doinput() ; process player input, hopefully!
Flip ; have to use this because we are drawing to the backbuffer so the drawing won't be seen during game play...
Wend
CloseFile(debugfile%) ; Close file used for debug output earlier...
; clean up code!
Delete Each fruit
;Delete Each special
Delete Each fruititems
Delete Each level
Delete Each player

;************************************************
;FILENAME:functions.bb
;PURPOSE:define all my functions used in game.
;************************************************
; Written By: Ken Cornett CEO - Pain Killa Entertainment(tm) - Copyright(c) 2004 - All Rights Reserved.
Global countx%
Global countz%

; Provides all the game setup features such as the cameras and lighting and backbuffer setup etc...
Function GameSetup()
; tell it to use backbuffer for all drawing operations until we flip it in main loop
SetBuffer BackBuffer()
; got to have one of these so we can see the world we create.
camera = CreateCamera()
; now placing the camera where we want it for the scene...
MoveEntity camera,0,400,-5
RotateEntity camera,90,0,0
; every scene must have even simple lighting...
light = CreateLight()
End Function

; This loads the level geometry from a b3d file into the testlevel variable.
; loadlevel("../media/floor.b3d","../media/twall.b3d","../media/bwall.b3d","../media/lwall.b3d","../media/rwall.b3d")
Function loadlevel%(filename1$, filename2$, filename3$, filename4$, filename5$)
; placeholder

; EntityBox entity,x#,y#,z#,width#,height#,depth# Use this to setup the various bounding boxes.
; Use MeshHeight, MeshWidth, MeshDepth to get values for each level piece to use in the entitybox setup stuff.
; May have to center each piece in milkshape, so when I call these values we get correct values for box size so it is only size of each piece.
; I need to get the width and depth of floor to help position the other cube pieces. Worse case scenario use cube objects created in blitz.
testlevel(1)\levfloor% = LoadMesh(filename1$)
testlevel(1)\levtwall% = LoadMesh(filename2$)
testlevel(1)\levbwall% = LoadMesh(filename3$)
testlevel(1)\levlwall% = LoadMesh(filename4$)
testlevel(1)\levrwall% = LoadMesh(filename5$)
EntityType(testlevel(1)\levfloor%,8,True) ; set this entitytype to 8 for collision checking in the setup_y function described later.
EntityType(testlevel(1)\levtwall%,8,True) ; set this entitytype to 8 for collision checking in the setup_y function described later.
EntityType(testlevel(1)\levbwall%,8,True) ; set this entitytype to 8 for collision checking in the setup_y function described later.
EntityType(testlevel(1)\levlwall%,8,True) ; set this entitytype to 8 for collision checking in the setup_y function described later.
EntityType(testlevel(1)\levrwall%,8,True) ; set this entitytype to 8 for collision checking in the setup_y function described later.
testlevel(1)\number% = 1
testlevel(1)\timelimit% = 300 ; 5 minutes = 60 * 5
testlevel(1)\name$ = "test"
NameEntity testlevel(1)\levfloor%, testlevel(1)\name$

Return -1
End Function

; This is to move the level geometry to absolute center 0,0,0 so that when we drop the fruit it lands on the level correctly positioned right...
Function positionlevel%()
; This function is for moving the level model into place, so that when we setup the fruit positions, and drop the Y coords it will be where it is supposed to be...
MoveEntity testlevel(1)\levfloor%,0,0,0
MoveEntity testlevel(1)\levtwall%,0,0,0
MoveEntity testlevel(1)\levbwall%,0,0,0
MoveEntity testlevel(1)\levlwall%,0,0,0
MoveEntity testlevel(1)\levrwall%,0,0,0
Return -1
End Function

; Loads the fruit models out of b3d files from hard drive into the fruitarray variable.
; Function updated 03_09_04 - Build 030904-a
; Created Fruit models, got initial x,y,z coords, rotate it, fit it into a 15x15x15 Bound Box
; Also set the entityName to whatever fruit it is.
Function setupfruit%()

Local count% = 1
Local meshx# = 0.0
Local meshy# = 0.0
Local meshz# = 0.0
Local sizex# = 0.0
Local sizey# = 0.0
Local sizez# = 0.0
Local avg# = 0.0

For count% = 1 To 7
If count% = 1 Then
fruitarray(count%)\fmodel% = LoadMesh("../media/cherry.b3d") ;Load initial model from b3d file.
meshx# = EntityX(fruitarray(count%)\fmodel%,True) ;get initial x,y,z coords for model.
meshy# = EntityY(fruitarray(count%)\fmodel%,True)
meshz# = EntityZ(fruitarray(count%)\fmodel%,True)
RotateMesh(fruitarray(count%)\fmodel%,60,30,0) ; Rotate the mesh after loading it.
;FitMesh(fruitarray(count%)\fmodel%, meshx#, meshy#, meshz#, 20.0, 20.0, 20.0, True) ;stuff it in a box
ScaleMesh(fruitarray(count%)\fmodel%,3,3,3)

sizex# = MeshWidth(fruitarray(count%)\fmodel%)
sizey# = MeshHeight(fruitarray(count%)\fmodel%)
sizez# = MeshDepth(fruitarray(count%)\fmodel%)

avg# = sizex# + sizey# + sizez# / 3

EntityRadius(fruitarray(count%)\fmodel%,avg# + 10.0) ; setting the entities collision radius to 20.
fruitarray(count%)\number% = count%
fruitarray(count%)\name$ = "cherry"
NameEntity fruitarray(count%)\fmodel%, "cherry" ;entityname for use in collision and points etc..
EndIf

If count% = 2 Then
fruitarray(count%)\fmodel% = LoadMesh("../media/strawberry.b3d")
meshx# = EntityX(fruitarray(count%)\fmodel%,True)
meshy# = EntityY(fruitarray(count%)\fmodel%,True)
meshz# = EntityZ(fruitarray(count%)\fmodel%,True)
RotateMesh(fruitarray(count%)\fmodel%,60,30,0) ; Rotate the mesh after loading it.
;FitMesh(fruitarray(count%)\fmodel%, meshx#, meshy#, meshz#, 20.0, 20.0, 20.0, True)
ScaleMesh(fruitarray(count%)\fmodel%,3,3,3)

sizex# = MeshWidth(fruitarray(count%)\fmodel%)
sizey# = MeshHeight(fruitarray(count%)\fmodel%)
sizez# = MeshDepth(fruitarray(count%)\fmodel%)

avg# = sizex# + sizey# + sizez# / 3

EntityRadius(fruitarray(count%)\fmodel%,avg# + 10.0) ; setting the entities collision radius to 20.
fruitarray(count%)\number% = count%
fruitarray(count%)\name$ = "strawberry"
NameEntity fruitarray(count%)\fmodel%, "strawberry"
EndIf

If count% = 3 Then
fruitarray(count%)\fmodel% = LoadMesh("../media/orange.b3d")
meshx# = EntityX(fruitarray(count%)\fmodel%,True)
meshy# = EntityY(fruitarray(count%)\fmodel%,True)
meshz# = EntityZ(fruitarray(count%)\fmodel%,True)
RotateMesh(fruitarray(count%)\fmodel%,60,30,0) ; Rotate the mesh after loading it.
;FitMesh(fruitarray(count%)\fmodel%, meshx#, meshy#, meshz#, 20.0, 20.0, 20.0, True)
ScaleMesh(fruitarray(count%)\fmodel%,3,3,3)

sizex# = MeshWidth(fruitarray(count%)\fmodel%)
sizey# = MeshHeight(fruitarray(count%)\fmodel%)
sizez# = MeshDepth(fruitarray(count%)\fmodel%)

avg# = sizex# + sizey# + sizez# / 3

EntityRadius(fruitarray(count%)\fmodel%,avg# + 10.0) ; setting the entities collision radius to 20.
fruitarray(count%)\number% = count%
fruitarray(count%)\name$ = "orange"
NameEntity fruitarray(count%)\fmodel%, "orange"
EndIf

If count% = 4 Then
fruitarray(count%)\fmodel% = LoadMesh("../media/pear.b3d")
meshx# = EntityX(fruitarray(count%)\fmodel%,True)
meshy# = EntityY(fruitarray(count%)\fmodel%,True)
meshz# = EntityZ(fruitarray(count%)\fmodel%,True)
RotateMesh(fruitarray(count%)\fmodel%,60,30,0) ; Rotate the mesh after loading it.
;FitMesh(fruitarray(count%)\fmodel%, meshx#, meshy#, meshz#, 20.0, 20.0, 20.0, True)
ScaleMesh(fruitarray(count%)\fmodel%,3,3,3)

sizex# = MeshWidth(fruitarray(count%)\fmodel%)
sizey# = MeshHeight(fruitarray(count%)\fmodel%)
sizez# = MeshDepth(fruitarray(count%)\fmodel%)

avg# = sizex# + sizey# + sizez# / 3

EntityRadius(fruitarray(count%)\fmodel%,avg# + 10.0) ; setting the entities collision radius to 20.
fruitarray(count%)\number% = count%
fruitarray(count%)\name$ = "pear"
NameEntity fruitarray(count%)\fmodel%, "pear"
EndIf

If count% = 5 Then
fruitarray(count%)\fmodel% = LoadMesh("../media/apple.b3d")
meshx# = EntityX(fruitarray(count%)\fmodel%,True)
meshy# = EntityY(fruitarray(count%)\fmodel%,True)
meshz# = EntityZ(fruitarray(count%)\fmodel%,True)
RotateMesh(fruitarray(count%)\fmodel%,60,30,0) ; Rotate the mesh after loading it.
;FitMesh(fruitarray(count%)\fmodel%, meshx#, meshy#, meshz#, 20.0, 20.0, 20.0, True)
ScaleMesh(fruitarray(count%)\fmodel%,3,3,3)

sizex# = MeshWidth(fruitarray(count%)\fmodel%)
sizey# = MeshHeight(fruitarray(count%)\fmodel%)
sizez# = MeshDepth(fruitarray(count%)\fmodel%)

avg# = sizex# + sizey# + sizez# / 3

EntityRadius(fruitarray(count%)\fmodel%,avg# + 10.0) ; setting the entities collision radius to 20.
fruitarray(count%)\number% = count%
fruitarray(count%)\name$ = "apple"
NameEntity fruitarray(count%)\fmodel%, "apple"
EndIf

If count% = 6 Then
fruitarray(count%)\fmodel% = LoadMesh("../media/pineapple.b3d")
meshx# = EntityX(fruitarray(count%)\fmodel%,True)
meshy# = EntityY(fruitarray(count%)\fmodel%,True)
meshz# = EntityZ(fruitarray(count%)\fmodel%,True)
RotateMesh(fruitarray(count%)\fmodel%,60,30,0) ; Rotate the mesh after loading it.
;FitMesh(fruitarray(count%)\fmodel%, meshx#, meshy#, meshz#, 20.0, 20.0, 20.0, True)
ScaleMesh(fruitarray(count%)\fmodel%,3,3,3)

sizex# = MeshWidth(fruitarray(count%)\fmodel%)
sizey# = MeshHeight(fruitarray(count%)\fmodel%)
sizez# = MeshDepth(fruitarray(count%)\fmodel%)

avg# = sizex# + sizey# + sizez# / 3

EntityRadius(fruitarray(count%)\fmodel%,avg# + 10.0) ; setting the entities collision radius to 20.
fruitarray(count%)\number% = count%
fruitarray(count%)\name$ = "pineapple"
NameEntity fruitarray(count%)\fmodel%, "pineapple"
EndIf

If count% = 7 Then
fruitarray(count%)\fmodel% = LoadMesh("../media/banana.b3d")
meshx# = EntityX(fruitarray(count%)\fmodel%,True)
meshy# = EntityY(fruitarray(count%)\fmodel%,True)
meshz# = EntityZ(fruitarray(count%)\fmodel%,True)
RotateMesh(fruitarray(count%)\fmodel%,60,30,0) ; Rotate the mesh after loading it.
;FitMesh(fruitarray(count%)\fmodel%, meshx#, meshy#, meshz#, 20.0, 20.0, 20.0, True)
ScaleMesh(fruitarray(count%)\fmodel%,3,3,3)

sizex# = MeshWidth(fruitarray(count%)\fmodel%)
sizey# = MeshHeight(fruitarray(count%)\fmodel%)
sizez# = MeshDepth(fruitarray(count%)\fmodel%)

avg# = sizex# + sizey# + sizez# / 3

EntityRadius(fruitarray(count%)\fmodel%,avg# + 10.0) ; setting the entities collision radius to 20.
fruitarray(count%)\number% = count%
fruitarray(count%)\name$ = "banana"
NameEntity fruitarray(count%)\fmodel%, "banana"
Return -1
EndIf
Next
End Function

; This sets up the type of fruit at each array position that makes up the level. Also setup the positions, point values, whether it is fruit or special item or not...
; This is the master array which holds the model handles for either fruit or special items both, and positions etc.. So an external special array is not necessary..
; One draw routine needed only because of this methodology. The setupspecial function loads in the special items models and stores that info in one location,
; which is copied from that array and also the setupfruit function stores the model and other info for the fruit models in one location, and this function brings both
; the two seperate arrays together into a two dimensional array for the map layout. This function will need to be called once for each new level loaded.
Function setupfruitarray%(levelsize%)
Local highval%=0 ; used for determing random point values, also used with lowval to make a decision if it is special item or just fruit.
Local lowval%=0
; Logic is this, if the lowvalue ends up being less than the high value then this is a piece of fruit, else we are a specialty item..
Local seedvalue%=0
Local fruitxyz$
countx% = 1
countz% = 1

seedvalue% = MilliSecs() ; We want truely random numbers so we seed the random values with the realtime clock value...
SeedRnd seedvalue%

; this function sets up the large array of fruit that makes up the level items including special items...
; We want truely random numbers so we seed the random values with the realtime clock value...
For countz% = 1 To levelsize%
For countx% = 1 To levelsize%
lowval% = Rand(1,10) ; Get a random number between 1 and 10 to use as a low value for comparison later on for fruit or special item!
highval% = Rand(1,10) ; Get a random number between 1 And 10 To use as a high value For comparison later on For fruit Or special item!

fruitlevel(countx%,countz%)\number% = Rand(1,7) ; pick a random number between 1 and 7, seven different fruits total to pick from...

fruitlevel(countx%,countz%)\Model% = CopyMesh(fruitarray(fruitlevel(countx%,countz%)\number%)\fModel%) ; grab fruit model handle assign it to this item in array
fruitlevel(countx%,countz%)\special% = 0 ; we are not a special item!
fruitlevel(countx%,countz%)\specnum% = 0 ; we are not a special item at all.
fruitlevel(countx%,countz%)\name$ = fruitarray(fruitlevel(countx%,countz%)\number%)\name$ ; grab fruit name and assign it to this array items name
WriteString(debugfile%, "Current Fruit = " + fruitlevel(countx%,countz%)\name$) ; Output debug info, so we know where it is stopping.
; Placeholder 03_07_04
; Need to set scale values seperately for each fruit to ensure it looks right and fruit is all the same size.

If name$ = "cherry" Then
fruitlevel(countx%,countz%)\points% = 25
EntityType(fruitlevel(countx%,countz%)\Model%, 1, False ) ; Here we are setting the cherry type to 1 for collisions !!!
Collisions(1,8,2,1) ; Here we are setting up to do stop on collision between Cherry and Level model... aka type 8
EndIf
If name$ = "strawberry" Then
fruitlevel(countx%,countz%)\points% = 50
EntityType(fruitlevel(countx%,countz%)\Model%, 2, False) ; Here we are setting the Strawberry type to 2 for collisions !!!
Collisions(2,8,2,1) ; Here we are setting up to do stop on collision between Strawberry and Level model... aka type 8
EndIf
If name$ = "orange" Then
fruitlevel(countx%,countz%)\points% = 75
EntityType(fruitlevel(countx%,countz%)\Model%, 3, False) ; Here we are setting the Orange type to 3 for collisions !!!
Collisions(3,8,2,1) ; Here we are setting up to do stop on collision between Orange and Level model... aka type 8
EndIf
If name$ = "pear" Then
fruitlevel(countx%,countz%)\points% = 100
EntityType(fruitlevel(countx%,countz%)\Model%, 4, False) ; Here we are setting the Pear type to 4 for collisions !!!
Collisions(4,8,2,1) ; Here we are setting up to do stop on collision between Pear and Level model... aka type 8
EndIf
If name$ = "apple" Then
fruitlevel(countx%,countz%)\points% = 250
EntityType(fruitlevel(countx%,countz%)\Model%, 5, False) ; Here we are setting the Apple type to 5 for collisions !!!
Collisions(5,8,2,1) ; Here we are setting up to do stop on collision between Apple and Level model... aka type 8
EndIf
If name$ = "pineapple" Then
fruitlevel(countx%,countz%)\points% = 500
EntityType(fruitlevel(countx%,countz%)\Model%, 6, False) ; Here we are setting the pineapple type to 6 for collisions !!!
Collisions(6,8,2,1) ; Here we are setting up to do stop on collision between Pineapple and Level model... aka type 8
EndIf
If name$ = "banana" Then
fruitlevel(countx%,countz%)\points% = 1000
EntityType(fruitlevel(countx%,countz%)\Model%, 7, False) ; Here we are setting the Banana type to 7 for collisions !!!
Collisions(7,8,2,1) ; Here we are setting up to do stop on collision between Banana and Level model... aka type 8
EndIf
; now we have points, name, model, next we must assign the location values for this item...

fruitlevel(countx%,countz%)\locz# = 50 * countz% - 160 ; Perfected z even spacing, fruit location offset as well to be inside level.
fruitlevel(countx%,countz%)\locx# = 50 * countx% - 175 ; Perfect x positioning for fruit offsets, location offset to be inside the level.

If dropitems(countx%,countz%, 1.0) = -1
fruitlevel(countx%,countz%)\dead% = 0
Else
fruitlevel(countx%,countz%)\dead% = 1 ; this item is dead and hidden currently.
EndIf
WriteString(debugfile%, "Dropped Fruit = " + fruitlevel(countx%,countz%)\name$)
fruitxyz$ = "Fruit X,Y,Z = " + Str fruitlevel(countx%,countz%)\locx# + "," + Str fruitlevel(countx%,countz%)\locy# + "," + Str fruitlevel(countx%,countz%)\locz#
WriteString(debugfile%, fruitxyz$)
WriteString(debugfile%, "-----------------------------------------------------------------------------------------") ; Seperate Items to make them easier to read.
Next
Next
End Function

; Drop the fruit items to a certain level, using collision detection to stop when it collides with the level.
; There is a memory bug in this function, I think it is because the collision stuff for level is not setup all the way for each wall.
; Need to setup bounding boxes, for floor and walls.
Function dropitems(countx%,countz%, destinationy#)
Local virtualspot#
Local coll% ; Returned entity from the collision the fruit item was involved in...
Local colcount% ; variable to count the number of collisions of the current fruit item...
; setup initial position for fruit to fall from!
colflag% = 0 ; initially no collisions with this fruit item and level!
colcount% = 0 ; initially no collisions to count.

PositionEntity fruitlevel.fruititems(countx%,countz%)\Model%, fruitlevel.fruititems(countx%,countz%)\locx# ,200.0,fruitlevel.fruititems(countx%,countz%)\locz#
fruitlevel.fruititems(countx%, countz%)\locy# = 200.0 ; Have to set initial Y starting position to 200 also...

For virtualspot# = 200.0 To destinationy# Step -20.0 ; Dropping -20 each time through loop til we collide on the level...

colcount% = CountCollisions(fruitlevel.fruititems(countx%,countz%)\Model%) ; how many collisions is fruit in ?
If colcount% > 0
coll% = CollisionEntity(fruitlevel.fruititems(countx%,countz%)\Model%, colcount%) ; return other entity in collision.

If EntityName(coll%) = EntityName(testlevel.level(1)\levfloor%)
fruitlevel.fruititems(countx%, countz%)\locy# = virtualspot# + 1.0 ;set Y coord to collision spot + 1.0
colflag% = 1
Return -1
EndIf
Else
MoveEntity fruitlevel.fruititems(countx%,countz%)\Model%, 0,-20.0,0 ; drop the entity by -10.0 same as loop to have item move downward!
fruitlevel.fruititems(countx%, countz%)\locy# = fruitlevel.fruititems(countx%, countz%)\locy# -20.0
EndIf
;If EntityDistance(fruitlevel.fruititems(countx%, countz%)\Model%, testlevel.level(1)\levfloor%) < 20.0
; fruitlevel.fruititems(countx%, countz%)\locy# = 5.0
; colflag% = 1
; Return -1
;EndIf
RenderWorld
Flip
Next
; If we get here we have not collided with level so we need to turn this item off. I will use the entityalpha value to set it to invisible.
;EntityAlpha fruitlevel.fruititems(countz%, countx%)\Model%, 0
If colflag% = 0
Return 0 ; We return false as this item did not collide with the level!
EndIf
End Function

; Load the player model out of b3d file, setup the player variables default values.
Function setupplayer%(controller%, startx#, starty#, startz#, lives%, roty#, speed#)
Local colnum% = 1 ; use to setup collisions between player and other fruit items!
playerone(1)\pmodel% = LoadMesh("../media/bubble.b3d") ; load the players initial model the bubble if you will!
ScaleEntity playerone(1)\pmodel%,3,3,3 ; We have to enlarge the player model to make them able to see...
playerone(1)\controller% = controller% ; what are we initially controlled by ? 1KB, 2MS, 3JS
playerone(1)\locx# = startx# ; These represent the initial starting locations for the player x,y,z
playerone(1)\locy# = starty#
playerone(1)\locz# = startz#
playerone(1)\roty# = roty# ; What direction are we currently facing 90degree increments, 0,90,180,270.
playerone(1)\direction% = 1
playerone(1)\speed# = speed# ; How far/fast we are going to move, each time we move the player model.
playerone(1)\special% = 0 ; we are not currently using specialty items, this is merely for easy expansion.
playerone(1)\fruit% = 0 ; fruit that we currently are, we start out as a bubble so 0, 1=cherry,2=strawberry,3=orange,4=pear,5=apple,6=pineapple,7=banana.
playerone(1)\points% = 0 ; players current score!, of course we start player out with 0 points anything else would be cheating!
playerone(1)\lives% = lives% ; How many lives do we start off with, I think I decided on 3 to start with, then 1up every 50000.
playerone(1)\dead% = 0 ; It's Alive! In other words set this initially to 0, because we are not dead yet.
EntityType(playerone(1)\pmodel%,9,True) ; set this entitytype to 9 for collision checking later.
NameEntity(playerone(1)\pmodel%,"player") ; setting up player entity name so its easier to check collisions.
Collisions(9,8,1,1) ; Here we are setting up to do stop on collision between Player type 9 and Level type 8
For colnum% = 1 To 7 ; Setting up stop collisions on player colliding into fruit items.
Collisions(9,colnum%,1,1)
Next
PositionEntity playerone(1)\pmodel%, playerone(1)\locx#, playerone(1)\locy#, playerone(1)\locz# ; Move the player model to the starting position, ready to begin.
MoveMouse(400,300) ; set the mouse pointer to the center of the screen
End Function

Function rotateplayer(direction%)

End Function

Function moveplayer()
If playerone(1)\roty# = 0
MoveEntity playerone(1)\pmodel%, playerone(1)\speed#, 0, 0

EndIf

If playerone(1)\roty# = 180
MoveEntity playerone(1)\pmodel%, playerone(1)\speed# * -1, 0, 0
EndIf

If playerone(1)\roty# = 90
MoveEntity playerone(1)\pmodel%, 0, 0,playerone(1)\speed#
EndIf

If playerone(1)\roty# = 270
MoveEntity playerone(1)\pmodel%, 0, 0,playerone(1)\speed# * -1
EndIf
RenderWorld
Flip
End Function

Function doinput()
Local direction%

If flagme% = 1
x# = 400
y# = 300
flagme% = flagme% + 1
EndIf

If playerone(1)\controller% = 2

xspeed# = MouseXSpeed()
yspeed# = MouseYSpeed()
x# = x# + xspeed# ; use to update the mouse coords.
y# = y# + yspeed#
x# = x# Mod 50
y# = y# Mod 50 ; This is for 50 pixel jumps, we still need to keep player in a Y Line if on left or right side, or X Line if above or below...
dispmouse$ = Str(x#+","+y#)
Text x#, y#, dispmouse$

MoveEntity playerone(1)\pmodel%, x#,y#, 0

If colflag% = 1
Text 1.0,1.0, "TRUE"
Else
Text 1.0,1.0, "FALSE"
EndIf

; Contstrain mouse movement inside the screen
If x# > GraphicsWidth() -1 Then
x# = GraphicsWidth() -1
EndIf
If x# < 0 Then
x# = 0
EndIf
If y# > GraphicsHeight() -1 Then
y# = GraphicsHeight() -1
EndIf
If y# < 0 Then
y# = 0
EndIf
; end mouse screen constraint code...
EndIf

If playerone(1)\controller% = 1
If KeyHit( 205 )=True
If playerone(1)\direction% = 1
TurnEntity playerone(1)\pmodel%, 0,0,0
playerone(1)\direction% = 1
EndIf
If playerone(1)\direction% = 2
TurnEntity playerone(1)\pmodel%, 0,270,0
playerone(1)\direction% = 1
EndIf
If playerone(1)\direction% = 3
TurnEntity playerone(1)\pmodel%, 0,180,0
playerone(1)\direction% = 1
EndIf
If playerone(1)\direction% = 4
TurnEntity playerone(1)\pmodel%, 0,90,0
playerone(1)\direction% = 1
EndIf
EndIf

If KeyHit( 203 )=True
If playerone(1)\direction% = 1
TurnEntity playerone(1)\pmodel%, 0,180,0
playerone(1)\direction% = 3
EndIf
If playerone(1)\direction% = 2
TurnEntity playerone(1)\pmodel%, 0,90,0
playerone(1)\direction% = 3
EndIf
If playerone(1)\direction% = 3
TurnEntity playerone(1)\pmodel%, 0,0,0
playerone(1)\direction% = 3
EndIf
If playerone(1)\direction% = 4
TurnEntity playerone(1)\pmodel%, 0,270,0
playerone(1)\direction% = 3
EndIf
EndIf

If KeyHit( 200 )=True
If playerone(1)\direction% = 1
TurnEntity playerone(1)\pmodel%, 0,90,0
playerone(1)\direction% = 2
EndIf
If playerone(1)\direction% = 2
TurnEntity playerone(1)\pmodel%, 0,0,0
playerone(1)\direction% = 2
EndIf
If playerone(1)\direction% = 3
TurnEntity playerone(1)\pmodel%, 0,270,0
playerone(1)\direction% = 2
EndIf
If playerone(1)\direction% = 4
TurnEntity playerone(1)\pmodel%, 0,180,0
playerone(1)\direction% = 2
EndIf
EndIf

If KeyHit( 208 )=True
If playerone(1)\direction% = 1
TurnEntity playerone(1)\pmodel%, 0,270,0
playerone(1)\direction% = 4
EndIf
If playerone(1)\direction% = 2
TurnEntity playerone(1)\pmodel%, 0,180,0
playerone(1)\direction% = 4
EndIf
If playerone(1)\direction% = 3
TurnEntity playerone(1)\pmodel%, 0,90,0
playerone(1)\direction% = 4
EndIf
If playerone(1)\direction% = 4
TurnEntity playerone(1)\pmodel%, 0,0,0
playerone(1)\direction% = 4
EndIf
EndIf
EndIf

;rotateplayer(playerone(1)\direction%)
;
If KeyHit(57)=True
moveplayer()
EndIf
End Function

; Next step are to test each function seperately in this game.bb file by calling only the necessary ones to display items, such as the level first, then move on to the
; difficult stuff such as testing and debugging the fruit/special items display functions.
; Finally a player item must be loaded and setup, with movement functions, and the functions to handle special items, countdown, useage, point system, lives, etc..


StOrM3(Posted 2004) [#13]
I hope someone can help me, or has the time to help, also feel free to use some of the code in your own projects if you like, but please don't steal my game idea, I have worked long and hard on this game, started in 3drad, then ported to blitz3d when I found that 3drad has problems with strings etc.. When talking to the creator/s of blitz3d I thought that I could handle it in blitz3d alot easier, but collision is not working as expected, nor is scaling stuff. Someone needs to write a tutorial about how to load a model from a b3d file, into a custom type, then scale it, then rotate it, then load another object and do the same to it, and show how to make collision work with it, maybe with rebound affects if collided with level, or stop when it hits a level, or if it hits an item to remove the item off the screen, using mouse input, to move the player around the outside of the items in 50 pixel increments. Or even if someone can help me with some of the pieces of this puzzle, I don't need anyone to write the whole game for me, but maybe with a level rectangle, and one or two items falling down to hit the level and stop, and a simple cube or sphere moved by the mouse, stopping at 50 pixel increments, demonstrating how to track collision between both the player to level, player to items, and items to level.

Thanks for everyones help, this community is one of the main reasons I decided on Blitz3D instead of DarkB*)ic .. I checked the forum out to make sure we had intelligent mature people willing to help out, so far you have not let me down in the least.

Ken


StOrM3(Posted 2004) [#14]
Hey just a thought, but maybe I shouldn't be using the built in collision routines from blitz, maybe I should use a userlib like coldet wrapper, or one of the other dll or user made libs in the code archives.. Wonder how long it would take to port it to Tokamak now that it has collision response and stuff in it. Any thoughts, or favorites that people have used with ease and success ? I am open to all suggestions, sorry for the ramblings, I am tired.. Night all. Ken