Java是目前比较流行的程序语言,很多软件或者游戏都是可以用java开发的,比如贪吃蛇游戏,那java贪吃蛇怎么改变速度?下面来我们就来给大家讲解一下java贪吃蛇开发原理及代码。
贪吃蛇实际上是一个较为简单的线程游戏,其制作思路主要为以下几个步骤:
1.主框架类(GameFrame):作为游戏的顶层容器和游戏程序的入口点。在代码中我将它写入了GamePanel里。
2.游戏面板类(GamePanel):作为游戏画面的显示组件,同时用来运行游戏循环,并对用户的输入事件进行处理。
3.贪吃蛇类(Snake):作为贪吃蛇的封装类,用来设置贪吃蛇的属性,并对其运动逻辑进行更新,同时对其图形进行绘制。
4.食物类(Food):作为食物的封装类,用来设置食物的属性,并对其运动逻辑进行更新,同时对其图形进行绘制。
游戏中常见的碰撞检测方法有两种:边界检测法和中心检测法,前者判断两个物体的坐标范围是否存在交集,后者计算两个物体中心键的距离是否小于一个指定值。
我在代码中使用了中心检测法,其描述可为如下形式:((x1+w1/2)-(x2+w2/2))*((x1+w1/2)-(x2+w2/2))+((y1+h1/2)-(y2+h2/2))*((y1+h1/2)-(y2+h2/2))<l*l< p="">
边界检测法更适合于类似俄罗斯方块的制作,其碰撞条件如下:x1-x2<w2&&x2-x1<w1&&y1-y2<h2&&y2-y1<h1< p="">
剩下的讲解我的代码中有详细的注释,大家可以自行学习理解。
import java.awt.Graphics; import java.awt.Image; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.image.BufferedImage; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JPanel; public class GamePanel extends JPanel implements Runnable, KeyListener { // 继承键盘事件监听接口 private int x, y; private int dx, dy; private int direction; // 保存方向值 public static final int SOUTH = 0, NORTH = 1, EAST = 2, WEST = 3; // 向南、北、东、西运动 private Snake sk; // 建立贪吃蛇对象 private Food bk; // 建立食物对象 Image im; Graphics g; ImageIcon ima = new ImageIcon("C:\\Users\\Alienware\\Desktop\\123.jpg"); public GamePanel() { JFrame f = new JFrame("贪吃蛇"); f.setLocation(600, 100); f.setSize(1000, 800); f.add(this); f.setDefaultCloseOperation(3); x = 50; y = 50; dx = 10; dy = 10; addKeyListener(this); // 注册键盘事件监听器 // this.setVisible(true); // System.out.println(this.getGraphics()); f.setVisible(true); // 实例化贪吃蛇的对象,并传递一个GamePanel对象的引用 sk = new Snake(this); // 实例化食物对象并传递一个GamePanel对象和Snake对象的引用 bk = new Food(this, sk); this.requestFocus(); } public void gameUpdate() { sk.update(); // 更新贪吃蛇坐标位置 bk.update(this); // 更新食物坐标位置 switch (direction) { case SOUTH: y = y + dy; break; case NORTH: y = y - dy; break; case EAST: x = x + dx; break; case WEST: x = x - dx; break; } } // Image im=new BufferedImage(100,100,BufferedImage.TYPE_4BYTE_ABGR); public void gameRender(Image im) { // System.out.println(im); Graphics dbg = im.getGraphics(); dbg.drawImage(ima.getImage(), 0, 0, this.getWidth(), this.getHeight(), null); sk.draw(dbg); // 在后备缓冲区绘制贪吃蛇图形 bk.draw(dbg); // 在后备缓冲区绘制食物图形 } public void gamePaint(Image im) { g = this.getGraphics(); // System.out.println(im); // System.out.println(g); g.drawImage(im, 0, 0, null); // 将后备缓冲区的内容在屏幕上显示出来 //g.dispose(); } boolean isPaused = false; public void run() { while (true) { try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } im = new BufferedImage(this.getWidth(), this.getHeight() , BufferedImage.TYPE_4BYTE_ABGR); if (isPaused == false) { gameUpdate(); } gameRender(im); gamePaint(im); //g.drawImage(im, 0, 0, null); // System.out.println("x="+x+" y="+y); } } public void keyPressed(KeyEvent e) { int keycode = e.getKeyCode(); // 获取按键信息 System.out.println("keycode=" + keycode); if (keycode == KeyEvent.VK_SPACE) // 若按下的是“空格”键。则切换 isPaused = !isPaused; switch (keycode) { // 根据不同的按键为direction赋值 case KeyEvent.VK_DOWN: // 如果按键盘“下”方向键 direction = SOUTH; System.out.println(direction); break; case KeyEvent.VK_UP: // 如果按键盘“上”方向键 direction = NORTH; System.out.println(direction); break; case KeyEvent.VK_RIGHT: // 如果按键盘“右”方向键 direction = EAST; System.out.println(direction); break; case KeyEvent.VK_LEFT: // 如果按键盘“左”方向键 direction = WEST; System.out.println(direction); break; } } public void keyTyped(KeyEvent e) { // TODO Auto-generated method stub } public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub } public int getDirection() { return direction; } public static void main(String[] args) { GamePanel g = new GamePanel(); Thread thread1 = new Thread(g); thread1.start(); } }
import java.awt.Color; import java.awt.Graphics; import java.awt.Point; public class Snake { GamePanel gameP; private Point[] body; //点类型数组,保存蛇身个小球坐标 public static final int MAXLENTH = 50; //蛇身最大长度 private int head; //指示蛇头位置 private int tail; //指示蛇尾位置 public int length; //蛇身长度 private int speed; //运行速度 public int x, y; //蛇头小球的横纵坐标 public int r; //蛇身小球的半径 public Snake(GamePanel gp) { gameP = gp; //通过构造方法的参数来获取对GamePanel对象的引用 body = new Point[MAXLENTH]; head = -1; tail = -1; length = 1; speed = 10; x = 50; y = 50; r = 10; } public void draw(Graphics g) { //绘制贪吃蛇的图形 System.out.println("head=" + head + " " + "tail=" + tail); g.setColor(Color.BLUE); //设置蛇身为蓝色 if (length > 1) { int i = tail; while (i != head) { //循环绘制蛇身各个小球 g.fillOval(body[i].x, body[i].y, r, r); i = (i + 1) % body.length; } } g.setColor(Color.RED); //设置蛇头为红色 g.fillOval(body[head].x, body[head].y, r, r); if (length == 1) { length++; } } public void update() { //更新游戏逻辑(贪吃蛇的坐标) int direction = gameP.getDirection(); switch (direction) { case GamePanel.SOUTH: y += speed; break; case GamePanel.NORTH: y -= speed; break; case GamePanel.EAST: x += speed; break; case GamePanel.WEST: x -= speed; break; } head = (head + 1) % body.length; //更新蛇头指针位置 tail = (head + body.length - length + 1) % body.length; //更新蛇尾指针坐标 body[head] = new Point(x, y); //保存蛇头小球坐标值 } }
import java.awt.Color; import java.awt.Graphics; import java.awt.Point; import java.util.Random; public class Food { private GamePanel gameP; private Snake snk; public Point location; //食物的坐标 public Point size; //食物方块的尺寸 private Random rand; //随机类对象 public Food(GamePanel gp, Snake sk) { gameP = gp; //通过构造方法的参数来获取对GamePanel对象的引用 snk = sk; //通过构造方法的参数来获取对Snake对象的引用 rand = new Random(); //食物随机的出现在屏幕上某个位置 location = new Point(Math.abs(rand.nextInt(gp.getWidth()) % gameP.getWidth()), Math.abs(rand.nextInt(gp.getHeight()) % gameP.getHeight())); size = new Point(sk.r, sk.r); //食物尺寸与贪吃蛇小球大小相同 } public void draw(Graphics g) { //绘制食物图形 g.setColor(Color.PINK); //设置食物颜色 g.fillRect(location.x, location.y, size.x, size.y); //绘制食物 } public void update(GamePanel gp) { //更新游戏逻辑(食物坐标) //碰撞检测(中心检测法),判断贪吃蛇是否吃到了食物 if ((snk.x - location.x) * (snk.x - location.x) + (snk.y - location.y) * (snk.y - location.y) < (snk.r * snk.r)) { //若贪吃蛇的蛇头与食物发生碰撞,则随机生成新的食物位置 location = new Point(Math.abs(rand.nextInt(gp.getWidth()) % gameP.getWidth()), Math.abs(rand.nextInt(gp.getHeight()) % gameP.getHeight())); if (snk.length < snake.maxlenth) { < p = "" > snk.length++; //若蛇身长度未达到最大值,则蛇身伸长一个单位 } } } }
java贪吃蛇游戏在制作的过程中一定要有清晰的开发思路,毕竟贪吃蛇游戏开发起来还是比较复杂的,只要思路清晰,代码正确,那就可以成功开发出贪吃蛇游戏了!最后大家如果想要了解更多java实例知识,敬请关注奇Q工具网。
推荐阅读: