一.前言
某日,看见隔壁家的小朋友在玩一款网络爆款贪吃蛇游戏,感觉很好玩。自己刚好正在学习JAVA编程,也想实现一个类似功能的游戏Demo练手,在网上查看了不少源码案例,全都是很古老的方块式贪吃蛇游戏案例,没有想要的实现,因此自己动手实现一个JAVA版的贪吃蛇游戏。
我在这个Dome完成之后重写了这个游戏的Android版,并重新更名为《蛇王传说》。也欢迎大家下载试玩。游戏下载地址:点这里下载app
我的另一篇博客有Androd版本的游戏介绍:蛇王传说1.0Android版发布_hawkol的专栏-CSDN博客https://blog.csdn.net/hawkol/article/details/
二、实现效果
1.启动界面 蛇头会左右摆动,动态效果
2、游戏主界面 地图上有不同的食物,用键盘控制蛇在地图上行走,每吃掉一个食物,蛇会自动生长一节
三、按键功能说明 左右键蛇转向,上键蛇加速行走。
四、美工准备
因自己不会美工,很多图都是从网上找的,然后用photoshop抠图,按自己的设计思路,做成以下样式。做片做的比较丑,就不放原图了。
1、images 文件夹
2、foolds文件夹
3、snake文件夹
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 block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.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 block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.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)>=0 this.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; //UI private 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 block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.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); // 将缓冲map break; case 1: reDrawGame(); //显示得分 showDisplayInformation(); gr.drawImage(bfGameMap,0,0, null); // 将缓冲map break; case 2: reDrawGame(); showDisplayInformation(); bfGameMapGraphics.drawImage(imeGameOver,250,100, null); gr.drawImage(bfGameMap,0,0, null); // 将缓冲map break; 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 block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.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
最新小程序案例
今天的文章
java贪吃蛇小游戏_java入门简单小游戏代码分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/89793.html