【项目】游戏开发期末大作业 之 基于Java的小游戏 “大鱼吃小鱼“ (代码素材齐全)
1.EatFish游戲開(kāi)發(fā)過(guò)程
1.游戲窗口創(chuàng)建 2.添加背景圖片 3.啟動(dòng)封面 4.啟動(dòng)頁(yè)面的點(diǎn)擊事件 5.游戲開(kāi)始的背景添加 6.雙緩存解決閃屏問(wèn)題 7.敵方魚類的生成 8.我方魚的生成 9.我方魚和敵方魚的碰撞檢測(cè) 10.游戲積分以及關(guān)卡的設(shè)置?2.游戲窗口的窗口創(chuàng)建
? ? ? 首先這個(gè)大魚吃小魚游戲在設(shè)計(jì)時(shí)就準(zhǔn)備做成一個(gè)窗口游戲,并且準(zhǔn)備采用Java進(jìn)行開(kāi)發(fā),所以理所當(dāng)然的想到了去使用Swing技術(shù)來(lái)支持開(kāi)發(fā)。當(dāng)然,現(xiàn)如今Swing也早就成為了時(shí)代的產(chǎn)物,逐漸被JavaJX替代了。由于時(shí)間以及難易程度的考慮,這里我們還是采用了Swing技術(shù)來(lái)開(kāi)發(fā)這個(gè)游戲。
3.?EatFish游戲中的5種狀態(tài)
? ? ? ?這里我們首先定義了一個(gè)static的對(duì)象state用來(lái)表示游戲狀態(tài),然后采用switch語(yǔ)句來(lái)判定每種游戲狀態(tài)對(duì)應(yīng)的窗口應(yīng)該做什么事情。首先,state=0表示“游戲未開(kāi)始”,state=1表示“游戲進(jìn)行中”,state=2表示“游戲結(jié)束”,state=3表示“通關(guān)成功”,state=4表示“游戲暫停”。
?4.我方魚類和敵方魚類的創(chuàng)建
敵方魚類:
?
?我方魚類:
? ? ? ?敵我方的魚類本質(zhì)其實(shí)就是一個(gè)個(gè)打的對(duì)象,我們要做的就是去創(chuàng)建它們對(duì)應(yīng)的類然后生成相應(yīng)的對(duì)象,然后通過(guò)createImage方法將這些魚類的圖片于對(duì)象進(jìn)行綁定,然后我們看到的就是如上生動(dòng)的魚類了。此外,由于我方魚類在向左向右移動(dòng)時(shí),以及敵方魚類出現(xiàn)時(shí)都是有左右兩個(gè)方向的,所以我們要提前準(zhǔn)備好連個(gè)方向的動(dòng)態(tài)圖以及在代碼中分別設(shè)計(jì)左右兩個(gè)方向的魚類對(duì)象。
?
?5.我方魚類的移動(dòng)以及大小的變化
? ? ? ?在工具類GameUtil中已經(jīng)定義了UP、DOWM、LEFT、RIGHT,分別對(duì)應(yīng)著鍵盤監(jiān)聽(tīng)事件。我方魚位置的變化由每次先前定義的speed以及當(dāng)前位置決定。比如向右移動(dòng),點(diǎn)擊一次“→”,我方魚X坐標(biāo)位置就加一個(gè)speed的大小。?在我方魚吃到比自己等級(jí)小的魚的時(shí)候,魚的體積是應(yīng)該變大的。這里是由給不同等級(jí)敵方魚類的分?jǐn)?shù)count決定的,當(dāng)吃掉比自己等級(jí)低的魚類后,會(huì)調(diào)用繪制自身的一個(gè)方法paintSelf(),由于參數(shù)中加了count的值,所以我方魚的體積就會(huì)變大。
?
?6.敵方魚類的批量生成
? ? ? ?首先敵方魚類我們?cè)O(shè)計(jì)成了三種:海馬、熱帶魚、劍魚。另外還有一種Boss鯊魚(無(wú)視任何其他魚類,實(shí)現(xiàn)通吃)。這里敵方魚類的生成是和游戲難度等級(jí)掛鉤的。當(dāng)level=1時(shí),我們讓窗口內(nèi)隨機(jī)不斷生成1級(jí)敵方魚:海馬。Level=2時(shí),生成熱帶魚。level=3時(shí),生成劍魚。Level=4時(shí),生成鯊魚。這里敵方魚的生成借助了一個(gè)指針time,將他作為計(jì)數(shù)器,用來(lái)控制每過(guò)多久添加一條敵方魚到敵方魚的集合中。
?
?7.魚類的碰撞檢測(cè)
? ? ? ?魚類碰撞檢測(cè)是大魚吃小魚游戲中很關(guān)鍵的步驟,這里我們采用的是矩形碰撞檢測(cè)的方法,即:通過(guò)獲取魚類自身矩形的方法,用于檢測(cè)不同矩形之間是否相交了來(lái)判斷魚類碰撞。Java中有原生的Rectangle類,我們?yōu)槊總€(gè)魚類生成一個(gè)可以返回Rectangle類的對(duì)象的方法即可。之后再通過(guò)Java中的intersects()方法去比較兩個(gè)返回的Rectangle對(duì)象是否相交就可以判斷出魚類間是否碰撞了。在碰撞后,將等級(jí)小的魚類位置坐標(biāo)更新到窗口之外就達(dá)到了被吃掉的效果
?
8.項(xiàng)目代碼?
Bg類:
package com.shu;import java.awt.*;public class Bg {void paintSelf(Graphics g , int fishLevel){g.drawImage(GameUtils.bgimg,0,0,null);switch (GameWin.state){case 0:GameUtils.drawWord(g,"開(kāi)始",Color.red,80,700,500);break;case 1:GameUtils.drawWord(g,"積分"+GameUtils.count,Color.ORANGE,50,200,120);GameUtils.drawWord(g,"難度"+GameUtils.level,Color.ORANGE,50,600,120);GameUtils.drawWord(g,"等級(jí)"+fishLevel,Color.ORANGE,50,1000,120);break;case 2:GameUtils.drawWord(g,"游戲結(jié)束!!!",Color.red,50,600,400);break;case 3:GameUtils.drawWord(g,"積分"+GameUtils.count,Color.ORANGE,50,200,120);GameUtils.drawWord(g,"難度"+GameUtils.level,Color.ORANGE,50,600,120);GameUtils.drawWord(g,"等級(jí)"+fishLevel,Color.ORANGE,50,1000,120);GameUtils.drawWord(g ,"勝利",Color.red,80,700,500);break;case 4:break;default:}} }?Enamy類:
package com.shu;import java.awt.*;public class Enamy {//定義圖片Image image;//定義物體坐標(biāo)int x;int y;int width;int height;//移動(dòng)速度int speed;//方向int dir = 1;//1為向右 -1為向左//類型int type;//分值int count;//繪制自身方法public void paintSelf(Graphics g){g.drawImage(image,x,y,width,height,null);}//獲取自身矩形用于碰撞檢測(cè)public Rectangle getRec(){return new Rectangle(x,y,width,height);} }//敵方魚左類 class Enamy_1_L extends Enamy {Enamy_1_L(){this.x = -45;this.y = (int)(Math.random()*700 + 100);this.width = 45;this.height = 69;this.speed = 10;this.count = 1;this.type = 1;this.image = GameUtils.enamyl_img;} }//敵方魚右類 class Enamy_1_R extends Enamy_1_L {Enamy_1_R(){this.x = 1400;dir = -1;this.image = GameUtils.enamyr_img;} }class Enamy_2_L extends Enamy {Enamy_2_L(){this.x = -100;this.y = (int)(Math.random()*700+100);this.width = 100;this.height = 100;this.speed = 5;this.count = 2;this.type = 2;this.image = GameUtils.enamyl_2img;} }class Enamy_2_R extends Enamy_2_L {Enamy_2_R(){this.x = 1400;dir = -1;this.image = GameUtils.enamyr_2img;} }class Enamy_3_L extends Enamy {Enamy_3_L(){this.x = -300;this.y = (int)(Math.random()*700+100);this.width = 300;this.height = 150;this.speed = 15;this.count = 3;this.type = 3;this.image = GameUtils.enamyl_3img;}@Overridepublic Rectangle getRec(){return new Rectangle(x + 40, y + 30,width - 80,height +- 60);} }class Enamy_3_R extends Enamy_3_L {Enamy_3_R(){this.x = 1400;dir = -1;this.image = GameUtils.enamyr_3img;} }class Enamy_Boss extends Enamy {Enamy_Boss(){this.x = -1000;this.y = (int)(Math.random()*700+100);this.width = 170;this.height = 170;this.speed = 40;this.count = 0;this.type = 10;this.image = GameUtils.bossimg;} }GameUtils類:
package com.shu;import java.awt.*; import java.util.ArrayList; import java.util.List;public class GameUtils {//方向static boolean UP =false;static boolean DOWN =false;static boolean LEFT =false;static boolean RIGHT =false;//分?jǐn)?shù)static int count = 0;//關(guān)卡等級(jí)static int level = 0;//敵方魚類集合public static List<Enamy> EnamyList = new ArrayList<>();//背景圖public static Image bgimg = Toolkit.getDefaultToolkit().createImage("images/sea.jpg");//敵方魚類public static Image enamyl_img = Toolkit.getDefaultToolkit().createImage("images/enemyFish/fish1_r.gif");public static Image enamyr_img = Toolkit.getDefaultToolkit().createImage("images/enemyFish/fish1_l.gif");public static Image enamyl_2img = Toolkit.getDefaultToolkit().createImage("images/enemyFish/fish2_r.png");public static Image enamyr_2img = Toolkit.getDefaultToolkit().createImage("images/enemyFish/fish2_l.png");public static Image enamyl_3img = Toolkit.getDefaultToolkit().createImage("images/enemyFish/fish3_r.png");public static Image enamyr_3img = Toolkit.getDefaultToolkit().createImage("images/enemyFish/fish3_l.png");public static Image bossimg = Toolkit.getDefaultToolkit().createImage("images/enemyFish/boss.gif");//我方魚類public static Image MyFishimg_L = Toolkit.getDefaultToolkit().createImage("images/myFish/myfish_left.gif");public static Image MyFishimg_R = Toolkit.getDefaultToolkit().createImage("images/myFish/myfish_right.gif");//繪制文字的工具類public static void drawWord(Graphics g,String str ,Color color,int size,int x, int y){g.setColor(color);g.setFont(new Font("仿宋",Font.BOLD,size));g.drawString(str, x, y);}}GameWin類:
package com.shu;import javax.swing.*; import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent;public class GameWin extends JFrame {/** 游戲狀態(tài) 0未開(kāi)始,1游戲中,2通關(guān)失敗,3通關(guān)成功,4暫停,5重新開(kāi)始*///定義游戲默認(rèn)狀態(tài)static int state = 0;Image offScreenImage;//寬高int width = 1440;int height = 900;double random;//計(jì)數(shù)器int time = 0;//背景Bg bg = new Bg();//敵方魚類Enamy enamy;//boss類Enamy boss;//是否生成bossboolean isboss = false;//我方魚類MyFish myFish = new MyFish();public void launch(){this.setVisible(true);this.setSize(width,height);this.setLocationRelativeTo(null);//this.setResizable(false);this.setTitle("大魚吃小魚");this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);this.addMouseListener(new MouseAdapter(){@Overridepublic void mouseClicked(MouseEvent e){super.mouseClicked(e);if(e.getButton() == 1 && state == 0){state = 1;repaint();}if(e.getButton() == 1 && state == 2 || state == 3){reGame();state = 1;}}});//鍵盤移動(dòng)this.addKeyListener(new KeyAdapter() {@Override//按壓public void keyPressed(KeyEvent e) {super.keyPressed(e);//WASDif (e.getKeyCode()==87){GameUtils.UP = true;}if (e.getKeyCode()==83){GameUtils.DOWN = true;}if (e.getKeyCode()==65){GameUtils.LEFT = true;}if (e.getKeyCode()==68){GameUtils.RIGHT = true;}if(e.getKeyCode() == 32){if(state == 1){state = 4;GameUtils.drawWord(getGraphics(),"游戲暫停!!!",Color.red,50,600,400);}else if(state == 4) state = 1;}if(e.getKeyCode() == 75)//后路,按k 增加50積分{GameUtils.count += 50;}}@Override//抬起public void keyReleased(KeyEvent e){super.keyPressed(e);//WASDif(e.getKeyCode() == 87){GameUtils.UP = false;}if(e.getKeyCode() == 83){GameUtils.DOWN = false;}if(e.getKeyCode() == 65){GameUtils.LEFT = false;}if(e.getKeyCode() == 68){GameUtils.RIGHT = false;}}});while(true){repaint();time ++;try{Thread.sleep(40);}catch (InterruptedException e){e.printStackTrace();}}}public void paint(Graphics g){//懶加載模式初始化對(duì)象 雙緩存解決閃屏問(wèn)題offScreenImage = createImage(width,height);Graphics gImage = offScreenImage.getGraphics();bg.paintSelf(gImage,myFish.level);//游戲狀態(tài)switch (state){case 0:break;case 1:myFish.paintSelf(gImage);logic();for(Enamy enamy:GameUtils.EnamyList){enamy.paintSelf(gImage);}if(isboss){boss.x = boss.x + boss.dir * boss.speed;boss.paintSelf(gImage);if(boss.x < 0){gImage.setColor(Color.red);gImage.fillRect(boss.x,boss.y,2400,boss.height/30);}}break;case 2:for(Enamy enamy:GameUtils.EnamyList){enamy.paintSelf(gImage);}if(isboss){boss.paintSelf(gImage);}break;case 3:myFish.paintSelf(gImage);break;case 4:return;default:}g.drawImage(offScreenImage,0,0,null);}void logic(){//關(guān)卡難度if(GameUtils.count<5){GameUtils.level = 0;GameUtils.level = 0;myFish.level = 1;}else if(GameUtils.count<=15){GameUtils.level = 1;}else if(GameUtils.count<=50){GameUtils.level = 2;myFish.level = 2;}else if(GameUtils.count <= 150){GameUtils.level = 3;myFish.level = 2;}else if(GameUtils.count <= 300){GameUtils.level = 4;myFish.level = 3;}else if(GameUtils.count > 300){state = 3;//游戲勝利}random = Math.random();//敵方魚生成switch (GameUtils.level){case 4:if(time % 60 == 0){boss = new Enamy_Boss();isboss = true;}case 3:case 2:if(time % 30 == 0){if(random > 0.5){enamy = new Enamy_3_L();}else{enamy = new Enamy_3_R();}GameUtils.EnamyList.add(enamy);}case 1:if(time % 20 == 0){if(random > 0.5){enamy = new Enamy_2_L();}else{enamy = new Enamy_2_R();}GameUtils.EnamyList.add(enamy);}case 0:if(time % 10 == 0){if(random > 0.5){enamy = new Enamy_1_L();}else{enamy = new Enamy_1_R();}GameUtils.EnamyList.add(enamy);}break;default:}//移動(dòng)方向for(Enamy enamy:GameUtils.EnamyList){enamy.x += enamy.dir * enamy.speed;//和boss魚類碰撞檢測(cè)if(isboss){if(boss.getRec().intersects(enamy.getRec())){enamy.x = -200;enamy.y = -200;}if (boss.getRec().intersects(myFish.getRec()))state = 2;}//我方魚與敵方魚碰撞檢測(cè)if(myFish.getRec().intersects(enamy.getRec())){if(myFish.level >= enamy.type){enamy.x = -200;enamy.y = -200;GameUtils.count = GameUtils.count + enamy.count;}else //我方魚被高級(jí)魚吃掉{state = 2;}}}}//重新開(kāi)始void reGame(){GameUtils.EnamyList.clear();time = 0;myFish.level = 1;GameUtils.count = 0;myFish.x = 700;myFish.y = 500;myFish.width = 50;myFish.height = 50;boss = null;isboss = false;}public static void main(String[] args) {GameWin gameWin = new GameWin();gameWin.launch();} }MyFish類:
package com.shu;import java.awt.*;public class MyFish {//圖片Image img = GameUtils.MyFishimg_L;//坐標(biāo)int x = 700;int y = 500;int width = 50;int height = 50;//移動(dòng)速度int speed = 20;//等級(jí)int level = 1;void logic(){if(GameUtils.UP){y = y - speed;}if(GameUtils.DOWN){y = y + speed;}if(GameUtils.LEFT){x = x - speed;img = GameUtils.MyFishimg_L;}if(GameUtils.RIGHT){x = x + speed;img = GameUtils.MyFishimg_R;}}//繪制自身的方法public void paintSelf(Graphics g){logic();g.drawImage(img,x,y,width + GameUtils.count,height + GameUtils.count,null);}//獲取自身矩形的方法,用于碰撞檢測(cè)public Rectangle getRec(){return new Rectangle(x,y,width + GameUtils.count,height + GameUtils.count);}}9.項(xiàng)目素材
??
?10.項(xiàng)目運(yùn)行結(jié)果演示
?
?
?
?
ps:該游戲并非博主開(kāi)發(fā),來(lái)源是下面的鏈接?
如果大家想看視頻學(xué)習(xí)的話可以到不到一小時(shí)教你用Java做出大魚吃小魚小游戲_Java游戲_Java入門_Java項(xiàng)目_Java面試_Java基礎(chǔ)_Java入門基礎(chǔ)教程_JAVA_Java_嗶哩嗶哩_bilibili進(jìn)行學(xué)習(xí)!這個(gè)up主也會(huì)給大家資料哦!很nice的。
總結(jié)
以上是生活随笔為你收集整理的【项目】游戏开发期末大作业 之 基于Java的小游戏 “大鱼吃小鱼“ (代码素材齐全)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 区块链开发指南_区块链开发权威指南
- 下一篇: PP模块工艺路线明细BAPI