導航:首頁 > 觀俄羅斯 > 如何製作俄羅斯方塊培學長

如何製作俄羅斯方塊培學長

發布時間:2022-05-13 01:37:48

『壹』 怎麼用vb製作俄羅斯方塊游戲啊,簡單點的。

visual basic繼承了basic語言易學易用的特點,特別適合於初學者學習windows系統編程。隨著21世紀信息社會的到來,計算機在人們的工作和生活中的深入,要求我們越來越多地與計算機打交道,為了使用戶在繁忙的日程工作中得到放鬆,於是出現了各種各樣的休閑軟體,如聊天工具,游戲等等。於是我們小組著手設計開始一個這樣的游戲軟體。通過這學期來Visual Basic的學習,我初步掌握了Visual Basic語言的最基本的知識,於是在牛榮和李鵬等老師的指導下動手用Visual Basic編寫俄羅斯方塊游戲。
我們之所以選擇開發俄羅斯方塊游戲,無可爭議,《俄羅斯方塊》是有史以來最偉大的游戲之一。 在曾經發布過的所有游戲中,《俄羅斯方塊》還被認為是僅有的一個能夠真正吸引廣泛人群的作品。誰能說清楚,迄今為止人們究竟花了多少萬個小時在這個游戲上?也許這些時間本來可以被花在更具生產力的活動上。某些批評家也許會聲稱,《俄羅斯方塊》要比過去二十年間出現的任何東西都要浪費人們的時間。至於我們,則要欣然提名它為GameSpot評選出的歷史上最偉大游戲之一。
為了懷念經典,也為了能夠給大多的計算機用戶在工作之餘找到一個休閑、娛樂的一個方式,我們小組開始著手用VB語言開發一個經典的俄羅斯方塊游戲。
工程概況
2.1 項目名稱
俄羅斯方塊游戲
2.2 設計平台
VB 全稱Visual Basic,它是以Basic語言作為其基本語言的一種可視化編程工具。
Vb是microsoft公司於1991年退出的windows應用程序開發工具visual意思是「可視化的」。在它剛推出來時,自身還存在一些缺陷,功能也相對少一些。但是經過多年的開發研究。最近microsoft公司又推出了VB6.0版本
VB6.0運行環境:硬體,要求486以上的處理器、16MB以上內存,50MB 以上的硬碟,cd-rom驅動器,滑鼠。軟體:要求windows 95以上版本。
2.3程序設計思想
游戲是用來給大家娛樂的,所以要能在使用的過程中給大家帶來快樂,消除大家的疲勞,所以我們在游戲中添加了漂亮的場景和動聽的音樂,設置了過關升級的功能,激發大家的娛樂激情。
從游戲的基本玩法出發,主要就是俄羅斯方塊的形狀和旋轉,我們在設計中在一個圖片框中構造了一個4*4的網狀小塊,由這些小塊組合成新的形狀,每四個小塊連接在一起就可以構造出一種造型,因此我們總共設計了7中造型,每種造型又可以通過旋轉而變化出2到4種形狀,利用隨機函數在一個欲覽窗體中提前展示形狀供用戶參考,然後將展示的形狀復制到游戲窗體中進行擺放,在游戲窗體中用戶就可以使用鍵盤的方向鍵來控制方塊的運動,然後利用遞歸語句對每一行進行判斷,如果有某行的方塊是滿的,則消除這行的方塊,並且使上面的方塊自由下落,其中,方塊向下的速度是有時鍾控制項控制的,在游戲中,用戶也可以使用向下鍵加快下落速度,定義一個變數,對消除的函數進行記錄,最後就可以得出用戶的分數,用if 語句對分數判斷,達到一定的積分就可以升級到下一個檔次。
俄羅斯方塊游戲設計的主要步驟為以下10個方面:
(1)游戲界面的設計。
(2)俄羅斯方塊的造型。
(3)俄羅斯方塊的旋轉。
(4)俄羅斯方塊的運動情況(包括向左,向右和向下)。
(5)俄羅斯方塊的自動消行功能。
(6)游戲級別的自由選擇。
(7)游戲速度的自由選擇。
(8)游戲得分的計算。
(9)游戲菜單選項的設計及功能實現。
(10)游戲的背景音樂及特效。
2.4運用的控制項和主要對象
我們在設計過程中主要用到的控制項有:command控制項,image控制項,picture控制項,label控制項,timer控制項,text控制項,windows media player控制項等等。
2.5主要實現的功能
我們開發的俄羅斯方塊游戲,主要實現了以下幾種功能:
1.可以靈活控制方塊在圖形框中運動。
2.游戲過程中方塊可以自由旋轉。
3.當某一行的方塊排列滿時,將自動將這一行方塊消除,然後將上面所有方塊向下移動,可以支持連續消行。
4.游戲前可以選擇游戲的速度和游戲的等級,游戲速度既為方塊下落速度,游戲等級為初始游戲時在基層隨機生成一定行數的無規律方塊,生成的行數由你來選擇,每行至少產生5個以上的無規律方塊,這樣增加了游戲難度,對於游戲高手來說,無疑不是一個新的挑戰。
5.游戲的得分支持積分,並且按照公式:
得分 = 原來分數+ 100 * (2 ^ 同時消除的行數-1)
這樣,你同一時間消除的行數越多,你的得分也就越高,當游戲積分到了一定時可以自動升級,這個升級指速度升級。
6.游戲中提供了一個漂亮的場景和動聽的音樂,給你帶來無限激情。
2.6開發人員
由於這次課程設計所選的題目太復雜,而時間又比較緊張,指導老師建議和同學分工完成。我們小組成員包括組長孫磊周,副組長鄒海星,此游戲由我們兩個人共同開發而成。
正文
3.1游戲設計的具體實現
在我們兩個人共同努力下,此次設計,終於能夠圓滿完成。由於時間的緊促,在設計中,也許會有一些考慮不周之處,但其功能已經能夠滿足大多用戶的需求,相信假以時日,一定能做出一個更經典,更完美的俄羅斯方塊游戲,下面我們將對每一步的具體如何實現展示給大家。
3.1.1游戲界面的設計和背景音樂及特效的實現
俄羅斯方塊游戲主要由兩個界面構成,登陸界面和開始游戲界面,在登陸界面中我們可以首先看到聖誕節的晚上飄梅花的場景,梅花從窗體頂部做函數曲線的下落運動,在窗體中定義一個Image控制項組,在通用中定義梅花X坐標變數動態數組,Y坐標變數動態數組,步距X的變數動態數組,步距Y的變數動態數組,以及振幅變數動態數組。然後在窗體form_load中可以定義梅花的數量,利用隨機函數產生隨機的梅花坐標,步距和振幅,Image控制項在運行時候就調用梅花圖片,Image控制項就可以由時鍾控制項控制下落速度,可以自由調節,梅花按snow(i).Left = xp(i) + am(i) * Sin(dx(i))函數在做縱向的正玄函數軌跡運動,豎直方向上為自由下落運動,,有am(i)來控制梅花的左右移動振幅。因此,我們就可以看到一個梅花在空中自由飄舞的畫面了。
背景畫面是用photoshop軟體處理的漂亮圖案,原本畫面中的動畫效果都是由Image控制項製作的,還有點擊進入游戲的按鈕是由Label控制項實現的,因為Image控制項沒有置前置後功能,不能將下雪的場景體現完整性,所以將這些圖案全部放在背景上,不影響雪花飄落的效果,當點擊畫面的時候一樣可以進入游戲界面。
游戲的背景音樂是由一段代碼調用系統播放器Windows Player播放背景音樂,由於本次設計主要是針對游戲如何設計的,所以在這里就不對播放背景音樂的功能做介紹了。
3.1.2俄羅斯方塊的造型
相信朋友們都玩過俄羅斯方塊,對這個游戲的玩法和方塊形狀都比較熟悉。我們這個游戲只選擇了最基本的7中造型,包括長條型,正方型,正S型,反S型,正7型,反7型,T型。如果需要我們可以添加更多的造型。將游戲界面的游戲區圖片框分割成10*20的小塊,每個小塊放置一個command控制項,預覽區圖片框按同樣比例分割成4*4的小塊,同樣有command控制項構成,我們可以把預覽區圖片框看作是從游戲區圖片框中選取的一個部分,游戲區的小方塊編號和欲覽區編號如下圖:
0 1 2 3 4 5 6 7 8 9
… … … … … … … … … …
… … … … … … … … … …
90 91 92 93 94 95 96 97 98 99
3 4 5 6
13 14 15 16
23 24 25 26
33 34 35 36
游戲區編號 欲覽區編號
利用Select將方塊的7中造型列出,比如長條型的設計,在欲覽區中分別有3.4.5.6和5.15.25.35四個方塊構成兩中形態,用數組為:
m(0) = 3: m(1) = 4: m(2) = 5: m(3) = 6: situation2 = 0
m(0) = 5: m(1) = 15: m(2) = 25: m(3) = 35: situation2 = 1
將它的形狀編號為0和1,在後面方便調用,其他的方塊造型同樣的方法。
3.1.3俄羅斯方塊的旋轉
俄羅斯方塊的旋轉主要將方塊的位置加以變換得到的,例如上述範例,長條型有兩中樣式,根據小方塊的編號變動來實現整個造型的旋轉,比如:
If n(0) - 18 >= 2 And n(3) + 9 <= 198 Then
If cmdfang(n(0) - 18).Visible = False And _
cmdfang(n(1) - 9).Visible = False And _
cmdfang(n(3) + 9).Visible = False Then
hidefang 0
n(0) = n(0) - 18
n(1) = n(1) - 9
n(3) = n(3) + 9
showfang 0
situation = 1
End If
End If
方塊的造型在旋轉的時候存在一個公式,當然首先要判斷是否滿足旋轉的要求,以上是一個長條型由橫著變成豎立狀態的旋轉,我們以它的造型中的第三個小方塊n(3)為中心旋轉,這樣,在開始運動的時候,長條形要發生旋轉最少要運動到第三行,才能由橫著變成豎立狀態,游戲區圖形框中第三行的第一個方塊的編號為20,所以長條造型的第一個小方塊的編號n(0)必須要大於20。同樣,長條型方塊在下落到底部的時候也有限制。如果長條下落到最後一行也將無法由橫著變成豎立狀態。
3.1.4如何實現方塊的運動和自動消除滿行的方塊
我們的這個俄羅斯方塊游戲主要是利用command控制項的visible屬性完成效果的,其實在游戲區圖形框可以看成是由許多的command小方塊組成,方塊運動的過程就是造型里方塊顯示或者隱藏,就像現在的霓虹燈效果一樣,由時鍾控制項控制visible屬性改變的速度,上一層的消失,下一層的顯示,這樣,從視覺效果可以看到方塊的下落運動效果。
方塊在下落的過程中會自動判斷每一行方塊的visible屬性,如果全部為true時,就會將這一行小方塊的visible屬性全部變成false,在將上面的小方塊向下移動,利用for語句進行循環判斷,將所有這樣情況的行改變小方塊visible屬性。當有多行同時出現這樣情況時使用遞歸調用,實現連續消行。具體程序代碼如下:
For i = 190 To 10 Step -10
If cmdfang(i).Visible = True And _
cmdfang(i + 1).Visible = True And _
cmdfang(i + 2).Visible = True And _
cmdfang(i + 3).Visible = True And _
cmdfang(i + 4).Visible = True And _
cmdfang(i + 5).Visible = True And _
cmdfang(i + 6).Visible = True And _
cmdfang(i + 7).Visible = True And _
cmdfang(i + 8).Visible = True And _
cmdfang(i + 9).Visible = True Then
For j = i + 4 To i Step -1
t = 1
cmdfang(j).Visible = False
cmdfang(2 * i + 9 - j).Visible = False
For k = 1 To 4000
DoEvents
Next
t = 0
Next
linenum = linenum + 1
For j = i - 1 To 0 Step -1
If cmdfang(j).Visible = True Then
cmdfang(j).Visible = False
cmdfang(j + 10).Visible = True
End If
Next
clearline '為了實現連消數行,這里使用遞歸調用
End If
Next
3.1.5游戲速度和游戲級別自由選擇
游戲速度的自由選擇無非就是改變時鍾控制項的頻率,我們在菜單中添加了選擇速度的功能,還有添加了考驗功能,將欲覽窗中的方塊造型隱藏,給玩家提高了難度,如果你不願意接受考驗也可以點擊顯示還原成原來狀態。
游戲級別的自由選擇是讓用戶選擇游戲開始時候,游戲區底部出現一定行數的隨機方塊,同樣給玩家增加了難度,功能代碼如下:
For i = 19 To 20 - Val(txthard.Text) Step -1
For j = i * 10 To i * 10 + 9
If Rnd >= 0.5 Then cmdfang(j).Visible = True
Next
Next
可以根據你選擇的難度系數在底層的每一行隨機產生超過半數(即5個以上)以上的小方塊,這樣適合喜歡高難度的玩家。
3.1.6游戲得分的計算和游戲菜單的編輯
游戲得分的計算主要是根據消除的行數來決定的,當然每一次同時消除的行數不一樣,每一行的得分也不一樣,如果你每次消除的行數為1,則最後得分是100分,如果同時消除2行,則最後得分是300分,同時消除3行,得分為700分,同時消除4行,得分為1500分,這由公式:得分 = 原來分數+ 100 * (2 ^ 同時消除的行數-1)。
游戲的編輯,讀者可以參照下面的功能介紹。
3.2 游戲功能的介紹
文件-------開始:開始游戲。
繼續:繼續游戲。
暫停:暫時停止游戲,點擊繼續的時候可以繼續游戲。
退出:退出遊戲。
設置-------選擇游戲級別。
選擇游戲速度。
考驗-------顯示:顯示欲覽去方塊。
隱藏:隱藏欲覽去方塊。
幫助-------操作提示以及版本信息和作者資料。

用戶界面具體如圖:

圖—登陸界面 圖—游戲界面

圖—菜單編輯界面 圖—游戲幫助界面
有關說明
經過兩個多星期的設計和開發,俄羅斯方塊游戲已經成功。其功能基本符合用戶需求,能夠完成游戲的控制,方塊的變換以及消層等功能。並提供游戲設置,對於一些技術性比較過硬的玩家,可以調游戲級別、以及游戲速度,使得玩家能夠充分的發揮競技游戲的特色,可以不斷的挑戰自我,挑戰極限。
4.1游戲設計中的不足之處
但是由於課程設計時間較短,所以該游戲還有許多不盡如人意的地方,比如方塊類型太少,退出遊戲不能存儲進度等多方面問題。這些都有待進一步改善,我們在游戲中還可以更換背景音樂,以適合不同的玩家,在每通過一關可以給玩家播放一段flash,吸引玩家去挑戰極限,不斷提高玩家的興趣,相信在以後的製作過程中我們將給大家帶來一個更新功能更全面的游戲。
4.2VB與C語言之間的不同之處
我們這個小游戲也可以用C語言來實現,在程序的編程上沒有VB語言方便實用,C語言和VB語言之間存在很多的共同點,雖然語法方面有點差異,但是在編程思路上完全一樣,VB能夠實現很多C#不能做到的功能,如When語句、Optional參數、局部Static變數、對象實例訪問靜態方法、Handles綁定事件、On Error處理異常、Object直接後期綁定等等。VB和C#語言,編譯出來的是同樣的CIL,但為什麼VB支持很多有趣的特性呢。我們一起來探究一下。
4.21局部靜態變數
VB支持用Static關鍵字聲明局部變數,這樣在過程結束的時候可以保持變數的數值:
Public Sub Test1()
Static i As Integer
i += 1 '實現一個過程調用計數器
End Sub
我們實現了一個簡單的過程計數器。每調用一次Test,計數器的數值就增加1。其實還有很多情況我們希望保持變數的數值。而C#的static是不能用在過程內部的。因此要實現過程計數器,我們必須聲明一個類級別的變數。這樣做明顯不如VB好。因為無法防止其他過程修改計數器變數。這就和對象封裝一個道理,本來應該是一個方法的局部變數,現在我要被迫把它獨立出來,顯然是不好的設計。那麼VB是怎麼生成局部靜態變數的呢?將上述代碼返匯編,我們可以清楚地看到在VB生成的CIL中,i不是作為局部變數,而是作為類的Field出現的: .field private specialname int32 $STATIC$Test1$2001$i
也就是說,i被改名作為一個類的欄位,但被冠以specialname。在代碼中試圖訪問$STATIC$Test1$2001$i是不可能的,因為它不是一個有效的標識符。但是在IL中,將這個變數加一的代碼卻與一般的類欄位完全一樣,是通過ldfld載入的。我覺得這個方法十分聰明,把靜態變數變成生命周期一樣的類欄位,但是又由編譯器來控制訪問的許可權,讓它成為一個局部變數。同時也解釋了VB為什麼要用兩個不同的關鍵字來聲明靜態變數——Static和Shared。由於局部靜態變數的實質是類的欄位,所以它和真正的局部變數還是有所不同的。比如在多線程條件下,對局部靜態變數的訪問就和訪問欄位相同。
4.2.2Handles和WithEvents
VB除了可以用C#那樣的方法來處理事件響應以外,還有從VB5繼承下來的獨特的事件處理方式——WithEvents。
我喜歡稱這種事件處理方式為靜態的事件處理,書寫響應事件的方法時就已經決定該方法響應的是哪一個事件,而C#則是在代碼中綁定事件的。VB中WithEvents靜態方法是非常有用的,它可以顯著增強代碼可讀性,同時也讓VB.net中的事件處理非常方便,不像C#那樣離開了窗體設計器就必須手工綁定事件。
4.2.3類型轉換運算符
在Visual Basic 2005中將加入一個新的運算符——TryCast,相當於C#的as運算符。我一直希望VB有這樣一個運算符。VB目前的類型轉換運算符主要有CType和DirectCast。他們的用法幾乎一樣。我詳細比較了一下這兩個運算符,得出以下結論:
1.在轉換成引用類型時,兩者沒有什麼區別,都是直接調用castclass指令,除非重載了類型轉換運算符CType。DirectCast運算符是不能重載的。
2.轉換成值類型時,CType會調用VB指定的類型轉換函數(如果有的話),比如將String轉換為Int32時,就會自動調用。
4.2.4默認屬性和屬性參數
在原先的VB6里,有一項奇特的功能——默認屬性。在VB6中,對象的名稱可以直接表示該對象的默認屬性。
4.2.5可選參數和按名傳遞
VB從4.0開始支持「可選參數」這一特性。就是說,函數或子程序的參數有些是可選的,調用的時候可以不輸入。其實VB從1.0開始就有一些函數帶有可選參數,只不過到了4.0才讓用戶自己開發這樣的過程。在VB4里,可選參數可以不帶默認值,而在VB里,如果使用可選參數,則必須帶有默認值。在調用的時候,VB若發現參數被省略,則自動讀取.param部分的默認值,並顯式傳遞給過程。這一部分完全由編譯器處理,而且沒有任何性能損失,和手工傳遞所有參數是完全一樣的。至於按名傳遞,VB會自動調整參數的順序,其結果與傳統方式的傳遞也沒有任何的不同。這說明我們可以放心地使用這項便利。而且帶有可選參數的過程拿到C#中,頂多變成不可選參數,也不會造成什麼其他的麻煩。
PS.很多COM組件都使用了默認參數,而且有些過程的參數列表非常長,在VB里可以輕松地處理它們,而在C#中經常讓開發者傳參數傳到吐血。
4.2.6在經過對比之後可得以下一個結論:
1.目前的主流編程語言沒有簡單的,如果你想學精通的話。
2.VB的門檻比較低,編程思想較容易接受。
3.學習C不能短期內見到成效。
4.據用戶調查69%的考生覺得VB更容易接受

致謝
在本次課程設計中,我從指導老師牛榮和李鵬身上學到了很多東西。老師認真負責的工作態度,嚴謹的治學精神和深厚的理論水平都使我收益匪淺。他無論在理論上還是在實踐中,都給與我很大的幫助,使我得到不少的提高這對於我以後的工作和學習都有一種巨大的幫助,感謝他耐心的輔導。
另外,在游戲開發過程中化希耀老師和杜義君老師也給於我們很大的幫助,幫助解決了不少的難點,使得游戲能及時開發完成,還有所有的同學同樣給與我不少幫助,這里一並表示感。

參考文獻:
[1]Vsual Basic 程序設計教程 作者:龔沛曾,陸慰民,楊志強 高等教育出版社出版
[2]Vsual Basic 6.0程序設計 作者:劉新民,蔡瓊,白糠生 清華大學出版社出版
[3]80例上手 VB6 編程 作者:唐凱軍,湯惠莉 山東電子音像出版社
[4]Vsual Basic 實例教程 作者:盧毅 科學出版社出版
[5]Vsual Basic 經典範例50講 作者:趙欣勝,亢慧娟,劉晟宏 科學出版社出版

『貳』 怎樣製作俄羅斯方塊

以下代碼粘貼在主場經第一禎,測試影片就看到了:
N = 20;//行數
WIDTH = 20;//方塊邊長
level = 0;//開始等級(下落速度)
ret = new Array();//當前出現的方塊
nextret = new Array();//下一個出現的方塊
bg = new Array();//背景數組
createEmptyMovieClip("panel", 1048575);//所有方塊都在此mc里
for (i = 0; i < 5; i++) {
//初始化方塊數組,2*5格式,前四行代表每個方塊的4個小塊的位置坐標,最後一行第一列是方塊形狀,第二列是方塊旋轉方向
ret.push(new Array(2));
nextret.push(new Array(2));
}
for (i = 0; i < 20; i++) {//初始化背景數組,10*20格式
bg.push(new Array(10));
}
X = Y = panel._x = panel._y = 0;//換為X、Y表示
function reach(x:Number, y:Number, ret:Object) {
//x、y為方塊位置,ret為方塊形狀,若方塊ret下落一格碰到邊界或者方塊返回1
var i:Number, j:Number, k:Number;
for (i = 0; i < N; i++) {
for (j = 0; j < 10; j++) {
if (bg[i][j] == 219) {
for (k = 0; k < 4; k++) {
if (x + ret[k][0] == j && y + ret[k][1] + 1 == i) {
return 1;
}
}
}
}
}
return 0;
}
function lrnotout(lorr:Number, a:Object) {
//lorr==-1代表a往左邊一格可行性的判斷,lorr==1代表右邊一格可行性的判斷,lorr==0代表a的位置合理性的判斷,出現不合理則返回0
var i:Number;
if (lorr == -1) {
for (i = 0; i < 4; i++) {
if (x + a[i][0] - 1 < 0 || reach(x - 1, y - 1, a)) {
return 0;
}
}
}
if (lorr == 1) {
for (i = 0; i < 4; i++) {
if (x + a[i][0] + 1 > 9 || reach(x - 1, y + 1, a)) {
return 0;
}
}
}
if (lorr == 0) {
for (i = 0; i < 4; i++) {
if (x + a[i][0] < 0 || x + a[i][0] > 9) {
return 0;
}
}
}
return 1;
}
function rv(a:Object, ret:Object) {
//方塊賦值,將a方塊賦值到ret方塊
var i:Number;
for (i = 0; i < 5; i++) {
ret[i][0] = a[i][0], ret[i][1] = a[i][1];
}
}
function rotate(ret:Object) {
//根據方塊ret最後一行(分別是形狀指示變數和旋轉方向變數)為ret的前四行賦以具體形狀值
switch (ret[4][0]) {
case 0 ://方形
a = [[1, 0], [2, 0], [1, 1], [2, 1], [0, 0]];
rv(a, ret);
return;
case 1 ://長形
switch (ret[4][1]) {
case 1 :
a = [[0, 0], [1, 0], [2, 0], [3, 0], [1, 0]];
if (lrnotout(0, a) && !reach(x, y - 1, a)) {
rv(a, ret);
}
return;
case 0 :
a = [[1, 0], [1, 1], [1, 2], [1, 3], [1, 1]];
if (lrnotout(0, a) && !reach(x, y - 1, a)) {
rv(a, ret);
}
return;
}
case 2 ://Z形
switch (ret[4][1]) {
case 1 :
a = [[0, 1], [1, 1], [1, 2], [2, 2], [2, 0]];
if (lrnotout(0, a) && !reach(x, y - 1, a)) {
rv(a, ret);
}
return;
case 0 :
a = [[2, 0], [1, 1], [2, 1], [1, 2], [2, 1]];
if (lrnotout(0, a) && !reach(x, y - 1, a)) {
rv(a, ret);
}
return;
}
case 3 ://反Z形
switch (ret[4][1]) {
case 1 :
a = [[1, 1], [2, 1], [0, 2], [1, 2], [3, 0]];
if (lrnotout(0, a) && !reach(x, y - 1, a)) {
rv(a, ret);
}
return;
case 0 :
a = [[1, 0], [1, 1], [2, 1], [2, 2], [3, 1]];
if (lrnotout(0, a) && !reach(x, y - 1, a)) {
rv(a, ret);
}
return;
}
case 4 ://T形
switch (ret[4][1]) {
case 3 :
a = [[1, 0], [0, 1], [1, 1], [2, 1], [4, 0]];
if (lrnotout(0, a) && !reach(x, y - 1, a)) {
rv(a, ret);
}
return;
case 0 :
a = [[1, 0], [0, 1], [1, 1], [1, 2], [4, 1]];
if (lrnotout(0, a) && !reach(x, y - 1, a)) {
rv(a, ret);
}
return;
case 1 :
a = [[0, 1], [1, 1], [2, 1], [1, 2], [4, 2]];
if (lrnotout(0, a) && !reach(x, y - 1, a)) {
rv(a, ret);
}
return;
case 2 :
a = [[1, 0], [1, 1], [2, 1], [1, 2], [4, 3]];
if (lrnotout(0, a) && !reach(x, y - 1, a)) {
rv(a, ret);
}
return;
}
case 5 ://倒L形
switch (ret[4][1]) {
case 3 :
a = [[1, 0], [2, 0], [1, 1], [1, 2], [5, 0]];
if (lrnotout(0, a) && !reach(x, y - 1, a)) {
rv(a, ret);
}
return;
case 0 :
a = [[0, 1], [0, 2], [1, 2], [2, 2], [5, 1]];
if (lrnotout(0, a) && !reach(x, y - 1, a)) {
rv(a, ret);
}
return;
case 1 :
a = [[2, 0], [2, 1], [1, 2], [2, 2], [5, 2]];
if (lrnotout(0, a) && !reach(x, y - 1, a)) {
rv(a, ret);
}
return;
case 2 :
a = [[0, 1], [1, 1], [2, 1], [2, 2], [5, 3]];
if (lrnotout(0, a) && !reach(x, y - 1, a)) {
rv(a, ret);
}
return;
}
case 6 ://L形
switch (ret[4][1]) {
case 3 :
a = [[1, 0], [2, 0], [2, 1], [2, 2], [5, 0]];
if (lrnotout(0, a) && !reach(x, y - 1, a)) {
rv(a, ret);
}
return;
case 0 :
a = [[0, 1], [1, 1], [2, 1], [0, 2], [5, 1]];
if (lrnotout(0, a) && !reach(x, y - 1, a)) {
rv(a, ret);
}
return;
case 1 :
a = [[1, 0], [1, 1], [1, 2], [2, 2], [5, 2]];
if (lrnotout(0, a) && !reach(x, y - 1, a)) {
rv(a, ret);
}
return;
case 2 :
a = [[2, 1], [0, 2], [1, 2], [2, 2], [5, 3]];
if (lrnotout(0, a) && !reach(x, y - 1, a)) {
rv(a, ret);
}
return;
}
}
}
function generate(ret:Object) {//隨機產生方塊函數(可進一步修正)
ret[4][0] = Math.floor(Math.random() * 7);
ret[4][1] = Math.floor(Math.random() * 4);
rotate(ret);//完成方塊ret的具體形狀的賦值
}
function init() {//初始化背景、方塊、運動函數
var i:Number, j:Number;
for (i = 0; i < N; i++) {//初始化背景,邊界為219,其餘為' '
for (j = 0; j < 10; j++) {
if (i == N - 1) {
bg[i][j] = 219;
} else {
bg[i][j] = ' ';
}
}
}
for (i = 0; i < 5; i++) {//為當前方塊賦初值0
ret[i][0] = ret[i][1] = 0;
}
generate(ret);//產生當前方塊
generate(nextret);//產生下一個方塊
y = 0, x = 3, score = lines = 0, level=0;//當前位置坐標和計分系統初始化
_tetris.removeTextField();//如果從結束過的游戲恢復,刪除結束標志
display();//顯示畫面
frameflag = 0;//標示下落時間間隔
onEnterFrame = function () {
frameflag++;
if (10 - frameflag < level) {//根據等級level確定下落時間間隔
frameflag = 0;
go();//下落及判斷
}
};
}
function drawblock(a, b, c, d) {//繪制方塊的小塊
with (panel) {
beginFill(0x000FFF, 100);
lineStyle(1, 0xFF00FF);
moveTo(panel._x + a, panel._y + b);
lineTo(panel._x + c, panel._y + b);
lineTo(panel._x + c, panel._y + d);
lineTo(panel._x + a, panel._y + d);
lineTo(panel._x + a, panel._y + b);
endFill();
}
}
function erase() {//刪除一行方塊
var n:Number = 0, i:Number, j:Number, k:Number, l:Number;
for (i = 0; i < N - 1; i++) {
for (j = 0; j < 10; j++) {
if (bg[i][j] == ' ') {//如果該行有空,則開始判斷下一行
i++, j = -1;
if (i == N - 1) {//行N-1為底線,不判斷
break;
}
} else if (j == 9) {//判斷到該行最後一列都沒有空
for (k = i; k >= 1; k--) {//上方方塊下落
for (l = 0; l < 10; l++) {
bg[k][l] = bg[k - 1][l];
}
}
for (l = 0; l < 10; l++) {//刪除該行
bg[0][l] = ' ';
}
n++;//此次刪除行數變數增一
if ((lines + n) % 30 == 0) {//刪除行數總數到30的倍數則等級上升
level = (level + 1) % 10;
}
}
}
}
lines += n, score += (n * n + n) * 50;//總行數增n,計算得分
}
function display() {
//顯示函數,採用全部清除再重繪制的方法(因為這個程序本來是在Turbo C 2.0的文本環境下完成的)
var i:Number, j:Number;
panel.clear();
with (panel) {//畫邊界
lineStyle(1, 0x0000FF);
moveTo(panel._x, panel._y);
lineTo(panel._x + WIDTH * 10, panel._y);
lineTo(panel._x + WIDTH * 10, panel._y + WIDTH * (N - 1));
lineTo(panel._x, panel._y + WIDTH * (N - 1));
lineTo(panel._x, panel._y);
}
for (i = 0; i < 4; i++) {//當前方塊占據的地方賦值為邊界類型219
bg[y + ret[i][1]][x + ret[i][0]] = 219;
}
for (i = 0; i < N - 1; i++) {//繪制背景方塊
for (j = 0; j < 10; j++) {
if (bg[i][j] == 219) {
drawblock(j * WIDTH + X, i * WIDTH + Y, j * WIDTH + WIDTH + X, i * WIDTH + WIDTH + Y);
}
}
}
for (i = 0; i < 4; i++) {//繪制當前方塊
drawblock(nextret[i][0] * WIDTH + 14 * WIDTH + X, nextret[i][1] * WIDTH + 12 * WIDTH + Y, nextret[i][0] * WIDTH + WIDTH + 14 * WIDTH + X, nextret[i][1] * WIDTH + WIDTH + 12 * WIDTH + Y);
}
for (i = 0; i < 4; i++) {//當前方塊繪制完畢,重新將當前位置改為' '
bg[y + ret[i][1]][x + ret[i][0]] = ' ';
}
createTextField("_lvltxt", 1, 270, 100, 100, 20);//繪制計分系統
createTextField("_scrtxt", 2, 270, 130, 100, 20);
createTextField("_lnstxt", 3, 270, 160, 100, 20);
_lvltxt.text = "Level: " + level;
_scrtxt.text = "Score: " + score;
_lnstxt.text = "Lines: " + lines;
}
function go() {//下落函數
var sss:Number = reach(x, y, ret);//當前方塊下落一格是否碰到邊界或方塊
var ii:Number;
if (!sss) {
y++;//如果當前方塊下落一格沒有碰到邊界或方塊則下落一格
}
display();//重新繪制
if (sss) {//碰到邊界或方塊
score += 10;//得10分
display();//重新繪制
for (ii = 0; ii < 4; ii++) {//修改背景數組,將當前方塊的位置改為邊界類型
bg[y + ret[ii][1]][x + ret[ii][0]] = 219;
}
erase();//刪除行判斷及執行
rv(nextret, ret);//將下一個方塊賦值為當前方塊
y = 0, x = 3;//重置方塊位置
generate(nextret);//生成下一個方塊
display();//重新繪制
if (reach(x, y, ret)) {//如果下一格碰到方塊則游戲結束
createTextField("_tetris", 100000, WIDTH * 3.3, WIDTH * N / 3, 70, 20);
_tetris._x += 200;
_tetris._y += 50;
_tetris._xscale = 300;
_tetris._yscale = 300;
_tetris.background = true;
_tetris.text = "Game Over!";
onEnterFrame = function () {//停止下落
};
}
}
}
function key() {
if (Key.isDown(Key.UP)) {
rotate(ret);
display();
}
if (Key.isDown(Key.LEFT)) {
if (lrnotout(-1, ret)) {//左移可行性判斷
x--;
display();
}
}
if (Key.isDown(Key.RIGHT)) {
if (lrnotout(1, ret)) {//右移可行性判斷
x++;
display();
}
}
if (Key.isDown(Key.DOWN)) {//鍵盤控制下落
go();
}
if (Key.isDown(Key.SPACE)) {//一鍵下落到底
while (!reach(x, y, ret)) {
y++;
}
go();
}
if (Key.isDown(82)) { //重新開始游戲
init();
}
}
init();//初始化
setInterval(key, 80);//每個80毫秒執行一次鍵盤事件函數
createTextField("hinttxt",33324,200,20,300,50);
hinttxt.text="鍵盤鍵:上,下,左,右,R(reset),空格";

『叄』 photoshop怎麼製作俄羅斯方塊那種格子!!!!

前三步幼兒操作級別:

1,新建圖層

2,矩形選框工具,按住shift鍵,在圖上畫一個正方形(Shift鍵是為了保證長寬一致)

3,給正方形上色,然後取消螞蟻線


重點在第四步:

4.該圖層直接Fx做「斜面與浮雕」

在「斜面和浮雕」中主要調整大小,數值要根據你的方框大小來定(記得打開預覽看看你調整的結果,另外你要做的精細的話,可以再描邊上~)

然後確定,就完成了~

『肆』 如何用ps做出俄羅斯方塊的效果

先做一張九宮格,然後上色,然後復制兩份,修改節點,使其破解成3D效果,還有,格子裡面的顏色要亂,但是不能重疊,弄完後最好做一個陰影效果,那樣會更好,

『伍』 用c語言編寫俄羅斯方塊程序 求詳解

1、用C語言繪制圖形界面

EasyX圖形庫(http://www.easyx.cn)即TC的圖形庫在VC下的移植。

包含庫#include <graphics.h>

先初始化圖形窗口

initgraph(WINDOW_WIDTH, WINDOW_HIGH) ;WINDOW_WIDTH為窗口的寬頻,WINDOW_HIGH為窗口的高度。

清空繪圖設備

cleardevice();

設置畫筆顏色

setcolor(RED) ;

設置線條風格

setlinestyle(PS_SOLID, NULL, 0);

畫矩形

rectangle

還有畫線、顯示文字等函數,可以參照其幫助文檔。

注意:由於我們用的是EasyX圖形庫,故源文件後綴要為.cpp,但其中內容都是C的語法。

2、存儲表示出俄羅斯方塊的形狀

一、我們可以用編號,不同的編號代表不同的俄羅斯方塊,根據編號把不同方塊的畫法寫在代碼中,這樣19種

方塊就得有19種相應的代碼來描繪。而且這樣擴展性不好,若以後設計了新的方塊,則需要更改大量源代碼。

二、我們很自然的想到可用字模點陣的形式來表示,即設置一個4行4列的數組,元素置1即代表這個位置有小

方塊,元素置0即代表這個位置無小方塊,這個整個的4*4的數組組成俄羅斯方塊的形狀。

1000

1000

1100

0000

我們把俄羅斯方塊點陣的數位存在rockArray中,我們可以事先把這19種方塊的字模點陣自己轉化成十六進制,然後在rockArray數組的初始化時賦值進去。

但這樣做未免有點太費力,且擴展性也不太好,若以後設計的新方塊種類加入,要改變數組rockArray中的值。

我們可以考慮把所有俄羅斯方塊的點陣存儲在配置文件中,在程序初始化時讀取文件,把這些點陣轉換成unsigned int的變數存儲在rockArray中。

這樣,以後我們增添新的方塊形狀只需要在配置文件中增加新的點陣即可。

@###

@###

@@##

####(為使得看起來更醒目,我們用@表示1,用#表示0)

3、讓圖形動起來

在某位置處用函數DrawRock在屏幕上畫出俄羅斯方塊,然後再擦除掉(即用背景色在原位置處重繪一次方塊),最後在下落的下一個位置處用函數DrawRock在屏幕上畫出俄羅斯方塊,如此循環,中間用計時器間隔一段時間以控制下落的速度。

同理,按下屏幕的左右鍵也是如此,只是在按下鍵盤時把方塊的位置重新計算了。

那麼按下上方向鍵時,如何讓方塊翻轉呢?

我們在配置文件中就把方塊的順時針翻轉形態放在了一起:

@###

@###

@@##

####

@@@#

@###

####

####

@@##

#@##

#@##

####

##@#

@@@#

####

####

我們每按一次上方向鍵改變一次方塊的形狀即可。若一直按上鍵,形狀應該是循環地翻滾。

我們想到了循環鏈表的數據結構可實現這個效果。

可是我們若把這些一種類的方塊的各種形態串成循環鏈表形式,那麼每次重新生成方塊時我們就難以隨機地生成方塊了。

故還是得用數組來存儲,但又要有循環鏈表的功能,於是我們想到了靜態循環鏈表。

我們用結構體來作為一個方塊在rockArray中的元素

typedef struct ROCK

{ //用來表示方塊的形狀(每一個位元組是8位,用每4位表示方塊中的一行)

unsigned int rockShapeBits ;

int nextRockIndex ; //下一個方塊,在數組中的下標

} RockType ;

這樣,當我們按下上方向鍵時,把傳入函數DrawRock中的rockIndex變為當前方塊結構體中的nextRockIndex即可。

『陸』 如何在PPT中製作俄羅斯方塊效果

在ppt上,頁面點擊右鍵,選擇背景>填充效果>圖片>選擇圖片。你想要的。 給以俄羅斯方塊為背景的PPT模板 ,好像沒有。不過可以自己製作嘛。你截取圖片,

『柒』 java俄羅斯方塊製作方法 全面哦

代碼多了,傳不過去 分開給你傳吧
還是發你郵箱吧
下面是一部分代碼

代碼如下:
package com.tarena.tetris;//包名倒寫
//導包
import java.awt.image.BufferedImage;
/**
* 格子類
*/
public class Cell {
//1定義屬性
private int row;//行
private int col;//列
private BufferedImage image;//圖片
//2構造器
public Cell(int row, int col, BufferedImage image) {
super();
this.row = row;
this.col = col;
this.image = image;
}
//3屬性訪問方法
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public int getCol() {
return col;
}
public void setCol(int col) {
this.col = col;
}
public BufferedImage getImage() {
return image;
}
public void setImage(BufferedImage image) {
this.image = image;
}
//5移動方法
public void drop() {
row++;
}
public void moveLeft() {
col--;
}
public void moveRight() {
col++;
}
//4重寫toString
public String toString() {
return row + "," + col;
}
}

-----------------------------------------------------------------------
package com.tarena.tetris;//包名倒寫
//導包
import java.util.Arrays;
import java.util.Random;
/**
* 四格方塊類:包含七個子類T I J L S Z O
*/
public abstract class Tetromino {
//1創建四個格子
protected Cell[] cells = new Cell[4];
//9
protected State[] states;//旋轉狀態
protected int index = 10000;//旋轉狀態的序號 state[index%state.length]
//8旋轉 內部類
protected class State {
int row0,col0,row1,col1,row2,col2,row3,col3;//轉一圈 8個數
//構造器
public State(int row0, int col0, int row1, int col1, int row2,
int col2, int row3, int col3) {
super();
this.row0 = row0;
this.col0 = col0;
this.row1 = row1;
this.col1 = col1;
this.row2 = row2;
this.col2 = col2;
this.row3 = row3;
this.col3 = col3;
}
}
//10
/** 向右轉 */
public void rotateRight() {
//1取得變換的下個數據狀態state[n]
index++;
State s = states[index%states.length];
//2取得當前軸的row,col
Cell o = cells[0];
int row = o.getRow();
int col = o.getCol();
//3旋轉以後的數據=(row,col) + state[n]
cells[1].setRow(row + s.row1);
cells[1].setCol(col + s.col1);
cells[2].setRow(row + s.row2);
cells[2].setCol(col + s.col2);
cells[3].setRow(row + s.row3);
cells[3].setCol(col + s.col3);
}
//11
/** 向左轉 */
public void rotateLeft() {
//1取得變換的下個數據狀態state[n]
index--;
State s = states[index%states.length];
//2取得當前軸的row,col
Cell o = cells[0];
int row = o.getRow();
int col = o.getCol();
//3旋轉以後的數據=(row,col) + state[n]
cells[1].setRow(row + s.row1);
cells[1].setCol(col + s.col1);
cells[2].setRow(row + s.row2);
cells[2].setCol(col + s.col2);
cells[3].setRow(row + s.row3);
cells[3].setCol(col + s.col3);
}
//2工廠方法,隨機產生四個格子
public static Tetromino randomOne() {
//4隨機產生七種四格方塊
Random random = new Random();
int type = random.nextInt(7);
switch(type) {
case 0 : return new T();
case 1 : return new I();
case 2 : return new J();
case 3 : return new L();
case 4 : return new S();
case 5 : return new Z();
case 6 : return new O();
}
return null;
}
//5移動方法
public void softDrop() {
for(int i=0; i<cells.length; i++) {//迭代每一個方塊
cells[i].drop();//使每一個方塊下落
}
}
public void moveLeft() {
for(int i=0; i<cells.length; i++) {//迭代每一個方塊
cells[i].moveLeft();//使每一個方塊左移
}
}
public void moveRight() {
for(int i=0; i<cells.length; i++) {//迭代每一個方塊
cells[i].moveRight();//使每一個方塊右移
}
}
//6重寫toString
public String toStrig() {
return Arrays.toString(cells);
}
}
//3創建子類T繼承父類Tetromino
class T extends Tetromino {
//7
public T() {
cells[0] = new Cell(0,4,Tetris.T);
cells[1] = new Cell(0,3,Tetris.T);
cells[2] = new Cell(0,5,Tetris.T);
cells[3] = new Cell(1,4,Tetris.T);
//12
states = new State[4];
states[0] = new State(0,0, 0,-1, 0,1, 1,0);
states[1] = new State(0,0, -1,0, 1,0, 0,-1);
states[2] = new State(0,0, 0,1, 0,-1, -1,0);
states[3] = new State(0,0, 1,0, -1,0, 0,1);
}
}
//3創建子類I繼承父類Tetromino
class I extends Tetromino {
//7
public I() {
cells[0] = new Cell(0,4,Tetris.I);
cells[1] = new Cell(0,3,Tetris.I);
cells[2] = new Cell(0,5,Tetris.I);
cells[3] = new Cell(0,6,Tetris.I);
//12
states = new State[] {new State(0,0, 0,1, 0,-1, 0,-2),
new State(0,0, -1,0, 1,0, 2,0)};
}
}
//3創建子類J繼承父類Tetromino
class J extends Tetromino {
//7
public J() {
cells[0] = new Cell(0,4,Tetris.J);
cells[1] = new Cell(0,3,Tetris.J);
cells[2] = new Cell(0,5,Tetris.J);
cells[3] = new Cell(1,5,Tetris.J);
//12
states = new State[]{
new State(0,0, 0,-1, 0,1, 1,1),
new State(0,0, -1,0, 1,0, 1,-1),
new State(0,0, 0,1, 0,-1, -1,-1),
new State(0,0, 1,0, -1,0, -1,1)};
}
}
//3創建子類L繼承父類Tetromino
class L extends Tetromino {
//7
public L() {
cells[0] = new Cell(0,4,Tetris.L);
cells[1] = new Cell(0,3,Tetris.L);
cells[2] = new Cell(0,5,Tetris.L);
cells[3] = new Cell(1,3,Tetris.L);
//12
states = new State[]{
new State(0,0, 0,-1, 0,1, 1,-1),
new State(0,0, -1,0, 1,0, -1,-1),
new State(0,0, 0,1, 0,-1, -1,1),
new State(0,0, 1,0, -1,0, 1,1)};
}
}
//3創建子類S繼承父類Tetromino
class S extends Tetromino {
//7
public S() {
cells[0] = new Cell(0,4,Tetris.S);
cells[1] = new Cell(0,5,Tetris.S);
cells[2] = new Cell(1,3,Tetris.S);
cells[3] = new Cell(1,4,Tetris.S);
//12
states = new State[]{
new State(0,0, 0,1, 1,-1, 1,0),
new State(0,0, -1,0, 1,1, 0,1)};
}
}
//3創建子類Z繼承父類Tetromino
class Z extends Tetromino {
//7
public Z() {
cells[0] = new Cell(1,4,Tetris.Z);
cells[1] = new Cell(0,3,Tetris.Z);
cells[2] = new Cell(0,4,Tetris.Z);
cells[3] = new Cell(1,5,Tetris.Z);
//12
states = new State[]{
new State(0,0, -1,-1, -1,0, 0,1),
new State(0,0, -1,1, 0,1, 1,0)};
}
}
//3創建子類O繼承父類Tetromino
class O extends Tetromino {
//7
public O() {
cells[0] = new Cell(0,4,Tetris.O);
cells[1] = new Cell(0,5,Tetris.O);
cells[2] = new Cell(1,4,Tetris.O);
cells[3] = new Cell(1,5,Tetris.O);
//12
states = new State[]{
new State(0,0, 0,1, 1,0, 1,1),
new State(0,0, 0,1, 1,0, 1,1)};
}
}

『捌』 vb6.0如何編寫俄羅斯方塊

using System;
using System.Drawing;
using Microsoft.Win32;

namespace AnotherBlock
{
/// <summary>
/// Represents a Tetris game engine.
/// </summary>
public class Game
{
/// <summary>
/// Constant with the image width of the block unit (in pixels).
/// </summary>
public const int BlockImageWidth = 21;
/// <summary>
/// Constant with the image height of the block unit (in pixels).
/// </summary>
public const int BlockImageHeight = 21;
/// <summary>
/// Constant with the playing field width (in block units).
/// </summary>
public const int PlayingFieldWidth = 10;
/// <summary>
/// Constant with the playing field height (in block units).
/// </summary>
public const int PlayingFieldHeight = 20;
/// <summary>
/// Constante with the number of lines for each level.
/// </summary>
public const int LevelEveryLines = 12;

/// <summary>
/// Private attribute that holds the current game score.
/// </summary>
private int score = 0;
/// <summary>
/// Private attribute that holds the current game level.
/// </summary>
private short level = 1;
/// <summary>
/// Private attribute that holds the current number of completed lines.
/// </summary>
private int lines = 0;
/// <summary>
/// Private attribute that holds the current game state.
/// </summary>
private GameState gameState;
/// <summary>
/// Private attribute that holds the level where the game started.
/// </summary>
private short startLevel = 1;
/// <summary>
/// Private attribute that holds the current game pile.
/// </summary>
private Brick[,] pile = new Brick[(PlayingFieldWidth + 1), (PlayingFieldHeight + 1)];
/// <summary>
/// Private attribute that holds the current block.
/// </summary>
private Block currentBlock = new Block();
/// <summary>
/// Private attribute that holds the next block.
/// </summary>
private Block nextBlock = new Block();

/// <summary>
/// Class constructor that creates a game.
/// </summary>
public Game()
{
// Clears the game pile.
ClearPile();
}

/// <summary>
/// Class constructor that creates a game in a given level.
/// </summary>
/// <param name="level">The level where the game should start.</param>
public Game(short level)
{
// Sets the level attribute to the game level where the game should start.
this.level = level;
// Sets the startLevel attribute to the game level where the game should start.
startLevel = level;
// Clears the game pile.
ClearPile();
}

/// <summary>
/// Readonly property that holds the score of the current game.
/// </summary>
public int Score
{
get
{
// Returns the value in the score attribute.
return score;
}
}

/// <summary>
/// Readonly property that holds the level of the current game.
/// </summary>
public short Level
{
get
{
// Returns the value in the level attribute.
return level;
}
}

/// <summary>
/// Readonly property that holds the number of complete lines in the current game.
/// </summary>
public int Lines
{
get
{
// Returns the value in the lines attribute.
return lines;
}
}

/// <summary>
/// Property that holds and sets the current game state.
/// </summary>
/// <remarks>
/// The game state can be "Running", "Paused" or "Over".
/// </remarks>
public GameState GameState
{
get
{
// Returns the value in the gameState attribute.
return gameState;
}
set
{
// Checks if the current game state is "Over", and if the value to change is not "Over".
if ((gameState == GameState.Over) && (value != GameState.Over))
{
// The current game state is "Over", and it's changing to something else than "Over".
// Resets the score, level and lines.
score = 0;
level = startLevel;
lines = 0;
// Creates a new current block, and a new next block.
currentBlock = new Block();
nextBlock = new Block();
// Clears the game pile.
ClearPile();
}

// Sets the gameState attribute to the value.
gameState = value;
}
}

/// <summary>
/// Method that moves the current block down one position.
/// </summary>
/// <returns>True if there was a hit on the ground or on the pile, false if there wasn't.</returns>
public bool MoveCurrentBlockDown()
{
// Creates a "hit" flag, to check if the block has hit the pile or the ground.
bool hit = false;

// Increases the Top of the current block.
currentBlock.Top++;

// Checks if the current block has hit the ground.
// COLLISION DETECTION
if ((currentBlock.Top + currentBlock.Height) > PlayingFieldHeight)
{
// Current block has hit the ground.
// Sets the "hit" flag to "true".
hit = true;
}
else
{
// Checks if the current block has hit the pile.
// COLLISION DETECTION
for(int i = 0; i < currentBlock.Width; i++)
{
for(int j = 0; j < currentBlock.Height; j++)
{
int fx, fy;
fx = currentBlock.Left + i;
fy = currentBlock.Top + j;
if ((currentBlock.Shape[i, j].Filled == true) && (pile[fx, (fy + 1)].Filled == true))
{
// Current block has hit the pile.
// Sets the "hit" flag to "true".
hit = true;
}
}
}
}

// Checks if there was a hit.
if (hit)
{
// There was a hit.
// Puts the current block in the pile.
MoveBlockToPile();
// Checks if the current game state is not "Over".
if (this.GameState != GameState.Over)
{
// Current game state is not "Over".
// Creates a new block.
CreateNewBlock();
}
}

// Returns if there was a hit or not.
return hit;
}

/// <summary>
/// Method that moves the current block down until there is a hit.
/// </summary>
public void ()
{
// Moves the current block down until it has a hit.
while(!MoveCurrentBlockDown());
}

/// <summary>
/// Method that rotates the current block.
/// </summary>
/// <param name="clockwise">True if the block will be rotated clockwise, false if counterclockwise.</param>
public void RotateCurrentBlock(bool clockwise)
{
// Creates a "canRotate" flag, to check if the block can be rotated.
bool canRotate = true;

// Rotates the current block.
// This should be different. There should be an easy way to check FIRST if the block could
// be rotated, and then rotate it. I'll study this later.
currentBlock.Rotate(clockwise);

// Checks if the current block could be rotated.
// COLLISION DETECTION
for(int i = 0; i < currentBlock.Width; i++)
{
for(int j = 0; j < currentBlock.Height; j++)
{
int fx, fy;
fx = currentBlock.Left + i;
fy = (currentBlock.Top + 1) + j;
if ((currentBlock.Shape[i, j].Filled == true) && (pile[fx, fy].Filled == true))
{
// Current block can't be rotated.
// Sets the "canRotate" flag to "false".
canRotate = false;
}
}
}

// Checks if the block can't be rotated.
if (!canRotate)
{
// Block can't be rotated.
// Rotates the block back to its first position.
currentBlock.Rotate(!clockwise);
}
}

/// <summary>
/// Method that moves the current block to the right or to the left.
/// </summary>
/// <param name="left">True if the block will be moved to the left, false if to the right.</param>
public void MoveCurrentBlockSide(bool left)
{
// Creates a "canMove" flag, to check if the block can be moved to the sides.
bool canMove = true;

// Checks if the block is to be moved to the left.
if (left)
{
// The block is to be moved to the left.
// Checks if the block is not already at the most left of the playing field.
if (currentBlock.Left > 0)
{
// Block is not at the most left of the playing field.
// Checks if the current block can move to the left.
// COLLISION DETECTION
for(int i = 0; i < currentBlock.Width; i++)
{
for(int j = 0; j < currentBlock.Height; j++)
{
int fx, fy;
fx = currentBlock.Left + i;
fy = (currentBlock.Top + 1) + j;
if ((currentBlock.Shape[i, j].Filled == true) && (pile[(fx - 1), fy].Filled == true))
{
// Current block can't move to the left.
// Sets the "canMove" flag to "false".
canMove = false;
}
}
}

// Checks if the block can be moved to the left.
if (canMove)
{
// Block can be moved to the left.
// Moves the block to the left.
currentBlock.Left--;
}
}
}
else
{
// The block is not to be moved to the left (it is to be moved to the right).
// Checks if the block is not already at the most right of the playing field.
if ((currentBlock.Left + currentBlock.Width) < PlayingFieldWidth)
{
// Block is not at the most right of the playing field.
// Checks if the current block can move to the right.
// COLLISION DETECTION
for(int i = 0; i < currentBlock.Width; i++)
{
for(int j = 0; j < currentBlock.Height; j++)
{
int fx, fy;
fx = currentBlock.Left + i;
fy = (currentBlock.Top + 1) + j;
if ((currentBlock.Shape[i, j].Filled == true) && (pile[(fx + 1), fy].Filled == true))
{
// Current block can't move to the right.
// Sets the "canMove" flag to "false".
canMove = false;
}
}
}

// Checks if the block can be moved to the right.
if (canMove)
{
// Block can be moved to the right.
// Moves the block to the right.
currentBlock.Left++;
}
}
}
}

/// <summary>
/// Method that draws the pile in a surface.
/// </summary>
/// <param name="drawingSurface">The graphics surface where the pile will be drawn.</param>
public void DrawPile(Graphics drawingSurface)
{
// Runs through the playing field Width.
for (int i = 0; i < (PlayingFieldWidth + 1); i++)
{
// Runs through the playing field Height.
for (int j = 0; j < (PlayingFieldHeight + 1); j++)
{
// Checks if the current brick of the pile is set to be solid.
if (pile[i, j].Filled == true)
{
// Current brick of the pile is set to be solid.
// Creates a rectangle in the right position of this brick.
Rectangle rect = new Rectangle(i * BlockImageWidth, (j - 1) * BlockImageHeight, BlockImageWidth, BlockImageHeight);
// Draws the block image in the just created rectangle.
drawingSurface.DrawImage(pile[i, j].BrickImage, rect);
}
}
}
}

/// <summary>
/// Method that draws the current block in a surface.
/// </summary>
/// <param name="drawingSurface">The graphics surface where the current block will be drawn.</param>
public void DrawCurrentBlock(Graphics drawingSurface)
{
// Checks if there is a current block.
if (currentBlock != null)
{
// There is a current block.
// Draws the current block in the drawing surface.
currentBlock.Draw(drawingSurface);
}
}

/// <summary>
/// Method that draws the next block in a surface.
/// </summary>
/// <param name="drawingSurface">The graphics surface where the current block will be drawn.</param>
public void DrawNextBlock(Graphics drawingSurface)
{
// Checks if there is a next block.
if (nextBlock != null)
{
// There is a next block.
// Saves the current Left and Top properties of the next block.
short currentLeft = nextBlock.Left;
short currentTop = nextBlock.Top;

// Changes the current Left and Top properties of the next block, so they can be shown
// in the center of a drawing surface that has a size of 6x6 blocks.
nextBlock.Left = (short)((6 - nextBlock.Width) / 2);
nextBlock.Top = (short)((6 - nextBlock.Height) / 2);

// Draws the next block in the drawing surface.
nextBlock.Draw(drawingSurface);

// Retrieves the previously saved Left and Top properties, and put them back in the next block.
nextBlock.Left = currentLeft;
nextBlock.Top = currentTop;
}
}

/// <summary>
/// Private method that clears the current game pile.
/// </summary>
private void ClearPile()
{
// Runs through the playing field Width.
for(int i = 0; i < (PlayingFieldWidth + 1); i++)
{
// Runs through the playing field Height.
for(int j = 0; j < (PlayingFieldHeight + 1); j++)
{
// Clears the current brick of the pile.
pile[i, j].Filled = false;
}
}
}

/// <summary>
/// Private method that creates a new current block by getting it from the next block,
/// and creates a new random next block.
/// </summary>
private void CreateNewBlock()
{
// Checks if there is a next block.
if (this.nextBlock != null)
{
// There is a next block.
// Sets the current block to the next block.
currentBlock = nextBlock;
}
else
{
// There isn't a next block.
// Sets the current block as a new random block.
currentBlock = new Block();
}

// Sets the next block as a new random block.
nextBlock = new Block();
}

/// <summary>
/// Private method that moves the current block to the game pile.
/// While moving the block to the pile, it checks if there are complete lines, and count them, in
/// order to update the score, the lines and the level. It also checks for game over.
/// </summary>
private void MoveBlockToPile()
{
// Runs through the current block Width.
for(int i = 0; i < currentBlock.Width; i++)
{
// Runs through the current block Height.
for(int j = 0; j < currentBlock.Height; j++)
{
// Converts the current brick position the a playing field position.
int fx, fy;
fx = currentBlock.Left + i;
fy = currentBlock.Top + j;
// Checks if the current brick is solid.
if (currentBlock.Shape[i, j].Filled == true)
{
// The current brick is solid.
// Moves the current brick to the pile.
pile[fx, fy].Filled = true;
pile[fx, fy].BrickImage = currentBlock.Shape[i, j].BrickImage;
}
}
}

// Checks for complete lines.
CheckForLines();

// Checks for game over.
CheckForGameOver();
}

/// <summary>
/// Private method that checks the pile for complete lines.
/// </summary>
/// <returns>The number of found lines.</returns>
private int CheckForLines()
{
// Creates a variable that will hold the number of lines found.
int numLines = 0;
// Creates a variable that will hold the number of the complete lines found.
int[] completeLines = new int[PlayingFieldHeight];

// Runs through the playing field lines.
for (int j = PlayingFieldHeight; j > 0; j--)
{
// Checks if there is a complete line.
bool fullLine = true;

for (int i = 0; i < PlayingFieldWidth; i++)
{
if (pile[i, j].Filled == false)
{
fullLine = false;
break;
}
}

// Checks if there was a complete line.
if (fullLine)
{
// There was a complete line.
// Increases the number of complete lines found.
numLines++;
// Pauses the game so no block will come down while clearing the complete line.
this.GameState = GameState.Paused;
// Holds the number of the complete line found.
completeLines[numLines] = j;
// Sets the game state to "Running" again, to release the game.
this.GameState = GameState.Running;
}
}

// Checks if there were any complete lines.
if (numLines > 0)
{
// There were complete lines.
// Runs through all the complete lines, and clears them.
for(int i = 1; i <= numLines; i++)
{
// Clear a complete line.
ClearLine((completeLines[i] + (i - 1)));
}
// Updates the game score, lines and level.
score += 5 * (numLines * (numLines + 1));
lines += numLines;
level = (short)((lines / LevelEveryLines) + startLevel);
}

// Returns the number of complete lines.
return numLines;
}

/// <summary>
/// Private method that checks the pile for game over.
/// </summary>
private void CheckForGameOver()
{
// Checks if the top of the current block is on the top of the pile.
if (currentBlock.Top == 1)
{
// Current block is on the top the the pile.
// Sets the game state to "Over".
this.GameState = GameState.Over;
}
}

/// <summary>
/// Private method that clears a line from the pile.
/// </summary>
/// <param name="lineNumber">The number of the line to be cleared.</param>
private void ClearLine(int lineNumber)
{
// Runs through all the lines, from the line to be cleared up.
for (int j = lineNumber; j > 0; j--)
{
// Runs through all the bricks in one line.
for (int i = 0; i < PlayingFieldWidth; i++)
{
// Move the current brick down.
pile[i, j] = pile[i, (j - 1)];
}
}

// Runs through the top line bricks.
for (int i = 0; i < PlayingFieldWidth; i++)
{
// Sets the current brick to empty.
pile[i, 0].Filled = false;
}
}
}
}

這是其中之一最重要的部分,要全部代碼給我發郵件
[email protected]

『玖』 怎樣用c語言編寫俄羅斯方塊程序

俄羅斯方塊C源代碼

#include<stdio.h>

#include<windows.h>

#include<conio.h>

#include<time.h>

#defineZL4 //坐標增量,不使游戲窗口靠邊

#defineWID36 //游戲窗口的寬度

#defineHEI20 //游戲窗口的高度

inti,j,Ta,Tb,Tc; //Ta,Tb,Tc用於記住和轉換方塊變數的值

inta[60][60]={0}; //標記游戲屏幕各坐標點:0,1,2分別為空、方塊、邊框

intb[4]; //標記4個"口"方塊:1有,0無,類似開關

intx,y,level,score,speed; //方塊中心位置的x,y坐標,游戲等級、得分和游戲速度

intflag,next; //當前要操作的方塊類型序號,下一個方塊類型序號

voidgtxy(intm,intn); //以下聲明要用到的自編函數

voidgflag(); //獲得下一方塊序號

voidcsh(); //初始化界面

voidstart(); //開始部分

voidprfk(); //列印方塊

voidclfk(); //清除方塊

voidmkfk(); //製作方塊

voidkeyD(); //按鍵操作

intifmov(); //判斷方塊能否移動或變體

void clHA(); //清除滿行的方塊

voidclNEXT(); //清除邊框外的NEXT方塊

intmain()

{csh();

while(1)

{start();//開始部分

while(1)

{prfk();

Sleep(speed); //延時

clfk();

Tb=x;Tc=flag;//臨存當前x坐標和序號,以備撤銷操作

keyD();

y++;//方塊向下移動

if(ifmov()==0){y--;prfk();dlHA();break;}//不可動放下,刪行,跨出循環

}

for(i=y-2;i<y+2;i++){if(i==ZL){j=0;}} //方塊觸到框頂

if(j==0){system("cls");gtxy(10,10);printf("游戲結束!");getch();break;}

clNEXT(); //清除框外的NEXT方塊

}

return0;

}

voidgtxy(intm,intn)//控制游標移動

{COORDpos;//定義變數

pos.X=m;//橫坐標

pos.Y=n;//縱坐標

SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);

}

voidcsh()//初始化界面

{gtxy(ZL+WID/2-5,ZL-2);printf("俄羅斯方塊");//列印游戲名稱

gtxy(ZL+WID+3,ZL+7);printf("*******NEXT:");//列印菜單信息

gtxy(ZL+WID+3,ZL+13);printf("**********");

gtxy(ZL+WID+3,ZL+15);printf("Esc:退出遊戲");

gtxy(ZL+WID+3,ZL+17);printf("↑鍵:變體");

gtxy(ZL+WID+3,ZL+19);printf("空格:暫停游戲");

gtxy(ZL,ZL);printf("╔");gtxy(ZL+WID-2,ZL);printf("╗");//列印框角

gtxy(ZL,ZL+HEI);printf("╚");gtxy(ZL+WID-2,ZL+HEI);printf("╝");

a[ZL][ZL+HEI]=2;a[ZL+WID-2][ZL+HEI]=2;//記住有圖案

for(i=2;i<WID-2;i+=2){gtxy(ZL+i,ZL);printf("═");}//列印上橫框

for(i=2;i<WID-2;i+=2){gtxy(ZL+i,ZL+HEI);printf("═");a[ZL+i][ZL+HEI]=2;}//下框

for(i=1;i<HEI;i++){gtxy(ZL,ZL+i);printf("║");a[ZL][ZL+i]=2;}//左豎框記住有圖案

for(i=1;i<HEI;i++){gtxy(ZL+WID-2,ZL+i);printf("║");a[ZL+WID-2][ZL+i]=2;}//右框

CONSOLE_CURSOR_INFOcursor_info={1,0};//以下是隱藏游標的設置

SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);

level=1;score=0;speed=400;

gflag();flag=next;//獲得一個當前方塊序號

}

voidgflag() //獲得下一個方塊的序號

{srand((unsigned)time(NULL));next=rand()%19+1; }

voidstart()//開始部分

{gflag();Ta=flag;flag=next;//保存當前方塊序號,將下一方塊序號臨時操作

x=ZL+WID+6;y=ZL+10;prfk();//給x,y賦值,在框外列印出下一方塊

flag=Ta;x=ZL+WID/2;y=ZL-1;//取回當前方塊序號,並給x,y賦值

}

voidprfk()//列印俄羅斯方塊

{for(i=0;i<4;i++){b[i]=1;}//數組b[4]每個元素的值都為1

mkfk();//製作俄羅斯方塊

for(i=x-2;i<=x+4;i+=2)//列印方塊

{for(j=y-2;j<=y+1;j++){if(a[i][j]==1&&j>ZL){gtxy(i,j);printf("□");}}}

gtxy(ZL+WID+3,ZL+1); printf("level:%d",level); //以下列印菜單信息

gtxy(ZL+WID+3,ZL+3); printf("score:%d",score);

gtxy(ZL+WID+3,ZL+5); printf("speed:%d",speed);

}

voidclfk()//清除俄羅斯方塊

{for(i=0;i<4;i++){b[i]=0;}//數組b[4]每個元素的值都為0

mkfk();//製作俄羅斯方塊

for(i=x-2;i<=x+4;i+=2)//清除方塊

{for(j=y-2;j<=y+1;j++){if(a[i][j]==0&&j>ZL){gtxy(i,j);printf("");}}}

}

voidmkfk()//製作俄羅斯方塊

{a[x][y]=b[0];//方塊中心位置狀態:1-有,0-無

switch(flag)//共6大類,19種小類型

{case1:{a[x][y-1]=b[1];a[x+2][y-1]=b[2];a[x+2][y]=b[3];break;}//田字方塊

case2:{a[x-2][y]=b[1];a[x+2][y]=b[2];a[x+4][y]=b[3];break;}//直線方塊:----

case3:{a[x][y-1]=b[1];a[x][y-2]=b[2];a[x][y+1]=b[3];break;}//直線方塊:|

case4:{a[x-2][y]=b[1];a[x+2][y]=b[2];a[x][y+1]=b[3];break;}//T字方塊

case5:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x-2][y]=b[3];break;}//T字順時針轉90度

case6:{a[x][y-1]=b[1];a[x-2][y]=b[2];a[x+2][y]=b[3];break;}//T字順轉180度

case7:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x+2][y]=b[3];break;}//T字順轉270度

case8:{a[x][y+1]=b[1];a[x-2][y]=b[2];a[x+2][y+1]=b[3];break;}//Z字方塊

case9:{a[x][y-1]=b[1];a[x-2][y]=b[2];a[x-2][y+1]=b[3];break;}//Z字順轉90度

case10:{a[x][y-1]=b[1];a[x-2][y-1]=b[2];a[x+2][y]=b[3];break;}//Z字順轉180度

case11:{a[x][y+1]=b[1];a[x+2][y-1]=b[2];a[x+2][y]=b[3];break;}//Z字順轉270度

case12:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x-2][y-1]=b[3];break;}//7字方塊

case13:{a[x-2][y]=b[1];a[x+2][y-1]=b[2];a[x+2][y]=b[3];break;}//7字順轉90度

case14:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x+2][y+1]=b[3];break;}//7字順轉180度

case15:{a[x-2][y]=b[1];a[x-2][y+1]=b[2];a[x+2][y]=b[3];break;}//7字順轉270度

case16:{a[x][y+1]=b[1];a[x][y-1]=b[2];a[x+2][y-1]=b[3];break;}//倒7字方塊

case17:{a[x-2][y]=b[1];a[x+2][y+1]=b[2];a[x+2][y]=b[3];break;}//倒7字順轉90度

case18:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x-2][y+1]=b[3];break;}//倒7字順轉180度

case19:{a[x-2][y]=b[1];a[x-2][y-1]=b[2];a[x+2][y]=b[3];break;}//倒7字順轉270度

}

}

voidkeyD()//按鍵操作

{if(kbhit())

{intkey;

key=getch();

if(key==224)

{key=getch();

if(key==75){x-=2;}//按下左方向鍵,中心橫坐標減2

if(key==77){x+=2;}//按下右方向鍵,中心橫坐標加2

if(key==72)//按下向上方向鍵,方塊變體

{if(flag>=2&&flag<=3){flag++;flag%=2;flag+=2;}

if(flag>=4&&flag<=7){flag++;flag%=4;flag+=4;}

if(flag>=8&&flag<=11){flag++;flag%=4;flag+=8;}

if(flag>=12&&flag<=15){flag++;flag%=4;flag+=12;}

if(flag>=16&&flag<=19){flag++;flag%=4;flag+=16;}}

}

if(key==32)//按空格鍵,暫停

{prfk();while(1){if(getch()==32){clfk();break;}}} //再按空格鍵,繼續游戲

if(ifmov()==0){x=Tb;flag=Tc;} //如果不可動,撤銷上面操作

else{prfk();Sleep(speed);clfk();Tb=x;Tc=flag;} //如果可動,執行操作

}

}

intifmov()//判斷能否移動

{if(a[x][y]!=0){return0;}//方塊中心處有圖案返回0,不可移動

else{if((flag==1&&(a[x][y-1]==0&&a[x+2][y-1]==0&&a[x+2][y]==0))||

(flag==2&&(a[x-2][y]==0&&a[x+2][y]==0&&a[x+4][y]==0))||

(flag==3&&(a[x][y-1]==0&&a[x][y-2]==0&&a[x][y+1]==0))||

(flag==4&&(a[x-2][y]==0&&a[x+2][y]==0&&a[x][y+1]==0))||

(flag==5&&(a[x][y-1]==0&&a[x][y+1]==0&&a[x-2][y]==0))||

(flag==6&&(a[x][y-1]==0&&a[x-2][y]==0&&a[x+2][y]==0))||

(flag==7&&(a[x][y-1]==0&&a[x][y+1]==0&&a[x+2][y]==0))||

(flag==8&&(a[x][y+1]==0&&a[x-2][y]==0&&a[x+2][y+1]==0))||

(flag==9&&(a[x][y-1]==0&&a[x-2][y]==0&&a[x-2][y+1]==0))||

(flag==10&&(a[x][y-1]==0&&a[x-2][y-1]==0&&a[x+2][y]==0))||

(flag==11&&(a[x][y+1]==0&&a[x+2][y-1]==0&&a[x+2][y]==0))||

(flag==12&&(a[x][y-1]==0&&a[x][y+1]==0&&a[x-2][y-1]==0))||

( flag==13 && ( a[x-2][y]==0 && a[x+2][y-1]==0 && a[x+2][y]==0 ) ) ||

( flag==14 && ( a[x][y-1]==0 && a[x][y+1]==0 && a[x+2][y+1]==0 ) ) ||

(flag==15 && ( a[x-2][y]==0 && a[x-2][y+1]==0 && a[x+2][y]==0 ) ) ||

(flag==16 && ( a[x][y+1]==0 && a[x][y-1]==0 && a[x+2][y-1]==0 ) ) ||

( flag==17 && ( a[x-2][y]==0 && a[x+2][y+1]==0 && a[x+2][y]==0 ) ) ||

(flag==18 && ( a[x][y-1]==0 &&a[x][y+1]==0 && a[x-2][y+1]==0 ) ) ||

(flag==19 && ( a[x-2][y]==0 && a[x-2][y-1]==0

&&a[x+2][y]==0))){return1;}

}

return0; //其它情況返回0

}

voidclNEXT() //清除框外的NEXT方塊

{flag=next;x=ZL+WID+6;y=ZL+10;clfk();}

void clHA() //清除滿行的方塊

{intk,Hang=0; //k是某行方塊個數,Hang是刪除的方塊行數

for(j=ZL+HEI-1;j>=ZL+1;j--)//當某行有WID/2-2個方塊時,則為滿行

{k=0;for(i=ZL+2;i<ZL+WID-2;i+=2)

{if(a[i][j]==1)//豎坐標從下往上,橫坐標由左至右依次判斷是否滿行

{k++; //下面將操作刪除行

if(k==WID/2-2) { for(k=ZL+2;k<ZL+WID-2;k+=2)

{a[k][j]=0;gtxy(k,j);printf("");Sleep(1);}

for(k=j-1;k>ZL;k--)

{for(i=ZL+2;i<ZL+WID-2;i+=2)//已刪行數上面有方塊,先清除再全部下移一行

{if(a[i][k]==1){a[i][k]=0;gtxy(i,k);printf("");a[i][k+1]=1;

gtxy(i,k+1);printf("□");}}

}

j++;//方塊下移後,重新判斷刪除行是否滿行

Hang++;//記錄刪除方塊的行數

}

}

}

}

score+=100*Hang; //每刪除一行,得100分

if(Hang>0&&(score%500==0||score/500>level-1)) //得分滿500速度加快升一級

{speed-=20;level++;if(speed<200)speed+=20; }

}

『拾』 俄羅斯方塊怎麼做(要思想)

不要留空的

閱讀全文

與如何製作俄羅斯方塊培學長相關的資料

熱點內容
金華義烏國際商貿城雨傘在哪個區 瀏覽:777
俄羅斯如何打通飛地立陶宛 瀏覽:1151
韓國如何應對流感 瀏覽:934
在德國愛他美白金版賣多少錢 瀏覽:972
澳大利亞養羊業為什麼發達 瀏覽:1413
如何進入法國高等學府 瀏覽:1488
巴西龜喂火腿吃什麼 瀏覽:1421
巴西土地面積多少萬平方千米 瀏覽:1281
巴西龜中耳炎初期要用什麼葯 瀏覽:1244
國際為什麼鋅片如此短缺 瀏覽:1647
巴西是用什麼規格的電源 瀏覽:1471
在中國賣的法國名牌有什麼 瀏覽:1371
在菲律賓投資可用什麼樣的居留條件 瀏覽:1283
德國被分裂為哪些國家 瀏覽:892
澳大利亞跟團簽證要什麼材料 瀏覽:1227
德國大鵝節多少錢 瀏覽:887
去菲律賓過關時會盤問什麼 瀏覽:1212
澳大利亞女王為什麼是元首 瀏覽:1042
有什麼免費的韓國小說軟體 瀏覽:770
申請德國學校如何找中介 瀏覽:677