贪吃蛇 java实现超简单的贪吃蛇(附源代码)

贪吃蛇游戏

贪吃蛇是个非常经典的游戏,希望对初学Java的小伙伴有一定帮助。希望大家喜欢,因为写得简单,希望大家都能看得懂。

游戏界面(游戏背景素材不喜欢的话可以自己换,就别在乎我选的素材(🤦‍😳😳)!!!)贪吃蛇要美观的话背景素材选取还是比较重要的需要画小格子来匹配食物,蛇节点。如果需要美观一点的可以自己设计个,当然也可以留言&找我,有必要的话我会花时间弄一个出来
在这里插入图片描述

代码

1.Main

package cn.tedu.worm;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Main extends JPanel {
	/** 行数 */
	public static final int ROWS = 35;
	/** 列数 */
	public static final int COLS = 35;
	/** 格子大小 10个像素 */
	public static final int CELL_SIZE = 10;

	public static Image background;
	public static Image foodImage;
	public static Image cellImage;
	
	private Move worm;
	private Node food;

	public Main() {
		//如下加载图片的方法,知道即可,图片必须与Main.java
		//在同一个包中!
		background = Toolkit.getDefaultToolkit().
				createImage(getClass().getResource("bg.png"));
		foodImage = Toolkit.getDefaultToolkit().
				createImage(getClass().getResource("food.png"));
		cellImage = Toolkit.getDefaultToolkit().
				createImage(getClass().getResource("node.png"));
		worm = new Move();
		food = createFood();
	}

	/**
	 * 生成一个食物 1 生成随机数x,y 2 检查蛇是否包含x,y 2.1 如果包含 返回 1 3 创建食物节点。
	 * */
	private Node createFood() {
		int x;
		int y;
		Random r = new Random();
		do {
			x = r.nextInt(COLS);
			y = r.nextInt(ROWS);
		} while (worm.contains(x, y));
		return new Node(x, y);
	}

	public String toString() {
		return "worm:" + worm + "\nfood:" + food;
	}

	/** 重写绘图方法 */
	public void paint(Graphics g) {
		// 填充背景色
		g.drawImage(background, 0, 0, null);
		// 绘制食物
		g.translate(54, 49);
		g.drawImage(foodImage, 
				CELL_SIZE * food.getX(), CELL_SIZE * food.getY(), null);
		// 绘制蛇
		Node[] cells = worm.getCells();
		for (int i = 0; i < cells.length; i++) {
			Node node = cells[i];
			g.drawImage(cellImage, 
					CELL_SIZE * node.getX(), CELL_SIZE * node.getY(), null);

		}
	}

	/**  */

	public static void main(String[] args) {
		// 启动软件 Main.java
		JFrame frame = new JFrame("贪吃蛇");
		Main pane = new Main();// 面板
		frame.add(pane);// 窗口添加面板
		frame.setSize(470, 480);// 设置窗口的大小
		frame.setLocationRelativeTo(null);// frame居中
		frame.setVisible(true);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		pane.action();// 启动蛇的运行
	}

	private void action() {
		// worm.creep(food);
		// repaint();//swing JPanel 中声明的方法,会尽快的启动
		// 界面的重绘功能,尽快调用paint(g) 方法绘制界面
		Timer timer = new Timer();
		timer.schedule(new TimerTask() {
			public void run() {
				// 爬行控制逻辑
				if (worm.hit()) {
					worm = new Move();
					food = createFood();
				} else {
					boolean eat = worm.creep(food);
					if (eat) {
						food = createFood();
					}
				}
				repaint();
			}
		}, 0, 1000 / 7);
		// this 就是当前舞台面板
		this.requestFocus();
		this.addKeyListener(new KeyAdapter() {
			public void keyPressed(KeyEvent e) {
				// key 代表哪个按键被按下!
				int key = e.getKeyCode();
				switch (key) {
				case KeyEvent.VK_UP:// 上箭头按下!
					creepTo(Move.UP);
					break;
				case KeyEvent.VK_DOWN:// 下箭头按下!
					creepTo(Move.DOWN);
					break;
				case KeyEvent.VK_LEFT:// 左箭头按下!
					creepTo(Move.LEFT);
					break;
				case KeyEvent.VK_RIGHT:// 右箭头按下!
					creepTo(Move.RIGHT);
					break;
				}
			}
		});// addKeyListener
	}// action()

	/** 爬行控制方法,在按键按下时候调用 */
	private void creepTo(int direction) {
		if (worm.hit(direction)) {
			worm = new Move();
			food = createFood();
		} else {
			boolean eat = worm.creep(direction, food);
			if (eat) {
				food = createFood();
			}
		}
		repaint();
	}
}

2.Move

package cn.tedu.worm;

import java.util.Arrays;

/**
 * 贪吃蛇
 * 
 */
public class Move {
	public static final int DEFAULT_LENGTH = 12;
	private Node[] cells;

	public static final int UP = 1;
	public static final int DOWN = -1;
	public static final int LEFT = 2;
	public static final int RIGHT = -2;

	/** 蛇当前的运行方向 */
	private int currentDirection;

	public Move() {
		cells = new Node[DEFAULT_LENGTH];
		for (int i = 0; i < cells.length; i++) {
			cells[i] = new Node(i, 0);// [0,0] [1,0] [2,0]
		}
		currentDirection = DOWN;
		// cells = new Cell[]{new Cell(0,0),new Cell(1,0),...};
	}

	public boolean contains(int x, int y) {
		for (int i = 0; i < cells.length; i++) {
			Node node = cells[i];
			if (node.getX() == x && node.getY() == y) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 1) 计算currentDirection与direction的和, 如果是0表示反向了, 就结束方法返回, 不进行任何动作
	 * 2)currentDirection = direction 改变当前的方向, 作为下次运行的方向 3) 判断当前头节点的坐标与食物对象的坐标一致
	 * 如果一致说明是吃到食物了 4) 如果吃到食物, 就将cells数组进行扩容 将cells数组内容的每个元素向后移动. 5)
	 * 将新头节点插入的头位置cells[0]=newHead 6) 返回是否吃到食物
	 */
	public boolean creep(int direction, Node food) {
		if (currentDirection + direction == 0) {
			return false; // 反向了,不进行任何动作
		}
		currentDirection = direction;
		Node head = createHead(direction);
		boolean eat = head.getX() == food.getX() && head.getY() == food.getY();
		// boolean eat = false;
		// if(head.getX()==food.getX() &&
		// head.getY()==food.getY()){
		// eat = true;
		// }
		if (eat) {
			cells = Arrays.copyOf(cells, cells.length + 1);
		}
		for (int i = cells.length - 1; i >= 1; i--) {
			cells[i] = cells[i - 1];
		}
		cells[0] = head;
		return eat;
	}

	public boolean hit() {
		return hit(currentDirection);
	}

	public boolean hit(int direction) {
		// 修正,反向不处理碰撞
		if (currentDirection + direction == 0) {
			return false;
		}
		// System.out.println("方向(2):"+direction);
		Node head = createHead(direction);
		// System.out.println(head);
		if (head.getX() < 0 || head.getX() >= Main.COLS || head.getY() < 0
				|| head.getY() >= Main.ROWS) {
			return true;
		}
		for (int i = 0; i < cells.length - 1; i++) {
			Node node = cells[i];
			if (node.getX() == head.getX() && node.getY() == head.getY()) {
				return true;
			}
		}
		return false;
	}

	public boolean creep(Node food) {
		return creep(currentDirection, food);
	}

	public void creep() {
		for (int i = cells.length - 1; i >= 1; i--) {
			cells[i] = cells[i - 1];
		}
		cells[0] = createHead(currentDirection);
	}

	private Node createHead(int direction) {
		int x = cells[0].getX();
		int y = cells[0].getY();
		switch (direction) {
		case DOWN:
			y++;
			break;
		case UP:
			y--;
			break;
		case LEFT:
			x--;
			break;
		case RIGHT:
			x++;
			break;
		}
		return new Node(x, y);
	}

	/** Move.java */
	public Node[] getCells() {
		return Arrays.copyOf(cells, cells.length);
	}

	public String toString() {
		return Arrays.toString(cells);
	}

}

3.Node

package cn.tedu.worm;

/**
 * 一个单元格子
 * 
 */
public class Node {
	private int x;
	private int y;

	public Node() {
	}

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

	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;
	}

	public String toString() {
		return "[" + x + "," + y + "]";
	}
}

4.项目结构

在这里插入图片描述

源代码代码下载

百度盘下载

提取码:qwer

CSDN下载


其它小游戏

在这里插入图片描述

评论 34
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值