贪吃蛇-----小游戏

来源:互联网 发布:mac版的photoshop cc 编辑:程序博客网 时间:2024/06/05 08:42

贪吃蛇—–小游戏

  • Snake类
    分析Snake类,必须要考虑以下几个问题:
    1,贪吃蛇的身体如何绘制?
    2,位置和方向怎样更新?
    相信你有自己的答案,这里给出经验方法
    1,使用数组存放蛇身(蛇身由实心圆圈连成),数组的长度即为蛇身的最大长度。即将蛇变为数组处理
    2,利用上述数组,保证数组的循环,前一个圆圈的坐标作为下一个圆圈的坐标的更新值。意味着只有蛇头圆圈的坐标需要更新,其余圆圈的坐标直接采用数组上一个圆圈的保存值。
package tcs;import java.awt.Color;import java.awt.Graphics;import java.awt.Point;import java.util.Random;//导入随机类public class Food {    public Point location; // 食物的坐标    public Point size; // 食物的方块尺寸    private GamePanel gameP;    private Snake snk;    private Random rand;    public Food(GamePanel gp, Snake sk) {// 初始化各变量        gameP = gp;        snk = sk;        rand = new Random();        location = new Point(Math.abs(rand.nextInt() % gameP.width), Math.abs(rand.nextInt() % gameP.heigth));        size = new Point(sk.diameter, sk.diameter);// 尺寸与贪吃蛇圆圈相同    }    public void update() {// 判断是否重合,重合则认为Food被蛇吃到        if ((Math.abs((snk.x + snk.diameter / 2) - (location.x + size.x / 2)) < snk.diameter)                && (Math.abs((snk.y + snk.diameter / 2) - (location.y + size.y / 2)) < snk.diameter)) {            location = new Point(Math.abs(rand.nextInt() % gameP.width), Math.abs(rand.nextInt() % gameP.heigth));            if (snk.length < Snake.MAXLENTH) {                snk.length++;            }        }    }    public void draw(Graphics g) {        g.setColor(Color.black);// 食物是黑色        g.fillRect(location.x, location.y, size.x, size.y);// 食物用方块绘制    }}
  • Food类

分析Food类,同样需要考虑两个问题:
1,怎样判断食物被蛇吃了?
2,事物的坐标如何更新?
对于第一个问题,我们只需检测蛇头是否与食物发生了碰撞,如果两个对象碰到了一起,则认为食物被吃了,执行事物的坐标更新;第二个问题,导入Random随机类,在Panel上产生随机点作为Food的新位置

package tcs;import java.awt.Color;import java.awt.Graphics;import java.awt.Point;import java.util.Random;//导入随机类public class Food {    public Point location; // 食物的坐标    public Point size; // 食物的方块尺寸    private GamePanel gameP;    private Snake snk;    private Random rand;    public Food(GamePanel gp, Snake sk) {// 初始化各变量        gameP = gp;        snk = sk;        rand = new Random();        location = new Point(Math.abs(rand.nextInt() % gameP.width), Math.abs(rand.nextInt() % gameP.heigth));        size = new Point(sk.diameter, sk.diameter);// 尺寸与贪吃蛇圆圈相同    }    public void update() {// 判断是否重合,重合则认为Food被蛇吃到        if ((Math.abs((snk.x + snk.diameter / 2) - (location.x + size.x / 2)) < snk.diameter)                && (Math.abs((snk.y + snk.diameter / 2) - (location.y + size.y / 2)) < snk.diameter)) {            location = new Point(Math.abs(rand.nextInt() % gameP.width), Math.abs(rand.nextInt() % gameP.heigth));            if (snk.length < Snake.MAXLENTH) {                snk.length++;            }        }    }    public void draw(Graphics g) {        g.setColor(Color.black);// 食物是黑色        g.fillRect(location.x, location.y, size.x, size.y);// 食物用方块绘制    }}
  • GamePanel类

框架的建立十分重要,需要考虑很多问题,如:实现动画效果的帧变化;如何让帧速率稳定有效(创建线程);为何要离屏绘制及如何离屏绘制蛇身和食物等。
为了方便大家实验,这里先给出代码

package tcs;import java.awt.*;import java.awt.event.*;public class GamePanel extends Panel implements Runnable, KeyListener {    public int width; // 面板宽度    public int heigth; // 面板高度    public int incre = 1; // 面板    private Image im;    private Graphics dbg;    private Thread gamethread; // 线程控制游戏运行    private static final int FPS = 30; // 帧变化速度,表现为蛇移动速度    private boolean running = false;    private boolean isPaused = false;    private int direction;    public static final int SOUTH = 0; // 后期显示    public static final int NORTH = 1;    public static final int EAST = 2;    public static final int WEST = 3;    private Snake sk;    private Food bk;    public GamePanel() {// 面板初始化        width = 300;        heigth = 300;        setPreferredSize(new Dimension(width, heigth));        sk = new Snake(this);// 引用        bk = new Food(this, sk);// 引用        // 以下三句为按键检测        setFocusable(true);        requestFocus();        addKeyListener(this);    }    public int getDirection() {        return direction;    }    public void gameStart() {        if (!running) {            gamethread = new Thread(this);            gamethread.start(); // 启动此线程(实际上只有这一个线程)        }    }    public void gameStop() {        running = false;    }    public void gamePaint() {        Graphics g;        try {            g = this.getGraphics();            if (g != null && im != null) {                g.drawImage(im, 0, 0, null);            }            g.dispose();        } catch (Exception e) {        }    }    // 离屏绘制    public void gameRender() {        if (im == null) {            // 建立im对象,进行离屏绘制            im = createImage(width, heigth);            if (im == null) {                System.out.println("im is null");            } else {                dbg = im.getGraphics();            }        }        dbg.setColor(Color.white);        dbg.fillRect(0, 0, width, heigth);        sk.draw(dbg);        bk.draw(dbg);    }    public void gameUpdate() {        if (!isPaused) {            sk.update();            bk.update();        }    }    // 重载run()方法,将游戏循环放置其中    public void run() {        long t1, t2, dt, sleepTime;        long period = 1000 / FPS; //        t1 = System.nanoTime(); //        while (true) {            gameUpdate();            gameRender();            gamePaint();            t2 = System.nanoTime();            dt = (t2 - t1) / 1000000L;            sleepTime = period - dt;            if (sleepTime <= 0)                sleepTime = 2;            try {                Thread.sleep(sleepTime);            } catch (InterruptedException ex) {            }            t1 = System.nanoTime();        }    }    public void keyTyped(KeyEvent e) {    }    public void keyPressed(KeyEvent e) {        int keycode = e.getKeyCode();        if (keycode == KeyEvent.VK_P) {            isPaused = !isPaused;            System.out.println("key is P");        }        if (!isPaused) {            switch (keycode) {            case KeyEvent.VK_DOWN:                direction = SOUTH;                System.out.println("key is down" + direction);                break;            case KeyEvent.VK_UP:                direction = NORTH;                System.out.println("key is up" + direction);                break;            case KeyEvent.VK_RIGHT:                direction = EAST;                System.out.println("key is right" + direction);                break;            case KeyEvent.VK_LEFT:                direction = WEST;                System.out.println("key is left" + direction);                break;            }        }    }    public void keyReleased(KeyEvent e) {    }}

-Frame类

package tcs;import java.awt.*;import java.awt.event.*;public class GameFrame {    public GameFrame() {        Frame app = new Frame("GameFrame");        app.addWindowListener(new WindowAdapter() {            public void windowClosing(WindowEvent e) {                System.exit(0);            }        });        app.setLocation(100, 100);        GamePanel drawB = new GamePanel();        app.add(drawB, BorderLayout.CENTER);        app.pack();        app.setResizable(false);        app.setVisible(true);        drawB.gameStart();    }    /**     * @param args     *            the command line arguments     */    public static void main(String[] args) {        new GameFrame();        // TODO code application logic here    }}

实践创建java项目

运行GameFrame.java
这里写图片描述

注:文章转载,转载地址:
http://blog.csdn.net/qq_33232071/article/details/50583572

原创粉丝点击