目录:
- 1.贪吃蛇游戏介绍:(该游戏代码不是很完善,可后续不断优化哦)
- 2.贪吃蛇游戏的代码操作步骤/讲解:
- 3.贪吃蛇游戏的详细代码 :
- 3.1MPanel.java
- 3.2 Msnake.java
- 4.贪吃蛇游戏的代码分享 (获得代码 和 其中游戏图片)
- 5.(继续优化/完善中.....)
1.贪吃蛇游戏介绍:(该游戏代码不是很完善,可后续不断优化哦)
2.贪吃蛇游戏的代码操作步骤/讲解:
* 1:设计游戏图纸
* 2:设计游戏窗体
* 3:在窗体上添加面板
* 4:在面板上添加画笔方法(paintComponent方法)
*5 用super调用父类的paintComponent (来每一次刷新界面)
* 6:在面板上添加标题:用ImageIcon导入图片类来导入图片,然后调用有关方法
* 7:在面板上添加黑色游戏区框(添加黑色方框)-----在画新成分的paintComponent方 法中 直接用画笔的天面方框的g.fillRect()来填满方框(已达到添加黑色方框的)
* 8:放静态的蛇(包括身体和头):—与在画板上添加标题是差不多的。都是放入图片,与其格式类似
* 9:定义蛇的数据结构 ----记录蛇的长度并把蛇能达到的x y 坐标记录在数组中。数据结 构:意思是将蛇的部位的x y坐标放入到数组中(存放在数组中,以方便调用,此即为蛇 的数据结构)
* 10:控制蛇头的方向----通过设置变量 +if else语句来控制蛇头的方向变化。
* 11:放上开始字符提示----用画笔的g.drawString方法在面板直接有字符串出现 (要先改变画 笔的颜色,用setColor()方法来改变画笔的颜色 +设计字体的有关内容,如字体类型、大 小、是否粗体等的setFont方法)
* 12 :设置boolean变量来显示是否是开始状态,且结合此状态来判断开始字符提示是否应 该没有(不打印了)----只有状态是false才输出开始提示
* 13:设置获取键盘事件-----设置获取焦点的setFocusable()方法,这样就可获取键盘事件
* 14:设置键盘监听器 ----通过addKeyListener()方法来设置键盘监听器,(自己监听自己 是键盘事件,那就要实现KeyListener的接口)
* 15:重写实现KeyListener接口的方法
* 16:通过设置变量 + getKeyCode()方法 来获取到键盘敲了哪个数字 (因为每一个按键都 对应一个数字,getKeyCode()方法能获取到键盘敲了哪个数字)
* 17:判断键盘是否敲了空格键,如果敲了就改变isstarted的状态 (KeyEvent.VK_SPACA : 表示空格键)
* 18:按空格键开始游戏
* 19:设置时钟—让程序到成运行结束和 运行结束后找数: 一般游戏是找回自身的即找 回this。 (要实现ActionListener接口才能设置时钟)(时间到了就会调用重写的 ActionListener的方法)
* 20 :实现ActionListener接口—让时钟能够设置
* 21 :重写接口方法
* 22:在重写的方法中,重写paintComponent方法(即repaint) +通过Timer.start() 让时钟再次开始
* 23:在构造方法中让时钟启动起来。
* 24 :让身体移动起来
* 25 :让头发生移动 ----通过snakex[0] =snakex[0] + 25;让蛇一直向右移动
* 26 :给头的移动范围增加边界----用if语句 +如果snakex[0] =850,就有snakex[0] =25, 通过此让其回到反方向的边界处。(到了边界就从反方向边界出现)
* 27:实现暂停 ----按空格就可有蛇不再跑 —(反正括号里是true则输出其语句,如果 是false则不输出)
* 28:根据键盘事件改编direction的值
* 29 :根据direction的值的变化来改变头的移动方向—actionPerformed(ActionEvent) 方法处写代码。因为这是这是与移动有关的内容
*30:添加食物—打印食物的图片 + 随机生成食物的坐标
* 31:吃掉食物
* 32 :判断蛇是否失败 ----设置变量isFiled =false; --当没死的时候才会移动
—用for语句判断如果蛇头的坐标与食物的坐标重合的时候,把 isFiled =true(这样会让蛇没法移动了)
* 33:游戏结束提示----当isFiled = true的时候就用drawString输出一个结束字符串提 示游戏结束 (和打印开始提示很类似)
* 34:当游戏结束后,有红色提示出现后,再按空格时不想要白色的开始提示---- 在监听空格键那里把开始提示的变量改为相反的值即可(即把)-
* 34:游戏结束提示 和 实现重新开始功能
* 35:添加分数和长度
……….
( 接下来的步骤可自己结合代码深入理解 )
3.贪吃蛇游戏的详细代码 :
3.1MPanel.java
package moonsnake;import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;/****创建游戏面板格式:(讲解:可new对象 或者直接继承JPnanel,让其为父类,获得其属性和方法)*关键字为:JPanel*//*** 要在面板中画东西,如设置颜色等,前面都要有这两行内容* public void paintComponent(Graphics g) { * super.paintComponent(g); **/
public class MPanel extends JPanel implements KeyListener, ActionListener { //实现接口,让该面板能监听//创建图像类,传入图片到面板中。ImageIcon title = new ImageIcon("src/title.jpg"); //用ImageIcon有关的知识点来引入图片ImageIcon body= new ImageIcon("src/body.png"); ImageIcon up= new ImageIcon("src/up.png");ImageIcon down= new ImageIcon("src/down.png");ImageIcon left= new ImageIcon("src/left.png");ImageIcon right= new ImageIcon("src/right.png");ImageIcon food= new ImageIcon("src/food.png"); //然后用画笔画出来/*** 蛇的数据结构,即是有记忆的长度、宽度等是有记录的,长度是会增加的*///设置长度int len = 3; //蛇的身体长度默认是3//设置分数int score = 0;//定义数组来存放蛇的x坐标和y坐标: 即蛇能在框移动的位置范围为750x750int [] snakex = new int[750]; //蛇移动的位置:蛇移动产生的x、y坐标int [] snakey = new int[750];/*** 定义变量来确定蛇的方向,而不是只打印一个方向* * 通过R,L,U,D 来分别代表四个方向 * 先赋一个值,后面根据实际情况而改变*/String direction = "R"; //先赋一个值,后面会根据实际情况而改变//设置用于键盘监听器的变量//设置判断是否为开始状态 默认是falseboolean isStarted = false;//设置判断头是否是与身体重叠,重叠就让蛇 out掉boolean isFailed = false;//设置时钟,来让蛇体不断进行移动。 new 时钟(Timer)对象Timer timer = new Timer(150,this); //参数为(规定的时间,到点了找谁) ---就可到点了再找回了this,然后不断重复以实现不断的//(时钟设置好了,要在构造方法中进行开始)//设置食物/*** 随机生成食物--引入随机函数 Random */int foodx; //此变量在画的时候被用int foody;//引入随机函数/*** 生成随机数的格式是:调用生成随机数的nextInt()方法* 如:random.nextInt(34) //从0到33中随机选一个数*/Random random = new Random(); //构造方法 (必须要有空的构造方法)public MPanel() { //调用刷新图片的initSnake()方法initSnake(); //直接输入方法名//调用设置获取焦点的方法 即为setFocusable()方法//调用设置获取焦点this.setFocusable(true); //获取焦点 即可获取键盘事件//设置键盘监听器(参数中填this,即监听此面板的内容) :调用键盘监听器方法,然后监听自身this.addKeyListener(this); //此处要实现KeyListener的接口//开始已设置好的时钟timer.start(); /*** 时钟开始后,在actionPerformed(执行的操作中)进行蛇的移动的操作*/}//画游戏中的成分/组成部分的方法/*** 其中有Graphics画笔内容*/public void paintComponent(Graphics g) {//在这里面画东西super.paintComponent(g); //调用父类面板方法然后把this.paintComponent中的g传入到调用的方法中//设置面板颜色/*** 游戏窗体一般是不能设置颜色的,但游戏面板可以设置颜色* * 用this关键字调用方法则不用new对象的对象的引用来调用方法*/this.setBackground(Color.WHITE);//把引入的图片画出来title.paintIcon(this, g, 25, 11); //第一把为画在哪里(this表示画在此面板上。) g表示传进来的画笔 后两个表示距离窗体的距离//在游戏面板中画出黑色的框/*** 直接用画笔把想要的方框填成黑色* 即用fill.Rect()方法来在指定位置来填成黑色* (距离位置,距离位置,宽,高)* g即为画笔的引用*///画出黑色方框g.fillRect(25, 75, 850, 600);//先把画笔颜色设置为其他颜色,为打印长度和分数做准备g.setColor(Color.WHITE);//打印长度和分数(用drawString方法打印出字符串、字符)g.drawString("len:" +len,750 , 35);g.drawString("score:" +score,750 , 50);//画出身体、上下左右
// right.paintIcon(this, g, 100, 100);
// body.paintIcon(this, g, 75, 100);
// body.paintIcon(this, g, 50, 100); //这里就不能这样画出蛇的内容,数量多就不行,要用for循环。//打印头if (direction == "R") {right.paintIcon(this, g, snakex[0],snakey[0]); //如果是R,则打印向右的头图片}else if (direction == "L") {left.paintIcon(this, g, snakex[0],snakey[0]); //如果是L,则打印向左的头图片}else if (direction == "U") {up.paintIcon(this, g, snakex[0],snakey[0]); //如果是U,则打印向上的头图片}else if (direction == "D") {down.paintIcon(this, g, snakex[0],snakey[0]); //如果是D,则打印向下的头图片}//打印身体for(int i =1 ;i<len;i++) {//通过数组下标的增加来在for循环中,打印出蛇的身体 :其坐标为snakex[i],即可根据下标的改变而改变body.paintIcon(this, g, snakex[i] ,snakey[i]);}//打印食物food.paintIcon(this, g, foodx, foody);//把画笔变成其他颜色g.setColor(Color.WHITE);//改变字体大小 :导入font包,然后设置好参数(字体类型,字符是粗体/斜体,字体大小)g.setFont(new Font ("arial",Font.BOLD,40));/***在面板中打印开始语 :实际上是用画笔画出字符串*///画出开始语//当游戏开始时取消画笔画出来的字,isStarted为false时才打印if (isStarted ==false ) {g.drawString("Press Space to start", 300, 300);}g.setColor(Color.RED);g.setFont(new Font ("arial",Font.BOLD,40));//输出重新开始语 ---然后要重新开始就要在响应键盘事件:在响应键盘哪里天健if语句使isFailed变成flaseif (isFailed ==true) { //如果isFailed = true则输出重新开始语g.drawString("Failed:Press Space to start", 200, 300);}/*** 要让这个面板真正的有颜色和其中的方法有效果,就要在窗体中用add方法把面板加入到窗体中。*/}/*** 图片的x y坐标放入到数组中,然后要输入x y坐标时调用对应下标的数值即有,+配合for循环语句来打印图片,此过程即为蛇的数据结构*///建立初始化snake的方法 (刷新蛇的图片,让其产生移动的效果)public void initSnake() { //init :初始化len =3; //蛇开始长度是3/*** 蛇头的坐标是100x100,把存在数组的下标为0(x/y数组的下标都为0)*/snakex[0]=100;snakey[0]=100; //把蛇头的位置坐标存到数组中,且下标为0snakex[1]=75;snakey[1]=100;snakex[2]=50;snakey[2]=100;//设置食物的x y坐标位置/*** 用nextInt()生成随机数,然后给food坐标用上。 范围是25*(0-33)*/foodx = 25 +25*random.nextInt(34); //25 +... 的意思是 食物出现当后面的数是0时,就出现在第一个格子foody = 75 +25*random.nextInt(24); //然后画出来 在paintComponent方法中画出来//设置分数score = 0; //让重新开始时,分数不会再继续。} @Overridepublic void keyTyped(KeyEvent e) { //当键敲了}@Override //响应键盘事件public void keyPressed(KeyEvent e) { //当键敲到底了//KeyEvent :指的是敲了哪个键,设置int类型的变量进行接受/*** 使用getKeyCode()方法来获取到敲击了哪个按键 (每一个按键都对应一个数字)*/int keycode = e.getKeyCode(); //能够知道敲击了哪个键盘if ( keycode == KeyEvent.VK_SPACE ){ //keycode等于空格键就是isStarted的值改变为true//重新开始(响应键盘事件)if(isFailed) {isFailed = false;//格式化内容:即调用最开始的方法, 让蛇在一开始的地方重新开始 initSnake();}isStarted = !isStarted; //!isStarted是取反的意思 ,整体的意思就是值取反。//再次画图片 :重画图片:repaint();repaint(); //此即会重新调用方法}else if (keycode == KeyEvent.VK_RIGHT) { //如果键盘按了向右的键盘direction = "R";}else if (keycode == KeyEvent.VK_LEFT) { //如果键盘按了向右的键盘direction = "L";}else if (keycode == KeyEvent.VK_UP) { //如果键盘按了向右的键盘direction = "U";}else if (keycode == KeyEvent.VK_DOWN) { //如果键盘按了向右的键盘direction = "D"; //然后在actionPerformed中配合钟表来刷数据}}@Overridepublic void keyReleased(KeyEvent e) { //当键敲完然后抬起来了}@Overridepublic void actionPerformed(ActionEvent e) { //时间到了就会调用这个方法/*** 时间到了就会调用此方法,然后在此内容结尾再次开启时钟,已达到不断循环的效果*///到点了就重写repaint();//将图移动和空格键的内容连接起来if (isStarted && !isFailed ) { //如果isStarted是true 且 !isFailed(且不是失败的)/*** 让蛇动起来 :先是头动,即让头的图像x,y发生移动。*/for (int i = len-1; i>0;i--) {snakex[i] = snakex[i-1]; //蛇身体的x坐标移动snakey[i] = snakey[i-1]; //蛇身体的y坐标移动}if (direction == "R") {//direction = "R" 时执行的代码snakex[0] =snakex[0]+25;if (snakex[0] >850) snakex[0] = 25; //判断语句的简写形式}else if (direction =="L") {snakex[0] =snakex[0]-25;if (snakex[0] <25) snakex[0] = 850; //判断语句的简写形式}else if (direction =="U") {snakey[0] =snakey[0]-25;if (snakey[0] <75) snakey[0] = 650; //判断语句的简写形式}else if (direction =="D") {snakey[0] =snakey[0]+25;if (snakex[0] >650) snakex[0] = 75; //判断语句的简写形式}//吃掉食物/*** 判断食物的x、y坐标是否为头的x、y坐标是否重合*/if (snakex[0] == foodx && snakey[0]==foody) {len++; //头的图片和食物图片重合就长度+1 ---这样长度+1,身体就会变成。//长度增加后,分数也会增加 (然后把分数显示出来,把它画出来:实质是打印字符一样打印出来即可)score = score +10; //然后重新刷新图片foodx = 25 +25*random.nextInt(34); //25 +... 的意思是 食物出现当后面的数是0时,就出现在第一个格子foody = 75 +25*random.nextInt(24); //然后画出来 在paintComponent方法中画出来}//判断头是否和身体重合,如果是则 (用for语句来循环输出len的值/数组的值,然后判断是否有重合现象)for (int i = 1;i<len ;i++) {if (snakex[i]==snakex[0] && snakey[i]==snakey[0]) {//如果是重合的,那就有isFailed 变为true,让移动程序不再运行isFailed = true;}}}//重写repaint(); //然后还有让时钟再次开始timer.start();}
}
3.2 Msnake.java
package moonsnake;import java.awt.Color;import javax.swing.JFrame;/*** **画出窗体 :900x720**//*** 看着有颜色,实质上是面板中的颜色,而是窗体中的颜色。**/
public class Msnake {public static void main(String[] args) {/*** 窗体类关键字为:JFrame* 作用就是会有一个游戏面板一样的东西会出现在屏幕上,只要这个窗体是有颜色的话。*///画出窗体类 JFrame frame = new JFrame(); //new一个窗体类对象 //调用jframe的Bounds方法来设置窗体的大小和距离和距离屏幕的位置frame.setBounds(10,10,900,700);//用Resizable方法来设置面板不可拖动frame.setResizable(false);//用setDeafaultCloseOperation方法来关闭游戏界面frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);/*** 用add方法把面板类加入到窗体中*/frame.add(new MPanel());//用Visible方法来使窗体展现出来frame.setVisible(true);/*** 做完这些的结果就是有一个900x720的白色的距离左上屏幕10,10距离的窗体。*/ }
}
4.贪吃蛇游戏的代码分享 (获得代码 和 其中游戏图片)
链接:百度网盘获得“代码”和“游戏图片”