Wave's~ BlitzMax Tutorial for NG | ~ November, 2015 ~ Version 11 |
Beginners guide to BlitzMax | |
Some TList Functions and Methods | |
1: ListAddLast TankList,NewTank | 2: ListAddFirst YourList, YourType |
1a: tanklist.addlast(newtank) | 2a: YourList.AddFirst(YourYype) |
1 and 1a do the same thing. 1 is a normal function, 1a is a method and is called from your list instance. 2 and 2a do the same thing. 2 is a normal function, 2a is a method and is called from your list instance. These functions are in BlitzMax's TList-Type. | |
You can get the first object in a list by doing this: | |
my_firsttank:tanktype = Tank( TankType.List.First() ) | |
The reason for Tank( ... ) is that I have to force the object returned to be a Tank not just any object. | |
The following would be the same: | |
Local someobject:Object = TankType.List.First() If someObject Then Print "Object Found in list" Else Print "No Object found" End If Local FirstTank:TankType = TankType(someObject ) If FirstTank Then Print "Tank Found in the list" Else Print "No Tank found" End If | |
The reason we need to force the object is because First() returns an object and not a tank. If someObject is not a Tank then FirstTank would be = null. Read more about this in "casting" You will find the code for TList in BlitzMax/mod/brl.mod/linkedlist.mod/linkedlist.bmx. All source to BlitzMax comes along for free, open to you! Most of it is written in BlitzMax itself. | |
Arrays in Types | |
These could be useful to know about. To add a field with an array: field missiles[2]. I'll also show you the benefit of this reduced code. Build Example 1 and then compare it to the Example 2 which does the exact same thing but with reduced and simpler code. | |
Example 1 | |
Strict Global tanklist:TList = CreateList() Local Tank:WarTank Tank = New WarTank Tank.Name = "Thunder Tank" Tank.MissileSlot1 = "Infero Missile" Tank.AmmoSlot1 = 3 '3 missiles TankList.AddLast( Tank ) Tank = New WarTank Tank.Name = "Lightning Tank" Tank.MissileSlot2 = "Infero Missile" Tank.AmmoSlot2 = 1 Tank.MissileSlot3 = "Normal Missile" Tank.AmmoSlot3 = 1 TankList.AddLast( Tank ) Tank = New WarTank Tank.Name = "Storm Tank" Tank.MissileSlot1 = "Normal Missile" Tank.AmmoSlot1 = 3 Tank.MissileSlot2 = "Infero Missile" Tank.AmmoSlot2 = 1 Tank.MissileSlot3 = "Normal Missile" Tank.AmmoSlot3 = 2 TankList.AddLast( Tank ) For Local Tank:WarTank = EachIn TankList Print "" Repeat Select Tank.MissileSlot1 Case "Infero Missile" Tank.FireMissile( 1 ) Case "Normal Missile" Tank.FireMissile( 1 ) End Select Select Tank.MissileSlot2 Case "Infero Missile" Tank.FireMissile( 2 ) Case "Normal Missile" Tank.FireMissile( 2 ) End Select Select Tank.MissileSlot3 Case "Infero Missile" Tank.FireMissile( 3 ) Case "Normal Missile" Tank.FireMissile( 3 ) End Select Until Tank.AmmoSlot1 = 0 And tank.ammoslot2 = 0 And Tank.AmmoSlot3 = 0 Next Type WarTank Field Name$ = "Default Name" Field MissileSlot1$,MissileSlot2$,MissileSlot3$ Field AmmoSlot1%,AmmoSlot2%,AmmoSlot3% 'F I R E - - M I S S I L E '__________________________________________________________________ ' ' parameters: missileslot - the slot number you want to fire from. ' use: fires a missile if you got availible ammo else it don't ' '__________________________________________________________________ method firemissile( missleslotnr ) if missleslotnr > 3 Or MissleSlotNR < 1 Then return Select MissleSlotNR Case 1 If AmmoSlot1 <= 0 Print "Can't fire, No Ammo in Slot 1" Return EndIf Case 2 If AmmoSlot2 <= 0 Print "Can't fire, No Ammo in Slot 2" Return EndIf Case 3 If AmmoSlot3 <= 0 Print "Can't fire, No Ammo in Slot 3" Return EndIf EndSelect Print "Tank "+Name+" fired a missile from slot "+MissleSlotNR Select MissleSlotNR Case 1 AmmoSlot1:-1 Print "Last Missile Fired was a "+MissileSlot1 Case 2 AmmoSlot2:-1 Print "Last Missile Fired was a "+MissileSlot2 Case 3 AmmoSlot3:-1 Print "Last Missile Fired was a "+MissileSlot3 EndSelect EndMethod '____________________________________________________________________ End Type WarTank( TankList.First() ).FireMissile( 1 )' Try to fire with first tank | |
The above is NOT the way to do it, never, because if you use Arrays then you can use loops and auto set them: | |
Example 2 | |
Strict Global TankList:TList = CreateList() Local Tank:WarTank Tank = New WarTank Tank.Name = "Thunder Tank" Tank.Missile = ["Infero Missile"] Tank.Ammo = [ 3 ] TankList.AddLast( Tank ) Tank = New WarTank Tank.Name = "Lightning Tank" Tank.Missile = ["Infero Missile","Normal Missile"] Tank.Ammo = [ 1 , 1 ] TankList.AddLast( Tank ) Tank = New WarTank Tank.Name = "Storm Tank" Tank.Missile = ["Normal Missile","Infero Missile","Normal Missile"] Tank.Ammo = [ 3 , 1 , 2 ] TankList.AddLast( Tank ) 'Loop Each Tank For Local Tank:WarTank = EachIn TankList Print "---------------------------------" 'Loop Each Missile Slot For Local n = 0 Until Tank.Ammo.length 'Fire missiles until this slot is out-of-ammo Repeat Tank.FireMissile( n ) Until Tank.Ammo[n] <= 0 Next Next 'Try to fire first slot with first tank Print "------------------------------------" Print "Fire First Missile of the Last Tank" WarTank( TankList.Last() ).FireMissile( 0 ) Type WarTank Field Name$ = "Default Name" Field Missile$[] Field Ammo[] 'FIRE M I S S I L E '__________________________________________________________________ ' ' Parameters: MissileSlot - The slot number you want to fire from. ' Use: Fires a missile if you got availible ammo else it don't '___________________________________________________________________ Method FireMissile( MissleSlotNR ) If MissleSlotNR > Ammo.length Return If MissleSlotNR > Missile.length Return If MissleSlotNR < 0 return If ammo[ missleslotnr ] <= 0 Print "Can't fire, No Ammo in Slot "+MissleSlotNR Return End If Print "Tank "+Name+" fired a "+Missile[ MissleSlotNR ]+" from slot "+MissleSlotNR Ammo[ MissleSlotNR ]:-1 End Method '____________________________________________________________________ End Type | |
Always try to never replicate code, use loops and functions as much as possible. Also note how easy it would be to increase the number of weapon slots in the last example compared to the first. Our code is much more flexible now. Any of our tanks can have any number of weapon slots. Now let's take it one step further, think if we could have used a type instead of an array as our "missileslot". Instead of two arrays we can make it one type. This type will have its own methods and functions, like load and fire. Also our missile could be a type. We could load our slot with missiles and our tank with slots. Now it's starting to feel OOP. It will be a little longer but it will give us an even more flexible code. | |
Here is how that could look: | |
Example 3 | |
Strict Global tanklist:TList = CreateList() Local Tank:WarTank Tank = WarTank.Create( "Thunder Tank", 1 ) '--------------------------- Tank.GetSlot(1).Load( "Infero Missile", 1 )'Add 1 Inferno To Slot 1 Tank.GetSlot(1).Load( "Normal Missile", 1 )'Also Add Normal To Slot 2 Tank = WarTank.Create("Lightning Tank", 2 ) Tank.GetSlot(1).Load( "WirlWind Missile", 3 ) 'Add 3 WirlWind To Slot 1 Tank.GetSlot(2).Load( "Infero Missile" , 1 ) 'Add 1 Missile To Slot 2 Tank = WarTank.Create( "Storm Tank", 3 ) Tank.GetSlot(1).Load( "Normal Missile", 3 ) 'Add 3 Missiles to Slot 1 Tank.GetSlot(2).Load( "Infero Missile", 1 ) 'Add 1 Inferno to Slot 2 Tank.GetSlot(3).Load( "Normal Missile", 2 ) 'Add 2 Missiles To Slot 3 'Loop Each Tank For Tank:WarTank = Eachin TankList Print "---------------------------------" 'Loop Each Missile Slot in this Tank Local n For Local ThisSlot:WeaponSlot = EachIn Tank.Slot 'Fire missiles until this slot is out-of-ammo n:+1 Repeat Local Missile:TMissile = ThisSlot.Fire() If Missile Print Tank.Name+" fired a "+Missile.Name+" from slot "+n End If Until ThisSlot.Missile.Count() = 0 Next Next 'try to fire first slot with last tank Print "------------------------------------" Print "fire a missile in the first slot of the last tank" wartank( tanklist.last() ).fire( 1 ) ' w a r tank ' ' a tank which you can create and then fight with. ' Type wartank '-------------------------------------- Field name$ = "Default Name" Field Slot:TList = New TList Method GetSlot:WeaponSlot( Number ) Local n = 0 For Local W:WeaponSlot = EachIn Slot n:+1 If n = Number Then Return W Next End Method Method Fire( WhichSlot ) If WhichSlot > Slot.Count() Return If WhichSlot < 1 Return 'our slots start from 1! Local missile:tmissile = GetSlot( WhichSlot ).Fire() End Method Function Create:WarTank( Name$, WeaponSlots=1 ) Local Tank:WarTank = New WarTank Tank.Name = Name 'Create this tanks WeaponSlots ------ For Local n = 1 To WeaponSlots Tank.Slot.AddLast( New WeaponSlot ) Next '------------------------------------- 'Put the tank in the global tanklist TankList.AddLast( Tank ) Return Tank End Function End Type'------------------------------------------- 'W E A P O N S L O T 'Contains missiles which can be loaded or fired Type WeaponSlot Field Missile:TList = New TList ' Contains All Missiles in this Slot Field Number ' The Slot Number or ID ' F I R E '_________________________________________________________________ ' ' Use: Fires a missile if you got availible ammo else it don't '_________________________________________________________________ Method Fire:TMissile() If Missile.Count() <= 0 Print "No Ammo in Slot "+Number Return 'The above would be the same as the slot's ammo Local MissileToFire:TMissile MissileToFire = TMissile( Missile.First() ) 'Get first missile MissileToFire.Launch() 'Fire the missile Missile.Remove( MissileToFire ) Return MissileToFire End Method '_________________________________________________________________ ' ' L O A D '_________________________________________________________________ ' ' Use: Loads one or more missiles '_________________________________________________________________ Method Load( MissileName$, Count = 1 ) For Local n = 1 To Count Local NewMissile:TMissile NewMissile = New TMissile NewMissile.Name = MissileName Missile.AddLast( NewMissile ) Next End Method '_________________________________________________________________ End Type ' T M I S S I L E Type TMissile Field Name$ = "Unknown Missile" Method Launch() End Method End Type | |
The above example is pretty advanced so if you don't understand everything above do not worry, keep reading and learning, one day you might. | |
To Index | Next Page | page 12 |