贪吃蛇java小程序

<p>class Control代码:</p><p>import java.awt.event.KeyEvent;</p>import java.awt.event.KeyListener;

public class Control implements KeyListener {  //对键盘进行监听

	SnakeModel snake=null;
	public Control(SnakeModel snake) {
		this.snake=snake;
	}
	@Override
	public void keyPressed(KeyEvent e) {
		if(e.getKeyCode()==KeyEvent.VK_UP){
			snake.changeDirection(SnakeModel.UP);
		}
		if(e.getKeyCode()==KeyEvent.VK_DOWN){  //监听按键↓,向下移动
			snake.changeDirection(SnakeModel.DOWN);
		}
		if(e.getKeyCode()==KeyEvent.VK_LEFT){  //监听按键←,向左移动
			snake.changeDirection(SnakeModel.LEFT);
		}
		if(e.getKeyCode()==KeyEvent.VK_RIGHT){    //监听按键↑,向上移动
			snake.changeDirection(SnakeModel.RIGHT);
		}
		if(e.getKeyCode()==KeyEvent.VK_RIGHT){   //监听按键→,向右移动
			snake.changeDirection(SnakeModel.RIGHT);
		}
		if(e.getKeyCode()==KeyEvent.VK_R){//监听按键R,重置
			snake.reStart();
		}
	}
	@Override
	public void keyTyped(KeyEvent e) {	}
	@Override
	public void keyReleased(KeyEvent e) {}
}
class SnakeModel 代码:
<pre name="code" class="java">import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.Timer;

import cn.hncu.xh.Snake.snakePoint.point;

/*
 * 思路: 利用动态数组装蛇模型,蛇身的点都只跟着蛇头(即:数组的第一个元素)动,
 *     每 repaint()一次,就把动态数组里面的蛇全部数出来。
 *     每吃一个食物时,就添加在蛇头,蛇头往后移动一步,然后蛇身跟着移动。
 * 注意:在蛇吃到食物时,要避免捆绑!!!
 */
public class SnakeModel extends Canvas implements ActionListener {
	private snakePoint[] snakePoint;   //装蛇的数组
	private static Timer timer;       //定时器
	private static int score = 0;    //分数
	private int Dx, Dy;// 蛇头所在坐标
	private int Px, Py;           //食物的坐标
	static final int LEFT = 1;
	static final int UP = 2;
	static final int DOWN = 4;
	static final int RIGHT = 3;
	int direction = 4;             //初始方向为向下移动
	boolean isFrist = true;         //控制第一个食物的位置
	boolean isOne = true;          //控制每次刷新一次蛇只能按一次键盘
	boolean food;                  //控制没吃到一个食物才去刷新食物的坐标

	public SnakeModel(int delay) {// 构造蛇模型
		this.snakePoint = new snakePoint[300]; // 用来装蛇头
		snakePoint[1] = new snakePoint(100, 100);// 画蛇头

		// 使用定时器
		timer = new Timer(delay, this);
		timer.start();
	}

	public static int getScore() { // 获取分数
		return score;
	}

	class snakePoint {         //蛇身(每条蛇由很多蛇身构成)
		int x, y;

		public snakePoint(int x, int y) {
			this.x = x;
			this.y = y;
		}

		snakePoint(snakePoint p) {
			this.x = p.x;
			this.y = p.y;
		}
	}

	@Override
	public void paint(Graphics g) {
		
		//食物
		creatFood();

		// 每走一次就让数组自动移动一次
		if (score != 0) {
			for (int i = score + 2; i > 1; i--) {
				snakePoint[i] = new snakePoint(snakePoint[i - 1]);
			}
		}
		switch (direction) {// 判断蛇头的走向
		case UP:
			snakePoint[1].y -= 10;
			break;
		case DOWN:
			snakePoint[1].y += 10;
			break;
		case LEFT:
			snakePoint[1].x -= 10;
			break;
		case RIGHT:
			snakePoint[1].x += 10;
			break;
		}

		// 吃到了食物
		//要考虑食物的坐标不可能与蛇头坐标重合
		if (snakePoint[1].x <= Px + 7 && snakePoint[1].x >= Px - 5
				&& snakePoint[1].y <= Py + 7 && snakePoint[1].y >= Py - 5) {
			score++; // 分数加一
			food = true; // 刷新食物
			SnakeMain.re(); // 刷新分数
			timer.setDelay((timer.getDelay() - 4) <= 0 ? 20
					: timer.getDelay() - 4);   //每次吃到食物后就会加速蛇的移动速度
			// System.out.println(timer.getDelay());
			
			// 吃掉一个食物后,在蛇头增加一个长度
			for (int j = score + 1; j > 1; j--) {
				snakePoint[j] = new snakePoint(snakePoint[j - 1]);
			}

			// 让蛇头往移动方向走一步
			switch (direction) {// 判断蛇头的走向
			case UP:
				snakePoint[1].y -= 10;
				break;
			case DOWN:
				snakePoint[1].y += 10;
				break;
			case LEFT:
				snakePoint[1].x -= 10;
				break;
			case RIGHT:
				snakePoint[1].x += 10;
				break;
			}
		}
		
		g.setColor(Color.RED);//食物为红色		
		g.fillRect(Px, Py, 10, 10);// 画食物
		
		
		g.setColor(Color.BLACK);//蛇为黑色
		// 画蛇,把蛇从数组中画出来
		for (int i = 1; i <= score + 1; i++) {
			g.fillRect(snakePoint[i].x, snakePoint[i].y, 10, 10);
		}
	}

	private void creatFood() {
		if (isFrist) {
			Px = legal(380);// 获得合法的x值,
			Py = legal(330);// 获得合法的y值,即与x组合成食物坐标后不在蛇身上
			isFrist = false;
			return;
		}
		// 下一个食物坐标
		if (food) {
			Px = legal(380);//同上
			Py = legal(330);
			food = false;
		}
		// System.out.println(Px);
		// System.out.println(Py);
	}

	private int legal(int i) {
		Random r = new Random();   //生成随机数
		if (i == 380) {   //生成食物的y坐标
			while (true) {
				int n = (r.nextInt(37) + 1) * 10;
				for (int j = 1; j <= score + 1; j++) { //每次都要与蛇身进行匹配,避免食物出现在蛇身上;下同
					if (snakePoint[j].x != n && j == (score + 1)) {
						return n;
					}
				}
			}
		}
		if (i == 330) {   //生成食物的x坐标
			while (true) {
				int n = (r.nextInt(32) + 1) * 10;
				for (int j = 1; j <= score + 1; j++) {
					if (snakePoint[j].y != n && j == (score + 1)) {
						return n;
					}
				}
			}
		}
		return 0;
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		isOver();// 判断是否结束游戏
		repaint();
		isOne = true;
		// System.out.println(snakePoint[1].x+"  "+snakePoint[1].y);
	}

	private void isOver() {
		if (isCondition()) {// isCondition()//判断是否结束的所有条件放在里面
			timer.stop();
			SnakeMain.gameOver(); // 游戏结束,弹出对话框
		}
	}

	private boolean isCondition() { //游戏结束的条件
		// 出界(撞墙)
		if (snakePoint[1].x <= 0 || snakePoint[1].x >= 380
				|| snakePoint[1].y <= 0 || snakePoint[1].y >= 330) {
			return true;
		}
		//蛇头吃到蛇身了
		for (int i = 2; i <= score + 1; i++) {
			if (snakePoint[1].x == snakePoint[i].x
					&& snakePoint[1].y == snakePoint[i].y) {
				return true;
			}
		}
		return false;
	}

	public void changeDirection(int newDirection) { // 改变方向
		if (direction % 2 != newDirection % 2 && isOne) {// 改变的方向不能与原来的方向相同或相反
			direction = newDirection;
			isOne = false;
		}
	}

	public static void stop() {
			timer.stop();
	}

	public static void start() {
		timer.start();
		
	}
	//重置所有的数据
	public void reStart(){
		score=0;
		direction = 4;
		isFrist = true;
		isOne = true;
		food=false;
//		snakePoint=null;
		snakePoint[1].x=100;
		snakePoint[1].y=100;
		creatFood();
		timer.start();
	}
}


 
class SnakeMain 代码:
<pre name="code" class="java">import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class SnakeMain extends JFrame implements ActionListener {
	private static JTextField scoreField;
	private JButton  stop,start;

	public static void main(String[] args) {
		new SnakeMain();
	}

	public SnakeMain() {
		super("贪吃蛇");
		this.setBounds(300, 100, 400, 400);
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.setResizable(false);

		JPanel p = new JPanel();
		this.getContentPane().add(p, "North");
		p.add(new JLabel("Score:"));
		scoreField = new JTextField("0", 5);
		scoreField.setEditable(false);

		stop = new JButton("stop");
		start = new JButton("start");

		// 让这些组件丢失焦点
		scoreField.setFocusable(false);
		stop.setFocusable(false);
		start.setFocusable(false);
     
		//添加组件到面板p
		p.add(scoreField);
		p.add(stop);
		p.add(start);

		SnakeModel snake = new SnakeModel(400);// 500为刷新时间
		this.getContentPane().add(snake); // 把蛇加入到面板中 (蛇的运行范围:0<=x<=380
											// 0<=y<=330)
		Control control = new Control(snake); // 控制蛇

		// 进行监听
		stop.addActionListener(this);
		start.addActionListener(this);
		this.addKeyListener(control);

		// 显示
		this.setVisible(true);
	}

	public static void re() { // 刷新分数框
		scoreField.setText("" + SnakeModel.getScore());
	}

	public static void gameOver() {// 游戏结束
		JOptionPane.showMessageDialog(null, "Game Over!!!");
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == stop) {   
			SnakeModel.stop();
		}
		if (e.getSource() == start) {
			SnakeModel.start();
		}
	}

}


 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值