文章目录

  • 一、使用知识
  • 二、使用工具
  • 三、开发过程
    • 3.1素材准备
    • 3.2 开发过程
      • 3.2.1 创建项目
      • 3.2.2 页面设计
      • 3.23 画蛇
      • 3.24创建蛇的食物
      • 3.2.5增加蛇的存活状态
      • 3.2.6 增加按钮
  • 四 打jar包
  • 源码

在我们学习java的时候,为了提高我们的兴趣,我们经常会使用所学到的知识去做一些小游戏,这篇blog就介绍了一个经典而且好理解的小游戏-贪吃蛇。

访问个人blog 经典小游戏贪吃蛇

一、使用知识

  • Jframe
  • GUI
  • 双向链表
  • 线程

二、使用工具

  • IntelliJ IDEA
  • jdk 1.8

三、开发过程

3.1素材准备

首先在开发之前应该准备一些素材,已备用,我主要找了一个图片以及一段优雅的音乐。

3.2 开发过程

3.2.1 创建项目
  • 首先进入idea首页 open一个你想放项目的文件夹
  • 进入之后右键文件名 new 一个新的Directory——Snake

  • 把准备好的素材复制到文件中
  • 继续创建目录 src/Sanke
  • 选中src Mark Directory as — Souces 把src添加为根目录
3.2.2 页面设计
  • 创建java Class 文件 Snake - new - java class SnakeName 接下来的时候会对这个SnakeName.java里面的代码不停完善
    首先设置窗口格式
package Sanke;import javax.swing.*;/*** @author Swyee**/
public class SnakeGame extends JFrame {SnakeGame(){this.setBounds(100, 50, 700, 500);//设置窗口大小this.setLayout(null);//更改layout 以便添加组件this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭窗口的状态this.setResizable(false);//窗口不可以改变大小this.setVisible(true);//设置焦点状态为true}public static void main(String[] args) {new SnakeGame();}}

  • 继续创建新的文件 SnakeGrid
package Sanke;import java.awt.*;/*** @author Swyee**/
public class SnakeGrid extends Panel {SnakeGrid(){this.setBounds(0, 0, 700, 400);this.setBackground(Color.black);设置背景颜色}}
  • 将页面引用到SnakeGame.java中
package Sanke;import javax.swing.*;/*** @author Swyee**/
public class SnakeGame extends JFrame {SnakeGrid snakeGrid= new SnakeGrid();SnakeGame(){this.setBounds(100, 50, 700, 500);//设置窗口大小this.setLayout(null);//更改layout 以便添加组件this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭窗口的状态this.setResizable(false);//窗口不可以改变大小this.add(snakeGrid);this.setVisible(true);//设置焦点状态为true}public static void main(String[] args) {new SnakeGame();}}

运行样式

  • 设置背景图片 背景音乐
    在SnakeGrid.java中增加Music方法 设置画笔 绘图
package Sanke;import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.*;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.swing.JPanel;/*** @author Swyee**/
public class SnakeGrid extends JPanel {ImageIcon image = new ImageIcon("Snake/sky.jpg");//图片文件地址File f= new File("Snake/music.wav");//音乐文件地址SnakeGrid(){this.setBounds(0, 0, 700, 400);this.setBackground(Color.black);}/*** 设置画笔* @param g*/@Overridepublic void paint(Graphics g) {super.paint(g);image.paintIcon(this, g, 0, 0); //设置背景图片}//读取音乐文件void Music(){try {URI uri = f.toURI();URL url = uri.toURL();AudioClip aau= Applet.newAudioClip(url);aau.loop();} catch (MalformedURLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}
}

在SnakeName中调用

package Sanke;import javax.swing.*;/*** @author Swyee**/
public class SnakeGame extends JFrame {SnakeGrid snakeGrid= new SnakeGrid();SnakeGame(){this.setBounds(100, 50, 700, 500);//设置窗口大小this.setLayout(null);//更改layout 以便添加组件this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭窗口的状态this.setResizable(false);//窗口不可以改变大小this.add(snakeGrid);//设置焦点snakeGrid.setFocusable(true);snakeGrid.requestFocus();snakeGrid.Music();//调用打开音乐的方法this.setVisible(true);//设置焦点状态为true}public static void main(String[] args) {new SnakeGame();}}

呈现

3.23 画蛇

蛇的身体将会有双向链表组成,双向链表能记录一个节点的上一个节点和下一个节点。蛇的移动其实就是节点的变化,从而达到一种移动的视觉。

  • 新建java Snake 创建节点
package Sanke;import java.awt.Graphics;public class Snake {public static final int span=20;//间距public static final String up="u";public static final String down="d";public static final String left="l";public static final String right="r";class Node{int row;int col;String dir;//方向Node next;Node pre;Node(int row,int col,String dir){this.row = row;this.col = col;this.dir = dir;}public void draw(Graphics g) {g.fillOval(col*span, row*span, span,span);}}}
  • 画蛇
    在snake里面增加draw()方法
/*把蛇画出来*/public void draw(Graphics g) {g.setColor(Color.yellow);for(Node n=head;n!=null;n=n.next){n.draw(g);g.setColor(Color.green);}}

在SnakeGrid.java中创建蛇

Snake snake = new Snake();//创建蛇

并在paint中调用snake.draw(g);

 /*** 设置画笔* @param g*/@Overridepublic void paint(Graphics g) {super.paint(g);image.paintIcon(this, g, 0, 0); //设置背景图片snake.draw(g);}
  • 控制蛇的移动
    在snake中增加键盘调用的方法:
/*调用键盘的上下左右键head.dir记录现在操作的是什么按钮,从而更改蛇的状态向上移送时,下键失效,其他四个方向也是如此判断*/public void keyboard(KeyEvent e) {switch(e.getKeyCode()){case KeyEvent.VK_UP:if(head.dir.equals(down)){break;}head.dir=up;break;case KeyEvent.VK_DOWN:if(head.dir.equals(up)){break;}head.dir=down;break;case KeyEvent.VK_LEFT:if(head.dir.equals(right)){break;}head.dir=left;break;case KeyEvent.VK_RIGHT:if(head.dir.equals(left)){break;}head.dir=right;break;default:break;}}

增加头部的方法

/*
增加头部
不管移动哪个方向都是在相应位置增加一个节点*/public void addHead(){Node node = null;switch (head.dir){case "l":node = new Node(head.row,head.col-1,head.dir);break;case "r":node = new Node(head.row,head.col+1,head.dir);break;case "u":node = new Node(head.row-1,head.col,head.dir);break;case "d":node = new Node(head.row+1,head.col,head.dir);break;default:break;}node.next=head;head.pre=node;head=node;}

删除尾部的方法

/*
删除尾部 删除最后一个节点*/
public void deleteTail(){tail.pre.next=null;tail=tail.pre;
}

增加move的方法

/*
增加move方法 一增一减,实现蛇的移动*/public void move() {addHead();deleteTail();}

在SnakeGrid中创建一个线程类,用来执行蛇的移动方法

class SnakeThread extends Thread{@Overridepublic void run() {while (true){try {Thread.sleep(300);//沉睡300ms 用来控制蛇的移动速度} catch (InterruptedException e) {e.printStackTrace();}repaint();//每次沉睡完之后都执行一下repaint()方法,重新绘画} }

print方法中调用remove 在SnakeGrid()创建键盘监听事件:

package Sanke;import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.swing.JPanel;/*** @author Swyee**/
public class SnakeGrid extends JPanel {Snake snake = new Snake();//创建蛇ImageIcon image = new ImageIcon("Snake/sky.jpg");//图片文件地址File f= new File("Snake/music.wav");//音乐文件地址SnakeThread snakeThread = new SnakeThread();SnakeGrid(){this.setBounds(0, 0, 700, 400);this.setBackground(Color.black);snakeThread.start();this.addKeyListener(new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {snake.keyboard(e);}});}/*** 设置画笔* @param g*/@Overridepublic void paint(Graphics g) {super.paint(g);image.paintIcon(this, g, 0, 0); //设置背景图片snake.move();//蛇移动snake.draw(g);}//读取音乐文件void Music(){try {URI uri = f.toURI();URL url = uri.toURL();AudioClip aau= Applet.newAudioClip(url);aau.loop();} catch (MalformedURLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}class SnakeThread extends Thread{@Overridepublic void run() {while (true){try {Thread.sleep(300);//沉睡300ms 用来控制蛇的移动速度} catch (InterruptedException e) {e.printStackTrace();}repaint();//每次沉睡完之后都执行一下repaint()方法,重新绘画}}
}}

执行main方法可以看到可以通过键盘进行控制移动了

3.24创建蛇的食物

增加食物的实例 以及画食物的方法 反映食物坐标的方法 新建Food.java

package Sanke;import java.awt.*;public class Food {int row;int col;Food(){row = 10;//创建食物的大小col  =10;}public void repearShow(){row = (int)(Math.random()*18);//生成随机数 乘以食物的大小可以得到坐标col = (int)(Math.random()*32);}public void draw(Graphics g) {//把食物画出来g.setColor(Color.red);g.fillRect(col*20, row*20, 20, 20);//表示坐标}public Rectangle getCoordinates(){return new Rectangle(col*20,row*20,20,20);//获得食物的坐标}}

修改Snake.java 增加判断蛇头位置的方法,修改午无参构造方法,改为有参构造,把food添加进来 修改move方法

package Sanke;import java.awt.*;
import java.awt.event.KeyEvent;/*** @author Swyee*/
public class Snake {public static final int span=20;//间距public static final String up="u";public static final String down="d";public static final String left="l";public static final String right="r";Node body;//蛇的身体Node head;//蛇的头部Node tail;//蛇的头部Food food;Snake(Food food){body = new Node(5,20,left);head = body;tail = body;this.food=food;}class Node{int row;int col;String dir;//方向Node next;Node pre;Node(int row,int col,String dir){this.row = row;this.col = col;this.dir = dir;}public void draw(Graphics g) {g.fillOval(col*span, row*span, span,span);//坐标}}/*把蛇画出来*/public void draw(Graphics g) {g.setColor(Color.yellow);for(Node n=head;n!=null;n=n.next){n.draw(g);g.setColor(Color.green);}}/*调用键盘的上下左右键head.dir记录现在操作的是什么按钮,从而更改蛇的状态向上移送时,下键失效,其他四个方向也是如此判断*/public void keyboard(KeyEvent e) {switch(e.getKeyCode()){case KeyEvent.VK_UP:if(head.dir.equals(down)){break;}head.dir=up;break;case KeyEvent.VK_DOWN:if(head.dir.equals(up)){break;}head.dir=down;break;case KeyEvent.VK_LEFT:if(head.dir.equals(right)){break;}head.dir=left;break;case KeyEvent.VK_RIGHT:if(head.dir.equals(left)){break;}head.dir=right;break;default:break;}}
/*
增加头部*/public void addHead(){Node node = null;switch (head.dir){case "l":node = new Node(head.row,head.col-1,head.dir);break;case "r":node = new Node(head.row,head.col+1,head.dir);break;case "u":node = new Node(head.row-1,head.col,head.dir);break;case "d":node = new Node(head.row+1,head.col,head.dir);break;default:break;}node.next=head;head.pre=node;head=node;}
/*
删除尾部*/
public void deleteTail(){tail.pre.next=null;tail=tail.pre;
}
/*
增加move方法*/public void move() {addHead();if(this.getSnakeRectangle().intersects(food.getCoordinates())){//当蛇头与食物重合的时候 蛇吃食物 食物刷新,不再删除尾巴,达到一种蛇增长的要求food.repearShow();}else{deleteTail();}}public Rectangle getSnakeRectangle(){//获取蛇头的坐标return new Rectangle(head.col*span,head.row*span,span,span);}
}

在修改snakegrid.java 贪吃蛇的功能就基本实现了

Food food = new Food();Snake snake = new Snake(food);//创建蛇ImageIcon image = new ImageIcon("Snake/sky.jpg");//图片文件地址File f= new File("Snake/music.wav");//音乐文件地址SnakeThread snakeThread = new SnakeThread();
 @Overridepublic void paint(Graphics g) {super.paint(g);image.paintIcon(this, g, 0, 0); //设置背景图片snake.move();//蛇移动snake.draw(g);food.draw(g);}
3.2.5增加蛇的存活状态

在Snake中增加蛇的存活状态,每一次移动都判断下是否存活,修改SnakeGrid的线程,执行时进行判断是否存活

public void DeadOrLive(){//超出边框范围 蛇头撞到身体 游戏结束if(head.row<0 || head.row>rows-1 || head.col<0 ||head.col>cols){islive=false;}for(Node n=head.next;n!=null;n=n.next){if(n.col==head.col && n.row==head.row){islive=false;}}}
public void move() {addHead();if(this.getSnakeRectangle().intersects(food.getCoordinates())){//当蛇头与食物重合的时候 蛇吃食物 食物刷新,不再删除尾巴,达到一种蛇增长的要求food.repearShow();}else{deleteTail();}DeadOrLive();//每移动一步都要判断一下是否存活}
 class SnakeThread extends Thread{boolean flag = true;@Overridepublic void run() {while (Snake.islive && flag) {try {Thread.sleep(300);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}if (Snake.islive ) {repaint();}}if (!flag == false) {JOptionPane.showMessageDialog(SnakeGrid.this, "游戏结束");}}
3.2.6 增加按钮
  • 最后的时候,给这个小游戏增加几个按钮,用来实现暂停开始
    新建Button.java
package Sanke;import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;public class Button extends JPanel{public static boolean isMove=true;//表示运行状态 SnakeGrid snakeGrid;Button(SnakeGrid snakeGrid){this.snakeGrid=snakeGrid;this.setBounds(0, 400, 700, 100);JButton jb1 = new JButton("暂停游戏");JButton jb2 = new JButton("继续游戏");JButton jb3 = new JButton("重新游戏");this.add(jb1);this.add(jb2);this.add(jb3);jb1.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {isMove=false;}});jb2.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {isMove=true;snakeGrid.setFocusable(true);snakeGrid.requestFocus();}});jb3.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {//重新创建蛇等 重新开始游戏snakeGrid.snakeThread.stopThread();Food food = new Food();snakeGrid.food=food;snakeGrid.snake=new Snake(food);Snake.islive=true;isMove=true;SnakeGrid.SnakeThread st = snakeGrid.new SnakeThread();snakeGrid.snakeThread=st;st.start();snakeGrid.setFocusable(true);snakeGrid.requestFocus();}});}
}

再修改SnakeGrid中的thread

package Sanke;import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.swing.JPanel;/*** @author Swyee**/
public class SnakeGrid extends JPanel {Food food = new Food();Snake snake = new Snake(food);//创建蛇ImageIcon image = new ImageIcon("Snake/sky.jpg");//图片文件地址File f= new File("Snake/music.wav");//音乐文件地址SnakeThread snakeThread = new SnakeThread();SnakeGrid(){this.setBounds(0, 0, 700, 400);this.setBackground(Color.black);snakeThread.start();this.addKeyListener(new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {snake.keyboard(e);}});}/*** 设置画笔* @param g*/@Overridepublic void paint(Graphics g) {super.paint(g);image.paintIcon(this, g, 0, 0); //设置背景图片snake.move();//蛇移动snake.draw(g);food.draw(g);}//读取音乐文件void Music(){try {URI uri = f.toURI();URL url = uri.toURL();AudioClip aau= Applet.newAudioClip(url);aau.loop();} catch (MalformedURLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}class SnakeThread extends Thread{boolean flag = true;@Overridepublic void run() {while(Snake.islive &&flag){try {Thread.sleep(300);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}if(Snake.islive&& Button.isMove){repaint();}}if(!flag==false){JOptionPane.showMessageDialog(SnakeGrid.this, "游戏结束");}}public void stopThread(){flag=false;}}
}

在主页面中把按钮添加上去

package Sanke;import javax.swing.*;/*** @author Swyee**/
public class SnakeGame extends JFrame {SnakeGrid snakeGrid= new SnakeGrid();Button button = new Button(snakeGrid);SnakeGame(){this.setBounds(100, 50, 700, 500);//设置窗口大小this.setLayout(null);//更改layout 以便添加组件this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭窗口的状态this.setResizable(false);//窗口不可以改变大小this.add(snakeGrid);this.add(button);//设置焦点snakeGrid.setFocusable(true);snakeGrid.requestFocus();snakeGrid.Music();//调用打开音乐的方法this.setVisible(true);//设置焦点状态为true}public static void main(String[] args) {new SnakeGame();}}


到这里这个小游戏就全部做完了,当然也可以在其基础上增加其他功能

也可以把这个小游戏打成jar包的形式进行运行
,将打好的jar包和资源文件放在同一个目录下,即可正常运行访问

四 打jar包

idea打jar包方式:
https://blog.csdn.net/qq_44433261/article/details/107433540
命令行运行jar包方式:
https://blog.csdn.net/qq_44433261/article/details/107433355

源码

最后附上源码链接:
链接: https://pan.baidu.com/s/1iUmSUnvpi_YKUNsPs3ugIQ 提取码: zxsk

Java经典小游戏——贪吃蛇简单实现(附源码)相关推荐

  1. C#winform 经典小游戏贪吃蛇V1.0(一)

    关于V1.0   为什么我给这个版本定义为V1.0嘞,因为在这个版本中仅仅实现了蛇的自动行进,按键对蛇的行进方向的操作和吃掉食物蛇身的增长等操作. 但是任何事情都必须一步一步来,当我们完成这个乞丐版的 ...

  2. JAVA练习小游戏——贪吃蛇小游戏 PLUS版

    目录 基础版本 新增内容 1.添加START开始界面 2.新增背景音乐 3.添加SCORE计分 4.新增游戏机制 代码实现 实机演示 基础版本 JAVA练习小游戏--贪吃蛇小游戏_timberman6 ...

  3. C++小游戏笔记——射击小行星(附源码)

    C++小游戏笔记--射击小行星(附源码) 游戏展示图 一.飞船 1.飞船的绘制 2.飞船的角度 二.小行星 1.小行星的绘制 2."凹凸不平"效果的形成 3.小行星的分裂 三.子弹 ...

  4. Android 300行代码实现经典小游戏贪吃蛇

    前言 贪吃蛇算是一个非常经典的小游戏了,本人00后,初次游玩是在小时候用诺基亚手机进行游玩的.这次算是复刻一下经典hhh,贪吃蛇算是一个制作起来非常简单的小游戏,本文使用Kotlin语言进行开发,用J ...

  5. 如何用不到200行代码实现经典小游戏贪吃蛇,附源代码及详细实现思路

    不多废话,直接上链接 链接:https://pan.baidu.com/s/1ZKtVNhzR4fIzNZSGWgFKQw?pwd=zglt  提取码:zglt 有需要的好兄弟们可以直接取用,想要了解 ...

  6. python经典小游戏贪吃蛇_Python开发贪吃蛇小游戏

    独完成一个设计的工作量的可能性很小,因为你总会遇到这样那样的问题.在编写的时候,一个小小的符号,一个常量变量的设定,这都无不考量着我们的细心与严谨.所以,我理解到了作为一个编程人员首先应具有良好的心理 ...

  7. 《游戏学习》教你上手一个简单的java小游戏《打纸飞机》附源码

    源码下载地址: https://download.csdn.net/download/weixin_40986713/20701376 项目结构目录 部分代码展示 import java.awt.Fo ...

  8. Python小游戏——坦克飞机大战(附源码)

    一.学习目标: 1.掌握用Python写自己的小游戏. 2.掌握面向对象编程语言的特点. 3.掌握Python基础 二.学习内容: 1.Python文件操作. 2.Python 类的定义与使用 3.P ...

  9. ZZNUOJ_用Java编写程序实现1527:简单加法(附源码)

    题目描述 计算一个数与它各位数字之和.   如输入123,123+1+2+3=129:   123456,123456+1+2+3+4+5+6=123477: 输入 输入数据有多组,每组只有一行,包含 ...

最新文章

  1. 30分钟搞定数据竞赛刷分夺冠神器LightGBM!
  2. 揭秘毕加索被隐藏千年的“画中画”,神经网络让它重新面世
  3. C++二维数组名的再探索
  4. 2018 年视频监控企业竞争力分析 海康威视连续七年蝉联全球第一
  5. 【代码笔记】iOS-UILable电子表显示
  6. vaspkit使用_VASP 的光学性质计算及 vaspkit 的安装与使用
  7. wpf 界面加载 Command
  8. 排序之插入排序(二分法)
  9. qt中的句柄类,实体类
  10. (二)外显子组数据分析之原始数据sra数据下载
  11. Summery about show input info bar of MTK
  12. maven-聚合工程
  13. 共轭梯度法确实存在数值精度的要求
  14. 51单片机 8x8LED点阵屏循环显示数字0~9
  15. verilog “function”函数一直报错解决办法
  16. 懂技术的产品就是全栈产品?扯.J.B.淡
  17. 洛谷_3975 [TJOI2015]弦论(后缀自动机)
  18. 第十三次CCF认证经历
  19. 绿联USB4扩展坞,VL830拆解分析
  20. 百度地图android版 v4.0,百度地图4.0正式发布 支持iOS与Android

热门文章

  1. js月份的计算公式_JS实现招财宝约定年化收益率6.30%(按月等额本金还款)计算公式...
  2. Solidity 中的对数计算
  3. Silverlight入门教程(奋斗的小鸟)_PDF 电子书
  4. 搜狗广告投放平台介绍!搜狗广告投放有效果吗?
  5. 上周热点回顾(7.29-8.4)
  6. 工作中使用到的单词(软件开发)_第二版
  7. 有关《快速软件开发》的几点不解 By Yiming Qian
  8. 22-06-24 西安 linux(01) linux环境搭建、常用命令、vim编辑
  9. 条件变量(生产者消费者问题)
  10. 一个人的宽度决定了他的高度