Java實(shí)戰(zhàn)之貪吃蛇小游戲(源碼+注釋)
一、工程文件
二、Main.java
package com.company; import javax.swing.*; public class Main { public static void main(String[] args) { //創(chuàng)建窗體對(duì)象 JFrame frame = new JFrame(); //創(chuàng)建窗體參數(shù)() frame.setBounds(10,10,900,720); //設(shè)置不允許更改大小 //frame.setResizable(false); //設(shè)置關(guān)閉方式 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //添加主題邏輯框架 frame.add(new Mpanel()); //設(shè)置窗體可見 frame.setVisible(true); } }
三、Mpanel.java
package com.company; import javax.imageio.ImageIO; import javax.sound.sampled.*; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Random; //基本套路,繼承JPanel,實(shí)現(xiàn)KeyListener, ActionListener接口 public class Mpanel extends JPanel implements KeyListener, ActionListener { //定義所需要的圖片元素 //標(biāo)題 ImageIcon title; //蛇的身體部位 ImageIcon body; //蛇向上方向的頭 ImageIcon up; //蛇向下方向的頭 ImageIcon down; //蛇向左方向的頭 ImageIcon left; //蛇向右方向的頭 ImageIcon right; //食物元素 ImageIcon food; //定義初始長度 int len = 3; //定義初始分?jǐn)?shù) int score = 0; //存放蛇位置坐標(biāo)的數(shù)組 int[] snakex = new int[750]; int[] snakey = new int[750]; //定義方向 String fx = "R"; //定義游戲是否開始 Boolean isStart = false; //定義游戲是否失敗 Boolean isFailed = false; //定義游戲時(shí)鐘,在此可以設(shè)置蛇移動(dòng)速度,默認(rèn)100ms Timer timer = new Timer(100,this); //定義食物的坐標(biāo) int foodx; int foody; //引入隨機(jī)數(shù),用于生成食物的隨機(jī)位置 Random random = new Random(); //定義背景音樂 Clip bgm; //構(gòu)造方法 public Mpanel(){ //加載圖片元素 loadImages(); //初始化數(shù)據(jù) initSnake(); //設(shè)置聚焦 this.setFocusable(true); //設(shè)置鍵盤監(jiān)聽 this.addKeyListener(this); //開始計(jì)時(shí) timer.start(); //加載背景音樂 loadBGM(); } //設(shè)置繪圖元素 public void paintComponent(Graphics g){ //調(diào)用父類方法 super.paintComponent(g); //設(shè)置背景顏色為白色 this.setBackground(Color.white); //設(shè)置標(biāo)題元素位置 title.paintIcon(this,g,25,11); //設(shè)置白色背景填充位置 g.fillRect(25,75,850,600); //設(shè)置畫筆顏色為白色 g.setColor(Color.white); //設(shè)置長度顯示 g.drawString("Len: " + len,750,35); //設(shè)置分?jǐn)?shù)顯示 g.drawString("Score: " + score,750,50); //根據(jù)方向調(diào)用相應(yīng)的蛇頭元素 if(fx == "R"){ right.paintIcon(this,g,snakex[0],snakey[0]); } else if(fx == "L"){ left.paintIcon(this,g,snakex[0],snakey[0]); } else if(fx == "U"){ up.paintIcon(this,g,snakex[0],snakey[0]); } else if(fx == "D"){ down.paintIcon(this,g,snakex[0],snakey[0]); } for(int i=1;i<len;i++){ body.paintIcon(this,g,snakex[i],snakey[i]); } //調(diào)用食物元素 food.paintIcon(this,g,foodx,foody); //游戲開始的處理 if(isStart == false){ //設(shè)置畫筆顏色 g.setColor(Color.white); //設(shè)置字體 g.setFont(new Font("arial",Font.BOLD,40)); //設(shè)置具體文字 g.drawString("Press Space To Start",250,300); } //游戲失敗的處理 if(isFailed){ //設(shè)置畫筆顏色 g.setColor(Color.red); //設(shè)置字體 g.setFont(new Font("arial",Font.BOLD,40)); //設(shè)置具體文字 g.drawString("Failed: Press Space To Start",250,300); } } //初始化數(shù)據(jù) public void initSnake(){ len = 3; snakex[0] = 100; snakey[0] = 100; snakex[1] = 75; snakey[1] = 100; snakex[2] = 50; snakey[2] = 100; //設(shè)置食物的初始隨機(jī)生成位置 foodx = 25 + 25 * random.nextInt(34); foody = 75 + 25 * random.nextInt(24); //設(shè)置初始值 fx = "R"; score = 0; } //接口要求的實(shí)現(xiàn)方法 @Override public void keyTyped(KeyEvent e) { } @Override public void keyPressed(KeyEvent e) { //獲取鍵盤監(jiān)聽 int keyCode = e.getKeyCode(); //空格 if(keyCode == KeyEvent.VK_SPACE){ //如果失敗則重置信息 if(isFailed){ isFailed = !isFailed; //重新開始 initSnake(); } //設(shè)置開始 else { isStart = !isStart; } //判斷開始后循環(huán)播放背景音樂 if(isStart){ bgm.loop(Clip.LOOP_CONTINUOUSLY); } //未開始和暫停則不播放背景音樂 else { bgm.stop(); } //重新繪圖 repaint(); } //右鍵處理并設(shè)置不能回頭 else if(keyCode == KeyEvent.VK_LEFT && fx != "R"){ fx = "L"; } //左鍵 else if(keyCode == KeyEvent.VK_RIGHT && fx != "L"){ fx = "R"; } //上鍵 else if(keyCode == KeyEvent.VK_UP && fx != "D"){ fx = "U"; } //下鍵 else if(keyCode == KeyEvent.VK_DOWN && fx != "U"){ fx = "D"; } } //接口要求的實(shí)現(xiàn)方法 @Override public void keyReleased(KeyEvent e) { } //事件監(jiān)聽 @Override public void actionPerformed(ActionEvent e) { //開始且沒有失敗的情況 if(isStart && !isFailed){ //循環(huán)移動(dòng)蛇身 for(int i=len-1;i>0;i--){ snakex[i]=snakex[i-1]; snakey[i]=snakey[i-1]; } //向右移動(dòng)并判斷是否撞墻,撞墻則失敗 if(fx == "R"){ snakex[0]=snakex[0]+25; if(snakex[0]>825)isFailed=true; } //向左移動(dòng)并判斷是否撞墻,撞墻則失敗 else if(fx == "L"){ snakex[0]=snakex[0]-25; if(snakex[0]<50)isFailed=true; } //向上移動(dòng)并判斷是否撞墻,撞墻則失敗 else if(fx == "U"){ snakey[0]=snakey[0]-25; if(snakey[0]<100)isFailed=true; } //向下移動(dòng)并判斷是否撞墻,撞墻則失敗 else if(fx == "D"){ snakey[0]=snakey[0]+25; if(snakey[0]>625)isFailed=true; } //吃到食物的判斷 if(snakex[0]==foodx&&snakey[0]==foody){ //身體加長,分加多,并且隨機(jī)生成新食物 len++; score += 10; foodx = 25 + 25 * random.nextInt(34); foody = 75 + 25 * random.nextInt(24); } //撞到自身的處理 for(int i=1;i<len;i++){ if(snakex[i]==snakex[0] && snakey[i]==snakey[0]){ isFailed = true; } } //重新繪圖 repaint(); } //事件刷新 timer.start(); } //加載背景音樂 public void loadBGM(){ try { //從類所在文件引入 bgm = AudioSystem.getClip(); InputStream is = this.getClass().getClassLoader().getResourceAsStream("com/company/sound/bgm.wav"); AudioInputStream ais = AudioSystem.getAudioInputStream(new BufferedInputStream(is)); bgm.open(ais); //bgm.loop(Clip.LOOP_CONTINUOUSLY); } //相應(yīng)的異常處理 catch (LineUnavailableException e) { e.printStackTrace(); } catch (UnsupportedAudioFileException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } //加載圖片 public void loadImages(){ InputStream is; try { //依次添加響應(yīng)元素 is = getClass().getClassLoader().getResourceAsStream("com/company/img/title.jpg"); title = new ImageIcon(ImageIO.read(is)); is = getClass().getClassLoader().getResourceAsStream("com/company/img/body.png"); body = new ImageIcon(ImageIO.read(is)); is = getClass().getClassLoader().getResourceAsStream("com/company/img/up.png"); up = new ImageIcon(ImageIO.read(is)); is = getClass().getClassLoader().getResourceAsStream("com/company/img/down.png"); down = new ImageIcon(ImageIO.read(is)); is = getClass().getClassLoader().getResourceAsStream("com/company/img/left.png"); left = new ImageIcon(ImageIO.read(is)); is = getClass().getClassLoader().getResourceAsStream("com/company/img/right.png"); right = new ImageIcon(ImageIO.read(is)); is = getClass().getClassLoader().getResourceAsStream("com/company/img/food.png"); food = new ImageIcon(ImageIO.read(is)); } catch (IOException e) { e.printStackTrace(); } } }
四、效果
到此這篇關(guān)于Java實(shí)戰(zhàn)之貪吃蛇小游戲(源碼+注釋)的文章就介紹到這了,更多相關(guān)java貪吃蛇小游戲內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于Spring中的@Configuration中的proxyBeanMethods屬性
這篇文章主要介紹了關(guān)于Spring中的@Configuration中的proxyBeanMethods屬性,需要的朋友可以參考下2023-07-07springboot添加多數(shù)據(jù)源的方法實(shí)例教程
這篇文章主要給大家介紹了關(guān)于springboot添加多數(shù)據(jù)源方法的相關(guān)資料,在實(shí)際開發(fā)中經(jīng)??赡苡龅皆谝粋€(gè)應(yīng)用中可能要訪問多個(gè)數(shù)據(jù)庫多的情況,需要的朋友可以參考下2023-09-09深入理解Java基礎(chǔ)之try-with-resource語法糖
這篇文章主要介紹了深入理解Java基礎(chǔ)之try-with-resource語法糖,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-02-02Linux實(shí)時(shí)查看Java接口數(shù)據(jù)的案例方法
在Linux系統(tǒng)中實(shí)時(shí)查看Java接口數(shù)據(jù)通常涉幾個(gè)步驟,通過示例代碼說明如何使用Python的requests庫和Linux的cron作業(yè)來定期查詢Java應(yīng)用程序的接口并打印結(jié)果,感興趣的朋友跟隨小編一起看看吧2024-06-06詳解Java Bellman-Ford算法原理及實(shí)現(xiàn)
Bellman-Ford算法與Dijkstra算法類似,都是以松弛操作作為基礎(chǔ),Bellman-Ford算法是對(duì)所有邊都進(jìn)行松弛操作,本文將詳解Bellman-Ford算法原理及實(shí)現(xiàn),感興趣的可以了解一下2022-07-07spring?jpa設(shè)置多個(gè)主鍵遇到的小坑及解決
這篇文章主要介紹了spring?jpa設(shè)置多個(gè)主鍵遇到的小坑及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06MyBatis-Plus枚舉和自定義主鍵ID的實(shí)現(xiàn)步驟
這篇文章主要給大家介紹了關(guān)于MyBatis-Plus枚舉和自定義主鍵ID的相關(guān)資料,文中通過實(shí)例代碼以及圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-02-02