❶ 關於俄羅斯方塊的寫法
最好辦法就是在網上搜一些關與俄羅斯方塊的演算法,再看看別人的源代碼。
❷ java初級俄羅斯方塊寫法
1:首先自己定義一個類,比如MyLabel,繼承jlabel,設置大小比如 (40,40)設置成方塊,這就是游戲裡面最小的單位,下落的圖形,就是四個這個樣的單位組合到一起,位置不同。
2:定義自己的圖形(就是游戲中下落的部分)比如MyPic ,這個類是控制MyLabel的,一般是4個MyLabel組合成一個MyPic,
3:定義自己的面板,大小是 (n*40,m*40 )就是上面最小單位的整數行和列,然後建一個二位數組
int [n][m],數組裡面默認為0,標示這個位置沒有MyLabel ,是空的,如果位置有 MyLabel,設置成1
,這個是數組是,圖形下落的時候判斷是否繼續下落還是要停下了,下面有了就停,否則繼續下落,下落停止後,根據數組,看某一行是否全部為1 是的話,把這行清空
圖形的下落要用定時器或者自己寫線程實現,然後就是判斷下面是否有東西,是下落,還是停止,
圖形的旋轉的話,自己研究吧,位置的變換,也不好做
❸ 俄羅斯方塊論文怎麼寫
5月15日 16:34 游戲起源、歷史、簡介
俄羅斯方塊是一款風靡全球的電視游戲機和掌上游戲機游戲,它曾經造成的轟動與造成的經濟價值可以說是游戲史上的一件大事。這款游戲最初是由蘇聯的游戲製作人Alex Pajitnov製作的,它看似簡單但卻變化無窮,令人上癮。相信大多數用戶都還記得為它痴迷得茶不思飯不想的那個俄羅斯方塊時代。
究其歷史,俄羅斯方塊最早還是出現在PC機上,而我國的用戶都是通過紅白機了解、喜歡上它的。現在聯眾又將重新掀起這股讓人沉迷的俄羅斯方塊風潮。對一般用戶來說,它的規則簡單,容易上手,且游戲過程變化無窮,而在"聯眾俄羅斯方塊"中,更有一些聯眾網路游戲所獨有的魅力――有單機作戰與兩人在線對戰兩種模式,用戶可任選一種進行游戲。網路模式還增加了積分制,使用戶既能感受到游戲中的樂趣,也給用戶提供了一個展現自己高超技藝的場所。
★★ 一些和俄羅斯方塊有關的故事
俄羅斯方塊操作簡單,難度卻不低。作為家喻戶曉老少皆宜的大眾游戲,時至今日玩游戲的人(以及許多不怎麼玩游戲的人)中誰要是不知道的話可真所謂是火星上的熊貓了。但是,誰知道這么優秀的娛樂工具,出自哪位神人之手呢?
顧名思義,俄羅斯方塊自然是俄羅斯人發明的。這位偉人叫做阿列克謝·帕基特諾夫(Alexey Patnov) 。
然而,很少有人知道,這個著名的游戲在80年代曾經在法律界掀起軒然大波,那就是著名的俄羅斯方塊產權之爭。這次產權爭奪,幾家歡喜,幾家哀愁,幾家公司倒閉,幾家公司賺錢,其中的是是非非,一言難盡。
1985年6月
工作於莫斯科科學計算機中心的阿列克謝·帕基特諾夫在玩過一個拼圖游戲之後受到啟發,從而製作了一個以Electronica 60(一種計算機)為平台的俄羅斯方塊的游戲。後來經瓦丁·格拉西莫夫(Vadim Gerasimov)移植到PC上,並且在莫斯科的電腦界傳播。帕基特諾夫因此開始小有名氣。
1986年7月
PC版俄羅斯方塊在匈牙利的布達佩斯被當地的一群電腦專家移植到了Apple II 和 Commodore 64 上,這些版本的軟體引起了當時英國一個叫Andromeda的游戲公司經理羅伯特·斯坦恩(Robert Stein)的注意,他向帕基特諾夫以及匈牙利的電腦專家們收購了俄羅斯方塊的版權,並且在買到版權之前把它們倒手賣給了英國的Mirrorsoft (注意不是Microsoft!) 以及美國的Spectrum Holobyte。
1986年11月
斯坦恩和帕基特諾夫經過談判,就版權收購問題未取得成果。斯坦恩甚至直接飛到莫斯科和帕基特諾夫面談,但是空手而歸。由於俄羅斯人對於已經在西方興起的電子游戲產業知道不多,斯坦恩決定竊取Tetris的版權,於是他放出謠言說這是匈牙利人開發的游戲。
與此同時,PC版的俄羅斯方塊已經由英國的Mirrorsoft出品並且在歐洲銷售,受到當時人們的極大關注。不僅僅因為這個游戲好玩,而且這是「第一個來自鐵幕國家的游戲。」當時的游戲宣傳海報上有濃郁的冷戰色彩,比如戰爭畫面,加加林太空飛行等。而斯坦恩仍然沒有正式合法的版權。
1987年6月
斯坦恩最終取得了在IBM-PC及其兼容機上的Tetris的版權,版權機種包括「其他任何電腦系統」。但是,他沒有和蘇聯方面簽署協議,也就是說,這個版權是不完全的。(註: 這個「其他任何電腦系統」在原文中的描述是any other computer system,這種說法在當時看來也很不嚴密,從而為後來的產權之爭埋下了伏筆)
1988年1月
Tetris在電腦平台的熱銷,一時造成「洛陽紙貴」(倫敦磁碟貴??)的局面。而當CBS晚報采訪了俄羅斯方塊之父帕基特諾夫之後,斯坦恩盜竊版權的計劃徹底泡湯了。一個新的公司ELORG(Electronorgtechinca,蘇聯一家軟體公司)開始和斯坦恩就游戲程序問題進行協商。ELORG的負責人亞歷山大·阿列欣科( Alexander Alexinko)知道斯坦恩雖然沒有版權,但是會以手中的游戲開發程序為籌碼威脅中斷談判。
1988年5月
經過幾個月的爭吵之後,筋疲力盡的斯坦恩終於和ELORG簽定了PC俄羅斯方塊版權的合約。當時的合約禁止開發街機版和掌機版的方塊游戲,而電腦版的Tetris則成為當時最暢銷的游戲。
1988年7月
斯坦恩與阿列欣科商談開發街機版俄羅斯方塊的問題。阿列欣科當時尚未從斯坦恩那裡拿到一分錢的版權費,但是同時的Spectrum 和 Mirrorsoft已經開始向電子游戲商出售了俄羅斯方塊的版權。Spectrum 將Tetris的游戲機和PC在日本的版權賣給了Bullet-Proof Software (FC和GB版俄羅斯方塊的製作商),而Mirrorsoft則把它在日本和北美的版權賣給了美國的Atari。這樣一來兩家公司的矛盾就開始了。1988年11月,BPS在FC上發行的俄羅斯方塊(大家不很熟悉的俄羅斯方塊1)在日本發售,銷量達200萬份。
1988年11月
隨著GB的開發,NOA(任天堂美國分公司)的經理荒川實(任天堂山內溥老爺子的女婿)希望將Tetris做成GB上的游戲。於是他聯系了BPS的總裁亨克·羅傑斯(Henk Rogers),羅傑斯再與斯坦恩聯系的時候卻吃了閉門羹。於是他直接去莫斯科購買版權。而斯坦恩覺察出風頭,也乘飛機前往莫斯科;與此同時,Spectrum的負責人羅伯特·麥克斯韋(Robert Maxwell)的兒子凱文·麥克斯韋(Kevin Maxwell) 也在向莫斯科進發。就這樣,三路人馬幾乎在同時趕到了冰天雪地的紅色都市。
1989年2月21日
羅傑斯首先會見了ELORG的代表葉甫蓋尼·別里科夫(Evgeni Belikov,和那個「裝在套子里的人」同名)。他給帕基特諾夫等蘇聯人留下了深刻印象,並且簽了手掌機方塊游戲的版權。之後他向俄國人展示了FC版Tetris,這使別里科夫極為震驚。因為他並沒有授予羅傑斯家用機的版權!羅傑斯則向他們說這是向TENGEN購買的版權,但是別里科夫也從來聽說過TENGEN這個公司的名字。羅傑斯為了緩和尷尬的局面,將斯坦恩隱瞞的事實如數告訴了別里科夫,並且答應付給蘇聯方面更多支票作為已經賣出的FC版俄羅斯方塊的版權費用。這時羅傑斯發現自己有機會買到Tetris全部機種的版權(但是當時還沒買),雖然Atari會對他虎視耽耽,但是別忘了,他和BPS的背後還有任天堂這個大靠山給自己撐腰。
注意:羅伯特·斯坦恩原先所簽的協議只是電腦版Tetris的版權,其他的版權並不是他的。
後來,斯坦恩和ELORG重新簽署了協議。別里科夫強迫他重簽的合約中修改的內容是:「電腦的定義:包含有中央處理器,監視器,磁碟驅動器,鍵盤和操作系統的機器」。而斯坦恩當時卻沒有仔細看這些定義。(這回輪到他犯混了……)後來他才意識到這是羅傑斯從自己手中搶走版權而耍的花招。但是為時已晚。第二天他被告知雖然簽署的文件已經不能改過來,但是他還可以得到街機版Tetris的開發權。三天之後,他簽下了街機版的協議。
1989年2月22日
凱文·麥克斯韋訪問了ELORG。別里科夫拿出羅傑斯給他的FC游戲卡向他詢問這件事情。麥克斯韋在卡帶上看到了Mirrorsoft的名字後才想起他的公司已經把部分版權倒賣給了Atari。(糊塗人辦糊塗事……)當他想繼續談街機和手掌機版權的問題的時候,卻發現他自己能夠簽的,就只有除電腦,街機,家用機和掌機以外的協議了。(其實等於沒有協議可簽,除非他發明一種新的娛樂系統,比方說俄羅斯方塊積木……)在糊塗之餘這傢伙靈機一動,告訴別里科夫說此卡帶為盜版(汗……),然後也要簽家用機的協議。
最後的結果是:凱文·麥克斯韋只帶走一張白紙,羅伯特·斯坦恩帶走了街機協議書。由於麥克斯韋聲稱所有的FC卡都是盜版,ELORG保留了家用機的版權,沒賣給任何人。假如麥克斯韋想獲得家用機版權的話,就必須出價比任天堂高才行。亨克·羅傑斯買到了掌機的版權,並且通知了荒川實。BPS就製作GB版Tetris向任天堂達成交易:這筆交易額高大500萬-1000萬美元。
1989年3月15日
亨克·羅傑斯回到莫斯科,並且代表任天堂出巨資收購家用機版Tetris的版權。版權費的價格雖然沒有向外界透露,但是這個數字將是Mirrorsoft永遠拿不出來的。連荒川實和NOA的首席執行官霍華德·林肯(Howard Lincoln)都親自前往蘇聯助陣。
1989年3月22日
ELORG和任天堂的家用機協議終於達成。任天堂方面堅持加入一款聲明,在協議簽定之後,如果和其他出現法律糾紛,蘇聯方面必須派人去美國的法庭上做證。實際上,這種法律上的爭端將是不可避免的。據說ELORG僅僅得到的定金有300-500萬美元之多。別里科夫向Mirrorsoft通知,說Mirrorsoft, Andromeda和Tengen都沒有家用機的版權,現在版權都歸任天堂所有。當天晚上任天堂和BPS的頭目們在莫斯科酒店裡舉行了慶祝party。
(各位看明白了,現在家用機和掌機的版權已經被任天堂和BPS分別掌握在手中。無論是Atari還是Tengen都沒有權利製作FC版的俄羅斯方塊。)
1989年3月31日
霍華德·林肯愉快(幸災樂禍?)地向Atari發去最後通牒(傳真),告訴他們立刻停止FC(NES)版的俄羅斯方塊游戲。這使得Atari和麥克斯韋都十分震怒。他們以Tengen的名義回信說在4月7日那天他們就已經享有家用機俄羅斯方塊的版權了。
1989年4月13日
Tengen撰寫了一份申請書,要求擁有Tetris的「影音作品,源程序和游戲音樂」版權。但是申請書中並沒有提及阿列克謝·帕基特諾夫和任天堂的游戲版權問題。(忽視了阿列克謝·帕基特諾夫真是個大錯誤!)
與此同時,麥克斯韋利用自己掌握的媒體勢力,企圖奪回Tetris的陣地。甚至搬出了蘇聯與英國政府,對俄羅斯方塊版權問題進行干預。(好大的面子啊!)結果挑起了蘇共與ELORG之間的矛盾。甚至連戈爾巴喬夫都向麥克斯韋保證「以後不用擔心日本公司的問題」。(汗……這位麥克斯韋果然不是善主……偉大的蘇聯政府都對俄羅斯方塊關注起來了……)
在4月晚些時候,霍華德·林肯回到莫斯科的時候,發現ELORG已經在蘇聯政府的打壓下抬不起頭來,而就在那天半夜,NOA方面給他打電話,說Tengen已經起訴了任天堂。(山雨欲來風滿樓啊……)
第二天,他面會了別里科夫,帕基特諾夫和其他幾位ELORG的成員,以確保他們能夠為任天堂的官司佐證。(這回合同里的條款可生效了)隨後NOA立刻反訴Tengen,並且開始收集證據。
1989年5月17日
Tengen在USA Today上登載了大幅Tertis廣告,雖然法庭大戰已經迫在眉睫。
1989年6月
Tengen與任天堂的案子終於開庭審理。
論戰主要圍繞一個議題展開:NES(FC)究竟是電腦,還是電子游戲機。(大家不許笑,在法庭上這可是很嚴肅的話題)Atari認為NES是電腦系統,因為它擁有擴展機能,而且日本的Famicom也有網路功能存在。而任天堂的證據則更加切題:ELORG中的蘇聯人從來沒有意向出售Tetris的家用機版權,而所謂的「電腦」的概念則早在和斯坦恩的協議中提到了。
1989年6月15日
法庭召開聽證會,討論關於任天堂和Tengen互相命令對方終止生產和銷售各自的Tetris軟體的行為。法官福恩·史密斯(Fern Smith)宣布Mirrorsoft 與 Spectrum Holobyte均沒有家用機版權,因此他們提供給Tengen的權利也不能生效。任天堂的請求最後得到了許可。
1989年6月21日
Tengen版的俄羅斯方塊全部撤下了貨架,該游戲卡帶的生產也被迫中止。數十萬份軟體留在包裝盒裡,封存在倉庫中。
1989年7月
任天堂NES版Tetris在美國發售。全美銷量大約300萬。與此同時,和GB版Tetris捆綁銷售的Game Boy席捲美國,美利堅大地上颳起一陣方塊旋風。
關於Tetris的混戰此時已經告一段落。而任天堂和Tengen之間的法庭糾紛則一直持續到1993年。
尾聲
Atari Games仍然開發了街機版的Tetris,共賣出約2萬台機器。近來Atari Games 被 Williams/WMS收購,而那些封存在倉庫里的NES版Tetris的命運則沒人知道。Tengen不能從其他途徑把它們處理掉,所以估計這些軟體都被銷毀了。但是據說仍然有約10萬份Tengen版的Tetris流入了市場。
我們今天在64合一等游戲D版卡里玩到的所謂「俄羅斯方塊2」其實就是當年的Tengen版,平心而論,這一版的方塊比BPS的版本要好玩許多。首先,這版的操作感和按鍵設定十分到位,AB分別是正轉和反轉,而BPS版是用十字鍵的下來轉動,只支持一個方向,按A就直接「啪」地落下來,手感十分不爽;其次,它支持的二人對戰,與電腦競爭和合作的模式也讓人耳目一新。還有,音樂也是沒的說。
羅伯特·斯坦恩,這個版權問題的始作俑者,在Tetris上總共只賺了25萬美元。本來他可以掙多點錢的,但是Atari和Mirrorsoft在付他版稅的時候沒有給足。(應得的報應……)
Spectrum Holobyte 則需要和ELORG重新協商,以確保電腦版Tetris的版權。
羅伯特·麥克斯韋的媒體堡壘在混戰中逐漸分崩離析,老麥克斯韋在做生意時做幕後黑手的事實也在調查中,而他卻突然暴病身亡。(氣死的……)Mirrorsoft 英國公司也慘淡地退出了歷史舞台。
真正的大贏家是BPS的總裁亨克·羅傑斯,還有幕後的任天堂。俄羅斯方塊究竟為任天堂賺了多少銀子呢?答案恐怕永遠說不清了。想一想吧,在美國GB都是和Tetris捆綁銷售,以增加GB的出貨量……然後因為Tetris買了GB的人還會買其他的GB卡……要是這么算起來的話,那利潤簡直就像滾雪球一樣了。現在GB版的Tetris(Z版)總共生產了3000萬張。(後來GB的俄羅斯方塊又在SFC上出了復刻版,和《馬里奧醫生》一起出現在屏幕上,成為不朽之作。)
至於蘇聯方面,除了蘇聯政府,誰也沒有從Tetris那裡得到多少好處。蘇聯解體之後,原ELORG的人員都四散到了全國乃至世界各地,許多人繼續開發游戲(比方說帕基特諾夫)。
阿列克謝·帕基特諾夫幾乎沒有從Tetris上賺到一分錢。ELORG本來打算給他Tetris的銷售權,但是旋即取消了這筆交易。不過帕基特諾夫仍然為自己能夠製作出這么一個世界聞名的優秀游戲而欣慰。他從科學院里得到一台286(當時在蘇聯可是了不起的電腦)作為獎勵。而且分到了比同事們家寬敞明亮的房子。在1996年,亨克·羅傑斯支付給他一筆報酬(還算是個知恩圖報的人),帕基特諾夫組建了Tetris Company LLC 公司,終於能夠自己創作游戲,並且收取版權費了。
註:當年俄羅斯方塊紅遍世界的各個角落,一個本來是吃大鍋飯的人在消極怠工的時候發明的娛樂工具成了造福全人類的寶貝,它的價值遠遠超越了開發這個軟體時候的預想。Atari雖然在法庭上慘敗,但是拜亞洲盜版商人所賜,Tengen版的俄羅斯方塊已經在中國玩家心目中生根發芽,長葉開花,任天堂的正統Tetris在中國反而沒人玩了。其實說了那麼多,歸根到底,平平淡淡才是真。有機會的話,下載一個FC的模擬器和一個64合一的經典ROM,回家體會一下俄羅斯方塊的魅力吧……
附上Alex Pajitnov照片一張。
該回答在5月15日 19:30由回答者修改過
❹ 如何用最簡單的語句寫一個俄羅斯方塊
動腦子
❺ 怎樣寫一個俄羅斯方塊用JAVA SWING
將游戲區劃成小格
設定一個移動像素,比如5
設定好幾個方塊的類,比如--,⊥等等。都由小格組成
隨機NEW那一個類。
判斷方塊最下面的的小格是否已到「底」,底:下面是小格是否已被添滿。
判斷一行從左到右是否沒有空格,否則刪除這行,再調用向下方法。
❻ 一個簡單的c語言寫的俄羅斯方塊程序
1、考慮怎麼存儲俄羅斯方塊
俄羅斯方塊的形狀一共有19種類型,如果拿數組來表示的話,可能會比較會浪費空間(網上有很多實現代碼)
考慮到每種方塊形狀的范圍是4 *4的小方塊,用 字模點陣的方式來存儲,即設置一個4行4列的數組,元素置1即代表這個位置有小
方塊,元素置0即代表這個位置無小方塊,這個整個的4*4的數組組成俄羅斯方塊的形狀。
1000
1000
1100
0000
上述4*4來表示L形狀的方塊。
4*4 =16 bit 正好為short類型,所以每一個方塊可以用一個short類型的數據來表示。
我們把俄羅斯方塊點陣的數位存在rockArray中,我們可以事先把這19種方塊的字模點陣自己轉化成十六進制,然後在rockArray數組的初始化時賦值進去。
但是這種方式擴展性不好,每當有一種新方塊時需要改動,
所以可以寫一個配置文件來表示19種方塊。(RockShape.ini)
@###@###@@######1234
從配置文件中讀取方塊的類型的代碼在(Init.h的ReadRock函數中)在下面3中解釋下代碼如何實現
2如何畫出方塊
可以使用EasyX庫來畫出簡單的圖形,
EasyX庫是在VC下實現TC的簡單繪圖功能的一個庫,這個庫很容易學會(直接 網路EasyX庫,裡面有詳細的教程)
那麼如何畫出方塊,方塊已經存儲到一個short類型中了
從short中讀取出,可以用一個掩碼mask = 1來與short的每個bit位相與,結果為1,則畫出一個小方塊;
函數聲明:
void DisplayRock(int rockIdx, RockLocation_t* LocatePtr, bool displayed)1
參數1:表示在數組中的下標,取出short類型的方塊表示數據
參數2:表示當前坐標,即畫出方塊的左上角的坐標x,y
參數3:true表示畫出該方塊,false 表示擦除該方塊。
//方塊在圖形窗口中的位置(即定位4*4大塊的左上角坐標) typedef struct LOCATE
{ int left; int top;
} RockLocation_t;123456
3如何實現同一種類型方塊的翻轉,
在按『↑』時應該翻轉同一種類型的方塊,
比如下面的橫桿和豎桿
@###@###@###@###@@@@############****1234567891011
可以假想成靜態循環鏈表來實現這種方式
使同一種類型的方塊循環起來,
用一個struct結構來表示一種方塊
typedef struct ROCK
{ //用來表示方塊的形狀(每一個位元組是8位,用每4位表示方塊中的一行)
unsigned short rockShapeBits; int nextRockIndex; //下一個方塊,在數組中的下標 } RockType;123456
定義一個RockType類型的數組來存儲19種方塊
RockType RockArray[19] = { (0, 0) };
當我們按「↑」時,把傳入畫方塊函數DrawRock中的rockIndex變為當前方塊結構體中的nextRockIndex即可。
簡單解釋下ReadRock函數的實現:當讀取到空行的時候表示 一種方塊已經讀取完畢,當讀取到****行時 表示同一種類型的方塊讀取完畢,具體看代碼實現,代碼中具體的注釋
4、主要游戲實現的邏輯
貼一個預覽圖吧
註:上述預覽圖的游戲控制區和游戲顯示區在Draw.h的DrawGameWindow()函數實現的
(1)在初始位置畫出方塊,在預覽區畫出下一次的方塊
(2)方塊有兩種行為:響應鍵盤命令UserHitKeyBoard(),自由下落
如果敲擊鍵盤了(w ,a ,s ,d, )空格表示暫停,如果在規定時間內沒有敲擊鍵盤的話,方塊自由下落一個單位
if (kbhit()) //如果敲擊鍵盤了 就處理按鍵
{
userHit = getch();
UserHitKeyBoard(userHit, &curRockIndex, &curRockLocation);
} //沒有 就自動下移一個單位 :不能用else,因為可能按鍵不是上下左右
DWORD newtime = GetTickCount(); if (newtime - oldtime >= (unsigned int)(300) && moveAbled == TRUE)
{
oldtime = newtime;
DisplayRock(curRockIndex, &curRockLocation, false);
curRockLocation.top += ROCK_SQUARE_WIDTH; //下落一格
}1234567891011121314
(3)當方塊落地(即不能下移了)時,判斷是否滿行,如果滿行則消除,然後再判斷游戲是否結束,游戲結束的話,直接退出遊戲
判斷滿行:FullLine()函數,從最底下的一行開始判斷,直到遇到一行空行,
while (count != xROCK_SQUARE_NUM ) //遇到空行 14
{
linefull = true; count = 0; for (int i = 1; i <= xROCK_SQUARE_NUM; ++i)
{ if (game_board[idx][i] == 0)
{
linefull = false; count++;
}
} if (linefull) //滿行,消除當前行,更新分數
{
DelCurLine(idx);//消除滿行
game_socres += 3;
UpdateSocres(game_socres);
idx++;//因為下面要減1
}
idx--;
}
(4)消除滿行
將要刪除的滿行擦除:即將方塊化成與背景色相同的,該代碼為黑色
然後將上面的一行向下移,移一行刪除一行,直到遇到空行
具體看代碼的具體實現 game.h
void DelCurLine(int rowIdx)
(4)判斷方塊是否能移動
在game.h中實現
bool MoveAble(int rockIndex, RockLocation_t* currentLocatePtr, int f_direction)1
**比較當前位置的坐標(左上角)開始,能否放下rockIndex的方塊。
註:f_direction為」↑」的話,則傳入的rockIndex為下一個方塊**
如果不能移動的話,給游戲game_board設置標記表示該位置被佔有
//全局變數-游戲板的狀態描述(即表示當前界面哪些位置有方塊) //0表示沒有,1表示有(多加了兩行和兩列,形成一個圍牆,便於判斷方塊是否能夠移動) int game_board[yROCK_SQUARE_NUM + 2][xROCK_SQUARE_NUM + 2] = { 0 };123
實現過程遇到的一些問題
(1)在快速下落的時候,可能方塊會掉出圍牆的范圍內,
快速下落是使方塊每次下落2個單位距離。
在判斷不能下落時,使當前坐標的top即y減去一個單位的距離
(2)遇到多行滿行時消除不了,
在判斷滿行時,循環找出滿行,找出一個滿行,就消除一行,然後繼續判斷是否滿行,直到遇到空行
❼ 俄羅斯方塊如何編寫及代碼
網上很多呀,有很多javascript寫的網頁俄羅斯方塊游戲,可以直接查看網頁源碼,偷懶的話修改成c++的就成了。
但也不要太懶了,如果你是學生的話。。。。。。
❽ 問下 用C 語言寫俄羅斯方塊 怎麼寫啊 最好那個人才能幫我寫個 謝謝
用C寫?
我有一個Delphi / CBC版本的.
基本思想:
定義基本的7種方塊(含四種狀態)二維數組變數.
Terial[7][4]. 用數組下標索引方塊的種類和狀態.
定義方塊運行的區域(二維數組變數) 如(高23,寬10)
用它存儲方塊下落後的狀態.
左移和右移判斷是方塊是否左右溢出、是否會疊在運行區的格子上。
同樣改變狀態(變形)也得判斷是否會出現左右溢出、是否會疊在運行區格子上。
下落後,對運行區的空格子進行賦值。
❾ 用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即可。
❿ 怎樣用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; }
}