JAVA游戏开发-超炫酷贪吃蛇游戏源码及教程

article/2025/10/15 6:22:56

一.前言

某日,看见隔壁家的小朋友在玩一款网络爆款贪吃蛇游戏,感觉很好玩。自己刚好正在学习JAVA编程,也想实现一个类似功能的游戏Demo练手,在网上查看了不少源码案例,全都是很古老的方块式贪吃蛇游戏案例,没有想要的实现,因此自己动手实现一个JAVA版的贪吃蛇游戏。

我在这个Dome完成之后重写了这个游戏的Android版,并重新更名为《蛇王传说》。也欢迎大家下载试玩。游戏下载地址:点这里下载app

我的另一篇博客有Androd版本的游戏介绍:蛇王传说1.0Android版发布_hawkol的专栏-CSDN博客https://blog.csdn.net/hawkol/article/details/90608813

二、实现效果

1.启动界面 蛇头会左右摆动,动态效果

1

2、游戏主界面   地图上有不同的食物,用键盘控制蛇在地图上行走,每吃掉一个食物,蛇会自动生长一节

2

三、按键功能说明  左右键蛇转向,上键蛇加速行走。

四、美工准备

因自己不会美工,很多图都是从网上找的,然后用photoshop抠图,按自己的设计思路,做成以下样式。做片做的比较丑,就不放原图了。

1、images 文件夹

3

2、foolds文件夹

4

3、snake文件夹

5

4、在s0,s1,s2,s3,s4文件夹分别放以下5张图,可以做成不同颜色和样式(也就是蛇的皮肤)

五、打开Eclipse新建HawkRetroSnaker 项目,目录文件结构如下图:

从目录结构可以看出,此游戏有5个JAVA类,分别是

Foods.java (食物),

Snake.java (蛇),

SnakePlayer.java (游戏主程),

Tools.java (工具类),

UIGameStart.java (启动时的Ui).

六、游戏代码:关键代码地方都有注释,我就不多啰嗦了,代码写的比较烂,只是为了实现功能,有很多地方可以优化,大家也可提出自己的见解。

1.Foods.java

package com.hawkonline.retorsnaker;import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;import javax.imageio.ImageIO;public class Foods {private int imgID;//食物图片D 以foodsX private int drawX;// 图块显示中心的X位置private int drawY;// 图块显示中心的Y位置private int generateEnergy;//产生能量private  int offsetX;// 图块块显示的X位置偏移值-自动计算private  int offsetY;// 图块块显示的X位置偏移值-自动计算private BufferedImage imgFoods;//public Foods(int imgID, int drawX, int drawY, int generateEnergy) {super();this.imgID = imgID;this.drawX = drawX;this.drawY = drawY;this.generateEnergy = generateEnergy;//加载食物图片try {imgFoods= ImageIO.read(new FileInputStream("images\\foods\\foods"+imgID+".png"));} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}this.offsetX = imgFoods.getWidth()/2;this.offsetY = imgFoods.getHeight()/2;}//画食物public void drawFoods(Graphics cg,int x,int y ){cg.drawImage(imgFoods, drawX-offsetX+x, drawY-offsetY+y, null);cg.setColor(Color.WHITE);//参照线-------------------cg.fillRect(drawX-1+x, drawY-1+y, 2, 2);}public Foods() {super();}public int getImgID() {return imgID;}public void setImgID(int imgID) {this.imgID = imgID;}public int getDrawX() {return drawX;}public void setDrawX(int drawX) {this.drawX = drawX;}public int getDrawY() {return drawY;}public void setDrawY(int drawY) {this.drawY = drawY;}public int getGenerateEnergy() {return generateEnergy;}public void setGenerateEnergy(int generateEnergy) {this.generateEnergy = generateEnergy;}public int getOffsetX() {return offsetX;}public void setOffsetX(int offsetX) {this.offsetX = offsetX;}public int getOffsetY() {return offsetY;}public void setOffsetY(int offsetY) {this.offsetY = offsetY;}
}

 大家好,最近在开发微信小程序,用了一个月的晚上时间,手撸一个仿蚂蚁森林微信小程序,欢迎大家扫描体验!

2.Snake.java

package com.hawkonline.retorsnaker;import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
import java.util.Random;import javax.imageio.ImageIO;public class Snake {private Random rand = new Random();private int to=0;//自动移动模式标记蛇移动的方向,1左,2右// 蛇图片相关显示属性private int step;// 步长private int offsetX;// 图块块显示的X位置偏移值-自动计算private int offsetY;// 图块块显示的X位置偏移值-自动计算private BufferedImage imgSnakeHead;// 蛇头图片private BufferedImage imgSnakeBody1;// 蛇身体奇数图片private BufferedImage imgSnakeBody2;// 蛇身体偶数图片private BufferedImage imgSnakeTait1;// 蛇尾巴图片private BufferedImage imgSnakeTait2;// 蛇尾巴图片private BufferedImage imgRotate;// 旋转后的图片// 蛇的属值private int energy;// 吃豆得到的能量private int snakeLength;// 蛇的长度--默认3节,根椐能量获得的多少自动生长// 蛇头private int snakeHeadX;// 蛇头X坐标private int snakeHeadY;// 蛇头Y坐标private int snakeHeadDirection;// 蛇头移动的方向private int snakeDisplayStyle;// 蛇显示风格private boolean snakeIsDeath;//蛇死亡标记   True-生存, false=死亡// 蛇身体private int[] bodyX;// 蛇身体X坐标private int[] bodyY;// 蛇身体Y坐标private int[] bodyDirection;// 蛇身体方向// 构造函数public Snake(int snakeHeadX, int snakeHeadY, int snakeHeadDirection, int snakeDisplayStyle) {super();this.snakeHeadX = snakeHeadX;this.snakeHeadY = snakeHeadY;this.snakeHeadDirection = snakeHeadDirection;this.snakeDisplayStyle = snakeDisplayStyle;this.snakeIsDeath = true;//蛇死亡标记   True-生存, false=死亡snakeLength =6;// 加载图片try {imgSnakeHead = ImageIO.read(new FileInputStream("images\\snake\\s" + snakeDisplayStyle + "\\head.png"));imgSnakeBody1 = ImageIO.read(new FileInputStream("images\\snake\\s" + snakeDisplayStyle + "\\body1.png"));imgSnakeBody2 = ImageIO.read(new FileInputStream("images\\snake\\s" + snakeDisplayStyle + "\\body2.png"));imgSnakeTait1 = ImageIO.read(new FileInputStream("images\\snake\\s" + snakeDisplayStyle + "\\tait1.png"));imgSnakeTait2 = ImageIO.read(new FileInputStream("images\\snake\\s" + snakeDisplayStyle + "\\tait2.png"));} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}this.offsetX =imgSnakeHead.getWidth()/2;this.offsetY =imgSnakeHead.getHeight()/2;this.step = 8;// 蛇身体-构造时为3节bodyX = new int[snakeLength];bodyY = new int[snakeLength];bodyDirection = new int[snakeLength];for (int i = 0; i < snakeLength; i++) {bodyX[i] = snakeHeadX - (i + 1) * step;bodyY[i] = snakeHeadY;bodyDirection[i] = 0;}}// 画蛇public void snakeShow(Graphics cg,int x,int y) {// 画蛇身体for (int i = snakeLength - 1; i >= 0; i--) {if (i == snakeLength - 1) {// 画蛇尾if ((i % 2 == 0)) {imgRotate = Tools.rotateImage(imgSnakeTait1, bodyDirection[i]);} else {imgRotate = Tools.rotateImage(imgSnakeTait2, bodyDirection[i]);}} else {// 画蛇身体if ((i % 2) == 0) {imgRotate = Tools.rotateImage(imgSnakeBody1, bodyDirection[i]);} else {imgRotate = Tools.rotateImage(imgSnakeBody2, bodyDirection[i]);}}cg.drawImage(imgRotate, bodyX[i] - offsetX+x, bodyY[i] - offsetY+y,null);// 参照线-------------------cg.setColor(Color.WHITE);cg.fillRect(bodyX[i] - 1+x, bodyY[i] - 1+y, 2, 2);}// 画蛇头imgRotate = Tools.rotateImage(imgSnakeHead, snakeHeadDirection);cg.drawImage(imgRotate, snakeHeadX - offsetX+x, snakeHeadY - offsetY+y,null);// 参照线-------------------cg.setColor(Color.WHITE);cg.fillRect(snakeHeadX - 1+x, snakeHeadY - 1+y, 2, 2);cg.setColor(Color.BLUE);int sX = (int) (snakeHeadX + 150 * Math.cos(snakeHeadDirection * 3.14 / 180));int sY = (int) (snakeHeadY + 150 * Math.sin(snakeHeadDirection * 3.14 / 180));cg.fillRect(sX - 1+x, sY - 1+y, 2, 2);sX = (int) (snakeHeadX + 100 * Math.cos((snakeHeadDirection+45) * 3.14 / 180));sY = (int) (snakeHeadY + 100 * Math.sin((snakeHeadDirection+45) * 3.14 / 180));cg.fillRect(sX - 1+x, sY - 1+y, 2, 2);sX = (int) (snakeHeadX + 100 * Math.cos((snakeHeadDirection-45) * 3.14 / 180));sY = (int) (snakeHeadY + 100 * Math.sin((snakeHeadDirection-45) * 3.14 / 180));cg.fillRect(sX - 1+x, sY - 1+y, 2, 2);// 参照线-------------------cg.setColor(Color.WHITE);cg.fillRect(snakeHeadX - 1+x, snakeHeadY - 1+y, 2, 2);}public void snakeAutoMove(){// 蛇智能移动方案3//蛇下一步的位置int sX = (int) (snakeHeadX + 150 * Math.cos(snakeHeadDirection * 3.14 / 180));int sY = (int) (snakeHeadY + 150 * Math.sin(snakeHeadDirection * 3.14 / 180));//蛇死亡了if(sX<=20||sX>=(Tools.MAP_X-20)||sY<=20||sY>=(Tools.MAP_Y-20)){boolean isL=false,isR=false;//看下左边45度会不会死sX = (int) (snakeHeadX + 100 * Math.cos((snakeHeadDirection+45) * 3.14 / 180));sY = (int) (snakeHeadY + 100 * Math.sin((snakeHeadDirection+45) * 3.14 / 180));if(sX<=20||sX>=(Tools.MAP_X-20)||sY<=20||sY>=(Tools.MAP_Y-20)){isL=true;}//看下左边45度会不会死sX = (int) (snakeHeadX + 100 * Math.cos((snakeHeadDirection-45) * 3.14 / 180));sY = (int) (snakeHeadY + 100 * Math.sin((snakeHeadDirection-45) * 3.14 / 180));if(sX<=20||sX>=(Tools.MAP_X-15)||sY<=20||sY>=(Tools.MAP_Y-15)){isR=true;}//左右死if((isL)&&(isL)){if(rand.nextInt(1)==1){snakeHeadDirection+=(rand.nextInt(5)+20);//增大旋转角度to=1;}else{snakeHeadDirection-=(rand.nextInt(5)+20);//增大旋转角度to=2;}}else if(isL){snakeHeadDirection-=(rand.nextInt(5)+5);//增大旋转角度to=2;}else{snakeHeadDirection+=(rand.nextInt(5)+5);//增大旋转角度to=1;}}else{if(rand.nextInt(rand.nextInt(20)+10)==1){to=rand.nextInt(3);}if (to==1) snakeHeadDirection+=(rand.nextInt(5)+2);if (to==2) snakeHeadDirection-=(rand.nextInt(5)+2);}snakeMove();}// 蛇移动-按照设置的方向前行public void snakeMove() {if (snakeIsDeath) {// 蛇的后一节的值继承前一节的值for (int i = snakeLength - 1; i > 0; i--) {bodyX[i] = bodyX[i - 1];bodyY[i] = bodyY[i - 1];bodyDirection[i] = bodyDirection[i - 1];}// 第一节的值继承蛇头的值bodyX[0] = snakeHeadX;bodyY[0] = snakeHeadY;bodyDirection[0] = snakeHeadDirection;snakeHeadX = (int) (snakeHeadX + step * Math.cos(snakeHeadDirection * 3.14 / 180));snakeHeadY = (int) (snakeHeadY + step * Math.sin(snakeHeadDirection * 3.14 / 180));}}// 蛇生长--数组自动扩容1节public void snakGrow() {snakeLength = snakeLength + 1;if (snakeLength > bodyX.length) {bodyX = Arrays.copyOf(bodyX, snakeLength);bodyY = Arrays.copyOf(bodyY, snakeLength);bodyDirection = Arrays.copyOf(bodyDirection, snakeLength);}}// 蛇死亡public void snakeDeath() {this.snakeIsDeath = false;//蛇死亡标记   True-生存, false=死亡// 随机数--产生蛇块断裂Random rand = new Random();for (int i = 0; i < snakeLength; i++) {bodyX[i] = bodyX[i] + rand.nextInt(step * 2) - rand.nextInt(step * 2);bodyY[i] = bodyY[i] + rand.nextInt(step * 2) - rand.nextInt(step * 2);bodyDirection[i] = bodyDirection[i] + rand.nextInt(360);}//snakeHeadX = snakeHeadX + rand.nextInt(step) - rand.nextInt(step);//snakeHeadY = snakeHeadY + rand.nextInt(step) - rand.nextInt(step);snakeHeadX = (int) (snakeHeadX + step * Math.cos(snakeHeadDirection * 3.14 / 180));snakeHeadY = (int) (snakeHeadY + step * Math.sin(snakeHeadDirection * 3.14 / 180));}// get---- set-----public int getSnakeHeadDirection() {return snakeHeadDirection;}public void setSnakeHeadDirection(int snakeHeadDirection) {this.snakeHeadDirection = snakeHeadDirection;}public int getSnakeHeadX() {return snakeHeadX;}public void setSnakeHeadX(int snakeHeadX) {this.snakeHeadX = snakeHeadX;}public int getSnakeHeadY() {return snakeHeadY;}public void setSnakeHeadY(int snakeHeadY) {this.snakeHeadY = snakeHeadY;}public boolean getSnakIsDeath() {return snakeIsDeath;}public boolean isSnakeIsDeath() {return snakeIsDeath;}public void setSnakeIsDeath(boolean snakeIsDeath) {this.snakeIsDeath = snakeIsDeath;}public int getEnergy() {return energy;}public void setEnergy(int energy) {this.energy = energy;if((energy-5)>=0){//每获取5点能量,蛇生长一节(12-5)>=0this.snakGrow();//蛇生长this.energy=this.energy-5;}}public int getSnakeLength() {return snakeLength;}public void setSnakeLength(int snakeLength) {this.snakeLength = snakeLength;}public int getSnakeDisplayStyle() {return snakeDisplayStyle;}public void setSnakeDisplayStyle(int snakeDisplayStyle) {this.snakeDisplayStyle = snakeDisplayStyle;}}

3.SnakePlayer.java

package com.hawkonline.retorsnaker;import java.awt.Color;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.Graphics;import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Random;import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;public class SnakePlayer  extends JFrame implements Runnable, KeyListener{Random rand = new Random();private int runGame=0;//UIprivate UIGameStart uiGameStart=null;private int inputSleep=80;//线程执行间隔时长private int drawMapX,drawMapY;private static BufferedImage bfMap= new BufferedImage(Tools.MAP_X, Tools.MAP_Y, BufferedImage.TYPE_3BYTE_BGR); // 创建一张1920*1080的地图源图private static BufferedImage bfGameMap = new BufferedImage(Tools.SCREEN_X, Tools.SCREEN_Y, BufferedImage.TYPE_3BYTE_BGR); // 创建一张1920*1080的缓冲图片private static Graphics bfGameMapGraphics =bfGameMap.getGraphics();// 获取缓冲图片的画笔private BufferedImage imgDisplayInformation=null;private BufferedImage imeGameOver=null;private Foods []foods=null;//小圆点食物private Snake snake=null;//蛇//private Snake enemy=null;public SnakePlayer() {this.setTitle(Tools.GameName);// 设置框架的大小this.setSize(Tools.SCREEN_X, Tools.SCREEN_Y);// 设置框架大小可以改变this.setResizable(false);//设置窗体居中显示this.setLocationRelativeTo(null);// 设置点击关闭按钮 关闭界面this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置GUI的窗口图标ImageIcon snakeIcon = new ImageIcon("images\\snakeIcon.png");this.setIconImage(snakeIcon.getImage());// 允许显示游戏界面this.setVisible(true); // 添加键盘监听器  this.addKeyListener(this);// 添加鼠标监听器 //鼠标样式this.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));//创建UI界面uiGameStart=new UIGameStart();loadGameResources();//加载游戏资源bfMapDraw();//画背地图,以后不用多次画了setFoods();setSnake();Thread thread = new Thread(this); // 创建线程  thread.start(); // 启动线程  }//加载游戏资源private void loadGameResources() {try {imgDisplayInformation = ImageIO.read(new FileInputStream("images\\DisplayInformation.png"));imeGameOver = ImageIO.read(new FileInputStream("images\\GameOver.png"));} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}//设置蛇private void setSnake() {snake=new Snake(Tools.MAP_X/2, Tools.MAP_Y/2, 0,rand.nextInt(Tools.SNAKE_STYLE_SUM));//		int sx=rand.nextInt(Tools.MAP_X-40)+20;
//		int sy=rand.nextInt(Tools.MAP_Y-40)+20;
//		int sd=rand.nextInt(360);
//		int ss=rand.nextInt(Tools.SNAKE_STYLE_SUM);
//
//		enemy=new Snake(sx, sy, sd, ss);}// 设置食物private void setFoods() {foods=new Foods[Tools.FOODS_SUM];for(int i=0;i<Tools.FOODS_SUM;i++){int imgID=rand.nextInt(Tools.FOODS_TYPE_SUM);int drawX=rand.nextInt(Tools.MAP_X-40)+20;int drawY=rand.nextInt(Tools.MAP_Y-40)+20;//-------------可设计从XML文件读入int generateEnergy;if (imgID<7){generateEnergy=1;}else {generateEnergy=5;}foods[i]=new Foods(imgID, drawX, drawY, generateEnergy);}}// 设置游戏地图private void bfMapDraw() {Graphics bfMapGraphics =bfMap.getGraphics();// 获取缓冲图片的画笔bfMapGraphics.setColor(Color.BLACK); // 设置map外框为黑色bfMapGraphics.fillRect(0, 0, Tools.MAP_X, Tools.MAP_Y);bfMapGraphics.setColor(new Color(90, 90, 90)); // 设置map墙为黑色bfMapGraphics.fillRect(10, 10, Tools.MAP_X - 20, Tools.MAP_Y - 20);bfMapGraphics.setColor(new Color(208, 208, 224)); // 设置map背景色bfMapGraphics.fillRect(20, 20, Tools.MAP_X - 40, Tools.MAP_Y - 40);// 画map格bfMapGraphics.setColor(new Color(241, 241, 240));for (int i = 20; i < Tools.MAP_Y; i += 20) {bfMapGraphics.drawLine(0 + 12, i, Tools.MAP_X -12, i);}for (int j = 20; j < Tools.MAP_X; j += 20) {bfMapGraphics.drawLine(j, 0 + 12, j, Tools.MAP_Y - 12);}}public void reDrawGame(){//得到画地图的偏移值drawMapX=-snake.getSnakeHeadX()+Tools.SCREEN_X/2;drawMapY=-snake.getSnakeHeadY()+Tools.SCREEN_Y/2;//画地图背景bfGameMapGraphics.setColor(Color.red);bfGameMapGraphics.fillRect(0, 0, Tools.SCREEN_X, Tools.SCREEN_Y);bfGameMapGraphics.drawImage(bfMap, drawMapX, drawMapY, null);//显示第一层背景地图for(int i=0;i<Tools.FOODS_SUM;i++){int distance = (int) Math.sqrt(Math.abs((foods[i].getDrawX() -  snake.getSnakeHeadX())*(foods[i].getDrawX() -  snake.getSnakeHeadX()))+Math.abs((foods[i].getDrawY() -  snake.getSnakeHeadY())*(foods[i].getDrawY() -  snake.getSnakeHeadY())));if (distance<25){//如果贪吃蛇离食物有20,测吃掉食物snake.setEnergy(snake.getEnergy()+foods[i].getGenerateEnergy());//能量加//产生新的食物foods[i].setDrawX(rand.nextInt(Tools.MAP_X-40)+20);foods[i].setDrawY(rand.nextInt(Tools.MAP_Y-40)+20);}foods[i].drawFoods(bfGameMapGraphics, drawMapX,drawMapY);}//===============================================if (snake.getSnakIsDeath()){//如果蛇在活着//snake.snakeMove();//蛇移动snake.snakeAutoMove();//判断蛇是否撞墙if(snake.getSnakeHeadX()<=20||snake.getSnakeHeadX()>=(Tools.MAP_X-20)||snake.getSnakeHeadY()<=20||snake.getSnakeHeadY()>=(Tools.MAP_Y-20)){snake.snakeDeath();//蛇死亡了runGame=2;//游戏结束}}snake.snakeShow(bfGameMapGraphics,drawMapX,drawMapY);}public void paint(Graphics gr) {switch (runGame){case 0:uiGameStart.drawUIGameStart(bfGameMapGraphics);gr.drawImage(bfGameMap,0,0, null); // 将缓冲mapbreak;case 1:reDrawGame();//显示得分showDisplayInformation();gr.drawImage(bfGameMap,0,0, null); // 将缓冲mapbreak;case 2:reDrawGame();showDisplayInformation();bfGameMapGraphics.drawImage(imeGameOver,250,100, null);gr.drawImage(bfGameMap,0,0, null); // 将缓冲mapbreak;default:break;}}  //显示得分private void showDisplayInformation() {bfGameMapGraphics.drawImage(imgDisplayInformation,300,30, null); bfGameMapGraphics.setColor(Color.RED);bfGameMapGraphics.setFont(new Font("arial",Font.BOLD, 30));bfGameMapGraphics.drawString(snake.getSnakeLength()+"", 460, 66);bfGameMapGraphics.drawString(snake.getEnergy()+"", 680, 66);}/** * 线程执行方法 */  public void run() {  try {  while (true) {  this.repaint();  Thread.sleep(inputSleep);  }  } catch (InterruptedException e) {  e.printStackTrace();  }  }  /** * 按下时调用 */  public void keyPressed(KeyEvent e) {  int keyCode = e.getKeyCode();//	游戏刚启动时,按任意键开始游戏        if (runGame==0){runGame=1;}if (keyCode ==KeyEvent.VK_LEFT&&runGame==1) { // 左按键  snake.setSnakeHeadDirection(snake.getSnakeHeadDirection()-5);//蛇左转}  if (keyCode == KeyEvent.VK_RIGHT&&runGame==1) { // 右按键  snake.setSnakeHeadDirection(snake.getSnakeHeadDirection()+5);//蛇右转}  if(keyCode==KeyEvent.VK_UP&&runGame==1){//加速inputSleep=20;}if(keyCode==KeyEvent.VK_L&&runGame==2){//复活snake.setSnakeHeadX(Tools.MAP_X/2);snake.setSnakeHeadY(Tools.MAP_Y/2);runGame=1;snake.setSnakeIsDeath(true);}if(keyCode==KeyEvent.VK_Y&&runGame==2){//重新开始snake.setSnakeHeadX(Tools.MAP_X/2);snake.setSnakeHeadY(Tools.MAP_Y/2);snake.setSnakeLength(3);snake.setEnergy(0);runGame=1;snake.setSnakeIsDeath(true);}}  /** * 释放按键时调用 */  public void keyReleased(KeyEvent e) {  int keyCode = e.getKeyCode(); if(keyCode==KeyEvent.VK_UP){inputSleep=80;}}  /** * 不解释 */  public void keyTyped(KeyEvent e) {  }  public static void main(String[] args) {  new SnakePlayer();  }}

4、Tools.java

package com.hawkonline.retorsnaker;import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;public class Tools {public static final int MAP_X = 1920;public static final int MAP_Y = 1080;public static final int SCREEN_X = 800;public static final int SCREEN_Y = 600;public static final String GameName = "美卡贪吃蛇1.0.0";public final static int FOODS_TYPE_SUM = 19;// 食物种类public final static int FOODS_SUM = 50;// 小圆食物总数public final static int SNAKE_STYLE_SUM = 6;// 蛇皮肤总数public final static int SNAKE__SUM=10;//蛇的数量/*** 旋转图片为指定角度* * @param bufferedimage*            目标图像* @param degree*            旋转角度* @return*/public final static BufferedImage rotateImage(final BufferedImage bufferedimage, final int degree) {int w = bufferedimage.getWidth();// 得到图片宽度。int h = bufferedimage.getHeight();// 得到图片高度。int type = bufferedimage.getColorModel().getTransparency();// 得到图片透明度。BufferedImage img;// 空的图片。Graphics2D graphics2d;// 空的画笔。(graphics2d = (img = new BufferedImage(w, h, type)).createGraphics()).setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);graphics2d.rotate(Math.toRadians(degree), w / 2, h / 2);// 旋转,degree是整型,度数,比如垂直90度。graphics2d.drawImage(bufferedimage, 0, 0, null);// 从bufferedimagecopy图片至img,0,0是img的坐标。graphics2d.dispose();return img;// 返回复制好的图片,原图片依然没有变,没有旋转,下次还可以使用。}}

5、UIGameStart.java

package com.hawkonline.retorsnaker;import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;import javax.imageio.ImageIO;public class UIGameStart {private BufferedImage gameStart=null;private BufferedImage snakeImage=null;private BufferedImage snakeTxt=null;private BufferedImage imgRotate;// 旋转后的图片private int retate=0;private boolean left=true;public UIGameStart() {try {gameStart = ImageIO.read(new FileInputStream("images\\gameStart.png"));snakeImage = ImageIO.read(new FileInputStream("images\\snakeImage.png"));snakeTxt = ImageIO.read(new FileInputStream("images\\snakeTxt.png"));} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public void drawUIGameStart(Graphics cg){cg.setColor(Color.BLACK);cg.fillRect(0, 0, Tools.SCREEN_X, Tools.SCREEN_Y);//画背景cg.drawImage(gameStart,0, 0, Tools.SCREEN_X, Tools.SCREEN_Y,null);//蛇头动画参数if (left){retate+=2;if (retate==20) left=false;}else{retate-=2;if (retate==-20) left=true;}imgRotate = Tools.rotateImage(snakeImage, retate);//居中显示cg.drawImage(imgRotate, (Tools.SCREEN_X-snakeImage.getWidth())/2, (Tools.SCREEN_Y-snakeImage.getHeight())/2, null);cg.drawImage(snakeTxt, (Tools.SCREEN_X-snakeTxt.getWidth())/2, (Tools.SCREEN_Y-snakeTxt.getHeight())/2, null);cg.setColor(Color.RED);cg.setFont(new Font("arial",Font.BOLD, 30));	}
}

直接运行。完工!!

snake.snakeAutoMove()是自动行走模式,实现了简单的AI智能,经测试蛇在地图上可以长时间不撞墙死掉。

如果改为snake.snakeMove()是手动操控模式。

 企业网站/微信小程序/app定制开发请添加微信:Hawkonline

 最新小程序案例

​  ​   ​    


http://chatgpt.dhexx.cn/article/UKahgNu6.shtml

相关文章

Java实现贪吃蛇游戏【代码】

Java实现贪吃蛇游戏【代码】 花了两个下午写了一个贪吃蛇小游戏&#xff0c;本人想写这游戏很长时间了。作为以前诺基亚手机上的经典游戏&#xff0c;贪吃蛇和俄罗斯方块一样&#xff0c;都曾经在我们的童年给我们带来了很多乐趣。世间万物斗转星移&#xff0c;诺基亚曾经作为手…

JavaSE项目 | 纯Java实现贪吃蛇小游戏

目录 一&#xff1a;贪吃蛇游戏的实现步骤 1. 画出窗口 2. 在窗口上添加画布 3. 在画布上添加黑色游戏区 4. 放静态蛇 5. 定义蛇的数据结构 6. 控制蛇头方向 7. 放上开始提示信息 8. 按空格键开始游戏 9. 让蛇动起来 10. 实现暂停 11. 实现转向功能 12. 添加食物 …

java 贪吃蛇 源码+图片

本人也是个初学者&#xff0c;有什么不对的地方&#xff0c;请大佬指点&#xff01;&#xff01;&#xff01; 一、涉及到的知识点如下&#xff1a; 循环&#xff0c;分支方法的抽取数组的使用面向对象继承&#xff0c;子类方法的重写接口&#xff0c;接口的实现 二、游戏图形…

JAVA贪吃蛇代码(带注释)

贪吃蛇 这是游戏效果图片是代码里面的素材游戏数据类 package com.tang.retor_snaker;import javax.swing.*; import java.net.URL;public class Data {private static URL bodyURL Data.class.getResource("/com/tang/retor_snaker/statics/body.png");private st…

JAVA贪吃蛇小游戏源代码系列

欢迎关注公众号&#xff1a; 获取贪吃蛇小游戏的源代码。 贪吃蛇小游戏运行结果如下&#xff1a; 启动界面&#xff1a; 运行界面&#xff1a; 重启界面&#xff1a; 源代码框架如下&#xff1a; 注&#xff1a;在运行程序的时候&#xff0c;得重新设计窗体的大小&#x…

JAVA 实现《贪吃蛇大作战》游戏|CSDN创作打卡

前言 贪吃蛇&#xff08;也叫做贪食蛇&#xff09;游戏是一款休闲益智类游戏&#xff0c;有PC和手机等多平台版本。既简单又耐玩。该游戏通过控制蛇头方向吃东西&#xff0c;从而使得蛇变得越来越长。 本程序是通过java的swing来实现《贪吃蛇大作战》这款游戏。 主要需求 1…

java贪吃蛇源码

欢迎访问我的个人博客 https://jialaner.cn/​​​​​​​ java是一种面向对象的语言&#xff0c;有着其中不用质疑的优点。学习java将近三个月了&#xff0c;一直在琢磨着“万物皆对象”的意义&#xff0c;却总是只知其表不知其意&#xff0c;做完这个java贪吃蛇后才有了那么…

贪吃蛇 java实现超简单的贪吃蛇(附源代码)

贪吃蛇游戏 贪吃蛇是个非常经典的游戏&#xff0c;希望对初学Java的小伙伴有一定帮助。希望大家喜欢&#xff0c;因为写得简单&#xff0c;希望大家都能看得懂。 游戏界面&#xff08;游戏背景素材不喜欢的话可以自己换&#xff0c;就别在乎我选的素材&#xff08;&#x1f9…

java实现贪吃蛇小游戏(源码+注释)

一.工程文件 二.Main.java package com.company;import javax.swing.*;public class Main {public static void main(String[] args) {//创建窗体对象JFrame frame new JFrame();//创建窗体参数&#xff08;&#xff09;frame.setBounds(10,10,900,720);//设置不允许更改大小…

使用Java实现一个简单的贪吃蛇小游戏

基于java实现贪吃蛇小游戏&#xff0c;主要通过绘制不同的图片并以一定速度一帧一帧地在窗体上进行展示。 开发工具&#xff1a;eclipse java工具包&#xff1a;jdk1.8 一、创建新项目 创建一个新的项目&#xff0c;并命名。创建一个名为images的文件夹用来存放游戏相关图片…

Java贪吃蛇全代码

用Java编写精典小游戏——贪吃蛇&#xff01; 前言 我想贪吃蛇应该是不少90后和00后的童年&#xff08;我本人是01年的&#xff09;&#xff0c;回想起从前偷偷拿着我爹的诺基亚在被窝里玩贪吃蛇&#xff0c;不禁感慨万分&#xff0c;时间飞逝&#xff0c;没想到10年后的我也可…

JAVA小项目(四)—— 贪吃蛇【轻松入门,附源码】

目录 &#xff08;一&#xff09;效果图 &#xff08;二&#xff09;代码实现 &#xff08;1&#xff09;将图片加载到程序中 &#xff08;2&#xff09;创建窗体 &#xff08;3&#xff09;创建面板 &#xff08;4&#xff09;绘制静态的小蛇 &#xff08;5&#xff09; 加入监…

Java贪吃蛇大作战

作为Java新手小白&#xff0c;渴望学习一些好玩有趣的java程序 废话不多说&#xff0c;接下来我会一步一步实现java小程序&#xff1a;贪吃蛇大作战哦&#xff01; 实现 Java贪吃蛇一共分四个步骤&#xff1a; 1、画出窗体对象 2、绘制静态ui 3、使用鼠标监听器事件和定时器事…

Java简易小游戏贪吃蛇(Java实战)

这个版本的贪吃蛇我是跟着“黑马程序员”写的。小伙伴们可以跟着视频试着做一下&#xff0c;同时视频也会更详细。 B站学习链接&#xff1a;【黑马】两个小时带你用Java语言写一个贪吃蛇游戏【配套源码笔记】_哔哩哔哩_bilibili 相对于新手而言&#xff0c;贪吃蛇应该算是一个…

JAVA实现贪吃蛇游戏

本文实现的功能有: 1.绘制静态窗口 2.绘制游戏面板 3.绘制静态小蛇 4.通过键盘控制小蛇移动 5.吃食物 6.积分系统和失败判定 最近在学GUI&#xff0c;然后又有读者希望我写一下相关的实战。刚好博主在b站漫无目的的寻找着题材的时候看到了一个写贪吃蛇游戏的视频&#xff0c;于…

Java实现贪吃蛇大作战小游戏(完整版)

大家好&#xff0c;今天尝试用swing技术写一个贪吃蛇大作战小游戏&#xff0c;供大家参考。 效果展示 目录 效果展示 一、游戏界面 二、得分情况 项目介绍 项目背景 总体需求 实现过程 代码展示 主类 &#xff1a;Demo类 MyPanel类 ①构造方法 ②初始化方法 ③绘制方法…

用java写一个贪吃蛇小游戏(源码在最后)

一、引入 涉及技能&#xff1a; 循环、分支方法的抽取数组的使用面向对象继承&#xff0c;子类方法的重写接口&#xff0c;接口的实现GUI&#xff08;图像化界面编程&#xff09; GUI中的组件&#xff1a; 7.1 窗口 7.2 弹窗 7.3 面板 7.4 文本框 7.5 列表框 7.6 按钮 7.7 图…

安卓蓝牙开发总结(一)—蓝牙开启与关闭

蓝牙开启与关闭 1、引言2、布局文件3、蓝牙打开与关闭  3.1 通过对按钮监听方法  3.2 通过设置点击事件 4、结果展示及总结5、参考链接 1、引言 最近在学习如何在安卓手机上对蓝牙进行操控&#xff0c;作为初学者发现大多数博客对安卓开发的初学者极为不友好&#xff0c;特…

【Bluetooth|蓝牙开发】二、蓝牙开发入门

个人主页&#xff1a;董哥聊技术 我是董哥&#xff0c;嵌入式领域新星创作者 创作理念&#xff1a;专注分享高质量嵌入式文章&#xff0c;让大家读有所得&#xff01; 【所有文章汇总】 1、蓝牙基础概念 蓝牙&#xff0c;是一种利用低功率无线电&#xff0c;支持设备短距离…

nimble 蓝牙开发一:BLE 蓝牙 Host 规范概述

目录 nimble 蓝牙开发一&#xff1a;概述一、BLE 简介二、BLE 基础知识蓝牙设备地址BLE 广播类型标准广播数据 三、BLE 工作概述BLE 常见的操作有&#xff1a;BLE 常见的工作流程&#xff1a; 四、BLE 使用的协议规范GAP1. GAP 工作角色2. GAP 工作模式3. GAP 工作流程4. GAP 工…