Java實(shí)現(xiàn)經(jīng)典游戲泡泡堂的示例代碼
前言
《泡泡堂I》是一個(gè)基于java的自制游戲,游戲設(shè)計(jì)為雙人pk積分賽模式,在這個(gè)模式里面,玩家只要率先達(dá)到一定分?jǐn)?shù)既可以贏得比賽。玩家可以通過炸箱子可以得到少量的分?jǐn)?shù),也可以通過炸掉對(duì)手然后戳破包圍對(duì)手的水泡得到大量分?jǐn)?shù)。而玩家如果被泡泡爆炸擊中,會(huì)被泡泡包裹一段時(shí)間,在這段時(shí)間內(nèi)不可以移動(dòng)和放泡泡,需要等時(shí)間過去或者被對(duì)手戳破水泡才能獲得自由。但如果玩家被自己放的泡泡炸中,會(huì)扣一定的分?jǐn)?shù)。
主要設(shè)計(jì)
- 設(shè)計(jì)游戲界面,用swing實(shí)現(xiàn)
- 繪制游戲啟動(dòng)界面、結(jié)束界面、地圖、主角、道具
- 實(shí)現(xiàn)泡泡爆炸
- 實(shí)現(xiàn)雙主角PK(積分制)
- 實(shí)現(xiàn)道具掉落和相應(yīng)屬性加成
- 實(shí)現(xiàn)游戲音效和背景音樂
功能截圖
游戲啟動(dòng)界面:
游戲開始界面:
移動(dòng)效果:
釋放泡泡
泡泡爆炸效果:
代碼實(shí)現(xiàn)
游戲啟動(dòng)類
public class GameStart { public static void main(String[] args) { //整個(gè)程序的入口 啟動(dòng) StartFrame startFrame = new StartFrame(); startFrame.setVisible(true); } }
核心監(jiān)聽類
public class GameListener implements KeyListener { private List<?> list; @Override public void keyTyped(KeyEvent e) { // TODO Auto-generated method stub } //按下 左37 右39 下40 上38 w87 a65 s83 d68 空格32 enter10 @Override public void keyPressed(KeyEvent e) { // TODO Auto-generated method stub //System.out.println("keypressed"+e.getKeyCode()); list = ElementManager.getInstance().getElementList("play"); Player oneplayer = (Player)list.get(0); Player twoPlayer = (Player)list.get(1); switch (e.getKeyCode()) { case 65: oneplayer.setLEFT(true); // oneplayer.setStop(false); break; case 87: oneplayer.setUP(true); // oneplayer.setStop(false); break; case 68: oneplayer.setRIGHT(true); // oneplayer.setStop(false); break; case 83: oneplayer.setDOWN(true); // oneplayer.setStop(false); break; case 32: oneplayer.setPk(true); break; case 37: twoPlayer.setLEFT(true); break; case 38: twoPlayer.setUP(true); break; case 39: twoPlayer.setRIGHT(true); break; case 40: twoPlayer.setDOWN(true); break; case 10: twoPlayer.setPk(true); break; } } //松開 @Override public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub //System.out.println("keyreleased"+e.getKeyCode()); list = ElementManager.getInstance().getElementList("play"); Player oneplayer = (Player)list.get(0); Player twoPlayer = (Player)list.get(1); switch (e.getKeyCode()) { case 65: // if (oneplayer.isLEFT()) { // oneplayer.setStop(true); // } oneplayer.setLEFT(false); break; case 87: // if (oneplayer.isUP()) { // oneplayer.setStop(true); // } oneplayer.setUP(false); break; case 68: // if (oneplayer.isRIGHT()) { // oneplayer.setStop(true); // } oneplayer.setRIGHT(false); break; case 83: // if (oneplayer.isDOWN()) { // oneplayer.setStop(true); // } oneplayer.setDOWN(false); break; case 32: oneplayer.setPk(false); break; case 37: twoPlayer.setLEFT(false); break; case 38: twoPlayer.setUP(false); break; case 39: twoPlayer.setRIGHT(false); break; case 40: twoPlayer.setDOWN(false); break; case 10: twoPlayer.setPk(false); break; } } }
核心線程類
public class GameThread extends Thread{ //計(jì)時(shí)數(shù)據(jù) private static int time ; private boolean flag=true; //重構(gòu)老項(xiàng)目 @Override public void run() { //這個(gè)循環(huán)控制游戲整體進(jìn)度 // while(flag){ // 死循環(huán) 狀態(tài)變量進(jìn)行控制 //1.加載地圖 人物 loadElement(); //2.顯示地圖人物(流程 自動(dòng)化(移動(dòng),碰撞)) time = 0; loadBGM(); runGame(); //3.結(jié)束地圖 try { TimeUnit.MILLISECONDS.sleep(150); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } // } } //控制進(jìn)度 但是作為控制 請(qǐng)不要接觸load 只能通過元素管理器訪問元素 public void loadElement(){ ElementManager.getInstance().load(); } public void runGame(){ //這個(gè)循環(huán)控制每個(gè)關(guān)卡 地圖中玩的狀態(tài) ElementManager manager = ElementManager.getInstance(); while(flag){ Map<String, List<SuperElement> > map = manager.getMap(); Set<String> set = map.keySet(); List<String> temp = new ArrayList<>(); temp.addAll(set); //迭代器在遍歷的過程中,迭代器中的元素不可以變化(增加或減少) for (int i=temp.size()-1; i>=0 ; i--) { List<SuperElement> list = map.get(temp.get(i)); for (int j = 0; j < list.size(); j++) { SuperElement superElement = list.get(j); superElement.update(); if (!superElement.isVisible()) { manager.removeElementByPx(superElement.getY(), superElement.getX()); list.remove(j); } } } //使用一個(gè)獨(dú)立的方法來進(jìn)行判定 PK(); //游戲的流程控制 linkGame(); try { TimeUnit.MILLISECONDS.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } //死亡 通關(guān)狀態(tài) 結(jié)束runGame方法 overGame(); time++; //一秒鐘增加10 } } public void PK() { // TODO Auto-generated method stub List<SuperElement> players = ElementManager.getInstance().getElementList("play"); List<SuperElement> enemys = ElementManager.getInstance().getElementList("enemylist"); //進(jìn)行比較 listPK(players, enemys); } public void listPK(List<SuperElement> list1,List<SuperElement> list2){ for (int i = 0; i < list1.size(); i++) { for (int j = 0; j < list2.size(); j++) { if (list1.get(i).gamePK(list2.get(j))) { list2.get(j).setVisible(false); } } } } public void overGame(){ Player player1 = (Player)(ElementManager.getInstance().getElementList("play").get(0)); Player player2 = (Player)(ElementManager.getInstance().getElementList("play").get(1)); if(player1.getNum()>=1000||player2.getNum()>=1000) { flag = false; new Thread() { public void run() { new audioPlay(Audio.OVER).player(); } }.start(); } } //游戲的流程控制 public void linkGame(){ // Map< String , List<SuperElement> > map = // ElementManager.getInstance().getMap(); // List<SuperElement> enemys = map.get("enemylist"); // //一秒鐘增加一個(gè)敵機(jī) // if (time%10 == 0) { // enemys.add(Enemy.createEnemy("")); // } ElementManager.getInstance().linkGame(time); } public static int getTime() { return time; } public static void setTime(int time) { GameThread.time = time; } private void loadBGM() { new Thread() { public void run() { while(flag) { audioPlay play = new audioPlay(Audio.BGM); play.player(); if(!flag) { play.stop(); } } } }.start(); } //敵機(jī)的創(chuàng)建 }
總結(jié)
通過此次的《泡泡堂I》實(shí)現(xiàn),讓我對(duì)JAVA的相關(guān)知識(shí)有了進(jìn)一步的了解,對(duì)java這門語言也有了比以前更深刻的認(rèn)識(shí)。
java的一些基本語法,比如數(shù)據(jù)類型、運(yùn)算符、程序流程控制和數(shù)組等,理解更加透徹。java最核心的核心就是面向?qū)ο笏枷?,?duì)于這一個(gè)概念,終于悟到了一些。
到此這篇關(guān)于Java實(shí)現(xiàn)經(jīng)典游戲泡泡堂的示例代碼的文章就介紹到這了,更多相關(guān)Java泡泡堂內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot實(shí)現(xiàn)接口版本控制的示例代碼
這篇文章主要介紹了springboot如何實(shí)現(xiàn)接口版本控制,接口版本控制,比如微服務(wù)請(qǐng)求中某個(gè)接口需要升級(jí),正常做法是升級(jí)我們的版本,文中有詳細(xì)的代碼示例供大家參考,具有一定的參考價(jià)值,需要的朋友可以參考下2024-03-03構(gòu)建springboot自動(dòng)生成mapper文件和dao接口項(xiàng)目的步驟和配置方法
這篇文章主要介紹了構(gòu)建springboot自動(dòng)生成mapper文件和dao接口項(xiàng)目的步驟和配置方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-05-05Mybatis的Mapper代理對(duì)象生成及調(diào)用過程示例詳解
這篇文章主要為大家介紹了Mybatis的Mapper代理對(duì)象生成及調(diào)用過程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09使用AbstractRoutingDataSource實(shí)現(xiàn)數(shù)據(jù)源動(dòng)態(tài)切換的實(shí)例
AbstractRoutingDataSource 是 Spring 框架提供的一個(gè)抽象類,用于實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源路由,這個(gè)類主要用于多數(shù)據(jù)源場(chǎng)景,其中可以根據(jù)不同的條件動(dòng)態(tài)地切換到不同的數(shù)據(jù)源,本文給大家介紹了如何使用AbstractRoutingDataSource實(shí)現(xiàn)數(shù)據(jù)源動(dòng)態(tài)切換,需要的朋友可以參考下2024-03-03分析xxljob登入功能集成OIDC的統(tǒng)一認(rèn)證
這篇文章主要為大家介紹分析xxljob登入功能集成OIDC的統(tǒng)一認(rèn)證的詳解說明,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-02-02手把手帶你理解java線程池之工作隊(duì)列workQueue
這篇文章主要介紹了java線程池之工作隊(duì)列workQueue,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09Java實(shí)現(xiàn)簡(jiǎn)易提款機(jī)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡(jiǎn)易提款機(jī),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01