贪吃蛇

贪吃蛇是个十分经典的游戏,而且做起来也很有意思

刚开始打算使用网格布局来做,后来发现使用画布会有更高的效率,也更容易实现

这个就当做我的第一个版本吧,给出详细的解析,步骤

素材是在别人那里来的

下面是效果图


main函数new 一个JFrame,设定好窗口的一些属性

import javax.swing.JFrame;

public class Main {
	public static void main(String[] args) {
		JFrame snakeFrame = new JFrame();
		snakeFrame.setBounds(330, 5, 800, 725);// 窗口位置,大小
		snakeFrame.setResizable(false);// 窗口大小不可变
		snakeFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 点击关闭按钮的操作

		SnakeJPanel snakeJPanel = new SnakeJPanel();
		snakeFrame.add(snakeJPanel);// 将面板加到窗口

		snakeFrame.setVisible(true);// 设为可见
	}
}

游戏显示都是使用画布来做的,所以再建一个类,继承JPanel

首先定义好相关变量

/// 定义区/
	final int MAXLEN = 200;//蛇身最大长度
	

	boolean isStared = false;// 游戏是否开始
	boolean isFailed = false;// 游戏是否结束
	boolean isFirst;// 是否第一次打开游戏
	// 设置游戏的默认属性
	int snakeLen;// 蛇身长度(包括蛇头)
	int score = 0;// 得分
	String direction = "R";// 蛇头方向
        //蛇头,蛇身,食物的图片(一定要注意图片的位置书写,不然就会无法显示,而且也没有任何提示)
       ImageIcon body = new ImageIcon("src//img//body.png");
	ImageIcon down = new ImageIcon("src//img//down.png");
	ImageIcon food = new ImageIcon("src//img//food.png");
	ImageIcon left = new ImageIcon("src//img//left.png");
	ImageIcon right = new ImageIcon("src//img//right.png");
	ImageIcon up = new ImageIcon("src//img//up.png");

	/* 蛇的每一部分
	 * snakex[0], snakey[0]表示蛇头
	 * snakex[1], snakey[1]表示蛇身的第一个部分......
	 * 里面的参数表示位置
	 * */
	int[] snakex = new int[MAXLEN];
	int[] snakey = new int[MAXLEN];

	// 随机生成食物(需要根据游戏面板的大小来设定)
	Random ran = new Random();
	int foodX = ran.nextInt(30) * 25 + 25;//一个图像为25像素,也就是一行有30个图片,从25像素开始显示
	int foodY = ran.nextInt(26) * 25 + 25;

	// 计时器
	// Timer(delay, listener)
	// 每五十毫秒调用一次监听(也就是50毫秒走一步)
	Timer timer = new Timer(150, this);

然后是构造方法和对游戏的初始化

public SnakeJPanel() {
		isFirst = true;// 第一次打开游戏
		this.setFocusable(true);
		init();// 初始化
		this.addKeyListener(this);
	}

// 初始化
	public void init() {
		snakeLen = 3;// 蛇神长度
		score = 0;// 分数
		direction = "R";
		stringTime = "0";
		snakex[0] = 100;
		snakex[1] = 75;
		snakex[2] = 50;
		snakey[0] = 75;
		snakey[1] = 75;
		snakey[2] = 75;
	}

再将面板画出来,覆盖paint()方法

@Override
	public void paint(Graphics graphics) {
		graphics.clearRect(450, 0, 150, 25);//清空指定区域
		
		graphics.fillRect(25, 25, 750, 650);// (330, 5, 800, 725)
		// 上面显示信息--分数,时间
		graphics.setColor(Color.BLACK);
		graphics.setFont(new Font("楷体", Font.BOLD, 20));
		//分数
		graphics.drawString("分数:" + score*10, 450, 20);
		
		// 蛇头
		if (direction.equals("R")) {
			right.paintIcon(this, graphics, snakex[0], snakey[0]);
		} else if (direction.equals("L")) {
			left.paintIcon(this, graphics, snakex[0], snakey[0]);
		} else if (direction.equals("U")) {
			up.paintIcon(this, graphics, snakex[0], snakey[0]);
		} else if (direction.equals("D")) {
			down.paintIcon(this, graphics, snakex[0], snakey[0]);
		}
		// 蛇身
		for (int i = 1; i < snakeLen; i++) {
			body.paintIcon(this, graphics, snakex[i], snakey[i]);
		}
		// 如果第一次进入游戏
		if (isFirst) {
			graphics.setColor(Color.white);
			graphics.setFont(new Font("方正舒体", Font.BOLD, 38));
			graphics.drawString("~~欢迎来到贪吃蛇游戏~~", 180, 270);
			
			graphics.setFont(new Font("方正舒体", Font.BOLD, 22));
			graphics.drawString("游戏规则:", 350, 400);
			graphics.drawString("空格键开始或停止游戏", 285, 450);
			graphics.drawString("方向键来控制蛇的方向", 285, 475);
			isFirst = false;
			return;
		}
		// 如果是继续游戏(没有开始且没有失败)
		if (!isStared && !isFailed && !isFirst) {
			graphics.setColor(Color.white);
			graphics.setFont(new Font("方正舒体", Font.BOLD, 38));
			graphics.drawString("~~请按空格键开始游戏~~", 180, 270);
		}
		// 如果已经失败了
		if (!isStared && isFailed && !isFirst) {
			graphics.setColor(Color.white);
			graphics.setFont(new Font("方正舒体", Font.BOLD, 35));
			graphics.drawString("游戏结束", 320, 180);
			graphics.drawString("~~请按空格键继续~~", 220, 240);
		}
		// 如果已经开始
		if (isStared) {
			// 显示食物
			food.paintIcon(this, graphics, foodX, foodY);
		}
	}

最后也是最为关键的,也就是监听了

ActionListener  和  KeyListener 进行时间和键盘的监听

	@Override
	public void actionPerformed(ActionEvent e) {
		if (isStared && !isFailed) {
			// 蛇身
			for (int i = snakeLen; i > 0; i--) {
				snakex[i] = snakex[i - 1];
				snakey[i] = snakey[i - 1];
			}
			// 蛇头
			if (direction.equals("U")) {
				snakey[0] -= 25;
				if (snakey[0] < 25) {
					snakey[0] = 650;
				}
			} else if (direction.equals("D")) {
				snakey[0] += 25;
				if (snakey[0] > 650) {
					snakey[0] = 25;
				}
			} else if (direction.equals("L")) {
				snakex[0] -= 25;
				if (snakex[0] < 25) {
					snakex[0] = 750;
				}
			} else if (direction.equals("R")) {
				snakex[0] += 25;
				if (snakex[0] > 750) {
					snakex[0] = 25;
				}
			}
			// 吃掉食物
			if (foodX == snakex[0] && foodY == snakey[0]) {
				// 重新定义食物位置
				foodX = ran.nextInt(30) * 25 + 25;
				foodY = ran.nextInt(26) * 25 + 25;
				// 蛇身长度加一,分数改变
				snakeLen++;
				score++;
			}
			// 如果蛇吃掉了自己?
			for (int i = snakeLen; i > 0; i--) {
				if (snakex[i] == snakex[0] && snakey[i] == snakey[0]) {
					isFailed = true;
					isStared = false;
				}
			}
		}
		repaint();
	}

	@Override
	public void keyPressed(KeyEvent e) {
		timer.start();
		int key = e.getKeyCode();
		// 空格键
		if (KeyEvent.VK_SPACE == key) {
			// 如果已经失败了就重新开始
			// 否则就暂停或开始
			if (isFailed) {
				isFailed = false;
				isStared = false;
				init();
			} else {
				isStared = !isStared;
			}
		}

		if (key == KeyEvent.VK_UP && !direction.equals("D")) {// 方向--上
			direction = "U";
		} else if (key == KeyEvent.VK_DOWN && !direction.equals("U")) {// 方向--下
			direction = "D";
		} else if (key == KeyEvent.VK_LEFT && !direction.equals("R")) {// 方向--左
			direction = "L";
		} else if (key == KeyEvent.VK_RIGHT && !direction.equals("L")) {// 方向--右
			direction = "R";
		}
		repaint();
	}

	@Override
	public void keyTyped(KeyEvent e) {}
	@Override
	public void keyReleased(KeyEvent e) {}


最后,如果有需要的,可以到这里来下载整个小程序

贪吃蛇1

相关的事项在那也讲到了的

当然,如果仅仅是参考一下的就完全没必要了,因为这里的代码已经很全

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值