編譯者:sosei
歡迎
歡迎來到BlitzMax-NG用戶指南剩盒。
本文將向您介紹BlitzMax(也就是BlitzMax-ng)背后的一些概念棕硫,以及如何實(shí)際使用它别凤。
BlitzMax是一種基于流行的BASIC編程語言的計(jì)算機(jī)編程語言建芙。BASIC代表初學(xué)者通用符號(hào)指令代碼旷偿。正如它的名字所暗示的那樣速缆,BASIC的設(shè)計(jì)是易于使用的降允,但它在很多方面都很有用。
BlitzMax是一個(gè)編譯器艺糜。它將包含源代碼的文本文件作為程序的輸入剧董,并將其作為可運(yùn)行的程序的輸出。最后的程序由由CPU解釋的低級(jí)機(jī)器碼語句組成倦踢。
Blitzmax還包括在更現(xiàn)代的編程語言中發(fā)現(xiàn)的一些高級(jí)特性送滞。特別是,BlitzMax支持稱為繼承和多態(tài)性的面向?qū)ο缶幊碳夹g(shù)辱挥。然而犁嗅,BlitzMax的設(shè)計(jì)讓你在準(zhǔn)備好之前不必學(xué)習(xí)這些技術(shù)(如果有的話!)
BlitzMax是如何工作的
BlitzMax獲取您程序的源代碼并將其轉(zhuǎn)換為可執(zhí)行代碼晤碘。這一過程包括兩個(gè)主要步驟:
編譯源代碼:此步驟涉及將項(xiàng)目中的每個(gè)源代碼文件轉(zhuǎn)換為相應(yīng)的目標(biāo)代碼文件褂微。目標(biāo)代碼文件包含實(shí)際的機(jī)器碼功蜓,但不能單獨(dú)運(yùn)行。它必須首先與其他對(duì)象文件鏈接…
鏈接目標(biāo)代碼:這一步涉及到將所有目標(biāo)代碼文件鏈接在一起宠蚂,以產(chǎn)生一個(gè)可以實(shí)際運(yùn)行的程序式撼。此步驟是必要的,因?yàn)槟繕?biāo)文件通常需要在其他目標(biāo)文件中找到的信息求厕。有效地將目標(biāo)代碼文件相互連接起來著隆。
編譯和鏈接項(xiàng)目的這個(gè)過程稱為構(gòu)建項(xiàng)目,每當(dāng)您編輯項(xiàng)目中的源文件或其他資源時(shí)呀癣,都必須這樣做美浦。
構(gòu)建項(xiàng)目有兩種主要方法:使用MaxIDE或使用BMK實(shí)用程序。
MaxIDE是一個(gè)集成開發(fā)環(huán)境项栏。它允許您修改源代碼文件和構(gòu)建項(xiàng)目浦辨。
BMK是一個(gè)較低級(jí)別的命令行實(shí)用工具,也用于構(gòu)建項(xiàng)目沼沈。事實(shí)上流酬,BlitzMax IDE使用BMK在幕后來建造項(xiàng)目。
BlitzMax IDE
BlitzMax IDE是一個(gè)用于編輯源代碼文件和構(gòu)建項(xiàng)目的應(yīng)用程序列另。IDE代表“集成開發(fā)環(huán)境”芽腾。
BlitzMax IDE操作起來非常像文本編輯器或文字處理器。
開始
好了页衙,是時(shí)候編譯并運(yùn)行您的第一個(gè)程序了晦嵌!
首先,從文件菜單或工具欄中選擇New拷姿。這將創(chuàng)建一個(gè)新的惭载、空的源文件供您使用。
接下來响巢,輸入以下小程序:
'
'My first BlitzMax program
'
Print "Hello World!"
現(xiàn)在描滔,到了構(gòu)建和運(yùn)行的時(shí)候了:從程序菜單中選擇build和run。你應(yīng)該看到以下輸出:
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
恭喜您踪古!您剛剛創(chuàng)建了您的第一個(gè)程序含长!
BlitzMax入門指南
概述
我為那些剛接觸BlitzMax,有一點(diǎn)編程基礎(chǔ)的人寫了這本指南伏穆,特別推薦給那些想在BlitzMax中邁出OOP第一步的人拘泞。如果您正在從其他任何編程語言(包括Blitz3D/Plus)轉(zhuǎn)換到BlitzMax,那么這篇介紹應(yīng)該是有用的枕扫。它不是作為一個(gè)BlitzMax基礎(chǔ)→BlitzMax教程編寫的陪腌。我的目標(biāo)是讓每個(gè)人都有機(jī)會(huì)在學(xué)習(xí)神奇的BlitzMax中有一個(gè)好的開始。如果你是從Blitz3D/Plus中轉(zhuǎn)換過來,你將會(huì)受到?jīng)_擊诗鸭,因?yàn)橛泻芏嘈聳|西染簇。方式改變了,但我向你保證强岸,一切都會(huì)好起來的锻弓。當(dāng)你已經(jīng)邁出了第一步,并了解了周圍的路蝌箍,沒有其他地方像BlitzMax一樣;)
一個(gè)好的學(xué)習(xí)方法是做青灼。閱讀我的例子,但試著自己寫妓盲。它提供了良好的編碼實(shí)踐聚至。如果您想使用本指南中的任何代碼,請(qǐng)這樣做本橙,代碼是公開的。
變量
您可能知道:變量是存儲(chǔ)數(shù)字或文本的地方脆诉。根據(jù)不同的使用甚亭,有不同的變量“類型”。以下是最基本的類型:存儲(chǔ)數(shù)字的整數(shù)击胜、存儲(chǔ)文本的字符串和存儲(chǔ)小數(shù)的浮點(diǎn)數(shù)亏狰。我們也有對(duì)象-“類型”,其中包括這些基本類型偶摔,如數(shù)組暇唾,列表和您自己的自定義類型(稍后更多關(guān)于這些)。如果您想了解更多關(guān)于BlitzMax變量的信息辰斋,請(qǐng)參閱語言參考策州。
如果你想增加一個(gè)變量,比如說速度宫仗。你可以寫 speed = speed + acceleration够挂,或者用更短的方式寫 speed:+acceleration。兩者是一樣的藕夫,但后者較短孽糖。在使用之前必須聲明變量。
Local speed: Float=0 , acceleration:Int , name:String = "Name"
Local speed#= 0 , acceleration , name$ = "Name"
這兩行兩種寫法等價(jià)的毅贮。(譯者推薦用第一種办悟,可讀性更好。)
注:Local是聲明變量的一種方式滩褥。
注:在BlitzMax NG中變量定義的編譯檢查嚴(yán)格程度有兩個(gè)等級(jí)病蛉。可在程序源文件開頭(只能在文件開頭)分別用Strict和SuperStrict關(guān)鍵字設(shè)置。如果不設(shè)置铡恕,那默認(rèn)是Strict等級(jí)琢感。(譯者推薦都設(shè)成SuperStrict等級(jí))
Strict等級(jí)下整型變量的聲明可從 Local/Global VarName:Int 省略掉“:Int”部分,也就是 Local/Global VarName 就可以了探熔。
SuperStrict等級(jí)下你必須聲明所有的類型驹针,包括Int變量。
沒有返回類型的函數(shù)/方法不能返回任何東西诀艰。
例子:
'
'My first BlitzMax program
'
Strict
Local speed = 10
Print speed
注意:BlitzMax認(rèn)為“Speed”柬甥、“speed”和“sPeEd”是相同的變量。因?yàn)锽litzMax里不區(qū)分大小寫其垄,任何關(guān)鍵字也是苛蒲。(譯者推薦:關(guān)鍵字、函數(shù)名绿满、方法名和類型名的每個(gè)單詞首字母大寫臂外;常量名的所有單詞都大寫并“_”分隔單詞;變量名的所有單詞都小寫并“_”分隔單詞)
Global或Local
變量可以是全局的喇颁,也可以是局部的漏健。全局變量可以從整個(gè)程序中訪問。另一方面橘霎,局部變量更加復(fù)雜蔫浆,因?yàn)樗鼈兊拇嬖谌Q于它們?cè)谀睦锫暶鳌_@稱為局部作用域姐叁。若要聲明局部變量瓦盛,請(qǐng)?jiān)谧兞棵懊媸褂藐P(guān)鍵字local。如果你在一個(gè)函數(shù)中聲明一個(gè)局部變量外潜,它將只存在于那個(gè)函數(shù)中原环。如果它是在一個(gè)循環(huán)中聲明的,那么它將只在您處于該循環(huán)中時(shí)存在处窥。如果一個(gè)局部變量在一個(gè)If語句中扮念,那么它只存在于那個(gè)If語句中。
常量
您還可以聲明常量碧库。一個(gè)常量將具有您在第一次聲明它時(shí)所賦予的值柜与。常數(shù)的值永遠(yuǎn)不會(huì)改變,它將永遠(yuǎn)保持不變嵌灰。如果你試圖改變一個(gè)常量的值弄匕,編譯器會(huì)在編譯時(shí)警告你。常量對(duì)于始終保持不變的值非常有用沽瞭。
例子:
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
單引號(hào)“'”表示該行的其余部分將是注釋城丧。
你也可以使用:
Rem
If you want to comment out several lines
Useless line 1
Useless line 2
EndRem
來完成多行注釋延曙。
If指令
If語句用于檢查是否滿足了某個(gè)條件,然后根據(jù)該條件采取行動(dòng)亡哄。
例子:
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
這個(gè)例子沒有什么特別的枝缔,它只是向您展示了如何使用If、ElseIf蚊惯、Else和EndIf愿卸。(a,b,r是變量)
注:“ElseIf”、“EndIf”也可以寫成“Else If”截型、“End If”趴荸。(譯者推薦用ElseIf、EndIf)
源程序中關(guān)鍵字Then可以省略宦焦。
If A = 1 Then B = 2 等價(jià)于? If A = 1 B = 2 发钝。
但是從可讀性考慮,不要這么做波闹。
注:邏輯判斷中數(shù)值0就等于False酝豪,非零就等于True。如果一個(gè)對(duì)象是“null”(不存在)舔痪,它就是false,否則就是true
“<>”是“不等于”運(yùn)算符锌唾。If a <> 10 等價(jià)于 If Not a = 10
循環(huán)
循環(huán)是告訴Blitz重復(fù)做一件事锄码。
例子:
For Local i:Int = 10 To 0 Step -1
? Print i
Next
這個(gè)輸出就是10,9晌涕,……0滋捶。輸出了11個(gè)數(shù),循環(huán)包括開頭與結(jié)尾的數(shù)余黎。
例子:
Local a:Int[]=[0,5,12,13,20]
For Local b:Int = EachIn a
? Print b
Next
關(guān)鍵字EachIn表示遍歷數(shù)組或集合重窟。
例子:
Local i:Int = 0
While i<=5
? Print i
? i:+1
Wend
關(guān)鍵字While表示直到條件為假終止循環(huán)。
注:Wend位置也可用EndWhile惧财,兩個(gè)關(guān)鍵字等價(jià)的巡扇。(譯者推薦用Wend)
例子:
Local i:Int = 0
Repeat
? Print i
? i:+1
Until i=5
關(guān)鍵字Until表示直到條件為真終止循環(huán)。
例子:
Local i:Int = 0
Repeat
? Print i+" Ctrl-C to End!"
? i:+1
Forever
關(guān)鍵字Forever表示是個(gè)死循環(huán)垮衷。
輸入
輸入是BlitzMax的一個(gè)簡(jiǎn)單的部分厅翔。(我們說的是鍵盤和鼠標(biāo)輸入,而不是輸入命令)
例子:
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刀闷,以此類推,表示所有字母和數(shù)字。有關(guān)鍵碼的完整列表甸昏,請(qǐng)參閱手冊(cè)的掃描代碼部分顽分。
Functions
函數(shù)是重用代碼的一種方式。它還可以將代碼分割成更容易管理的部分施蜜。
一個(gè)函數(shù)例子:
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)
函數(shù)可以返回任何類型的數(shù)據(jù)卒蘸,包括對(duì)象。它返回的類型是在函數(shù)名后面指定的花墩,跟“$”就表示返回一個(gè)字符串型值悬秉。如果要返回整型,就寫成 Function CollectData:Int 或 Function CollectData%
注:如上函數(shù)類型改整型冰蘑,Return 一個(gè)字符串類型和泌,那么編譯階段就會(huì)報(bào)錯(cuò)通不過。
下面是另一個(gè)簡(jiǎn)單函數(shù)的例子:
'--------------------- 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
注:注釋函數(shù)是很重要的祠肥。寫出參數(shù)是什么武氓,它返回什么,它做什么仇箱。
隨機(jī)
一個(gè)最有用的命令是Rand(A, B)县恕,它在A和B之間創(chuàng)建一個(gè)隨機(jī)值。
例子:
Local test = Rand(1,3)
這將把test設(shè)置為1剂桥、2或3忠烛。如果只使用一個(gè)參數(shù)調(diào)用Rand(A),因?yàn)閰?shù)B缺省值是1权逗,函數(shù)將返回一個(gè)介于A到1之間的值美尸。這意味著Rand(-1)應(yīng)該是-1、0或1斟薇。
數(shù)組
數(shù)組是在一個(gè)地方存儲(chǔ)多個(gè)值的一種方式师坎。數(shù)組中的所有元素必然具有相同的類型!
例子:
Local name_list$[] = [ "Dawn" , "Trac" , "Fire" ,"Nitro" ,"Nex"]
這將創(chuàng)建一個(gè)包含5個(gè)字符串的數(shù)組堪滨。所有元素都是字符串胯陋。
例子:
NameList[0] = "None"
Local Text$ = NameList[2]
存取數(shù)組元素。數(shù)組下標(biāo)從0開始袱箱。
NameList[2] refers to element 2 of Array NameList. Arrays start at 0, so this would give us "Fire"
多維數(shù)組
例子:
Local my_array[3,3]
For Local x = 0 To 2
? For Local y = 0 To 2
? ? Print my_array[x, y]
? Next
Next
聲明了一個(gè)3x3遏乔,9個(gè)元素的2維數(shù)組。
如果我們想遍歷2維數(shù)組中的所有元素发笔,就必須使用雙重For-Next循環(huán)按灶。
數(shù)組的數(shù)組
例子:
Local grid[][] = [[1,1,1,2],[7,7],[5,5,5]]
這將創(chuàng)建三個(gè)一維數(shù)組,第一個(gè)長(zhǎng)度為4筐咧,第二個(gè)長(zhǎng)度為2鸯旁,第三個(gè)長(zhǎng)度為3噪矛。這些數(shù)組用作較大數(shù)組中的行。為了得到一個(gè)元素铺罢,我們使用grid[WhichArray][PlaceInThisArray]艇挨。如果想得到第一個(gè)子數(shù)組,那就grid[0]韭赘。
獲得數(shù)組長(zhǎng)度和排序
例子:
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)是降序排序。
數(shù)組切片
切片是數(shù)組的一部分的拷貝泉瞻。格式是StringOrArray [ StartIndex .. EndIndex ]
StartIndex是切片的起始下標(biāo)脉漏,EndIndex表示切片的截止下標(biāo)(不包括本下標(biāo))。
省略StartIndex那么默認(rèn)從0開始袖牙,省略EndIndex那么默認(rèn)取開始下標(biāo)后所有元素侧巨。
如果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
這將復(fù)制下標(biāo)2司忱、下標(biāo)3的元素。