java贪吃蛇

/* 
 * 完成了蛇撞到自己的检测.修改方法是在蛇的初始化的时候,用双循环来置FALSE;
 * 在重写代码的时候,我借鉴了别人的思路:将整个游戏的界面定义为一个布尔型的二维数组.
 * 用一个LinkedList来储存蛇.当蛇移动的时候,在蛇的头部增加一个节点,然后删除最后一个节点.
 * 因为只是做练习,所以没做游戏界面,比如菜单栏,计分栏什么的.另外还有一个问题,就是当两次点击回车时,蛇的移动速度会变快
 */
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class Game {
	public static void main(String args[]) {
		GameFrame frame = new GameFrame();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setResizable(false);
		frame.show();
		JOptionPane.showMessageDialog(null, "上,下左,右控制蛇的方向\n回车开始,S暂停");
	}
}

class GameFrame extends JFrame {
	public GameFrame() {
		setSize(294, 482);
		setTitle("贪吃蛇DEMO");
		this.setLocation(360, 100);
		Container c = getContentPane();
		GamePanel panel = new GamePanel();
		c.add(panel, BorderLayout.CENTER);
	}
}

class GamePanel extends JPanel implements KeyListener {
	static int panelWidth = 294;

	static int panelHeight = 450;

	int rectX = 15;

	int rectY = 15;

	Snake snake;

	Node n;

	public GamePanel() {
		snake = new Snake(this, panelWidth / rectX, panelHeight / rectY);
		setBackground(Color.WHITE);
		setSize(panelWidth, panelHeight);
		setFocusable(true);
		addKeyListener(this);
	}

	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		Graphics2D g2 = (Graphics2D) g;
		LinkedList list = snake.snakeList;
		Iterator it = list.iterator();
		g2.setColor(Color.black);
		while (it.hasNext()) {
			n = (Node) it.next();
			drawNode(g2, n);
		}
		g2.setColor(Color.ORANGE);
		Node f = snake.food;
		drawNode(g2, f);
		snake.drawMap(g2);// 绘制地图
	}

	public void keyPressed(KeyEvent e) {
		int keycode = e.getKeyCode();
		if (keycode == KeyEvent.VK_ENTER) {
			begin();
		} else if (keycode == KeyEvent.VK_UP) {
			snake.changeDirection(Snake.up);
		} else if (keycode == KeyEvent.VK_DOWN) {
			snake.changeDirection(Snake.down);
		} else if (keycode == KeyEvent.VK_LEFT) {
			snake.changeDirection(Snake.left);
		} else if (keycode == KeyEvent.VK_RIGHT) {
			snake.changeDirection(Snake.right);
		} else if (keycode == KeyEvent.VK_S) {
			Snake.run = false;
		}
	}

	public void keyReleased(KeyEvent e) {
	}

	public void keyTyped(KeyEvent e) {
	}

	public void drawNode(Graphics2D g, Node n) {
		g.fillRect(n.x * rectX, n.y * rectY, rectX - 2, rectY - 2);
	}

	public void begin() {
		Snake.run = true;
		SnakeThread thread = new SnakeThread(snake);
		thread.start();
	}
}

class Node {
	int x;

	int y;

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

class SnakeThread extends Thread {
	Snake snake;

	public SnakeThread(Snake s) {
		snake = s;
	}

	public void run() {
		Snake.run = true;

		while (Snake.run) {
			try {
				snake.move();
				sleep(200);
			} catch (InterruptedException e) {
			}
		}
		Snake.run = false;
	}
}

class Snake {
	GamePanel panel;

	Node food;

	boolean[][] all;

	public static boolean run;

	int maxX;

	int maxY;

	public static int left = 1;

	public static int up = 2;

	public static int right = 3;

	public static int down = 4;

	int direction = 4;

	LinkedList snakeList = new LinkedList();

	public Snake(GamePanel p, int maxX, int maxY) {
		panel = p;
		this.maxX = maxX;
		this.maxY = maxY;
		all = new boolean[maxX][maxY];
		for (int i = 0; i < maxX; i++) {
			for (int j = 0; j < maxY; j++) {
				all[i][j] = false;
			}
		}
		int arrayLength = maxX > 20 ? 10 : maxX / 2;
		for (int i = 0; i < arrayLength; i++) {
			int x = maxX / 10 + i;
			int y = maxY / 10;
			snakeList.addFirst(new Node(x, y));
			all[x][y] = true;
		}
		food = createFood();
		all[food.x][food.y] = true;
	}

	// 蛇移动的方法
	public void move() {
		Node n = (Node) snakeList.getFirst();
		int x = n.x;
		int y = n.y;

		if (direction == 3) {
			x++;
		} else if (direction == 4) {
			y++;
		} else if (direction == 1) {
			x--;
		} else if (direction == 2) {
			y--;
		}
		// 实现对蛇撞到自身的检测
		if ((0 <= x && x <= GamePanel.panelWidth / 15 - 1)
				&& (0 <= y && y <= GamePanel.panelHeight / 15 - 1)) {
			if (all[x][y]) {
				if (x == food.x && y == food.y) {
					snakeList.addFirst(food);
					food = createFood();
					all[food.x][food.y] = true;
				} else {
					JOptionPane.showMessageDialog(null, "你撞到自己了");
					System.exit(0);
				}
			} else {
				snakeList.addFirst(new Node(x, y));
				all[x][y] = true;
				Node l = (Node) snakeList.getLast();
				snakeList.removeLast();
				all[l.x][l.y] = false;
			}
		} else {
			JOptionPane.showMessageDialog(null, "越界了,游戏结束");
			System.exit(0);
		}
		panel.repaint();
	}

	public Node createFood() {
		int x = 0;
		int y = 0;
		do {
			Random r = new Random();
			x = r.nextInt(maxX - 10);
			y = r.nextInt(maxY - 10);

		} while (all[x][y]);
		return new Node(x, y);
	}
//设置蛇不能回头
	public void changeDirection(int newDirection) {
		if (direction % 2 != newDirection % 2) {
			direction = newDirection;
		}
	}

	public void drawMap(Graphics2D g) {
		for (int i = 0; i < maxX; i++) {
			for (int j = 0; j < maxY; j++) {
				if (all[i][j] == true) {
					g.setColor(Color.red);
					g.fillRect(i, j, 4, 4);
				}
			}
		}
	}
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值