java贪吃蛇怎么改变速度?java贪吃蛇开发原理及代码

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工具网。

推荐阅读:

java多线程如何保证线程安全?线程安全的实现方法

java面试都有哪些数据类型?java数据类型介绍

json数据里有双引号怎么解析?json数据双引号解析方法