public class StartGame {
public static void main(String[] args) {
JFrame jFrame = new JFrame("贪吃蛇");
jFrame.setBounds(10, 10, 900, 720);
jFrame.add(new GamePanel());
jFrame.setResizable(false);
jFrame.setVisible(true);
jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
}
public class GamePanel extends JPanel {
private int length; //蛇的长度
private int[] snakeX; //蛇的X坐标 34 * 24
private int[] snakeY; //蛇的X坐标 34 * 24
private String direction; //默认向右移动
private boolean isStart = false; //游戏当前状态(是否开始, 默认为false)
private boolean isFail = false; //游戏当前状态(是否失败, 默认为false)
//随机生成食物
private Random random;
private int footX; //食物X坐标
private int footY; //食物Y坐标
public GamePanel() {
startOff();
//获得焦点和键盘事件
this.setFocusable(true);
}
//初始化数据
public void init() {
//设置背景
this.setBackground(Color.WHITE);
this.length = 3; //初始为3
direction = "R"; //默认向右移动
snakeX = new int[816]; //蛇的X坐标 34 * 24
snakeY = new int[816]; //蛇的Y坐标 34 * 24
//初始蛇身体坐标
this.snakeX[0] = 100;
this.snakeY[0] = 100; //蛇头
this.snakeX[1] = 75;
this.snakeY[1] = 100; //第一节身体
this.snakeX[2] = 50;
this.snakeY[2] = 100; //第二节身体
//食物坐标
random = new Random();
this.footX = 25 + 25 * random.nextInt(34);
this.footY = 75 + 25 * random.nextInt(24);
}
//
public void startOff() {
init();
//键盘监听
this.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
//按下空格
if (keyCode == KeyEvent.VK_SPACE) {
if (isFail) {
//重新开始
isFail = false;
init();
} else {
isStart = !isStart; // 暂停/开始
}
}
//按下上键
if (keyCode == KeyEvent.VK_UP && !direction.equals("D")) {
direction = "U"; // 上
}
//按下下键
if (keyCode == KeyEvent.VK_DOWN && !direction.equals("U")) {
direction = "D"; // 下
}
//按下左键
if (keyCode == KeyEvent.VK_LEFT && !direction.equals("R")) {
direction = "L"; // 左
}
//按下右键
if (keyCode == KeyEvent.VK_RIGHT && !direction.equals("L")) {
direction = "R"; // 右
}
repaint(); //重新绘制该组件
}
});
//定时器(事件监听)
new Timer(100, (e) -> {
//如果开始. 就移动
if (isStart && !isFail) {
//身体移动
for (int i = length - 1; i > 0; i--) {
snakeX[i] = snakeX[i - 1];
snakeY[i] = snakeY[i - 1];
}
//蛇头上移动
if ("U".equals(direction)) {
//触碰上边界
/*if (snakeY[0] <= 75) {
snakeY[0] = 675;
}*/
snakeY[0] = snakeY[0] - 25;
}
//蛇头下移动
if ("D".equals(direction)) {
//触碰下边界
/*if (snakeY[0] >= 650) {
snakeY[0] = 50;
}*/
snakeY[0] = snakeY[0] + 25;
}
//蛇头左移动
if ("L".equals(direction)) {
//触碰左边界
/*if (snakeX[0] <= 25) {
snakeX[0] = 850;
}*/
snakeX[0] = snakeX[0] - 25;
}
//蛇头右移动
if ("R".equals(direction)) {
//触碰右边界
/*if (snakeX[0] >= 850) {
snakeX[0] = 0;
}*/
snakeX[0] = snakeX[0] + 25;
}
//失败判断,撞到边界
if (snakeX[0] <= 0 || snakeX[0] >= 875 || snakeY[0] <= 50 || snakeY[0] >= 675) {
snakeX[0] = -25;
snakeY[0] = -25;
isFail = true;
}
//吃食物
if (snakeX[0] == footX && snakeY[0] == footY) {
//长度加1
length++;
//重新生成食物
footX = 25 + 25 * random.nextInt(34);
footY = 75 + 25 * random.nextInt(24);
}
//失败判断(撞到自己)
for (int i = 1; i < length; i++) {
if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]) {
isFail = true;
break;
}
}
}
repaint(); //重新绘制该组件
}).start(); //开启定时器
}
//绘制面板
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g); //清屏
//绘制静态面板
g.setColor(Color.BLACK);
g.fillRect(25, 11, 850, 53); //头部
g.fillRect(25, 75, 850, 600); //游戏界面
//绘制小蛇
g.setColor(Color.GRAY);
g.fillRect(snakeX[0], snakeY[0], 25, 25);
g.setColor(Color.WHITE);
//g.fillRect(snakeX[1], snakeY[1], 25, 25);
//g.fillRect(snakeX[2], snakeY[2], 25, 25);
for (int i = 1; i < length; i++) {
g.fillRect(snakeX[i], snakeY[i], 25, 25);
}
//头部文字
g.setFont(new Font("华文彩云", Font.BOLD, 40)); //设置字体
g.drawString("贪 吃 蛇", 400, 50);
//积分
g.setFont(new Font("微软雅黑", Font.BOLD, 18)); //设置字体
g.drawString("长度 " + length, 35, 35);
g.drawString("分数 " + (length - 3) * 10, 35, 55);
//游戏状态
if (!isStart && !isFail) {
g.setFont(new Font("微软雅黑", Font.BOLD, 40)); //设置字体
g.drawString("按下空格开始游戏!", 300, 300);
}
if (isFail) {
g.setColor(Color.RED);
g.setFont(new Font("微软雅黑", Font.BOLD, 40)); //设置字体
g.drawString("游戏失败,按空格键重新开始", 200, 300);
}
//绘制食物
g.setColor(Color.GRAY);
g.fillOval(footX, footY, 25, 25);
}
}