編譯者:sosei
歡迎
歡迎來到BlitzMax-NG用戶指南。
本文將向您介紹BlitzMax(也就是BlitzMax-ng)背后的一些概念,以及如何實際使用它。
BlitzMax是一種基于流行的BASIC編程語言的計算機編程語言。BASIC代表初學者通用符號指令代碼。正如它的名字所暗示的那樣,BASIC的設計是易于使用的,但它在很多方面都很有用。
BlitzMax是一個編譯器。它將包含源代碼的文本文件作為程序的輸入,并將其作為可運行的程序的輸出。最后的程序由由CPU解釋的低級機器碼語句組成。
Blitzmax還包括在更現(xiàn)代的編程語言中發(fā)現(xiàn)的一些高級特性。特別是,BlitzMax支持稱為繼承和多態(tài)性的面向?qū)ο缶幊碳夹g。然而,BlitzMax的設計讓你在準備好之前不必學習這些技術(如果有的話!)
BlitzMax是如何工作的
BlitzMax獲取您程序的源代碼并將其轉(zhuǎn)換為可執(zhí)行代碼。這一過程包括兩個主要步驟:
編譯源代碼:此步驟涉及將項目中的每個源代碼文件轉(zhuǎn)換為相應的目標代碼文件。目標代碼文件包含實際的機器碼,但不能單獨運行。它必須首先與其他對象文件鏈接…
鏈接目標代碼:這一步涉及到將所有目標代碼文件鏈接在一起,以產(chǎn)生一個可以實際運行的程序。此步驟是必要的,因為目標文件通常需要在其他目標文件中找到的信息。有效地將目標代碼文件相互連接起來。
編譯和鏈接項目的這個過程稱為構建項目,每當您編輯項目中的源文件或其他資源時,都必須這樣做。
構建項目有兩種主要方法:使用MaxIDE或使用BMK實用程序。
MaxIDE是一個集成開發(fā)環(huán)境。它允許您修改源代碼文件和構建項目。
BMK是一個較低級別的命令行實用工具,也用于構建項目。事實上,BlitzMax IDE使用BMK在幕后來建造項目。
BlitzMax IDE
BlitzMax IDE是一個用于編輯源代碼文件和構建項目的應用程序。IDE代表“集成開發(fā)環(huán)境”。
BlitzMax IDE操作起來非常像文本編輯器或文字處理器。
開始
好了,是時候編譯并運行您的第一個程序了!
首先,從文件菜單或工具欄中選擇New。這將創(chuàng)建一個新的、空的源文件供您使用。
接下來,輸入以下小程序:
'
'My first BlitzMax program
'
Print "Hello World!"
現(xiàn)在,到了構建和運行的時候了:從程序菜單中選擇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
恭喜您!您剛剛創(chuàng)建了您的第一個程序!
BlitzMax入門指南
概述
我為那些剛接觸BlitzMax,有一點編程基礎的人寫了這本指南,特別推薦給那些想在BlitzMax中邁出OOP第一步的人。如果您正在從其他任何編程語言(包括Blitz3D/Plus)轉(zhuǎn)換到BlitzMax,那么這篇介紹應該是有用的。它不是作為一個BlitzMax基礎→BlitzMax教程編寫的。我的目標是讓每個人都有機會在學習神奇的BlitzMax中有一個好的開始。如果你是從Blitz3D/Plus中轉(zhuǎn)換過來,你將會受到?jīng)_擊,因為有很多新東西。方式改變了,但我向你保證,一切都會好起來的。當你已經(jīng)邁出了第一步,并了解了周圍的路,沒有其他地方像BlitzMax一樣;)
一個好的學習方法是做。閱讀我的例子,但試著自己寫。它提供了良好的編碼實踐。如果您想使用本指南中的任何代碼,請這樣做,代碼是公開的。
變量
您可能知道:變量是存儲數(shù)字或文本的地方。根據(jù)不同的使用,有不同的變量“類型”。以下是最基本的類型:存儲數(shù)字的整數(shù)、存儲文本的字符串和存儲小數(shù)的浮點數(shù)。我們也有對象-“類型”,其中包括這些基本類型,如數(shù)組,列表和您自己的自定義類型(稍后更多關于這些)。如果您想了解更多關于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變量。
沒有返回類型的函數(shù)/方法不能返回任何東西。
例子:
'
'My first BlitzMax program
'
Strict
Local speed = 10
Print speed
注意:BlitzMax認為“Speed”、“speed”和“sPeEd”是相同的變量。因為BlitzMax里不區(qū)分大小寫,任何關鍵字也是。(譯者推薦:關鍵字、函數(shù)名、方法名和類型名的每個單詞首字母大寫;常量名的所有單詞都大寫并“_”分隔單詞;變量名的所有單詞都小寫并“_”分隔單詞)
Global或Local
變量可以是全局的,也可以是局部的。全局變量可以從整個程序中訪問。另一方面,局部變量更加復雜,因為它們的存在取決于它們在哪里聲明。這稱為局部作用域。若要聲明局部變量,請在變量名前面使用關鍵字local。如果你在一個函數(shù)中聲明一個局部變量,它將只存在于那個函數(shù)中。如果它是在一個循環(huán)中聲明的,那么它將只在您處于該循環(huán)中時存在。如果一個局部變量在一個If語句中,那么它只存在于那個If語句中。
常量
您還可以聲明常量。一個常量將具有您在第一次聲明它時所賦予的值。常數(shù)的值永遠不會改變,它將永遠保持不變。如果你試圖改變一個常量的值,編譯器會在編譯時警告你。常量對于始終保持不變的值非常有用。
例子:
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語句用于檢查是否滿足了某個條件,然后根據(jù)該條件采取行動。
例子:
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 。
但是從可讀性考慮,不要這么做。
注:邏輯判斷中數(shù)值0就等于False,非零就等于True。如果一個對象是“null”(不存在),它就是false,否則就是true
“<>”是“不等于”運算符。If a <> 10 等價于 If Not a = 10
循環(huán)
循環(huán)是告訴Blitz重復做一件事。
例子:
For Local i:Int = 10 To 0 Step -1
? Print i
Next
這個輸出就是10,9,……0。輸出了11個數(shù),循環(huán)包括開頭與結(jié)尾的數(shù)。
例子:
Local a:Int[]=[0,5,12,13,20]
For Local b:Int = EachIn a
? Print b
Next
關鍵字EachIn表示遍歷數(shù)組或集合。
例子:
Local i:Int = 0
While i<=5
? Print i
? i:+1
Wend
關鍵字While表示直到條件為假終止循環(huán)。
注:Wend位置也可用EndWhile,兩個關鍵字等價的。(譯者推薦用Wend)
例子:
Local i:Int = 0
Repeat
? Print i
? i:+1
Until i=5
關鍵字Until表示直到條件為真終止循環(huán)。
例子:
Local i:Int = 0
Repeat
? Print i+" Ctrl-C to End!"
? i:+1
Forever
關鍵字Forever表示是個死循環(huán)。
輸入
輸入是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,以此類推,表示所有字母和數(shù)字。有關鍵碼的完整列表,請參閱手冊的掃描代碼部分。
Functions
函數(shù)是重用代碼的一種方式。它還可以將代碼分割成更容易管理的部分。
一個函數(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ù),包括對象。它返回的類型是在函數(shù)名后面指定的,跟“$”就表示返回一個字符串型值。如果要返回整型,就寫成 Function CollectData:Int 或 Function CollectData%
注:如上函數(shù)類型改整型,Return 一個字符串類型,那么編譯階段就會報錯通不過。
下面是另一個簡單函數(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ù)是什么,它返回什么,它做什么。
隨機
一個最有用的命令是Rand(A, B),它在A和B之間創(chuàng)建一個隨機值。
例子:
Local test = Rand(1,3)
這將把test設置為1、2或3。如果只使用一個參數(shù)調(diào)用Rand(A),因為參數(shù)B缺省值是1,函數(shù)將返回一個介于A到1之間的值。這意味著Rand(-1)應該是-1、0或1。
數(shù)組
數(shù)組是在一個地方存儲多個值的一種方式。數(shù)組中的所有元素必然具有相同的類型!
例子:
Local name_list$[] = [ "Dawn" , "Trac" , "Fire" ,"Nitro" ,"Nex"]
這將創(chuàng)建一個包含5個字符串的數(shù)組。所有元素都是字符串。
例子:
NameList[0] = "None"
Local Text$ = NameList[2]
存取數(shù)組元素。數(shù)組下標從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
聲明了一個3x3,9個元素的2維數(shù)組。
如果我們想遍歷2維數(shù)組中的所有元素,就必須使用雙重For-Next循環(huán)。
數(shù)組的數(shù)組
例子:
Local grid[][] = [[1,1,1,2],[7,7],[5,5,5]]
這將創(chuàng)建三個一維數(shù)組,第一個長度為4,第二個長度為2,第三個長度為3。這些數(shù)組用作較大數(shù)組中的行。為了得到一個元素,我們使用grid[WhichArray][PlaceInThisArray]。如果想得到第一個子數(shù)組,那就grid[0]。
獲得數(shù)組長度和排序
例子:
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是切片的起始下標,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的元素。