编译者:sosei
Type
BlitzMax里的Type类似于别的程序语言中的Class。类型是BlitzMax的一部分,使它成为一种OOP(面向对象编程)语言。如果您刚接触OOP,Type是最难处理的部分之一。
设置和创建Type
假设我们想要一艘宇宙飞船,那么让我们先为它创建一个结构体:
Type SpaceShip 'declares a new type
Const help:String="this is what the structure contains"
Global fleet:String
Field max_speed:Float
Field armor:Int=2000
Field name:String
EndType 'ends declaration
Local ship:SpaceShip
这里定义变量ship为SpaceShip类型。这时的变量并不是个实例对象,要用下面方式创建一个实例对象:
ship = New SpaceShip
也可以合并定义:
Local ship:SpaceShip = New SpaceShip
注:变量里其实放的是实例对象的地址。如果我们不创建一个新的ship,我们的ship将是= null。
现在可以使用ship.SpaceShipFieldName设置该对象的字段:
ship.max_speed = 3.5 'Read: Ship's MaxSpeed set to 3.5
Ship.armor = 5000 'Default was 2000 (See the type)
Ship.name = "wavebreaker"
继续例子:
Local ship2:SpaceShip = New SpaceShip
ship.max_speed = 5.5
ship2 = ship
当给变量ship2赋值成ship中的地址,ship2原指向的实例对象地址就没有被任何变量保存,那么此实例对象将被BlitzMax自动删除。一个实例对象可以有多个指向它的指针。实例对象本身是唯一的,但是它的地址可以驻留在几个不同的变量中。
类型SpaceShip中的变量fleet是用关键字Global定义的,意味着这是类似于Python中的类变量。这种变量在其类型所派生的实例对象中是共享的。即使没有该类型的任何实例,也可以使用它。类型中关键字Const声明的也是所派生的实例对象中是共享的,跟Global的区别是这定义的是个常量。
例子:
Print SpaceShip.help
SpaceShip.fleet = "Quantum Light"
直接对类型SpaceShip的Global变量fleet赋值了。
TList类型
这是列表类型,列表比数组更具动态性,不用在声明时就定下尺寸。
下面是一个用到列表的程序例子:
Global number_of_tanks = 10 'How many tanks to create?
' Having a Global like the one above makes it easy To change how the program
' acts at least in small examples like this. Now let's declare a new type
' called Tank.
Type TTank 'The extra T infront of the type name is good use
Field x#, y#
Field dir, armor = 100
Field speed# = 0.2, size = 25
EndType
Graphics 800,600
Global TankList:TList = CreateList() 'Create a list to store all tanks
' TankList:TList defines TankList To be of the List-Type, CreateList() returns
' a New List. The variable TankList will be used whenever you want To add
' remove or alter this TList.
' Note that TList is a BlitzMax built-in Type And it has it's own methods and
' functions.
' Create a bunch of new Tanks
For Local n = 1 To number_of_tanks ' number_of_tanks is a Global
Local NewTank:TTank 'Declares a variable to store our Tank-Type
'Put the address of this new Tank into variable NewTank
NewTank = New TTank
'Set a random armor 150 + 10,20,30,40 or 50
NewTank.armor = Rand( 5 )*10 + 150
'Random Start Location
NewTank.x = Rand( 5, 800 )
NewTank.y = Rand( 5, 600)
NewTank.dir = Rand( 0, 360 )
'Put this tank called NewTank into our TankList
ListAddLast( TankList, NewTank )
Next
While Not KeyDown(Key_Escape)
Cls
'Local T is declared to hold the current Tank each loop
'Because we called our Type TTank, Tank is availible as variable
For Local Tank:TTank = EachIn TankList
DrawOval( Tank.x, Tank.y, Tank.size, Tank.size )
DrawText "Number of Tanks : "+TankList.Count(), 20, 20
DrawText "Press ESC to exit", 20, 40 '20 is X-coordinate, 40 is Y
Tank.x:+ Tank.speed*Cos( Tank.dir )
Tank.y:+ Tank.speed*Sin( Tank.dir )
Next 'This loop will loop for every Tank that was added to TankList
Flip
Wend
Method
方法通常是类型的动作,它可以是FireShot()、Explode()、Turn()或Update()。
例子:
Type TWizard
Field x, y, mana
Method Teleport( x, y )
Self.x = x
Self.y = y
EndMethod
EndType
可以省略关键字Self,如下写法:
Type TWizard
Field x, y, mana
Method Teleport( x2, y2 )
x = x2
y = y2
EndMethod
EndType
所以为了可读性,推荐不要省略关键字Self
注:有一个特殊的方法。方法New(),每次创建该类型的实例时都会运行该方法。
我们也可以写成一个函数,但它看起来会是这样的:
Type TWizard
Field x, y, mana
Function Teleport( Wizard:TWizard, x, y )
Wizard.x = x
Wizard.y = y
EndFunction
EndType
类型的方法和类型的函数之间的区别有两点:
区别一,方法内可使用类型内的Global变量、常量、字段变量、方法、函数、类型,都可以直接引用。而类型的函数只可以直接使用类型内的Global变量、常量、函数、类型。
区别二,类型的方法只可以用类型派生的实例对象调用,类似Python中的实例方法;类型的函数既可以用类型派生的实例对象调用,也可以用类型直接调用,类似Python中的静态方法。
例子:
Type TT
Const x_const:Int=666
Global y_var
Type SubTT
Field f
EndType
Function z_func()
Print "z_func"
EndFunction
Function test_func(y)
Print x_const
Local y_var:Int = y
Print y_var
Local s:SubTT
z_func()
EndFunction
EndType
Local object_var:TT = New TT
object_var.test_func(999)
TT.test_func(999)
网友评论