编译者:sosei
欢迎
欢迎来到BlitzMax-NG用户指南。
本文将向您介绍BlitzMax(也就是BlitzMax-ng)背后的一些概念,以及如何实际使用它。
BlitzMax是一种基于流行的BASIC编程语言的计算机编程语言。BASIC代表初学者通用符号指令代码。正如它的名字所暗示的那样,BASIC的设计是易于使用的,但它在很多方面都很有用。
BlitzMax是一个编译器。它将包含源代码的文本文件作为程序的输入,并将其作为可运行的程序的输出。最后的程序由由CPU解释的低级机器码语句组成。
Blitzmax还包括在更现代的编程语言中发现的一些高级特性。特别是,BlitzMax支持称为继承和多态性的面向对象编程技术。然而,BlitzMax的设计让你在准备好之前不必学习这些技术(如果有的话!)
BlitzMax是如何工作的
BlitzMax获取您程序的源代码并将其转换为可执行代码。这一过程包括两个主要步骤:
编译源代码:此步骤涉及将项目中的每个源代码文件转换为相应的目标代码文件。目标代码文件包含实际的机器码,但不能单独运行。它必须首先与其他对象文件链接…
链接目标代码:这一步涉及到将所有目标代码文件链接在一起,以产生一个可以实际运行的程序。此步骤是必要的,因为目标文件通常需要在其他目标文件中找到的信息。有效地将目标代码文件相互连接起来。
编译和链接项目的这个过程称为构建项目,每当您编辑项目中的源文件或其他资源时,都必须这样做。
构建项目有两种主要方法:使用MaxIDE或使用BMK实用程序。
MaxIDE是一个集成开发环境。它允许您修改源代码文件和构建项目。
BMK是一个较低级别的命令行实用工具,也用于构建项目。事实上,BlitzMax IDE使用BMK在幕后来建造项目。
BlitzMax IDE
BlitzMax IDE是一个用于编辑源代码文件和构建项目的应用程序。IDE代表“集成开发环境”。
BlitzMax IDE操作起来非常像文本编辑器或文字处理器。
开始
好了,是时候编译并运行您的第一个程序了!
首先,从文件菜单或工具栏中选择New。这将创建一个新的、空的源文件供您使用。
接下来,输入以下小程序:
'
'My first BlitzMax program
'
Print "Hello World!"
现在,到了构建和运行的时候了:从程序菜单中选择build和run。你应该看到以下输出:
Building untitled1
Compiling:untitled1.bmx
flat assembler version 1.51
3 passes, 2417 bytes.
Linking:untitled1.debug.exe
Executing:untitled1.debug.exe
Hello World!
Process complete
恭喜您!您刚刚创建了您的第一个程序!
BlitzMax入门指南
概述
我为那些刚接触BlitzMax,有一点编程基础的人写了这本指南,特别推荐给那些想在BlitzMax中迈出OOP第一步的人。如果您正在从其他任何编程语言(包括Blitz3D/Plus)转换到BlitzMax,那么这篇介绍应该是有用的。它不是作为一个BlitzMax基础→BlitzMax教程编写的。我的目标是让每个人都有机会在学习神奇的BlitzMax中有一个好的开始。如果你是从Blitz3D/Plus中转换过来,你将会受到冲击,因为有很多新东西。方式改变了,但我向你保证,一切都会好起来的。当你已经迈出了第一步,并了解了周围的路,没有其他地方像BlitzMax一样;)
一个好的学习方法是做。阅读我的例子,但试着自己写。它提供了良好的编码实践。如果您想使用本指南中的任何代码,请这样做,代码是公开的。
变量
您可能知道:变量是存储数字或文本的地方。根据不同的使用,有不同的变量“类型”。以下是最基本的类型:存储数字的整数、存储文本的字符串和存储小数的浮点数。我们也有对象-“类型”,其中包括这些基本类型,如数组,列表和您自己的自定义类型(稍后更多关于这些)。如果您想了解更多关于BlitzMax变量的信息,请参阅语言参考。
如果你想增加一个变量,比如说速度。你可以写 speed = speed + acceleration,或者用更短的方式写 speed:+acceleration。两者是一样的,但后者较短。在使用之前必须声明变量。
Local speed: Float=0 , acceleration:Int , name:String = "Name"
Local speed#= 0 , acceleration , name$ = "Name"
这两行两种写法等价的。(译者推荐用第一种,可读性更好。)
注:Local是声明变量的一种方式。
注:在BlitzMax NG中变量定义的编译检查严格程度有两个等级。可在程序源文件开头(只能在文件开头)分别用Strict和SuperStrict关键字设置。如果不设置,那默认是Strict等级。(译者推荐都设成SuperStrict等级)
Strict等级下整型变量的声明可从 Local/Global VarName:Int 省略掉“:Int”部分,也就是 Local/Global VarName 就可以了。
SuperStrict等级下你必须声明所有的类型,包括Int变量。
没有返回类型的函数/方法不能返回任何东西。
例子:
'
'My first BlitzMax program
'
Strict
Local speed = 10
Print speed
注意:BlitzMax认为“Speed”、“speed”和“sPeEd”是相同的变量。因为BlitzMax里不区分大小写,任何关键字也是。(译者推荐:关键字、函数名、方法名和类型名的每个单词首字母大写;常量名的所有单词都大写并“_”分隔单词;变量名的所有单词都小写并“_”分隔单词)
Global或Local
变量可以是全局的,也可以是局部的。全局变量可以从整个程序中访问。另一方面,局部变量更加复杂,因为它们的存在取决于它们在哪里声明。这称为局部作用域。若要声明局部变量,请在变量名前面使用关键字local。如果你在一个函数中声明一个局部变量,它将只存在于那个函数中。如果它是在一个循环中声明的,那么它将只在您处于该循环中时存在。如果一个局部变量在一个If语句中,那么它只存在于那个If语句中。
常量
您还可以声明常量。一个常量将具有您在第一次声明它时所赋予的值。常数的值永远不会改变,它将永远保持不变。如果你试图改变一个常量的值,编译器会在编译时警告你。常量对于始终保持不变的值非常有用。
例子:
Rem
Const defines the preceeding variable declaration as constant.
EndRem
SuperStrict
Const ON:Int=True
Const OFF:Int=False
Const TWO_PI:Float=2*Pi
Print TWO_PI
注释
注释是解释代码的文本。您的程序不需要注释就可以工作,但是注释是您生活中不可缺少的东西之一!
下面是注释一例:
Local speed: Float=0 'Sets speed to zero
单引号“'”表示该行的其余部分将是注释。
你也可以使用:
Rem
If you want to comment out several lines
Useless line 1
Useless line 2
EndRem
来完成多行注释。
If指令
If语句用于检查是否满足了某个条件,然后根据该条件采取行动。
例子:
Local a=-1,b=2,r=0
If a > 10 Then
a = 10
ElseIf a < 0 and b => 2 Then
r:-10
Else
a:+b
EndIf
Print r
'Read: If a is greater than 10
'Read: Set a to 10
'Read: if a less than 0 and b is equal or greater than 2
'Read: Decrease r with 10. E.g. if r was 100 it is now 90
'Read: if none of above conditions is met do this
'Read: Add b to a. Or Increase A with b. That is: a = a + b
这个例子没有什么特别的,它只是向您展示了如何使用If、ElseIf、Else和EndIf。(a,b,r是变量)
注:“ElseIf”、“EndIf”也可以写成“Else If”、“End If”。(译者推荐用ElseIf、EndIf)
源程序中关键字Then可以省略。
If A = 1 Then B = 2 等价于 If A = 1 B = 2 。
但是从可读性考虑,不要这么做。
注:逻辑判断中数值0就等于False,非零就等于True。如果一个对象是“null”(不存在),它就是false,否则就是true
“<>”是“不等于”运算符。If a <> 10 等价于 If Not a = 10
循环
循环是告诉Blitz重复做一件事。
例子:
For Local i:Int = 10 To 0 Step -1
Print i
Next
这个输出就是10,9,……0。输出了11个数,循环包括开头与结尾的数。
例子:
Local a:Int[]=[0,5,12,13,20]
For Local b:Int = EachIn a
Print b
Next
关键字EachIn表示遍历数组或集合。
例子:
Local i:Int = 0
While i<=5
Print i
i:+1
Wend
关键字While表示直到条件为假终止循环。
注:Wend位置也可用EndWhile,两个关键字等价的。(译者推荐用Wend)
例子:
Local i:Int = 0
Repeat
Print i
i:+1
Until i=5
关键字Until表示直到条件为真终止循环。
例子:
Local i:Int = 0
Repeat
Print i+" Ctrl-C to End!"
i:+1
Forever
关键字Forever表示是个死循环。
输入
输入是BlitzMax的一个简单的部分。(我们说的是键盘和鼠标输入,而不是输入命令)
例子:
Graphics 800,600,0
Local x=500, y=500 '<- - - - - - - start location
'- - - - - - - - - - Loop Start - - - - - - - - - -
While Not KeyDown(Key_Escape) ' This loop is equal to repeat except the condition is at the top.
Cls
'DRAW___________________________________
DrawOval x,y,8,8 'Draw an Oval at x,y with a width and height of 8
DrawText "Press Arrow Keys to go around, Space to Center",20,20
'INPUT___________________________________
If KeyDown(Key_Left) Then x:-1 'Decrease x <-- go left
If KeyDown(Key_Right) Then x:+1 'increase x go right -->
If KeyDown(Key_Down) Then y:+1 'Increase y Go Down \/
If KeyDown(Key_Up) Then y:-1 'Decrease y Go Up /\
If KeyHit(Key_Space) Then 'Set position
x=400
y=300
EndIf
Flip
Wend
'- - - - - - - - - - Loop End - - - - - - - - - -
注:所有键的名称都是以Key_开头的,键A是Key_A,以此类推,表示所有字母和数字。有关键码的完整列表,请参阅手册的扫描代码部分。
Functions
函数是重用代码的一种方式。它还可以将代码分割成更容易管理的部分。
一个函数例子:
Function Collectdata$( name$, id, age ) ' $ means String, nothing means Int
Local total_data$ = "Name: " +name+ ", id: "+id+", Age: " +age
Return total_data
EndFunction
Local test_data$ = Collectdata("Blast" , 8, 30)
函数可以返回任何类型的数据,包括对象。它返回的类型是在函数名后面指定的,跟“$”就表示返回一个字符串型值。如果要返回整型,就写成 Function CollectData:Int 或 Function CollectData%
注:如上函数类型改整型,Return 一个字符串类型,那么编译阶段就会报错通不过。
下面是另一个简单函数的例子:
'--------------------- A D D ----------------------
' Parameters: a,b,c ; numbers to add
' Returns: The sum of these numbers
' Note: Only accepts integers
'_______________________________
Function Add:Int( a% , b% , c% = 0 )
Return a + b + c
EndFunction
'-------------------------------------------------
Number = Add(2,2,3) 'Will set Number to 7
Number = Add(2,2) 'Will set Number to 4
注:注释函数是很重要的。写出参数是什么,它返回什么,它做什么。
随机
一个最有用的命令是Rand(A, B),它在A和B之间创建一个随机值。
例子:
Local test = Rand(1,3)
这将把test设置为1、2或3。如果只使用一个参数调用Rand(A),因为参数B缺省值是1,函数将返回一个介于A到1之间的值。这意味着Rand(-1)应该是-1、0或1。
数组
数组是在一个地方存储多个值的一种方式。数组中的所有元素必然具有相同的类型!
例子:
Local name_list$[] = [ "Dawn" , "Trac" , "Fire" ,"Nitro" ,"Nex"]
这将创建一个包含5个字符串的数组。所有元素都是字符串。
例子:
NameList[0] = "None"
Local Text$ = NameList[2]
存取数组元素。数组下标从0开始。
NameList[2] refers to element 2 of Array NameList. Arrays start at 0, so this would give us "Fire"
多维数组
例子:
Local my_array[3,3]
For Local x = 0 To 2
For Local y = 0 To 2
Print my_array[x, y]
Next
Next
声明了一个3x3,9个元素的2维数组。
如果我们想遍历2维数组中的所有元素,就必须使用双重For-Next循环。
数组的数组
例子:
Local grid[][] = [[1,1,1,2],[7,7],[5,5,5]]
这将创建三个一维数组,第一个长度为4,第二个长度为2,第三个长度为3。这些数组用作较大数组中的行。为了得到一个元素,我们使用grid[WhichArray][PlaceInThisArray]。如果想得到第一个子数组,那就grid[0]。
获得数组长度和排序
例子:
Local test[] = [7,39,1,24,5,6,3,8,19,5,3,3,2,5,18,8,2,221,3,4,5,63,87,12,92]
Print "Length "+test.Length
test.Sort()
For Local n = EachIn test
Print n
Next
.Sort()是升序排序,而.Sort(False)是降序排序。
数组切片
切片是数组的一部分的拷贝。格式是StringOrArray [ StartIndex .. EndIndex ]
StartIndex是切片的起始下标,EndIndex表示切片的截止下标(不包括本下标)。
省略StartIndex那么默认从0开始,省略EndIndex那么默认取开始下标后所有元素。
如果EndIndex <= StartIndex,那么拷贝为空。
例子:
Local test[] = [0,1,2,3,4,5,6,7,8,9,10,11,12,13]
For Local n = EachIn test[2..4]
Print n
Next
这将复制下标2、下标3的元素。
网友评论