两个包:GamePanel和Snake
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class GamePanel extends JPanel {
private static final long serialVersionUID = 1L;
Snake snakehead = null;// 蛇头
Snake snakebody = null;// 蛇身
Snake food = null;// 食物
static JFrame mf = null;// 主窗体
GameThread gt = new GameThread();// 主线程
ArrayList<Point> snakeroad = new ArrayList<>();// 蛇走过的路径数组
ArrayList<Snake> snakes = new ArrayList<>();// 蛇头及蛇身的数组
static int width = 600;// 窗体大小
int row = width / 20;// 按窗体大小及蛇的大小分成上下左右各30格
int col = row;
int step = 1;// 蛇每次移动间隔
int threadspeed = 150;// 主线程sleep间隔
int score = 0; // 分数
boolean dir = false;// 蛇移动方向
boolean gameflag = false;// 游戏暂停或开始判断
boolean dead = false;// 游戏失败判断
// 构造函数
public GamePanel() {
setBounds(0, 0, width, width);// 窗体大小
setOpaque(false);// 窗体透明
createKeyListener();// 监听键盘
gt.start();// 线程开始
init();// 初始化
}
// 入口
public static void main(String[] args) {
mf = new JFrame();// frame实例化
mf.setSize(width + 18, width + 15 + 30);// frame大小
mf.setLocationRelativeTo(null);// 屏幕居中显示
mf.setLayout(null);// 布局无
mf.setTitle("Sanke");// 标题
mf.setResizable(false);// 不可放大
mf.getContentPane().setBackground(new Color(0, 139, 0));// 设置背景色
GamePanel gp = new GamePanel();// panel实例化
mf.add(gp);// panel加入frame
mf.setVisible(true);// 显示frame
}
// 初始化
void init() {
// 蛇头存在就产生身体
if (snakes.size() > 0) {
snakebody = new Snake(snakes.get(snakes.size() - 1).x, snakes.get(snakes.size() - 1).y, this);
snakes.add(snakebody);
} else {
snakehead = new Snake(1, 1, this);// 蛇头实例化
snakes.add(snakehead);
}
// food随机产生
food = new Snake((int) (Math.random() * row), (int) (Math.random() * row), this);
}
// 画蛇,食物,提示
@Override
public void paint(Graphics g) {
super.paint(g);
// 蛇头
if (snakes != null) {
snakes.get(0).drawhead(g);
}
// 蛇身体
if (snakes != null) {
for (int i = 1; i < snakes.size(); i++) {
snakes.get(i).draw(g);
}
}
// food
if (food != null) {
food.drawfood(g);
}
// 游戏失败提示
if (dead) {
g.setColor(new Color(255, 255, 255, 255));
g.setFont(new Font("仿宋", Font.BOLD, 30));
g.drawString("游戏失败!按“空格键”继续", width / 2 - 180, width / 2);
}
// 游戏暂停提示
if (!gameflag) {
g.setColor(new Color(255, 255, 255, 255));
g.setFont(new Font("仿宋", Font.BOLD, 30));
g.drawString("游戏暂停!按“P”键开始", width / 2 - 170, width / 2);
}
// 分数和速度显示
g.setFont(new Font("Arial", Font.BOLD, 14));
g.setColor(new Color(255, 255, 255, 255));
g.drawString("SCORE", 3, width - 5);
g.drawString(String.valueOf(score), 60, width - 5);// 显示分数
g.drawString("SPEED", 100, width - 5);
g.drawString(String.valueOf(threadspeed), 155, width - 5);// 显示速度
g.setFont(new Font("仿宋", Font.BOLD, 14));
g.drawString("按“R”重新开始游戏", width - 150, width - 5);// 重新开始游戏
//画格子
for(int i=0;i<row;i++) {
for(int j=0;j<col;j++) {
g.setColor(new Color(173,216,230,25));
g.drawRect(j*20, i*20, 20, 20);
}
}
repaint();
}
// 主线程
class GameThread extends Thread {
@Override
public void run() {
while (true) {
try {
Thread.sleep(threadspeed);// 间隔150毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
if (snakehead != null & !dead & gameflag) {
// 蛇头移动坐标录入snakeroad数组
snakeroad.add(new Point(snakehead.x, snakehead.y));
if (snakeroad.size() == snakes.size()) {
snakeroad.remove(0);// 控制snakeroad数组长度
}
// 蛇移动
snakehead.movebody(dir, step);
outofBoard();// 边界穿透
dead();// 游戏失败判断
hit();// 吃food判断
}
}
}
}
// 边界穿透
void outofBoard() {
Snake snake = null;
// 四边界限
for (int i = 0; i < snakes.size(); i++) {
snake = snakes.get(i);
if (snake.getY() < 0) {
snake.setY(row - 1);
} else if (snake.getY() > row - 1) {
snake.setY(0);
} else if (snake.getX() < 0) {
snake.setX(row - 1);
} else if (snake.getX() > row - 1) {
snake.setX(0);
}
}
}
// 吃food
void hit() {
if (food.getX() == snakehead.x & food.getY() == snakehead.y) {
init();// 新增food和蛇加长
score++;// 分数增加
}
}
// 蛇头碰到蛇身体则失败
void dead() {
for (int i = 0; i < snakes.size(); i++) {
for (int j = 0; j < snakes.size(); j++) {
if (i != j) {
if (snakes.get(j).getX() == snakes.get(i).getX() && snakes.get(j).getY() == snakes.get(i).getY()) {
dead = true;
}
}
}
}
}
// 重新开始游戏
void restart() {
snakehead = null;
food = null;
snakes.clear();
snakeroad.clear();
threadspeed = 150;
score = 0;
dir = false;
gameflag = false;
dead = false;
init();
}
// 键盘监听
private void createKeyListener() {
KeyAdapter l = new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
switch (key) {
case KeyEvent.VK_P:// 按p键控制游戏暂停或开始
if (!gameflag) {
gameflag = true;
} else {
gameflag = false;
}
break;
// 空格
case KeyEvent.VK_SPACE:
dead = false;
break;
// 向上
case KeyEvent.VK_UP:
case KeyEvent.VK_W:
dir = false;
step=-1;
break;
// 向右
case KeyEvent.VK_D:
case KeyEvent.VK_RIGHT:
dir = true;
step=1;
break;
// 向下
case KeyEvent.VK_S:
case KeyEvent.VK_DOWN:
dir = false;
step=1;
break;
// 向左
case KeyEvent.VK_A:
case KeyEvent.VK_LEFT:
dir = true;
step=-1;
break;
case KeyEvent.VK_1:
threadspeed += 5;// 按1速度减慢5
break;
case KeyEvent.VK_2:
if (threadspeed > 0) {
threadspeed -= 5;// 按2速度加快5
}
break;
case KeyEvent.VK_R:
restart();
break;
}
}
};
mf.addKeyListener(l);// 主窗体增加键盘监听
}
}
import java.awt.Color;
import java.awt.Graphics;
public class Snake {
private GamePanel panel = null;
int x = 0;
int y = 0;
public Snake(int x, int y, GamePanel panel) {
this.x = x;
this.y = y;
this.panel = panel;
}
// 画蛇身
void draw(Graphics g) {
g.setColor(new Color(255, 255, 255));
g.fillRect(x * 20, y * 20, 19, 19);
}
// 画食物
void drawfood(Graphics g) {
g.setColor(new Color(255, 255, 255,255));
g.fillOval(x * 20+5, y * 20+5, 10, 10);
}
// 画蛇头
void drawhead(Graphics g) {
g.setColor(new Color(255, 0, 0));
g.fillRect(x * 20, y * 20, 19, 19);
}
// 蛇头移动
void move(boolean dir, int step) {
if (dir) {
x+=step;
}else {
y+=step;
}
panel.repaint();
}
//蛇移动
public void movebody(Boolean dir, int step) {
// 蛇头移动
panel.snakehead.move(dir, step);
// 蛇身移动
for (int i = 1; i < panel.snakes.size(); i++) {
panel.snakes.get(i).x = panel.snakeroad.get(panel.snakeroad.size()-i).x;
panel.snakes.get(i).y = panel.snakeroad.get(panel.snakeroad.size()-i).y;
}
panel.repaint();
}
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;
}
}
浙公网安备 33010602011771号