坦克大戰(zhàn)游戲的設(shè)計(jì)
一、功能描述:
這個(gè)坦克大戰(zhàn)實(shí)現(xiàn)了我方坦克(玩家控制)以及敵方坦克(程序隨機(jī)控制)的對(duì)戰(zhàn),當(dāng)擊毀所有敵方坦克之后玩家獲勝,當(dāng)我方坦克生命值被消耗完畢后失敗。游戲中,敵方坦克分為兩類:一是快速的黃色坦克,二是有兩點(diǎn)生命值的慢速坦克。玩家坦克的生命值一共為三。其中鍵盤(pán)的w、s、a、d分別控制坦克上下左右四個(gè)方向的移動(dòng),點(diǎn)擊鼠標(biāo)之后為發(fā)射子彈。其中要注意的是,當(dāng)子彈擊中對(duì)方坦克或碰到障礙物消失之后才能發(fā)射下一個(gè)子彈。游戲過(guò)程中還會(huì)隨機(jī)出現(xiàn)加速道具,獲取之后玩家坦克的速度提升為初始的兩倍。下面便是游戲的圖片展示 :
游戲界面

右下角的生命值:


出現(xiàn)的加速道具:

游戲結(jié)束:

二,技術(shù)分析:
在坦克大戰(zhàn)的編寫(xiě)中,技術(shù)上不同于前面項(xiàng)目主要用到了兩點(diǎn),一個(gè)是多線程的應(yīng)用,另一個(gè)是界面加載圖形的處理,即雙緩沖技術(shù)。下面來(lái)進(jìn)行分析:
(一)多線程的處理:
在這個(gè)游戲中,最為核心的技術(shù)便是多線程的應(yīng)用,我方坦克,敵方的十輛坦克、我方發(fā)射的子彈以及敵方坦克發(fā)射的子彈均為獨(dú)立的線程,因此,在線程的控制上有了一定的難度,由于在彈球游戲的開(kāi)發(fā)中,計(jì)時(shí)線程與小球線程同時(shí)受一個(gè)主類里面變量的控制并在某個(gè)時(shí)候需同時(shí)對(duì)其進(jìn)行修改,因此,會(huì)出現(xiàn)搶占CPU時(shí)間片的情況從而使得程序的運(yùn)行結(jié)果出現(xiàn)意想不到的結(jié)果?;谶@個(gè)經(jīng)驗(yàn),我在這次的設(shè)計(jì)中將控制變量設(shè)置在某一個(gè)線程中,并且修改的動(dòng)作只發(fā)生在一個(gè)線程內(nèi),這樣的話便比較有效的解決類上述的問(wèn)題。當(dāng)然,有的同志也許會(huì)說(shuō)用線程同步synchronized來(lái)控制,但是這個(gè)的話會(huì)使的程序的復(fù)雜度更加加大,以至于你對(duì)每一個(gè)控制細(xì)節(jié)牢記于心。
(二)雙緩沖技術(shù):
當(dāng)框設(shè)計(jì)好之后,我信心滿滿的加上了仰慕已久的圖片,結(jié)果卻令我抓狂,因?yàn)槠聊簧弦呀?jīng)在不停的閃爍了,找到高手求教之后才明白這里涉及到雙緩沖的問(wèn)題,關(guān)于雙緩沖的詳細(xì)理解將在以后的技術(shù)博客中談及,這里的話簡(jiǎn)單介紹一下,就是通過(guò)重寫(xiě)窗體的upData()方法,將窗體的寫(xiě)入緩沖區(qū)內(nèi),具體的相關(guān)代碼如下 // 重寫(xiě)update方法,先將窗體上的圖形畫(huà)在圖片對(duì)象上,再一次性顯示
- public void update(Graphics g) {
- if (offScreenImage == null) { offScreenImage = this.createImage(WIDTH, HEIGHT); }
- Graphics gImage = offScreenImage.getGraphics();
- Color c = gImage.getColor();
- gImage.setColor(Color.BLACK);
- gImage.fillRect(0, 0, WIDTH, HEIGHT);
- gImage.setColor(c); paint(gImage);
- g.drawImage(offScreenImage, 0, 0, null);
- }
其中需要注意的一點(diǎn)是我在查找資料的時(shí)候發(fā)現(xiàn)有介紹雙緩沖機(jī)制主要用于awt之中,而在swing中已經(jīng)自動(dòng)實(shí)現(xiàn),因此我繼承了Frame類,改為swing組件中就沒(méi)有預(yù)定的效果了。因此我在想是否swing中已經(jīng)很好的處理了雙緩沖的問(wèn)題了呢。
三、總結(jié)分析
其實(shí)坦克大戰(zhàn)游戲設(shè)計(jì)的目的并不是想要單純的做一個(gè)小游戲,二是為了加強(qiáng)對(duì)多線程的掌握,這一點(diǎn)我想應(yīng)該可以通過(guò)游戲時(shí)一共運(yùn)行二十二個(gè)線程來(lái)證實(shí)吧。盡管初衷比較單純,但是設(shè)計(jì)過(guò)程之中卻感覺(jué)自己收獲了不少的東西,在此想和大家一起分享一下。
1、程序編寫(xiě)的框架十分重要,在程序編寫(xiě)的初期,我盡量的規(guī)范自己的代碼,雖然有些麻煩,但是后來(lái)的經(jīng)歷卻讓我慶幸這一點(diǎn)上的功夫,在加載一些障礙物圖片之后,坦克以及子彈線程的控制從碰到墻壁這一簡(jiǎn)單判斷增加要對(duì)障礙物也進(jìn)行判斷,由于各個(gè)線程的設(shè)計(jì)思路相似,因此我在玩家坦克類中成功測(cè)試石頭小河等障礙物后,比較輕松得就將判斷移植到其他的線程之中了。
2、在遇到新的一些問(wèn)題,比如說(shuō)雙緩沖,應(yīng)當(dāng)有獨(dú)立解決的能力,通過(guò)前面一些牛人的經(jīng)驗(yàn),網(wǎng)上的相關(guān)資料通過(guò)已學(xué)到的知識(shí)自己摸索這個(gè)問(wèn)題,而不是讓老師一句一句的解釋。這對(duì)于以后的發(fā)展是極為重要的。學(xué)到的知識(shí)總是有限的,更為重要的是掌握獲取知識(shí)的方法。
其實(shí),在這個(gè)坦克大戰(zhàn)中還有一些缺陷,比如說(shuō)功能道具太單調(diào),不能直接重啟結(jié)束后的游戲。但是我想對(duì)于java學(xué)習(xí)初期的我來(lái)說(shuō),更重要的是學(xué)會(huì)熟練掌握其中的基本知識(shí)與技能,而不是項(xiàng)目本身有多絢。因此今后自己還要更加得努力,與大家一起進(jìn)步。