通俗易懂的贪吃蛇游戏

来源:互联网 发布:数据库 关系图 编辑:程序博客网 时间:2024/05/20 11:20

Vars类

public class Vars {    //    定义贪吃蛇运动的边界范围{y的起点,y的终点,x的起点,x的终点}        public static final int XSTAR=40;    public static final int XEND=1200;    public static final int YSTAR=20;    public static final int YEND=700;    //    定义贪吃蛇运动初始化第一个节点的位置    public static final int XSNAKE=100;    public static final int YSNAKE=100;}

Food类

import java.awt.Dimension;import java.awt.Toolkit;import java.util.Random;//定义食物类,蛇头碰到食物后蛇身加1,食物在屏幕中随意出现public class Food {private int x;private int y;public Food() {super();Random rand=new Random();x=Vars.XSNAKE+rand.nextInt((Vars.XEND-Vars.XSTAR-Vars.XSNAKE)/20)*20;y=Vars.YSNAKE+rand.nextInt((Vars.YEND-Vars.YSTAR-Vars.YSNAKE)/20)*20;// TODO Auto-generated constructor stub}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + x;result = prime * result + y;return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Food other = (Food) obj;if (x != other.x)return false;if (y != other.y)return false;return true;}public int getX() {return x;}public void setX(int x) {this.x = x;}public int getY() {return y;}public void setY(int y) {this.y = y;}}
Jf类
import java.awt.Dimension;import java.awt.Toolkit;import javax.swing.JFrame;import snake.MyJPanel;public class Jf  extends JFrame{private Dimension d = Toolkit.getDefaultToolkit().getScreenSize();private JpanelPaint jpanel = new JpanelPaint();void init(){this.setSize(d);this.add(jpanel);this.addKeyListener(jpanel);this.setVisible(true);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}}

JpanelPaint类

package snakexiu;import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.util.Timer;import java.util.TimerTask;import javax.swing.JOptionPane;import javax.swing.JPanel;/* * 定义一个画蛇的画板 * 主要进行蛇的运动 * */public class JpanelPaint extends JPanel implements KeyListener {    // 新建一个蛇,通过构造函数在(100,100)的位置连续生成5个节点    Snake s = new Snake();    // 新建一个食物    Food f = new Food();    // 蛇启动的延迟时间,单位毫秒    long delayTime = 500;    // 蛇每次往前走一步的间隔时间,单位毫秒    long speed = 100;    int score = 0;    // 通过构造函数调用自动前行的方法    public JpanelPaint() {        this.setOpaque(false);        autoStep();        // TODO Auto-generated constructor stub    }    // 蛇身自动前行    public void autoStep() {        Timer t = new Timer();        t.schedule(new TimerTask() {            @Override            public void run() {                // TODO Auto-generated method stub                if (s.getSnakeMessage().equals("方向冲突")) {                    t.cancel();                    JOptionPane.showMessageDialog(null, "方向冲突,游戏结束");                } else if (s.getSnakeMessage().equals("超出边界")) {                    t.cancel();                    JOptionPane.showMessageDialog(null, "超出边界,游戏结束!");                }                repaint();                SnakeNode tFood = new SnakeNode(f.getX(), f.getY());                if (s.getSnake().getFirst().getX() == tFood.getX() && s.getSnake().getFirst().getY() == tFood.getY()) {                    s.step(s.getDir(), true);                    score += 2;                    f = new Food();                } else {                    s.step(s.getDir(), false);                }            }        }, delayTime, speed);    }    public void paint(Graphics p) {        super.paint(p);        // 画出蛇身        p.setColor(Color.GREEN);        for (int i = 0; i < s.getSnake().size(); i++) {            p.fillRect(s.getSnake().get(i).getX(), s.getSnake().get(i).getY(), SnakeNode.WIDTH, SnakeNode.HEIGHT);        }        // 画出食物        p.setColor(Color.PINK);        p.fillRect(f.getX(), f.getY(), SnakeNode.WIDTH, SnakeNode.HEIGHT);        // 画出边界        p.setColor(Color.BLACK);        p.setFont(new Font("Microsoft YaHei", Font.BOLD, 80));        //上下边框        for (int i = 0; i <=(Vars.YEND-Vars.YSTAR)/20; i++) {            p.drawLine(Vars.XSTAR, Vars.YSTAR+i*20, Vars.XEND, Vars.YSTAR+i*20);        }        //左右横线                for (int i = 0; i <=(Vars.XEND-Vars.XSTAR)/20; i++) {            p.drawLine(Vars.XSTAR+i*20, Vars.YSTAR, Vars.XSTAR+i*20, Vars.YEND);        }        //告警信息        p.setColor(Color.BLACK);        p.setFont(new Font("Microsoft YaHei", Font.BOLD, 20));        p.drawString(s.getSnakeMessage(), Vars.XSTAR, Vars.YEND + 50);        //分数        p.setColor(Color.BLACK);        p.setFont(new Font("Microsoft YaHei", Font.BOLD, 20));        p.drawString("分数:"+String.valueOf(score), Vars.XSTAR + 800, Vars.YEND + 50);    }    @Override    public void keyTyped(KeyEvent e) {        // TODO Auto-generated method stub    }    //通过事件获取键盘的上下左右    @Override    public void keyPressed(KeyEvent e) {        // TODO Auto-generated method stub        switch (e.getKeyCode()) {        case KeyEvent.VK_UP:            s.setDir(Snake.up);            break;        case KeyEvent.VK_DOWN:            s.setDir(Snake.down);            break;        case KeyEvent.VK_RIGHT:            s.setDir(Snake.right);            break;        case KeyEvent.VK_LEFT:            s.setDir(Snake.left);            break;        case KeyEvent.VK_SPACE:            s.setDir(Snake.pause);            break;        default:            break;        }    }    @Override    public void keyReleased(KeyEvent e) {        // TODO Auto-generated method stub    }}
Snake类

 package snakexiu;import java.util.LinkedList;import snake.SnakeNode;import snaketedu.Node;/* * 定义蛇身类 * 属性:集合类-蛇身  *      方向 *      初始节点数 *      告警信息 * 方法:构造函数Snake初始化一个蛇 *      定义蛇的运动 *      */public class Snake {private LinkedList<SnakeNode> snake = new LinkedList<SnakeNode>();public static final int up = -10;public static final int down = 10;public static final int left = -1;public static final int right = 1;public static final int pause = 0;private int dir;private int nodeNum=5;private String snakeMessage="游戏开始";//初始化一个蛇 从(100,100)每间隔节点宽添加一个坐标到蛇身public Snake() {int x = Vars.XSNAKE;int y = Vars.YSNAKE;for (int i = 0; i < nodeNum; i++) {SnakeNode st = new SnakeNode();st.setX(x);st.setY(y);snake.add(st);x += st.getWidth();}dir = right;}//定义蛇的运动//@dir 键盘输入方向//@eat 是否吃到食物 吃到食物为真,没吃到食物为假public void step(int dir,boolean eat){//新增一个蛇头SnakeNode n = snake.getFirst();int i = n.getX() + (dir % 10)*20;int j = n.getY() + (dir / 10)*20;// 判断是否超过边界,没有则将蛇头添加到列表if(i>=Vars.XEND||j>=Vars.YEND||i<=Vars.XSTAR||j<=Vars.YSTAR){snakeMessage="超出边界";}else{n = new SnakeNode(i, j);snake.addFirst(n);}// 判断是否吃到食物,没有吃到去掉蛇尾,吃到不去掉蛇尾if(!eat){snake.removeLast();}}public int getDir() {return dir;}public void setDir(int dir) {//判断方向是否前后冲突if((dir+this.dir)==0){snakeMessage="方向冲突";}else{this.dir = dir;}}public LinkedList<SnakeNode> getSnake() {return snake;}public void setSnake(LinkedList<SnakeNode> snake) {this.snake = snake;}public String getSnakeMessage() {return snakeMessage;}public void setSnakeMessage(String snakeMessage) {this.snakeMessage = snakeMessage;}}
SnakeNode类

package snakexiu;/* * 蛇身节点 * 一个正方形 (x,y,width,height) */public class SnakeNode {private int x;private int y;public final static int HEIGHT=20;public final static int WIDTH=20;public SnakeNode(int x, int y) {super();this.x = x;this.y = y;}public SnakeNode() {super();// TODO Auto-generated constructor stub}public int getX() {return x;}public void setX(int x) {this.x = x;}public int getY() {return y;}public void setY(int y) {this.y = y;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + x;result = prime * result + y;return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;SnakeNode other = (SnakeNode) obj;if (x != other.x)return false;if (y != other.y)return false;return true;}}

Test类

package snakexiu;public class Test {public static void main(String[] args) {Jf j=new Jf();j.init();}}


原创粉丝点击