亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        基于JAVA平臺(tái)的魔塔游戲設(shè)

        2018-09-05 10:19:04許益凡薛益鴿
        關(guān)鍵詞:血量怪物勇士

        許益凡 薛益鴿

        計(jì)文章編號(hào): 2095-2163(2018)03-0235-06中圖分類(lèi)號(hào): 文獻(xiàn)標(biāo)志碼: A

        摘要: 關(guān)鍵詞: (College of Information Engineering, Wenzhou Business College, Wenzhou Zhejiang 325035, China)

        Abstract: With the rise of the gaming market, various programming languages are widely used,JAVA language is the most widely used and the highest using proportion. This article takes the extremely classic magic tower game as an example, with the help of the JAVA languages object-oriented characteristic using the programming techniques: package and inherited.

        Key words:

        作者簡(jiǎn)介: 許益凡(1997-),男,本科生,主要研究方向:JAVA的桌面應(yīng)用、前端塔建; 薛益鴿(1990-),男,碩士,助教,主要研究方向:計(jì)算智能。

        通訊作者: 收稿日期: 引言

        游戲作為大眾生活必不可少的一項(xiàng)娛樂(lè)方式,近年來(lái)發(fā)展勢(shì)頭良好。開(kāi)發(fā)游戲的語(yǔ)言有很多種,JAVA是當(dāng)前最流行最熱門(mén)的一種編程語(yǔ)言, 因其是一種可以撰寫(xiě)跨平臺(tái)應(yīng)用程序的面向?qū)ο蟮某绦蛟O(shè)計(jì)語(yǔ)言\[3\],并具有卓越的通用性、高效性和平臺(tái)移植性\[2\],同時(shí),JAVA語(yǔ)言在游戲開(kāi)發(fā)方面,又因?yàn)槠湔Z(yǔ)言嚴(yán)謹(jǐn)、可讀性強(qiáng)、高度的便利性等優(yōu)勢(shì),在游戲開(kāi)發(fā)中具有非常重要的地位\[3\]。

        魔塔游戲是一款策略類(lèi)的RPG(角色扮演)游戲。游戲雖不大卻充滿難度,往往一步小小的失誤就會(huì)讓游戲失敗,前功盡棄\[4\]。本文基于JAVA平臺(tái)對(duì)魔塔游戲進(jìn)行設(shè)計(jì)和開(kāi)發(fā)。整個(gè)游戲在Microsoft Windows 7 64位操作系統(tǒng)下,利用 IntelliJ IDEA 2017.2.4 x64開(kāi)發(fā)工具進(jìn)行開(kāi)發(fā)。游戲的菜單欄、操作欄和商品購(gòu)買(mǎi)使用鼠標(biāo)進(jìn)行操作;勇士移動(dòng)使用方向鍵上、下、左、右操作;打開(kāi)/關(guān)閉怪物手冊(cè)用快捷鍵A; 往上跳躍樓層用快捷鍵Z;往下跳躍樓層用快捷鍵X。

        1需求分析及流程

        1.1功能需求

        通過(guò)對(duì)魔塔游戲的多次試玩和深入分析,可以發(fā)現(xiàn),該款游戲雖然像容易通關(guān)的地牢游戲,但每一小小的決定都影響著能否救出公主順利通關(guān)。如圖1所示,此游戲有著繁多的屬性和獨(dú)有的傷害計(jì)算公式,傷害所扣除的血量并不是簡(jiǎn)單地直接攻擊減去防御,而是需要經(jīng)過(guò)傷害次數(shù)的參與計(jì)算。傷害次數(shù)是敵人的血量除去自身攻擊與敵方防御之差。最終損失的血量又是需要次數(shù)乘以敵人的攻擊與自身防御之差,若損失的血量超過(guò)擁有的血量則無(wú)法攻擊此怪物,此時(shí),若不提升自身能力則會(huì)卡在這個(gè)怪物面前,導(dǎo)致游戲失敗。

        本文設(shè)計(jì)的游戲主要涉及下列功能模塊:戰(zhàn)斗以及血量的計(jì)算模塊、查看怪物手冊(cè)模塊、商店交易模塊、游戲的存檔與讀取模塊、重新開(kāi)始游戲模塊、退出游戲模塊、與NPC對(duì)話模塊、樓層跳轉(zhuǎn)和金手指系統(tǒng)模塊。功能結(jié)構(gòu)如圖2所示。

        1.2游戲整體流程

        游戲流程如下所述:游戲開(kāi)始,勇士出現(xiàn)在魔塔的一層,沒(méi)有配備裝備,只被賦予了初始的屬性和3把不同顏色的鑰匙。勇士行動(dòng)中遇到的事件如下:

        (1)獲取物品。可提升勇士的攻擊防御等屬性,增加勇士的綜合實(shí)力,同時(shí),有機(jī)會(huì)獲取到特殊物品,特殊物品具有的特殊功能對(duì)游戲進(jìn)展有很大幫助。

        (2)遭遇怪物。怪物種類(lèi)繁多,屬性也不近相同,如“小怪物”、“士兵隊(duì)長(zhǎng)”、“蝙蝠怪”、“骷髏怪”、“法師”、“衛(wèi)兵”等等。越高級(jí)的怪物屬性越高,所需勇士的實(shí)力也就越高。其中,魔王是整個(gè)游戲中最強(qiáng)大也是最困難的一個(gè)怪物類(lèi)NPC,魔王強(qiáng)具有強(qiáng)大的屬性和華麗的外觀,鎮(zhèn)守著去往救助公主的通道,只有打敗魔王才可以救出公主完成游戲。

        (3)遇到商店。玩家可根據(jù)自身的購(gòu)買(mǎi)能力提升自身的屬性或等級(jí),更好地進(jìn)行游戲。

        (4)NPC。在本文設(shè)計(jì)的游戲中,去除了一些購(gòu)買(mǎi)鑰匙的NPC,將其整合在商店和金手指中。同時(shí),保留了公主這個(gè)重要角色并添加了新的劇情:擊殺魔王后需解除公主手上的鎖鏈才能將她救走,則游戲成功,否則游戲失敗。流程如圖3所示。

        2程序?qū)崿F(xiàn)

        本款游戲具有以下3種特性:可靠性,即程序執(zhí)行時(shí)不會(huì)出現(xiàn)故障;可維護(hù)性,即在不破壞玩家數(shù)據(jù)的前提下進(jìn)行維護(hù)修復(fù)程序BUG;擴(kuò)展性,即在原有基礎(chǔ)上有更多的創(chuàng)新,使用戶不產(chǎn)生使用疲勞,開(kāi)發(fā)新的功能模塊\[5\]。下面,詳細(xì)介紹游戲中各功能的實(shí)現(xiàn)。

        2.1游戲界面的實(shí)現(xiàn)

        游戲界面是游戲開(kāi)發(fā)的點(diǎn)睛之筆。本文開(kāi)發(fā)的游戲界面在原版的基礎(chǔ)上增加了金手指菜單。游戲界面由以下3個(gè)板塊構(gòu)成:游戲主界面,顯示游戲的內(nèi)容,大部分游戲的操作全在這里操作并顯示;游戲控制面板,顯示勇者的屬性及攜帶的鑰匙數(shù)量,并提供了保存、讀取、退出、重玩游戲的按鈕;游戲菜單欄,集合了所有可進(jìn)行的操作,并添加了可玩性極高的金手指,給初玩者一個(gè)良好的體驗(yàn)。圖4示出了游戲界面。

        游戲主頁(yè)面中地圖復(fù)雜多樣、各個(gè)樓層的地圖都不相同,怪物NPC也是層出不窮,因此本文將圖片以數(shù)字形式儲(chǔ)存在一個(gè)二維數(shù)組里,需要時(shí)讀取該數(shù)組并“畫(huà)”在界面上,不同數(shù)字代表不同圖片,即代表不同的角色、不同的游戲環(huán)境。同時(shí),也為勇士行動(dòng)操作提供更好的判斷。第0層地圖的儲(chǔ)存圖的代碼如下:

        map1 = new int\[\]\[\]{

        {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},

        {-1, 1, 3, 3, 3, 3, 1000, 3, 3, 3, 3, 1, -1},

        .................. }

        魔塔有很多層,每一層創(chuàng)建一個(gè)數(shù)組,同時(shí),創(chuàng)建了一個(gè)專門(mén)用來(lái)儲(chǔ)存初始地圖的類(lèi)MapPackage,以方便調(diào)用讀取顯示。以下是部分代碼(第0、1層):

        public classSaveMap {

        public Map map;

        public int\[\]\[\] map1;

        public SaveMap() {

        map1 = new int\[\]\[\]{

        {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},

        {-1, 1, 3, 3, 3, 3, 1000, 3, 3, 3, 3, 1, -1},

        ....................... };

        為了在界面上畫(huà)出地圖,本文首先把所有圖片和怪物分類(lèi)存入數(shù)組,然后根據(jù)所在樓層找到相應(yīng)的二維數(shù)組,使用2個(gè)嵌套的for循環(huán)對(duì)其進(jìn)行遍歷,將數(shù)字與實(shí)例化的圖片對(duì)象進(jìn)行匹配,一個(gè)一個(gè)“畫(huà)”在界面上。部分代碼如下:

        importjavax.swing.*;

        public class Map {

        public MapPackge mapPackge;

        public Map() {

        mapPackge = new MapPackge();

        map = new int\[13\]\[13\];

        wall = Toolkit.getDefaultToolkit().getImage("image/05.jpg");

        ////NPC

        NPC01a = Toolkit.getDefaultToolkit().getImage("image/NPC01a.png");

        Princess = Toolkit.getDefaultToolkit().getImage("image/Princess.png");

        ////怪物ID、屬性、圖片

        monsters\[0\] = new Monster(49, "黃金B(yǎng)OSS", 1000, 500, 250, 22, 19, Toolkit.getDefaultToolkit().getImage("image/Yellow.png"));

        .............

        for (int i = 0; i < 13; i++) {

        for (int j = 0; j < 13; j++) {

        map\[i\]\[j\] = mapPackge.map1\[i\]\[j\];

        } }}

        public void DrawMap(Graphics g, JPanel i) {

        for (int z = 1; z < 12; z++) {

        for (int j = 1; j < 12; j++) {

        if (map\[z\]\[j\] == 1) {

        g.drawImage(wall, (j - 1) * 32, (z - 1) * 32, 32, 32, (ImageObserver) i);

        }

        ...........

        if (map\[z\]\[j\] >= 1000 && map\[z\]\[j\] < 2000) {

        g.drawImage(road, (j - 1) * 32, (z - 1) * 32, 32, 32, (ImageObserver) i);

        g.drawImage(up, (j - 1) * 32, (z - 1) * 32, 32, 32, (ImageObserver) i);

        }......}} }}

        2.2地圖改變的實(shí)現(xiàn)

        隨著游戲的進(jìn)行,地圖上的一些門(mén)被判定為已經(jīng)打開(kāi),一些怪物被判定為已經(jīng)被擊殺,因此,保存的原地圖包不能被讀取。為了原地圖進(jìn)行區(qū)分,需創(chuàng)建一個(gè)新的類(lèi)SaveMap用以儲(chǔ)存改變后的地圖包。由于SaveMap的結(jié)構(gòu)與MapPackage相同,這里就不對(duì)代碼進(jìn)行詳細(xì)描述。

        2.3勇士移動(dòng)的實(shí)現(xiàn)

        游戲的主要目的是讓勇士動(dòng)起來(lái)去突破艱難險(xiǎn)阻,擊殺怪物解救公主。由于勇士在行動(dòng)中會(huì)遇到不同的事物,從而使得勇士在行動(dòng)的每一步都要進(jìn)行判斷。本文運(yùn)用常見(jiàn)的動(dòng)作監(jiān)聽(tīng)事件,并將所有判斷的代碼打包在新的類(lèi)KeyPress里。部分代碼如下:

        public classKeyPress {

        public void Keypress(MSprite mSprite, Map map, Fight fight, FloorJump floorJump, SaveMap saveMap, int a, int b) {

        if (mSprite.m_posY >= 0 && mSprite.m_posY <= 320 && mSprite.m_posX >= 0 && mSprite.m_posX <= 320) {

        if (map.map\[mSprite.m_posY / 32 + 1 + a\]\[mSprite.m_posX / 32 + 1 + b\] == 100 && mSprite.YKey > 0) {

        map.map\[mSprite.m_posY / 32 + 1 + a\]\[mSprite.m_posX / 32 + 1 + b\] = 0;

        mSprite.YKey--;

        } } } }

        上述代碼在主菜單MCanvas的動(dòng)作監(jiān)聽(tīng)中被調(diào)用,在按下不同按鍵的同時(shí)進(jìn)行判斷操作。創(chuàng)建動(dòng)作監(jiān)聽(tīng)的部分代碼如下:

        @Override

        public void keyPressed(KeyEvent e) {

        if (VK1 == "UP") {

        VK1 = "";

        shop.addHP.setVisible(false);

        }

        if (VK == "") {

        if (e.getKeyCode() == KeyEvent.VK_DOWN) {

        int a = 1;

        int b = 0;

        keyPress.Keypress(mSprite, map, fight, floorJump, saveMap, a, b);

        } else if (e.getKeyCode() == KeyEvent.VK_UP) {

        int a = -1;

        int b = 0;

        keyPress.Keypress(mSprite, map, fight, floorJump, saveMap, a, b);

        if (map.map\[mSprite.m_posY / 32\]\[mSprite.m_posX / 32 + 1\] == 46) {

        if (VK1 == "UP") {

        VK1 = "";

        shop.addHP.setVisible(false);

        } else {

        VK1 = "UP";

        shop.addHP.setVisible(true);

        }}

        2.4戰(zhàn)斗過(guò)程的實(shí)現(xiàn)

        勇士移動(dòng)的路上布滿了怪物的防線,同時(shí),前面提到的戰(zhàn)斗公式也需要用代碼實(shí)現(xiàn)。為此,創(chuàng)造一個(gè)動(dòng)作類(lèi)Fight用來(lái)進(jìn)行戰(zhàn)斗部分的操作。首先,遇到怪物時(shí)調(diào)用該類(lèi)并打包在KeyPress中。然后,從怪物類(lèi)Monster中提取所遭遇怪物的屬性與勇士類(lèi)MSprite的現(xiàn)有數(shù)據(jù)進(jìn)行計(jì)算判斷,如果符合公式則扣除血量,如果不符合則無(wú)法進(jìn)行操作,勇士無(wú)法繼續(xù)前進(jìn)。部分代碼如下:

        public voidFighting(MSprite sprite, int monID, Map map, int a, int b) {

        for (int i = 0; i < 1; i++) {

        if (monID <= 70 && monID >= 49) {

        xmonster = map.monsters\[monID - 49\];

        monster = new Monster(monID, null, xmonster.HP, xmonster.DF, xmonster.ATK, xmonster.coin, xmonster.Exp, null);

        HP = sprite.HP;

        MHP = monster.HP;

        if (sprite.ATK > monster.DF) {

        while (MHP > 0) {

        if (sprite.DF < monster.ATK && MHP > 0) {

        MHP -= (sprite.ATK - monster.DF);

        HP -= (monster.ATK - sprite.DF);

        } else if (sprite.DF >= monster.ATK && MHP > 0) {

        MHP = 0;

        } }}

        if (sprite.ATK > monster.DF && HP > 0) {

        while (monster.HP > 0) {

        if (sprite.DF >= monster.ATK && sprite.ATK > monster.DF) {

        monster.HP = 0;

        map.map\[sprite.m_posY / 32 + 1 + a\]\[sprite.m_posX / 32 + 1 + b\] = 0;

        sprite.coin += monster.coin;

        }

        if (sprite.DF < monster.ATK && monster.HP > 0) {

        monster.HP -= (sprite.ATK - monster.DF);

        sprite.HP -= (monster.ATK - sprite.DF);

        }

        if (monster.HP <= 0) {

        map.map\[sprite.m_posY / 32 + 1 + a\]\[sprite.m_posX / 32 + 1 + b\] = 0;

        sprite.coin += monster.coin;

        sprite.exp += monster.Exp;

        } }} } }2.5樓層跳轉(zhuǎn)的實(shí)現(xiàn)

        跳轉(zhuǎn)樓層后每個(gè)樓層的出發(fā)點(diǎn)都不同,并且要確保跳轉(zhuǎn)的樓層已經(jīng)保存在SaveMap類(lèi)中,否則會(huì)出現(xiàn)地圖重復(fù)或者不更新的問(wèn)題。本文采用如下方法解決以上問(wèn)題,將勇士放在要去的樓層的上一個(gè)樓層的樓梯上,根據(jù)KeyPress里打包的判斷,勇士會(huì)自動(dòng)到下一層的出發(fā)點(diǎn),這樣就能找到所要到達(dá)樓層的出發(fā)點(diǎn)。部分代碼如下:

        public classFloorJump {

        public void Jump(int i, Map map, SaveMap saveMap, MSprite mSprite) {

        if (i >= 1000 && i < 2000) {

        int z = i - 1000;

        mSprite.floor = z + 1;

        for (int j = 0; j < 13; j++) {

        for (int h = 0; h < 13; h++) {

        Group\[z\]\[j\]\[h\] = map.map\[j\]\[h\];

        map.map\[j\]\[h\] = Group\[z + 1\]\[j\]\[h\];

        }}

        int x = 0, y = 0;

        for (int j = 1; j < 13; j++) {

        for (int h = 1; h < 13; h++) {

        if (Group\[z + 1\]\[j\]\[h\] >= 2000 && Group\[z + 1\]\[j\]\[h\] < 3000) {

        x = h;

        y = j;

        }} }

        2.6游戲存取的實(shí)現(xiàn)

        魔塔雖然是一個(gè)小游戲,但作為經(jīng)典的地牢闖關(guān)類(lèi)游戲,想要闖過(guò)層層關(guān)卡,取得游戲成功也并非容易實(shí)現(xiàn),想要闖關(guān)成功需要花費(fèi)大量時(shí)間,因此,游戲的存檔與讀取就顯得尤為重要。本文使用的存檔技術(shù)是JAVA比較常見(jiàn)的IO流技術(shù)。將游戲所有能讀取到且需要改變的屬性數(shù)值,通過(guò)IO流保存在一個(gè)外部文件中,并在需要時(shí)判斷是否存在,如果存在則讀取這些屬性,從而達(dá)到地圖和數(shù)據(jù)的保存功能。保存代碼和讀取代碼如下:

        importjava.io.DataOutputStream;

        import java.io.FileOutputStream;

        public class Save {

        private SaveMap saveMap = new SaveMap();

        try {

        DataOutputStream localDataOutPutStream = new DataOutputStream(new FileOutputStream("save" + a + ".dat"));

        for (int i = 0; i < Group.length; i++) {

        for (int j = 0; j < 13; j++) {

        for (int k = 0; k < 13; k++) {

        Group\[i\]\[j\]\[k\] = mCanvas.map.map\[j\]\[k\];

        localDataOutPutStream.writeInt(Group\[i\]\[j\]\[k\]);

        } } }

        } catch (Exception e) {

        e.printStackTrace();

        } } }

        importjavax.swing.*;

        public class Read {

        try {

        DataInputStream localDataInputStream = new DataInputStream(new FileInputStream("save" + a + ".dat"));

        for (int i = 0; i < Group.length; i++) {

        for (int j = 0; j < 13; j++) {

        for (int k = 0; k < 13; k++) {

        Group\[i\]\[j\]\[k\] = localDataInputStream.readInt();

        mCanvas.map.map\[j\]\[k\] = Group\[i\]\[j\]\[k\];

        } } }

        mSprite.m_posX = localDataInputStream.readInt();

        localDataInputStream.close();

        } catch (Exception e) {

        e.printStackTrace();

        JOptionPane.showMessageDialog(null, "讀取失敗!此存檔為空或損壞!", "讀取失敗", JOptionPane.WARNING_MESSAGE);

        } } }

        3結(jié)束語(yǔ)

        魔塔是一個(gè)十分經(jīng)典的RPG(角色扮演)游戲,(下轉(zhuǎn)封三)本文在實(shí)現(xiàn)原魔塔游戲功能的基礎(chǔ)上創(chuàng)建了新的功能。經(jīng)過(guò)測(cè)試,該游戲能夠運(yùn)行流暢,體驗(yàn)良好。通過(guò)設(shè)計(jì)該款游戲,體驗(yàn)到了JAVA在制作游戲方面的便捷性。

        參考文獻(xiàn)

        [1] 孫衛(wèi)琴. Java面向?qū)ο缶幊蘙M]. 電子工業(yè)出版社, 2006.

        [2] 牛芳. 異構(gòu)存儲(chǔ)系統(tǒng)中的節(jié)點(diǎn)失效并行化修復(fù)研究[D]. 中國(guó)科學(xué)技術(shù)大學(xué), 2014.

        [3] 楊豐盛. Android應(yīng)用開(kāi)發(fā)揭秘[M]. 機(jī)械工業(yè)出版社, 2010.

        [4] 龐萍.基于java的魔塔游戲的設(shè)計(jì)與實(shí)現(xiàn)[J]. 電腦知識(shí)與技術(shù),2016,12(34):246-247.

        [5] Julian Gold. 面向?qū)ο蟮挠螒蜷_(kāi)發(fā)[M]. 電子工業(yè)出版社, 2005.

        猜你喜歡
        血量怪物勇士
        科學(xué)神獸之戰(zhàn)
        紅細(xì)胞的奇妙旅行
        以一己之力拯救尷尬的都是勇士
        追求美的人 從來(lái)都是勇士
        海峽姐妹(2018年10期)2018-12-26 01:21:04
        失蹤的怪物等
        黃金時(shí)代 金州勇士 GOLDEN STATE WARRIORS
        NBA特刊(2018年7期)2018-06-08 05:48:32
        膀胱沖洗液中加入去氧腎上腺素在老年患者經(jīng)尿道前列腺電切術(shù)中的應(yīng)用
        Women in the Workplace, Fighting Spam, Money in the Museum, and the Mood for Food
        曾被誤認(rèn)為怪物的傘
        真的勇士,取于直面扣錢(qián)!
        花火A(2013年10期)2013-05-14 10:13:29
        av永久天堂一区二区三区| 久久精品日韩免费视频| 亚洲视频专区一区二区三区| 国产欧美va欧美va香蕉在| 亚洲永久无码7777kkk| 国产主播无套内射一区| 日本韩国一区二区高清| 亚洲av午夜精品无码专区| 色婷婷综合久久久久中文| 国产在线不卡免费播放| 亚洲综合偷拍一区二区| 亚洲av日韩av激情亚洲| 精品午夜福利无人区乱码一区| 欧美日韩免费一区中文字幕| 精品国产亚洲av久一区二区三区 | 亚洲国产av剧一区二区三区| 国产精品国产三级国产专区不| 三级全黄的视频在线观看 | 青青草视频视频在线观看| 国产极品粉嫩福利姬萌白酱| 特黄a级毛片免费视频| 国产一级淫片a免费播放口| 国产日产亚洲系列首页| 专干老熟女视频在线观看| 国产黑色丝袜在线观看下| 青青青草国产熟女大香蕉| 久久精品国产av麻豆五月丁| 人妻少妇精品无码专区动漫| 免费jjzz在线播放国产| 亚洲一区二区三区ay| 国产三级a三级三级| 亚洲欧美日韩中文无线码| 中文字幕有码高清| 国产在线观看视频一区二区三区| 国产午夜精品一区二区| 日韩在线看片| 国产av一区麻豆精品久久| 日韩人妻少妇一区二区三区| 波多野结衣免费一区视频| 看全色黄大色大片免费久久久| 一区二区三区国产精品乱码|