I could be missing something here, but how is that any better/more logical than this:
Nah your right, functionally they serve much the same purpose. Even behind the scenes it's only a tiny but different, mainly as types hold their fields in cluster. Much like a 2D array version of your example say. Where index 1 is the object and the second is the field your accessing.
ie.
Constant Hero_Status=1
Constant Hero_Xpos=2
Constant Hero_Ypos=3
Constant Hero_StructSize=4
Dim Hero(NumberOfHeros, Hero_StructureSize)
Syntax wise the typed version is perhaps more elegant to some.
Type tHero
Status,Xpos,Ypos, etc
EndType
Dim Hero(NumberOfHeros) as tHero
There's a few advantages I guess, it really depends upon your perspective. It's a
style thing if you ask me.
*)You can copy/move types using the
CopyArrayCells command, while it's far from an elegant command. It does allow you to copy the whole thing in one line. It doesn't matter what fields it has.
*) you can delete an entire type using
ClearArrayCells. if you pass CellArraycells a typed array, and fill any index with zeros, it'll de-allocate whatever type data was at this position, thus deleting the type.
*) You can find free types (those who haven't been allocated yet) using the FindArrayCell() function.
Ie. in the following example, the functions are being used to construct your own 'command set' that deals with the Heroes in your game. This is sort of layer of code that props up what's above it. The more robust you build the base layer, generally the easier it gets to build the game on top of it. Well, that's the theory
Ideally the function set layer is used to completely abstract the arrays behind them, so rather than dealing with the array directly, you end up calling a simplified function set to control the characters. Where you might have stuff PostionHero, Movehero, animated etc functions.
There's a few benefit of this style of approach, as by abstracting the underlying arrays & data structures, our "Game Engine Code" is no longer dependant directly upon data structures or PB command sets for that matter. Since all the required functionality of the characters is wrapped/hidden away inside the functions for us.
This can really make the game engine code
much simpler, and far less effected by changes made to the arrays underneath.
So imagine this type of layering,
> Game Engine Code
-----> Character function Layers
--------------> The arrays/low level variables each function layer encapsulates. Ideally the game avoids using this directly
Then in future projects, This approach could assist you via being able to simply import/grab (cut and paste) your Character Layers into a new project and just start work on the new game engine virtually immediately. Obviously it depends upon how specific the character layers are created though. But you get the idea.
Type tHero
Status,X#,y#,Speed#,score
EndType
Dim Hero(10) as tHero
Player1=newHero(100,200)
etc
Function NewHero(x,y)
Index=GetFreeHero()
If Index<>0
Hero(index).Status=true
Hero(index).x=x
Hero(index).Y=Y
endif
EndFunction Index
Function CloneHero(SrcHero,destHero)
; whis will clone whatever type data is at the src position
; into the dest position. If the destination wasn't empty, it
; be cleared (de allocated) for you.
CopyArraycells Hero().tHero,SrcHero,1,Hero().tHero,DestHero,1,1
EndFunction
Function GetFreeHero()
; make the function get the size of this array for us
ArraySize=GetArrayElements(hero().thero,1)
; search from index 1 to the size of the array, stepping
; forward 1 cell at a time. If a empty cell is found
; it will return the number steps it took, not the position
FreeIndex=FindArrayCell( hero().thero,1,1,ArraySize,0)
; If a cell was found add on the start position
If Freeindex<>-1 then inc FreeIndex
EndFunction FreeIndex
Function DeleteHero(Index)
; clear this cell within the array, which will force PB
; to be deallocated it. It avoids running through and setting
; all the fields to zero or null again.
ClearArrayCells Hero().tHero,Index,0,1,0
EndFunction
Another advantage that comes to mind occurs through using functions & subs however, where it's possible to build generic functions that can operation upon, not only the parent typed array, but it's children (others types derived from it). To do this you pass the array into a function. Providing your passing an array that either matches the receiver or is a descendant of receiver, it can be passed. This function can then operate upon whatever its given. Have a look at the Linked List code i posted the other day. It uses this approach.
Now I fully realize you can do
all of the above with arrays too. Hence it's all subjective.
For your current implementation, you can probably utilize array passing. And get much the same benefits. Ie. a bit less code in places
Current i'm guessing there's some code that is virtually the same, but based on different arrays. Like finding a free object (of whatever type) is one that comes to mind.
I.e.
Dim Hero_Status(maxHeros)
Dim Hero_Xpos#(maxHeros)
Etc etc
Dim Alien_Status(maxaliens)
Dim Alien_Xpos#(maxaliens)
Etc etc
Gosub FindFreeAlien
Print FreeAlien
Gosub FindFreeHero
Print FreeHero
FindFreeAlien:
FreeAlien=0
For lp=1 to MaXAliens
if Alien_status(lp)=false then FreeAlien=lp : Exit
next
return
FindFreeHero:
FreeHero=0
For lp=1 to MaXHero
if Hero_status(lp)=false then FreeHero=lp : Exit
next
return
If you had something like this, you could write a generic function that accepts any 1D array and will search for a free (set to zero) Item.. Like this
Function FindFree(SearchArray())
For lp=1 to GetArrayElements(SearchArray(),1)
if SearchArray(lp)=false then FreeIndex=lp : Exit
next
EndFunction FreeIndex
now you can use it to scan for free Heros or Aliens, or anything else
Ie.
FreeHero =FindFree(Hero_Status())
FreeAlien =FindFree(Alien_Status())
Update (10th,Oct,2012): - Some of the advice given here has been superseded by modern versions of the PlayBASIC. Today, it's generally more optimal to use TYPES because the modern versions of the PlayBASIC compiler include Type Caching features.