通俗易懂的贪吃蛇游戏

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
	}
	
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + x;
		result = prime * result + y;
		return result;
	}
	@Override
	public 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;
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + x;
		result = prime * result + y;
		return result;
	}
	
	@Override
	public 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();
	
}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值