[DEVELOPMENT ENVIRONMENT]
* NEW: Traditional Chinese translation made by Timothy Lin. * BUG: Correctly take the project tabulation size in automatic structure completion. * BUG: Fix the tips of the day language selection. [EXAMPLES] * NEW: New MineSweeper example made by Timothy Lin and slightly modified by me. [GB.EVAL.HIGHLIGHT] * BUG: 'undefined' is a javascript keyword. [GB.FORM.DIALOG] * NEW: Take the new Dialog.ShowHidden property into account. [GB.QT4.EXT] * BUG: Editor cursor is ensured to be visible when it is visible, not when it has just the focus. git-svn-id: svn://localhost/gambas/trunk@4458 867c0c6c-44f3-4631-809d-bfa615b0a4ec
@ -4051,7 +4051,7 @@ msgstr ""
|
||||
msgid "Tip of the day #&1"
|
||||
msgstr ""
|
||||
|
||||
#: FTips.class:105
|
||||
#: FTips.class:107
|
||||
msgid "Unable to read tip of the day !"
|
||||
msgstr ""
|
||||
|
||||
|
@ -678,9 +678,9 @@ Private Function InsertFunction(sProc As String, sType As String, bPublic As Boo
|
||||
Editor.Goto(iLine, 0)
|
||||
|
||||
If sType Then
|
||||
Editor.Insert("\n" & sStatic & sPublic & " FUNCTION " & sProc & "(" & sSign & ") AS " & sType & "\n\n" & Space$(Project.TabSize) & "\n\nEND\n")
|
||||
Editor.Insert("\n" & sStatic & sPublic & " Function " & sProc & "(" & sSign & ") As " & sType & "\n\n" & Space$(Project.TabSize) & "\n\nEnd\n")
|
||||
Else
|
||||
Editor.Insert("\n" & sStatic & sPublic & " SUB " & sProc & "(" & sSign & ")\n\n" & Space$(Project.TabSize) & "\n\nEND\n")
|
||||
Editor.Insert("\n" & sStatic & sPublic & " Sub " & sProc & "(" & sSign & ")\n\n" & Space$(Project.TabSize) & "\n\nEnd\n")
|
||||
Endif
|
||||
|
||||
Editor.End
|
||||
@ -894,7 +894,7 @@ Private Sub DoStructControlCompletion(iLine As Integer, sLine As String, aSymbol
|
||||
If Not bUnindent And If sClose And If Not Key.Shift Then Editor.Insert("\n" & sIndent & sClose)
|
||||
Endif
|
||||
Editor.End
|
||||
Editor.Goto(iLine + 1, 2 + Len(sIndent))
|
||||
Editor.Goto(iLine + 1, Project.TabSize + Len(sIndent))
|
||||
Stop Event
|
||||
Return True
|
||||
Endif
|
||||
|
@ -70,6 +70,8 @@ Private Function GetNextTip(Optional bPrev As Boolean) As String
|
||||
Endif
|
||||
|
||||
sLang = System.Language
|
||||
iPos = RInStr(sLang, ".")
|
||||
If iPos Then sLang = Left(sLang, iPos - 1)
|
||||
|
||||
sFile = "tips/tips." & sLang
|
||||
If Not Exist(sFile) Then
|
||||
|
@ -80,6 +80,7 @@
|
||||
2 Yannick Butin
|
||||
2 Sergio Caparrós
|
||||
2 Jason Scurtu
|
||||
2 Gaja Sophie Peters
|
||||
2 Brice Vidal
|
||||
2 Mathew Rule
|
||||
2 Daniel Reumerman
|
||||
@ -87,3 +88,4 @@
|
||||
1 Louviaux
|
||||
1 Cooke Dylan
|
||||
1 Leonardo Suárez Arce
|
||||
1 Marco Iosif Constantinescu
|
||||
|
442
app/src/gambas3/tips/tips.zh_TW
Normal file
@ -0,0 +1,442 @@
|
||||
[WELCOME]
|
||||
|
||||
<p> 歡迎使用<b>Gambas</b>!</p>
|
||||
|
||||
<p><b> Gambas</b>是一個基於高級<b>Basic</b>語言直譯器的圖形界面的開發環境。</p>
|
||||
|
||||
<p><b> Gambas</b>的目標是使您能輕易而快速地開發出功能強大的程式。但是高效而簡潔的程式還得靠您<b>自己</b>的努力...</p>
|
||||
|
||||
<p> 希望您會喜歡!</p>
|
||||
|
||||
<p align=right>Benoît Minisini<br>
|
||||
English:<u>gambas@users.sourceforge.net</u><br>
|
||||
中文:<u>yizhou.he@gmail.com</u></p>
|
||||
|
||||
[STARTUP]
|
||||
|
||||
<p> 每一個專案都需要有一個<b>啟動類別</b>,這個啟動類別必須定義一個名爲<b>Main</b>的無參數靜態公用方法,它將成爲您的程式的進入點。</p>
|
||||
|
||||
<p>定義啟動類別的方法是,用鼠標右鍵點擊工程目錄樹中要設爲啟動類別的類別,並在彈出的右鍵菜單中選中<b>啟動類別</b>。</p>
|
||||
|
||||
<p>您不需要在啟動視窗中定義一個<b>Main</b>方法,因爲<b>Gambas</b>己經預定義好了。</p>
|
||||
|
||||
<p>這個預定義的啟動方法創建並顯示視窗, 就像<b>Visual Basic™</b>一樣。</p>
|
||||
|
||||
|
||||
[OPEN]
|
||||
|
||||
<p> <b>Gambas</b>的<b>OPEN</b>函數和<b>Visual Basic</b>的不太一樣,它並不回傳整數,而是回傳一個<b>檔案</b>物件。</p>
|
||||
|
||||
<p>所以,不要使用:</p>
|
||||
|
||||
<pre>DIM handle AS Integer
|
||||
...
|
||||
OPEN "myfile" FOR READ AS #handle</pre>
|
||||
|
||||
<p>而應該使用:</p>
|
||||
|
||||
<pre>DIM handle AS File
|
||||
...
|
||||
handle = OPEN "myfile" FOR READ</pre>
|
||||
|
||||
|
||||
[CATDIR]
|
||||
|
||||
<p> 您知道嗎?您可以使用<b><tt>&/</tt></b>來連接資料夾和檔案名稱,這個運算子會自動處理路徑結尾的<b><tt>/</tt></b>以免重複。</p>
|
||||
|
||||
<p>例如:</p>
|
||||
|
||||
<pre>PRINT "/home/gambas" &/ ".bashrc"
|
||||
/home/gambas/.bashrc
|
||||
|
||||
PRINT "/home/gambas/" &/ "/tmp" &/ "foo.bar"
|
||||
/home/gambas/tmp/foo.bar
|
||||
</pre>
|
||||
|
||||
<p>怎麼樣?好用吧!</p>
|
||||
|
||||
|
||||
[EXEC]
|
||||
|
||||
<p> 可以將您的整個專案生成一個可執行檔,在<b>專案</b>選單中選擇<b>生成可執行檔</b>。</p>
|
||||
|
||||
<p>當<b>Gambas</b>生成可執行檔時,預設會將產生的可執行檔放到您的專案目錄下,可執行檔名和您的專案名稱相同。</p>
|
||||
|
||||
|
||||
[PATH]
|
||||
<p>
|
||||
相對路徑在<b>Gambas</b>中有特殊含義,它們總是指向您專案內的文件。
|
||||
<p>
|
||||
這裏沒有<b>當前目錄</b>的概念,沒有<b>CHDIR</b>之類的關鍵字來改變它。
|
||||
<p>
|
||||
<b>注意:</b>您只能用相對路徑存取專案中的檔案,因爲絕對路徑在您生成可執行檔後就不再可靠了。
|
||||
|
||||
|
||||
[GLOBAL]
|
||||
|
||||
<b>Gambas</b>裏不再有<b>全域變數</b>了!
|
||||
<p>
|
||||
新的處理方法是,在您的主模組中宣告它們爲<b>PUBLIC</b>(公用類型)。
|
||||
<p>
|
||||
如果您的專案中沒有主模組,只有主視窗,那麼宣告它們爲<b>STATIC PUBLIC</b>(靜態公用類型)。
|
||||
<p>
|
||||
要存取這些變數,您必須使用主模組名或主視窗名:<tt>MyMainModule.MyGlobalVariable</tt>或
|
||||
<tt>MyMainForm.MyGlobalVariable</tt>。
|
||||
|
||||
|
||||
[EMPTY]
|
||||
|
||||
<p> 要知道一個字串是否爲空,並不需要使用<b>Len()</b>函數,您可以直接測試它,因爲空字串爲<b>FALSE</b>非空字串爲<b>TRUE</b>。</p>
|
||||
|
||||
<p>例如,您不需要寫:</p>
|
||||
|
||||
<pre>IF Len(MyString) > 0 THEN ...
|
||||
IF Len(MyString) = 0 THEN ...</pre>
|
||||
|
||||
<p>您只需寫:</p>
|
||||
|
||||
<pre>IF MyString THEN ...
|
||||
IF NOT MyString THEN ...</pre>
|
||||
|
||||
[TRANSLATE]
|
||||
|
||||
<p> <b>Gambas</b>應用程式是可完全翻譯的,條件是您應指定哪些字串是必須要翻譯的。 </p>
|
||||
<p>用括號將字串括起來就表示該字串是可以被翻譯的。<p>
|
||||
|
||||
<pre>PRINT ("我可以被翻譯!")
|
||||
PRINT "我不能被翻譯!"</pre>
|
||||
|
||||
[EVENT]
|
||||
|
||||
<p> 每個控制項和每個物件都可以產生事件,都有一個<b>event observer</b>(事件觀察器)和一個事件 <b>group name</b>(組名)。</p>
|
||||
|
||||
<p>事件觀察器捕捉物件產生的每一個事件,事件組名將是您用來處理事件的類別名稱的前綴。</p>
|
||||
|
||||
<p>預設的事件觀察器是您創建的控制項的容器物件,事件組名是控制項名。</p>
|
||||
|
||||
<p>在這種狀況下,一個視窗會接收您在它上面創建的所有控制項發生的事件。</p>
|
||||
|
||||
<pre>' Gambas form
|
||||
DIM hButton AS Button
|
||||
|
||||
PUBLIC SUB _new()
|
||||
hButton = NEW Button(ME) AS "MyButton"
|
||||
END
|
||||
|
||||
PUBLIC SUB MyButton_Click()
|
||||
PRINT "You have clicked MyButton !"
|
||||
END
|
||||
</pre>
|
||||
|
||||
|
||||
[FORM]
|
||||
|
||||
<p> 在<b>Gambas</b>中,一個視窗是它自己的事件觀察器,所以您可以直接在它自己的類代碼中管理它的事件(像<b>Resize</b>,
|
||||
<b>Activate</b>, ...)。 </p>
|
||||
|
||||
<p>這樣,從<b>Visual Basic</b>轉來的新手們就不會迷失方向:-)。</p>
|
||||
|
||||
|
||||
[EMBED]
|
||||
|
||||
<p> 在<b>Gambas</b>中,您可以在視窗中嵌入視窗!</p>
|
||||
|
||||
<p> 要實現如此強大的功能,只要在初始化視窗物件時將父容器做爲最後一個參數傳給視窗構建函數。</p>
|
||||
|
||||
<p>例如:</p>
|
||||
<p><tt>DIM hForm AS MyDialog<br>
|
||||
DIM hSuperControl AS MyForm<br><br>
|
||||
' 創建一個對話框<br>
|
||||
hForm = NEW MyDialog<br>
|
||||
' 在此對話框中插入一個視窗<br>
|
||||
' 注意此視窗需要三個參數,最後一個參數是容器物件<br>
|
||||
hSuperControl = NEW MyForm(Param1, Param2, MyDialog)<br>
|
||||
' 移動並改變視窗的大小<br>
|
||||
hSuperControl.Move(8, 8, 128, 64)<br>
|
||||
</tt></p>
|
||||
|
||||
<p>小心:嵌入後的視窗還是個視窗,它還是它自己的事件觀察器。</p>
|
||||
|
||||
|
||||
[GROUP]
|
||||
|
||||
<p> 每個控制項都有一個<b>Group</b>(組)屬性,當此屬性被設置,事件處理名稱的前綴就將是組名而不是控制項名。</p>
|
||||
|
||||
<p> 假定您有一個<b>Button</b>(按鈕)名叫<b>btnAction</b>
|
||||
有一個<b>Click</b>事件處理:</p>
|
||||
|
||||
<pre>PUBLIC SUB btnAction_Click()</pre>
|
||||
|
||||
<p> 如果您將<b>btnAction</b>的<b>(Group)</b>屬性設爲<b>MyGroup</b>,那麼事件處理從按鈕收到的事件將是:</p>
|
||||
|
||||
<pre>PUBLIC SUB MyGroup_Click()</pre>
|
||||
|
||||
<p> 此屬性讓您在一個函數中處理不同的控制項的事件,同組中的控制項不需要有相同的類型!</p>
|
||||
|
||||
<p><b>註釋:</b> <b>Visual Basic</b>老手可能會認為這個屬性和VB中的<b>控制項陣列</b>相似,但更為強大。:-)</p>
|
||||
|
||||
|
||||
[TAG]
|
||||
|
||||
<p> 每一個控制項都有<b>Tag</b>屬性,此屬性是爲編程者設計的,可以是任何您想要的<b>VARIANT</b>(可變類型)數據。</p>
|
||||
|
||||
<p>這在使用同組的公用事件處理中區別控制項時非常有用。</p>
|
||||
|
||||
|
||||
|
||||
[LAST]
|
||||
|
||||
<p> <b>LAST</b>關鍵字回傳最近一次發生事件的控制項,當您要寫一個獨立於控制項名的事件處理函式就非常有用。</p>
|
||||
|
||||
<p>例如,假設您要寫一個計算器程式。
|
||||
您定義了十個按鈕,每個數字一個,它們都在一個名叫"Digit"的<b>群組</b>,每個控制項的<b>Tag</b>屬性都被設爲相應的數字。
|
||||
您的處理程序將會是:</p>
|
||||
|
||||
<p><tt>PUBLIC SUB Digit_Click()<br><br>
|
||||
Display = Display & LAST.Tag<br>
|
||||
RefreshDisplay<br><br>
|
||||
END</tt></p>
|
||||
|
||||
|
||||
[LEFT]
|
||||
|
||||
<p> 大名鼎鼎的<b>BASIC</b>函數<b>Left$</b>、<b>Right$</b>
|
||||
和<b>Mid$</b>在<b>Gambas</b>中有了新功能。</p>
|
||||
|
||||
<p><b>Left$</b>和<b>Right$</b>的第二個參數是可選的,預設值爲1。</p>
|
||||
|
||||
<p><tt>Left$("Gambas")</tt> 回傳<tt>"G"</tt><br>
|
||||
<tt>Right$("Gambas")</tt> 回傳<tt>"s"</tt></p>
|
||||
|
||||
<p>第二個參數可以是負數,它的用途是指定反方向上將被切掉的字元個數。</p>
|
||||
|
||||
<p><tt>Left$("Gambas", -2)</tt> 回傳<tt>"Gamb"</tt><br>
|
||||
<tt>Right$("Gambas", -2)</tt> 回傳<tt>"mbas"</tt></p>
|
||||
|
||||
<p>相同的,<b>Mid$</b>的第三個參數也可以是負數,指定字串末端將被切掉的字元的個數。</p>
|
||||
|
||||
<p><tt>Mid$("Gambas", 2, -2)</tt> 回傳<tt>"amb"</tt>
|
||||
|
||||
[OBSERVER]
|
||||
|
||||
<p> <b>Observer</b>類別允許您在物件發出事件之前先攔截它。 </p>
|
||||
|
||||
<pre>MyTextBox = NEW TextBox(ME) AS "MyTextBox"
|
||||
MyObserver = NEW Observer(MyTextBox) AS "MyObserver"
|
||||
...
|
||||
PUBLIC SUB MyObserver_KeyPress()
|
||||
DEBUG "Got it first"
|
||||
END
|
||||
|
||||
PUBLIC SUB MyTextBox_KeyPress()
|
||||
DEBUG "Got it next"
|
||||
END</pre>
|
||||
|
||||
<b>Observer</b>能取消事件,防止物件對外發出事件。
|
||||
|
||||
|
||||
[STRING]
|
||||
|
||||
<p> <b>Gambas</b>使用<b>UTF-8</b>字元編碼在記憶體中描述字串。</p>
|
||||
|
||||
<p>但是所有的標準<b>Gambas</b>字串函數只處理<b>ASCII</b>碼:
|
||||
<b>Left</b>、<b>Mid</b>、<b>Right</b>、<b>UCase</b>...
|
||||
|
||||
<p>如果想處理UTF-8編碼的字串,必須使用<b>String</b>靜態類別的方法,它們的名字和標準字串處理函數完全相同。
|
||||
|
||||
<pre>PRINT Len("bébé");; Left$("bébé", 3)
|
||||
6 bé
|
||||
PRINT String.Len("bébé");; String.Left("bébé", 3)
|
||||
4 béb</pre>
|
||||
|
||||
|
||||
[ASSIGNMENT]
|
||||
|
||||
<p> <b>Gambas</b>實現了<b>C/C++</b>程序員常用的快捷賦值。
|
||||
|
||||
<p><tt>MyVariable += 2</tt> 等價於 <tt>MyVariable = MyVariable + 2</tt>
|
||||
|
||||
<p><tt>MyVariable &= "Great"</tt> 等價於 <tt>MyVariable = MyVariable & "Great"</tt>
|
||||
|
||||
<p>諸如此類...
|
||||
|
||||
|
||||
[DEBUG]
|
||||
|
||||
<p> 可以使用<b>DEBUG</b>語句列印除錯信息到控制台(也就是stderr),用法和<b>PRINT</b>語句完全一樣。
|
||||
|
||||
<p>除錯信息前綴有類別名稱,方法名稱和<b>DEBUG</b>語句所在的行號。
|
||||
|
||||
<p>除錯信息在生成不包含除錯信息的可執行檔時會被自動刪除。
|
||||
|
||||
|
||||
[TRY]
|
||||
|
||||
<p> Gambas使用下面的語句實現錯誤管理:
|
||||
<b>TRY</b>,<b>ERROR</b>,<b>CATCH</b>和<b>FINALLY</b>。
|
||||
|
||||
<p><b>TRY</b>嘗試執行一個語句而不引發錯誤,隨後使用<b>ERROR</b>語句檢測語句執行中是否發生錯誤。
|
||||
|
||||
<pre>TRY MyFile = OPEN "/etc/password" FOR WRITE
|
||||
IF ERROR THEN PRINT "I cannot do what I want!"</pre>
|
||||
|
||||
|
||||
[CATCH]
|
||||
|
||||
<p> Gambas使用下面的語句實現錯誤管理:
|
||||
<b>TRY</b>,<b>ERROR</b>,<b>CATCH</b>和<b>FINALLY</b>。
|
||||
|
||||
<p><b>CATCH</b>標明函數或者過程中錯誤管理部分(錯誤處理常式)的程式碼的開頭。
|
||||
|
||||
<p>當錯誤發生於函數執行的起始到終止之間時,會跳去執行錯誤處理常式的部分。
|
||||
|
||||
<p>如果錯誤發生於執行錯誤處理常式期間,會繼續向下一層傳送。錯誤處理常式不保護自己!
|
||||
|
||||
<pre>SUB ProcessFile(FileName AS STRING)
|
||||
...
|
||||
OPEN FileName FOR READ AS #hFile
|
||||
...
|
||||
CLOSE #hFile
|
||||
CATCH ' 只在發生錯誤時執行
|
||||
PRINT "Cannot process file "; FileName
|
||||
END</pre>
|
||||
|
||||
|
||||
[FINALLY]
|
||||
|
||||
<p> Gambas使用下面的語句實現錯誤管理:
|
||||
<b>TRY</b>,<b>ERROR</b>,<b>CATCH</b>和<b>FINALLY</b>。
|
||||
|
||||
<p>在函數的尾部,<b>FINALLY</b>語句引領的代碼被執行,即使在其執行期間有錯誤發生。
|
||||
|
||||
<b>FINALLY</b>部分是非必要的。如果函數中有錯誤處理常式,<b>FINALLY</b>部分必須位於處理常式之前。
|
||||
|
||||
|
||||
<p><b>FINALLY</b>部分是非必要的。如果函數中有錯誤處理常式,<b>FINALLY</b>部分必須位於處理常式之前。
|
||||
|
||||
<p>如果錯誤發生於<b>FINALLY</b>部分執行期間,錯誤會正常傳送。
|
||||
|
||||
<pre>SUB ProcessFile(FileName AS STRING)
|
||||
...
|
||||
OPEN FileName FOR READ AS #hFile
|
||||
...
|
||||
FINALLY ' 即使有錯誤發生也會被執行
|
||||
CLOSE #hFile
|
||||
CATCH ' 只在錯誤發生時執行
|
||||
PRINT "Cannot print file "; FileName
|
||||
END</pre>
|
||||
|
||||
|
||||
[OPTIONAL]
|
||||
|
||||
<h3>Optional</h3>
|
||||
|
||||
<p>在<b>Gambas</b>裡面,函數和程序的參數可以含有選擇性的參數。</p>
|
||||
|
||||
<p>定義選擇性參數的方法是在參數名稱面加上 <b><tt>Optional</tt></b> 關鍵字。</p>
|
||||
|
||||
<p>您也可以在選擇性參數後面加上預設值,例如:</p>
|
||||
|
||||
<pre>Private Sub MyFunction(Param AS String, Optional Optim AS String = "Default")
|
||||
...
|
||||
Print "Required: "; param; ", Optional: "; optim
|
||||
...
|
||||
End</pre>
|
||||
|
||||
|
||||
[ARRAY]
|
||||
|
||||
<h3>For Each</h3>
|
||||
|
||||
<p>在 <b>Gambas</b> 裡面,您可以輕易地用迴圈跑過陣列、集合以及其他支援 <b><tt>For Each</tt></b> 的可列舉類別。</p>
|
||||
|
||||
<p>例如:</p>
|
||||
|
||||
<pre>Dim Xml As New XmlDocument
|
||||
Dim Node As XmlNode
|
||||
Dim I As Integer
|
||||
|
||||
' Open XML file
|
||||
Xml.Open("pokus.xml")
|
||||
' Children is indexed via [i], since it's an array
|
||||
For I = 0 To Xml.Root.Children.Count - 1
|
||||
'Attributes are looped via For Each, since it's a collection
|
||||
For Each Node In Xml.Root.Children[i].Attributes
|
||||
Print Node.Name;; Node.Value
|
||||
Next
|
||||
Next</pre>
|
||||
|
||||
|
||||
[ICON]
|
||||
|
||||
<h3>預設圖示</h3>
|
||||
|
||||
<p>您可以使用內建的圖示來建構更美觀的圖形程式。這些內建圖示提供多種大小 (<tt>"small"</tt>, <tt>"medium"</tt>, <tt>"large"</tt>,...),您也可以使用絕對大小 (從 16x16 到 256x256)。</p>
|
||||
|
||||
<p>例如:
|
||||
|
||||
<pre>Image1.Picture = Picture["icon:/32/warning"]
|
||||
Image2.Picture = Picture["icon:/small/error"]
|
||||
</pre>
|
||||
|
||||
<p><b>警告:</b> 這個功能需要 <tt>gb.form</tt> 元件.
|
||||
|
||||
|
||||
[SETTINGS]
|
||||
|
||||
<h3>設定</h3>
|
||||
|
||||
<p>如果您需要在程式中儲存一些設定值 (如視窗位置、大小),您很幸運,在 <b>Gambas</b>
|
||||
中做到這個是易如反掌。 :-)
|
||||
|
||||
<p>儲存視窗位置:
|
||||
<pre>Settings.Write(TheForm)</pre>
|
||||
|
||||
<p>回復視窗位置:
|
||||
<pre>Settings.Read(TheForm)</pre>
|
||||
|
||||
儲存設定的方法:
|
||||
<pre>Settings["Slot/Key"] = Value</pre>
|
||||
|
||||
讀取設定的方法:
|
||||
<pre>Value = Settings["Slot/Key", DefaultValue]</pre>
|
||||
|
||||
這些設定將被儲存在 <tt>~/.config/gambas3/<MyApplication>.conf</tt> 中,
|
||||
<tt><MyApplication></tt> 是您的專案名稱。
|
||||
|
||||
<p><b>警告:</b> 這個功能需要 <tt>gb.settings</tt> 元件。
|
||||
|
||||
|
||||
[EDITOR]
|
||||
|
||||
<p>來點編輯器的提示...</p>
|
||||
|
||||
<h3>兩種註解類型</h3>
|
||||
|
||||
<pre>' 普通註解</pre>
|
||||
<b><pre>'' 粗體註解</pre></b>
|
||||
|
||||
<p>粗體註解可以用來替程式碼撰寫文件.</p>
|
||||
|
||||
<h3>如何使用程式碼片段</h3>
|
||||
|
||||
<p>輸入 <tt>main</tt> 然後按下 <b>TAB</b> 鍵. 編輯器將自動插入 static public <tt>Main</tt>
|
||||
到程式碼中.
|
||||
|
||||
<p>輸入 <tt>ds</tt> 然後按下 <b>TAB</b> 鍵. 編輯器將自動插入區域字串變數的宣告, 之後可以立即輸入變數名稱.
|
||||
|
||||
<p>程式碼片段可以在開發環境的選項中設定.
|
||||
|
||||
|
||||
[END]
|
||||
|
||||
<p> 您己讀完所有的每日提示提示。我希望您己經是 <b>Gambas</b> 的專家了!:-)</p>
|
||||
|
||||
<p>如果您想爲Gambas貢獻一份力量,請用電子郵件發送新提示到:</p>
|
||||
英文:<p><u>gambas@users.sourceforge.net</u></p>
|
||||
中文:<p><u>yizhou.he@gmail.com</u></p>
|
||||
|
||||
<p>預先感謝!</p>
|
||||
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
# Gambas Project File 3.0
|
||||
# Compiled with Gambas 3.0.0
|
||||
# Compiled with Gambas 3.0.90
|
||||
Title=gb.eval.highlight
|
||||
Startup=Main
|
||||
Version=3.0.0
|
||||
Version=3.0.90
|
||||
VersionFile=1
|
||||
Component=gb.image
|
||||
Component=gb.qt4
|
||||
|
@ -22,9 +22,10 @@ File[1]="sql/datatypes:57.9"
|
||||
File[2]="sql/functions:206.0"
|
||||
File[3]="sql/keywords:543.0"
|
||||
File[4]="sql/operators:58.0"
|
||||
Active=5
|
||||
File[5]=".src/HighlightSQL.module:72.31"
|
||||
Count=5
|
||||
Active=6
|
||||
File[6]=".src/HighlightJavascript.module:16.0"
|
||||
Count=6
|
||||
|
||||
[Watches]
|
||||
Count=0
|
||||
|
@ -15,7 +15,7 @@ Public Sub _init()
|
||||
$cKeyword[sStr] = 0
|
||||
Next
|
||||
|
||||
For Each sStr In ["false", "null", "this", "true"]
|
||||
For Each sStr In ["false", "null", "this", "true", "undefined"]
|
||||
$cKeyword[sStr] = 1
|
||||
Next
|
||||
|
||||
|
@ -2,7 +2,7 @@ Main
|
||||
gb.eval.highlight
|
||||
0
|
||||
0
|
||||
3.0.0
|
||||
3.0.90
|
||||
|
||||
gb.image
|
||||
gb.qt4
|
||||
|
@ -1,8 +1,8 @@
|
||||
# Gambas Project File 3.0
|
||||
# Compiled with Gambas 3.0.0
|
||||
# Compiled with Gambas 3.0.90
|
||||
Title=Enhanced standard dialogs
|
||||
Startup=Main
|
||||
Version=3.0.0
|
||||
Version=3.0.90
|
||||
VersionFile=1
|
||||
Component=gb.image
|
||||
Component=gb.gui
|
||||
|
@ -17,6 +17,7 @@ Public Sub Form_Open()
|
||||
|
||||
Me.Title = Dialog.Title
|
||||
dchChoose.Root = "/"
|
||||
dchChoose.ShowHidden = Dialog.ShowHidden
|
||||
If Not Dialog.Path Then
|
||||
dchChoose.SelectedPath = "~"
|
||||
Else
|
||||
|
@ -35,6 +35,7 @@ Public Sub Form_Open()
|
||||
fchChoose.Multi = $bMulti
|
||||
'fchChoose.Root = "/"
|
||||
fchChoose.Filter = Dialog.Filter
|
||||
fchChoose.ShowHidden = Dialog.ShowHidden
|
||||
If Dialog.Path Then fchChoose.SelectedPath = Dialog.Path
|
||||
|
||||
If fchChoose.Filter.Count > 1 Then
|
||||
|
@ -8,7 +8,7 @@ VersionFile=1
|
||||
Component=gb.image
|
||||
Component=gb.gui
|
||||
Component=gb.form
|
||||
Environment="GB_GUI=gb.gtk"
|
||||
Environment="GB_GUI=gb.qt4"
|
||||
TabSize=2
|
||||
ExecPath=/home/benoit/gambas/examples/Basic/DragNDrop/DragNDrop
|
||||
Maintainer=benoit
|
||||
|
2
examples/examples/Games/MineSweeper/.directory
Normal file
@ -0,0 +1,2 @@
|
||||
[Desktop Entry]
|
||||
Icon=./.icon.png
|
BIN
examples/examples/Games/MineSweeper/.icon.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
examples/examples/Games/MineSweeper/.lang/ja.mo
Normal file
53
examples/examples/Games/MineSweeper/.lang/ja.po
Normal file
@ -0,0 +1,53 @@
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2002-11-01 04:27+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: FSettings.form:97
|
||||
msgid "Cancel"
|
||||
msgstr "キャンセル"
|
||||
|
||||
#: FMain.form:26
|
||||
msgid "&Change Game Parameters"
|
||||
msgstr "パラメータを設定(&C)"
|
||||
|
||||
#: FMain.form:23
|
||||
msgid "&Game"
|
||||
msgstr "ゲーム(&G)"
|
||||
|
||||
#: FSettings.form:54
|
||||
msgid "Height"
|
||||
msgstr "縦の長さ"
|
||||
|
||||
#: .project:1 FMain.form:19
|
||||
msgid "Minesweeper"
|
||||
msgstr "マインスイーパ"
|
||||
|
||||
#: FSettings.form:71
|
||||
msgid "Number of mines"
|
||||
msgstr "地雷の数"
|
||||
|
||||
#: FSettings.form:91
|
||||
msgid "OK"
|
||||
msgstr "-"
|
||||
|
||||
#: FMain.form:30
|
||||
msgid "&Quit"
|
||||
msgstr "終了(&Q)"
|
||||
|
||||
#: FSettings.form:21
|
||||
msgid "Settings"
|
||||
msgstr "設定"
|
||||
|
||||
#: FSettings.form:37
|
||||
msgid "Width"
|
||||
msgstr "横の長さ"
|
||||
|
BIN
examples/examples/Games/MineSweeper/.lang/zh.mo
Normal file
52
examples/examples/Games/MineSweeper/.lang/zh.po
Normal file
@ -0,0 +1,52 @@
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2002-11-01 04:27+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: FSettings.form:97
|
||||
msgid "Cancel"
|
||||
msgstr "取消"
|
||||
|
||||
#: FMain.form:26
|
||||
msgid "&Change Game Parameters"
|
||||
msgstr "修改游戏参数(&C)"
|
||||
|
||||
#: FMain.form:23
|
||||
msgid "&Game"
|
||||
msgstr "游戏"
|
||||
|
||||
#: FSettings.form:54
|
||||
msgid "Height"
|
||||
msgstr "高度"
|
||||
|
||||
#: FMain.form:19 .project:1
|
||||
msgid "Minesweeper"
|
||||
msgstr "扫雷"
|
||||
|
||||
#: FSettings.form:71
|
||||
msgid "Number of mines"
|
||||
msgstr "地雷数"
|
||||
|
||||
#: FSettings.form:91
|
||||
msgid "OK"
|
||||
msgstr "确定"
|
||||
|
||||
#: FMain.form:30
|
||||
msgid "&Quit"
|
||||
msgstr "离开(&Q)"
|
||||
|
||||
#: FSettings.form:21
|
||||
msgid "Settings"
|
||||
msgstr "参数设置"
|
||||
|
||||
#: FSettings.form:37
|
||||
msgid "Width"
|
||||
msgstr "宽度"
|
||||
|
BIN
examples/examples/Games/MineSweeper/.lang/zh_TW.mo
Normal file
52
examples/examples/Games/MineSweeper/.lang/zh_TW.po
Normal file
@ -0,0 +1,52 @@
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2002-11-01 04:27+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: .project:1 FMain.form:19
|
||||
msgid "Minesweeper"
|
||||
msgstr "踩地雷"
|
||||
|
||||
#: FMain.form:23
|
||||
msgid "&Game"
|
||||
msgstr "遊戲(&G)"
|
||||
|
||||
#: FMain.form:26
|
||||
msgid "&Change Game Parameters"
|
||||
msgstr "修改遊戲參數(&C)"
|
||||
|
||||
#: FMain.form:30
|
||||
msgid "&Quit"
|
||||
msgstr "離開(&Q)"
|
||||
|
||||
#: FSettings.form:21
|
||||
msgid "Settings"
|
||||
msgstr "設定"
|
||||
|
||||
#: FSettings.form:37
|
||||
msgid "Width"
|
||||
msgstr "寬度"
|
||||
|
||||
#: FSettings.form:54
|
||||
msgid "Height"
|
||||
msgstr "高度"
|
||||
|
||||
#: FSettings.form:71
|
||||
msgid "Number of mines"
|
||||
msgstr "地雷數"
|
||||
|
||||
#: FSettings.form:91
|
||||
msgid "OK"
|
||||
msgstr "確定"
|
||||
|
||||
#: FSettings.form:97
|
||||
msgid "Cancel"
|
||||
msgstr "取消"
|
15
examples/examples/Games/MineSweeper/.project
Normal file
@ -0,0 +1,15 @@
|
||||
# Gambas Project File 3.0
|
||||
# Compiled with Gambas 3.0.90
|
||||
Title=Minesweeper
|
||||
Startup=FMain
|
||||
Icon=image/expr_win.png
|
||||
Version=3.0.90
|
||||
VersionFile=1
|
||||
Component=gb.image
|
||||
Component=gb.gui
|
||||
Component=gb.form
|
||||
Authors="Timothy Lin"
|
||||
Environment="GB_GUI=gb.qt4"
|
||||
TabSize=3
|
||||
Translate=1
|
||||
Language=en
|
248
examples/examples/Games/MineSweeper/.src/FMain.class
Normal file
@ -0,0 +1,248 @@
|
||||
' Gambas class file
|
||||
|
||||
Private img_cover As Picture = Picture.Load("image/cover.png")
|
||||
Private img_cover_hovered As Picture = Picture.Load("image/coveron.png")
|
||||
Private img_false As Picture = Picture.Load("image/false.png")
|
||||
Private img_flag As Picture = Picture.Load("image/flag.png")
|
||||
Private img_face_normal As Picture = Picture.Load("image/expr_normal.png")
|
||||
Private img_face_win As Picture = Picture.Load("image/expr_win.png")
|
||||
Private img_face_lose As Picture = Picture.Load("image/expr_lose.png")
|
||||
Private img_face_o As Picture = Picture.Load("image/expr_o.png")
|
||||
Private img_mine As Picture
|
||||
Private img_num[10] As Picture
|
||||
|
||||
Private dlgSettings As FSettings = New FSettings
|
||||
|
||||
Private game_width As Integer = 20
|
||||
Private game_height As Integer = 15
|
||||
Private game_mines As Integer = game_width * game_height / 10
|
||||
|
||||
Private game As MineSweeperGame
|
||||
Private blocks As PictureBox[]
|
||||
|
||||
Private play_time As Integer = 0
|
||||
|
||||
Public Sub _new()
|
||||
' img_num[0] is none, img_num[9] is mine
|
||||
' img_num[1~8] is the number of adjacent mines
|
||||
' load number images
|
||||
Dim i As Integer
|
||||
Dim a As Integer[]
|
||||
img_num[0] = Picture.Load("image/empty.png")
|
||||
img_num[9] = Picture.Load("image/mine.png")
|
||||
For i = 1 To 8
|
||||
img_num[i] = Picture.Load("image/number_" & Str(i) & ".png")
|
||||
Next
|
||||
img_mine = img_num[9]
|
||||
|
||||
btnStatus.Resize(img_face_normal.Width + 10, img_face_normal.Height + 10)
|
||||
btnStatus.Picture = img_face_normal
|
||||
|
||||
Timer1.Enabled = False
|
||||
End
|
||||
|
||||
' ----- Window Events -----
|
||||
|
||||
Public Sub Form_Open()
|
||||
ReDimGame(game_width, game_height, game_mines)
|
||||
'Me.Maximized = True
|
||||
End
|
||||
|
||||
' Public Sub Form_Resize()
|
||||
' adjust_components()
|
||||
' End
|
||||
|
||||
Public Sub Block_MouseDown()
|
||||
Dim index As Integer = Last.Tag
|
||||
Dim x As Integer = index Mod game_width
|
||||
Dim y As Integer = index / game_width
|
||||
|
||||
If Mouse.Left Then
|
||||
If game.Status = game.GAME_STARTED And game.GetBlockStatus(x, y) = game.BLOCK_COVERED Then
|
||||
btnStatus.Picture = img_face_o
|
||||
Endif
|
||||
Endif
|
||||
End
|
||||
|
||||
|
||||
Public Sub Block_MouseUp()
|
||||
Dim index As Integer = Last.Tag
|
||||
Dim x As Integer = index Mod game_width
|
||||
Dim y As Integer = index / game_width
|
||||
'Message("Clicked (" & x & "," & y & ")")
|
||||
|
||||
If game.Status = game.GAME_STARTED Then
|
||||
btnStatus.Picture = img_face_normal
|
||||
Endif
|
||||
|
||||
' Skip the event if the mouse button is released outside the block it is pressed
|
||||
If Mouse.X > blocks[0, 0].Width Or Mouse.y > blocks[0, 0].Height Then Return
|
||||
|
||||
If Mouse.Right Then
|
||||
game.ToggleFlag(x, y)
|
||||
Else If Mouse.Left Then
|
||||
game.OpenBlock(x, y)
|
||||
Endif
|
||||
End
|
||||
|
||||
' highlight the block under cursor
|
||||
Public Sub Block_Enter()
|
||||
Dim index As Integer = Last.Tag
|
||||
Dim x As Integer = index Mod game_width
|
||||
Dim y As Integer = index / game_width
|
||||
|
||||
If game.Status = game.GAME_WIN Or game.Status = game.GAME_LOSE Then Return
|
||||
|
||||
If game.GetBlockStatus(x, y) = game.BLOCK_COVERED Then
|
||||
blocks[x, y].Picture = img_cover_hovered
|
||||
Endif
|
||||
End
|
||||
|
||||
' un-highlight the block under cursor
|
||||
Public Sub Block_Leave()
|
||||
Dim index As Integer = Last.Tag
|
||||
Dim x As Integer = index Mod game_width
|
||||
Dim y As Integer = index / game_width
|
||||
|
||||
If game.Status = game.GAME_WIN Or game.Status = game.GAME_LOSE Then Return
|
||||
|
||||
If game.GetBlockStatus(x, y) = game.BLOCK_COVERED Then
|
||||
blocks[x, y].Picture = img_cover
|
||||
Endif
|
||||
End
|
||||
|
||||
Public Sub btnStatus_Click()
|
||||
game.Reset()
|
||||
End
|
||||
|
||||
Public Sub Game_OnStart()
|
||||
Timer1.Enabled = True
|
||||
End
|
||||
|
||||
Public Sub Game_OnEnd()
|
||||
Timer1.Enabled = False
|
||||
End
|
||||
|
||||
Public Sub Game_OnRefresh()
|
||||
Dim x, y As Integer
|
||||
Dim s As Integer
|
||||
For x = 0 To game.Width - 1
|
||||
For y = 0 To game.Height - 1
|
||||
Select Case game.Status
|
||||
Case game.GAME_READY
|
||||
blocks[x, y].Picture = img_cover
|
||||
btnStatus.Picture = img_face_normal
|
||||
play_time = 0 ' reset the timer
|
||||
Timer1.Enabled = False
|
||||
refresh_timebox()
|
||||
Case game.GAME_STARTED
|
||||
s = game.GetBlockStatus(x, y)
|
||||
If s = game.BLOCK_COVERED Then
|
||||
blocks[x, y].Picture = img_cover
|
||||
Else If s = game.BLOCK_FLAGGED Then
|
||||
blocks[x, y].Picture = img_flag
|
||||
Else
|
||||
blocks[x, y].picture = img_num[game.GetBlockNumber(x, y)]
|
||||
Endif
|
||||
Case game.GAME_WIN, game.GAME_LOSE
|
||||
If game.GetBlockStatus(x, y) = game.BLOCK_FLAGGED Then
|
||||
If game.GetBlockNumber(x, y) = game.NUM_MINE Then
|
||||
blocks[x, y].Picture = img_flag
|
||||
Else
|
||||
blocks[x, y].Picture = img_false
|
||||
Endif
|
||||
Else ' the block has been uncovered
|
||||
blocks[x, y].Picture = img_num[game.GetBlockNumber(x, y)]
|
||||
Endif
|
||||
btnStatus.Picture = IIf(game.Status = game.GAME_WIN, img_face_win, img_face_lose)
|
||||
End Select
|
||||
Next
|
||||
Next
|
||||
refresh_flagbox()
|
||||
End
|
||||
|
||||
Public Sub Timer1_Timer()
|
||||
play_time += 1
|
||||
refresh_timebox()
|
||||
End
|
||||
|
||||
Public Sub menuQuit_Click()
|
||||
Me.Close()
|
||||
End
|
||||
|
||||
Public Sub menuReDim_Click()
|
||||
dlgSettings.FieldWidth = game_width
|
||||
dlgSettings.FieldHeight = game_height
|
||||
dlgSettings.MineCount = game_mines
|
||||
If dlgSettings.ShowModal() Then
|
||||
game_width = dlgSettings.FieldWidth
|
||||
game_height = dlgSettings.FieldHeight
|
||||
game_mines = dlgSettings.MineCount
|
||||
ReDimGame(game_width, game_height, game_mines)
|
||||
Endif
|
||||
End
|
||||
|
||||
|
||||
|
||||
' ----- Private Functions -----
|
||||
|
||||
|
||||
' Generate the a width x height board and adjust control positions
|
||||
Private Sub ReDimGame(width As Integer, height As Integer, mines As Integer)
|
||||
Dim x, y As Integer
|
||||
Dim blk As PictureBox
|
||||
|
||||
blocks = New PictureBox[width, height]
|
||||
|
||||
For x = 0 To width - 1
|
||||
For y = 0 To height - 1
|
||||
blk = New PictureBox(panelBoard)
|
||||
With blk
|
||||
.Picture = img_cover
|
||||
.Resize(img_cover.Width, img_cover.Height)
|
||||
.Move(x * .Width, y * .Height)
|
||||
.Tag = x + y * width
|
||||
Object.Attach(blk, Me, "Block")
|
||||
End With
|
||||
blocks[x, y] = blk
|
||||
Next
|
||||
Next
|
||||
|
||||
game = New MineSweeperGame(width, height, mines)
|
||||
Object.Attach(game, Me, "Game")
|
||||
game.Reset()
|
||||
|
||||
panelBoard.Resize(width * img_cover.Width, height * img_cover.Height)
|
||||
'adjust_components()
|
||||
End
|
||||
|
||||
' Private Sub adjust_components()
|
||||
' center_control(panelBoard)
|
||||
' center_control_horizontal(btnStatus)
|
||||
' btnStatus.top = panelBoard.top - btnStatus.Height
|
||||
' TimeBox.Left = 0
|
||||
' TimeBox.Top = panelBoard.Top - TimeBox.Height
|
||||
' FlagBox.Left = Me.Width - FlagBox.Width
|
||||
' FlagBox.Top = panelBoard.Top - FlagBox.Height
|
||||
' End
|
||||
|
||||
Private Sub refresh_timebox()
|
||||
lblTime.Text = Str(play_time)
|
||||
End
|
||||
|
||||
Private Sub refresh_flagbox()
|
||||
lblFlags.Text = Str(game.FlagCount)
|
||||
End
|
||||
|
||||
|
||||
|
||||
' Center the control in the main window
|
||||
' Private Sub center_control(c As Control)
|
||||
' c.Move((Me.Width - c.Width) / 2, (Me.Height - c.Height) / 2)
|
||||
' End
|
||||
'
|
||||
' ' Center the control horizontally in the main window
|
||||
' Private Sub center_control_horizontal(c As Control)
|
||||
' c.left = (Me.Width - c.Width) / 2
|
||||
' End
|
||||
|
78
examples/examples/Games/MineSweeper/.src/FMain.form
Normal file
@ -0,0 +1,78 @@
|
||||
# Gambas Form File 3.0
|
||||
|
||||
{ Form Form
|
||||
MoveScaled(0,0,81,65)
|
||||
Text = ("Minesweeper")
|
||||
Arrangement = Arrange.Vertical
|
||||
Spacing = True
|
||||
Margin = True
|
||||
{ menuGame Menu
|
||||
Text = ("&Game")
|
||||
{ menuReDim Menu
|
||||
Text = ("&Change Game Parameters")
|
||||
Picture = Picture["icon:/32/edit"]
|
||||
}
|
||||
{ menuQuit Menu
|
||||
Text = ("&Quit")
|
||||
Picture = Picture["icon:/32/quit"]
|
||||
}
|
||||
}
|
||||
{ HBox1 HBox
|
||||
MoveScaled(2,2,74,13)
|
||||
Margin = True
|
||||
{ PictureBox2 PictureBox
|
||||
MoveScaled(0,0,11,11)
|
||||
Picture = Picture["image/clock.png"]
|
||||
AutoResize = True
|
||||
Alignment = Align.Center
|
||||
}
|
||||
{ lblTime Label
|
||||
MoveScaled(12,2,12,7)
|
||||
Font = Font["20"]
|
||||
AutoResize = True
|
||||
}
|
||||
{ Panel2 Panel
|
||||
MoveScaled(30,3,1,7)
|
||||
Expand = True
|
||||
}
|
||||
{ btnStatus Button
|
||||
MoveScaled(32,2,7,7)
|
||||
}
|
||||
{ Panel3 Panel
|
||||
MoveScaled(40,3,1,7)
|
||||
Expand = True
|
||||
}
|
||||
{ PictureBox1 PictureBox
|
||||
MoveScaled(47,0,11,11)
|
||||
Picture = Picture["image/bigflag.png"]
|
||||
AutoResize = True
|
||||
Alignment = Align.Center
|
||||
}
|
||||
{ lblFlags Label
|
||||
MoveScaled(58,5,24,4)
|
||||
Font = Font["20"]
|
||||
AutoResize = True
|
||||
}
|
||||
}
|
||||
{ Panel6 Panel
|
||||
MoveScaled(25,17,10,1)
|
||||
}
|
||||
{ Panel4 HBox
|
||||
MoveScaled(8,19,70,35)
|
||||
Expand = True
|
||||
{ Panel1 Panel
|
||||
MoveScaled(4,7,1,13)
|
||||
Expand = True
|
||||
}
|
||||
{ panelBoard Panel
|
||||
MoveScaled(10,6,47,25)
|
||||
}
|
||||
{ Panel5 Panel
|
||||
MoveScaled(63,7,1,20)
|
||||
Expand = True
|
||||
}
|
||||
}
|
||||
{ Timer1 #Timer
|
||||
#MoveScaled(2,54)
|
||||
}
|
||||
}
|
66
examples/examples/Games/MineSweeper/.src/FSettings.class
Normal file
@ -0,0 +1,66 @@
|
||||
' Gambas class file
|
||||
|
||||
Property FieldWidth As Integer
|
||||
Property FieldHeight As Integer
|
||||
Property MineCount As Integer
|
||||
|
||||
Public Sub Run() As Boolean
|
||||
|
||||
Return Not Me.ShowModal()
|
||||
|
||||
End
|
||||
|
||||
Public Sub btnOK_Click()
|
||||
|
||||
Me.Close(True)
|
||||
|
||||
End
|
||||
|
||||
Public Sub btnCancel_Click()
|
||||
|
||||
Me.Close
|
||||
|
||||
End
|
||||
|
||||
Public Sub spinWidth_Change()
|
||||
UpdateMineRange()
|
||||
spinMines.Value = spinWidth.Value * spinHeight.Value / 10
|
||||
End
|
||||
|
||||
Public Sub spinHeight_Change()
|
||||
UpdateMineRange()
|
||||
spinMines.Value = spinWidth.Value * spinHeight.Value / 10
|
||||
End
|
||||
|
||||
Public Sub Form_Open()
|
||||
UpdateMineRange()
|
||||
End
|
||||
|
||||
Private Sub UpdateMineRange()
|
||||
spinMines.MinValue = 1
|
||||
spinMines.MaxValue = spinWidth.Value * spinHeight.Value - 1
|
||||
End
|
||||
|
||||
Private Function FieldWidth_Read() As Integer
|
||||
Return spinWidth.Value
|
||||
End
|
||||
|
||||
Private Sub FieldWidth_Write(Value As Integer)
|
||||
spinWidth.Value = Value
|
||||
End
|
||||
|
||||
Private Function FieldHeight_Read() As Integer
|
||||
Return spinHeight.Value
|
||||
End
|
||||
|
||||
Private Sub FieldHeight_Write(Value As Integer)
|
||||
spinHeight.Value = Value
|
||||
End
|
||||
|
||||
Private Function MineCount_Read() As Integer
|
||||
Return spinMines.Value
|
||||
End
|
||||
|
||||
Private Sub MineCount_Write(Value As Integer)
|
||||
spinMines.Value = Value
|
||||
End
|
71
examples/examples/Games/MineSweeper/.src/FSettings.form
Normal file
@ -0,0 +1,71 @@
|
||||
# Gambas Form File 3.0
|
||||
|
||||
{ Form Form
|
||||
MoveScaled(0,0,61,30)
|
||||
Text = ("Settings")
|
||||
Persistent = True
|
||||
Arrangement = Arrange.Vertical
|
||||
Spacing = True
|
||||
Margin = True
|
||||
{ VBox1 VBox
|
||||
MoveScaled(1,1,54,22)
|
||||
{ HBox2 HBox
|
||||
MoveScaled(2,1,50,6)
|
||||
{ lblX Label
|
||||
MoveScaled(1,1,24,4)
|
||||
Expand = True
|
||||
AutoResize = True
|
||||
Text = ("Width")
|
||||
}
|
||||
{ spinWidth SpinBox
|
||||
MoveScaled(14,1,9,4)
|
||||
MinValue = 5
|
||||
MaxValue = 50
|
||||
}
|
||||
}
|
||||
{ HBox4 HBox
|
||||
MoveScaled(2,8,50,6)
|
||||
{ lblY Label
|
||||
MoveScaled(1,1,24,4)
|
||||
Expand = True
|
||||
AutoResize = True
|
||||
Text = ("Height")
|
||||
}
|
||||
{ spinHeight SpinBox
|
||||
MoveScaled(26,1,9,4)
|
||||
MinValue = 5
|
||||
MaxValue = 25
|
||||
}
|
||||
}
|
||||
{ HBox6 HBox
|
||||
MoveScaled(2,15,50,6)
|
||||
{ lblMines Label
|
||||
MoveScaled(0,1,14,4)
|
||||
Expand = True
|
||||
AutoResize = True
|
||||
Text = ("Number of mines")
|
||||
}
|
||||
{ spinMines SpinBox
|
||||
MoveScaled(37,1,9,4)
|
||||
}
|
||||
}
|
||||
}
|
||||
{ HBox1 HBox
|
||||
MoveScaled(1,25,59,4)
|
||||
Spacing = True
|
||||
{ Panel1 Panel
|
||||
MoveScaled(4,0,4,4)
|
||||
Expand = True
|
||||
}
|
||||
{ btnOK Button
|
||||
MoveScaled(24,0,16,4)
|
||||
Text = ("OK")
|
||||
Default = True
|
||||
}
|
||||
{ btnCancel Button
|
||||
MoveScaled(41,0,16,4)
|
||||
Text = ("Cancel")
|
||||
Cancel = True
|
||||
}
|
||||
}
|
||||
}
|
194
examples/examples/Games/MineSweeper/.src/MineSweeperGame.class
Normal file
@ -0,0 +1,194 @@
|
||||
' Gambas class file
|
||||
|
||||
Property Read Width As Integer
|
||||
Property Read Height As Integer
|
||||
Property Read Status As Integer
|
||||
Property Read FlagCount As Integer
|
||||
|
||||
Event OnStart()
|
||||
Event OnEnd()
|
||||
Event OnRefresh()
|
||||
|
||||
Public Enum BLOCK_COVERED, BLOCK_FLAGGED, BLOCK_REVEALED
|
||||
Public Enum GAME_READY, GAME_STARTED, GAME_WIN, GAME_LOSE
|
||||
Public Enum NUM_MINE = 9
|
||||
|
||||
Private $width As Integer
|
||||
Private $height As Integer
|
||||
Private $blocks As New Integer[]
|
||||
Private $status As New Integer[]
|
||||
Private $mine_count As Integer
|
||||
Private $flag_count As Integer
|
||||
Private $covered_block_count As Integer
|
||||
Private $game_state As Integer
|
||||
|
||||
Public Sub _new(w As Integer, h As Integer, n As Integer)
|
||||
$width = w
|
||||
$height = h
|
||||
$mine_count = n
|
||||
$covered_block_count = 0
|
||||
$blocks = New Integer[w, h]
|
||||
$status = New Integer[w, h]
|
||||
Reset()
|
||||
End
|
||||
|
||||
Public Function Reset()
|
||||
Dim x, y As Integer
|
||||
For x = 0 To $width - 1
|
||||
For y = 0 To $height - 1
|
||||
$status[x, y] = BLOCK_COVERED
|
||||
$blocks[x, y] = 0
|
||||
Next
|
||||
Next
|
||||
$game_state = GAME_READY
|
||||
$covered_block_count = $width * $height
|
||||
$flag_count = $mine_count
|
||||
Raise OnRefresh()
|
||||
End
|
||||
|
||||
Public Function GetBlockNumber(x As Integer, y As Integer) As Integer
|
||||
Return $blocks[x, y]
|
||||
End
|
||||
|
||||
Public Function GetBlockStatus(x As Integer, y As Integer) As Integer
|
||||
Return $status[x, y]
|
||||
End
|
||||
|
||||
Public Sub OpenBlock(x As Integer, y As Integer)
|
||||
If $game_state = GAME_READY Then
|
||||
$game_state = GAME_STARTED
|
||||
GenerateRandomMines($mine_count, x, y)
|
||||
Raise OnStart()
|
||||
Endif
|
||||
|
||||
If $game_state = GAME_STARTED And $status[x, y] = BLOCK_COVERED
|
||||
If $blocks[x, y] = NUM_MINE Then ' stepped on a mine
|
||||
$game_state = GAME_LOSE
|
||||
Raise OnEnd()
|
||||
Else
|
||||
RecursiveOpen(x, y)
|
||||
If AllMinesFound() Then
|
||||
FlagAllMines()
|
||||
$game_state = GAME_WIN
|
||||
Raise OnEnd()
|
||||
Endif
|
||||
Endif
|
||||
Endif
|
||||
|
||||
Raise OnRefresh()
|
||||
End
|
||||
|
||||
Public Sub ToggleFlag(x As Integer, y As Integer)
|
||||
If $game_state = GAME_STARTED Then
|
||||
If $status[x, y] = BLOCK_COVERED Then
|
||||
$status[x, y] = BLOCK_FLAGGED
|
||||
$flag_count -= 1
|
||||
Else If $status[x, y] = BLOCK_FLAGGED Then
|
||||
$status[x, y] = BLOCK_COVERED
|
||||
$flag_count += 1
|
||||
Else
|
||||
Return
|
||||
Endif
|
||||
Raise OnRefresh()
|
||||
Endif
|
||||
End
|
||||
|
||||
|
||||
Private Function Width_Read() As Integer
|
||||
Return $width
|
||||
End
|
||||
|
||||
Private Function Height_Read() As Integer
|
||||
Return $height
|
||||
End
|
||||
|
||||
Private Function Status_Read() As Integer
|
||||
Return $game_state
|
||||
End
|
||||
|
||||
Private Function FlagCount_Read() As Integer
|
||||
Return $flag_count
|
||||
End
|
||||
|
||||
' Generate n mines in the field and guarantee that (nx, ny) does not contain a mine.
|
||||
Private Sub GenerateRandomMines(n As Integer, nx As Integer, ny As Integer)
|
||||
Dim i As Integer
|
||||
Dim x, y As Integer
|
||||
Dim x2, y2 As Integer
|
||||
Dim count As Integer = $width * $height
|
||||
Dim index As Integer
|
||||
|
||||
' check if the range is correct
|
||||
' note that the field should contain at most (w*h-1) mines, not w*h
|
||||
If n >= count Then Error.Raise("Index out of bounds")
|
||||
|
||||
' put n mines into the first blocks, and fill in zero in the rest
|
||||
For i = 0 To count - 1
|
||||
x = i Mod $width
|
||||
y = i / $width
|
||||
$blocks[x, y] = IIf(i < n, NUM_MINE, 0)
|
||||
Next
|
||||
|
||||
' if a mine is located in (nx, ny), then move the mine to the last block
|
||||
If $blocks[nx, ny] = NUM_MINE Then Swap $blocks[nx, ny], $blocks[$width - 1, $height - 1]
|
||||
|
||||
' shuffle
|
||||
For i = 0 To count - 1
|
||||
x = i Mod $width
|
||||
y = i / $width
|
||||
x2 = Int(Rnd(0, $width))
|
||||
y2 = Int(Rnd(0, $height))
|
||||
If (x = nx And y = ny) Or (x2 = nx And y2 = ny) Then Continue ' skip (nx, ny)
|
||||
Swap $blocks[x, y], $blocks[x2, y2]
|
||||
Next
|
||||
|
||||
' generate the numbers
|
||||
For x = 0 To $width - 1
|
||||
For y = 0 To $height - 1
|
||||
If $blocks[x, y] = NUM_MINE Then
|
||||
For x2 = x - 1 To x + 1
|
||||
For y2 = y - 1 To y + 1
|
||||
Try IncrementBlockMineCount(x2, y2)
|
||||
Next
|
||||
Next
|
||||
Endif
|
||||
Next
|
||||
Next
|
||||
End
|
||||
|
||||
Private Sub IncrementBlockMineCount(x As Integer, y As Integer)
|
||||
If $blocks[x, y] <> NUM_MINE Then $blocks[x, y] += 1
|
||||
End
|
||||
|
||||
Private Sub RecursiveOpen(x As Integer, y As Integer)
|
||||
Dim x2, y2 As Integer
|
||||
If $status[x, y] = BLOCK_COVERED Then
|
||||
$status[x, y] = BLOCK_REVEALED
|
||||
$covered_block_count -= 1
|
||||
If $blocks[x, y] = 0 Then
|
||||
For x2 = x - 1 To x + 1
|
||||
For y2 = y - 1 To y + 1
|
||||
RecursiveOpen(x2, y2)
|
||||
Next
|
||||
Next
|
||||
Endif
|
||||
Endif
|
||||
Catch
|
||||
|
||||
End
|
||||
|
||||
Private Function AllMinesFound() As Boolean
|
||||
Return $covered_block_count = $mine_count
|
||||
End
|
||||
|
||||
' Automatically mark all mines as flag
|
||||
Private Sub FlagAllMines()
|
||||
Dim x, y As Integer
|
||||
For x = 0 To $width - 1
|
||||
For y = 0 To $height - 1
|
||||
If $blocks[x, y] = NUM_MINE Then
|
||||
$status[x, y] = BLOCK_FLAGGED
|
||||
Endif
|
||||
Next
|
||||
Next
|
||||
End
|
10
examples/examples/Games/MineSweeper/.startup
Normal file
@ -0,0 +1,10 @@
|
||||
FMain
|
||||
Minesweeper
|
||||
0
|
||||
0
|
||||
3.0.90
|
||||
|
||||
gb.image
|
||||
gb.gui
|
||||
gb.form
|
||||
|
BIN
examples/examples/Games/MineSweeper/image/bigflag.png
Normal file
After Width: | Height: | Size: 7.2 KiB |
BIN
examples/examples/Games/MineSweeper/image/clock.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
examples/examples/Games/MineSweeper/image/cover.png
Normal file
After Width: | Height: | Size: 421 B |
BIN
examples/examples/Games/MineSweeper/image/coveron.png
Normal file
After Width: | Height: | Size: 357 B |
BIN
examples/examples/Games/MineSweeper/image/empty.png
Normal file
After Width: | Height: | Size: 274 B |
BIN
examples/examples/Games/MineSweeper/image/expr_lose.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
examples/examples/Games/MineSweeper/image/expr_normal.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
examples/examples/Games/MineSweeper/image/expr_o.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
examples/examples/Games/MineSweeper/image/expr_win.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
examples/examples/Games/MineSweeper/image/false.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
examples/examples/Games/MineSweeper/image/flag.png
Normal file
After Width: | Height: | Size: 849 B |
BIN
examples/examples/Games/MineSweeper/image/mine.png
Normal file
After Width: | Height: | Size: 772 B |
BIN
examples/examples/Games/MineSweeper/image/number_1.png
Normal file
After Width: | Height: | Size: 469 B |
BIN
examples/examples/Games/MineSweeper/image/number_2.png
Normal file
After Width: | Height: | Size: 579 B |
BIN
examples/examples/Games/MineSweeper/image/number_3.png
Normal file
After Width: | Height: | Size: 610 B |
BIN
examples/examples/Games/MineSweeper/image/number_4.png
Normal file
After Width: | Height: | Size: 543 B |
BIN
examples/examples/Games/MineSweeper/image/number_5.png
Normal file
After Width: | Height: | Size: 547 B |
BIN
examples/examples/Games/MineSweeper/image/number_6.png
Normal file
After Width: | Height: | Size: 636 B |
BIN
examples/examples/Games/MineSweeper/image/number_7.png
Normal file
After Width: | Height: | Size: 516 B |
BIN
examples/examples/Games/MineSweeper/image/number_8.png
Normal file
After Width: | Height: | Size: 683 B |
@ -380,7 +380,7 @@ GB_DESC CGslDesc[] =
|
||||
//GB_CONSTANT("M_SQRT2", "f", "1.41421356237309504880168872421"), /* sqrt(2) */
|
||||
//GB_CONSTANT("M_SQRT1_2", "f", "0.70710678118654752440084436210"), /* sqrt(1/2) */
|
||||
//GB_CONSTANT("M_SQRT3", "f", "1.73205080756887729352744634151"), /* sqrt(3) */
|
||||
//GB_CONSTANT("M_PI", "f", "3.14159265358979323846264338328"), /* pi */
|
||||
GB_CONSTANT("M_PI", "f", "3.14159265358979323846264338328"), /* pi */
|
||||
//GB_CONSTANT("M_PI_2", "f", "1.57079632679489661923132169164"), /* pi/2 */
|
||||
//GB_CONSTANT("M_PI_4", "f", "0.78539816339744830961566084582"), /* pi/4 */
|
||||
//GB_CONSTANT("M_SQRTPI", "f", "1.77245385090551602729816748334"), /* sqrt(pi) */
|
||||
|
@ -2223,7 +2223,7 @@ void GEditor::ensureCursorVisible()
|
||||
{
|
||||
int xx, yy;
|
||||
|
||||
if (!isUpdatesEnabled() || !hasFocus())
|
||||
if (!isUpdatesEnabled() || !isVisible())
|
||||
return;
|
||||
|
||||
xx = lineWidth(y, x); // + _charWidth['m'] / 2
|
||||
|