Snake类:
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JPanel;
//框架类
public class Snake {
public static void main(String[] args) {
SnakeMenu frame = new SnakeMenu("贪吃蛇");// 创建一个带有菜单的游戏界面框架
frame.setBounds(500, 150, 900, 720);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
SnakePanel panel = new SnakePanel(); // 添加画布
frame.add(panel);
frame.setVisible(true); // 允许显示游戏界面
}
}
SnakeMenu类:
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
//菜单类
public class SnakeMenu extends JFrame {
JMenuBar menubar;
JMenu menu, subMenu;
JMenuItem item1, item2;
SnakePanel snake=new SnakePanel();
public SnakeMenu(String s) {
init(s);
}
//初始化菜单栏
public void init(String s) {
setTitle(s);
menubar = new JMenuBar();
menu = new JMenu("选项");
subMenu = new JMenu("模式选择");
menu.add(subMenu);
//点击不同的模式时传入不同参数
item1 = subMenu.add(new JMenuItem("撞墙死"));
item1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent t) {
snake.changePattern(true);
}
});
item2 = subMenu.add(new JMenuItem("撞墙不死"));
item2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent t) {
snake.changePattern(false);
}
});
menubar.add(menu);
setJMenuBar(menubar);
}
}
SnakePanel
package java_dazuoye;
import java.awt.BasicStroke;
import java.awt.Graphics2D;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;
//主功能类
public class SnakePanel extends JPanel implements KeyListener, ActionListener {
ImageIcon up = new ImageIcon("up.jpg");// 蛇头
ImageIcon food = new ImageIcon("food.png"); // 食物
ImageIcon body = new ImageIcon("body.png");// 蛇身
ImageIcon title = new ImageIcon("title.jpg"); // 主题图片
ImageIcon backgrond = new ImageIcon("timg.jpg");// 背景图片
int[] snakex = new int[850];// 储存蛇身的数组
int[] snakey = new int[850];
Random rand = new Random();// 随机生成食物
int foodx = rand.nextInt(33) * 25 + 25;
int foody = rand.nextInt(23) * 25 + 75;
int len;// 长度
int score;// 分数
int maxScore = 0;// 最大分数
int maxLenth = 3;// 最长长度
String direction = "R"; // 方向:U上 D下 L左 R右
boolean isStarted = false; // 判断游戏是否开始
boolean isFailed = false; // 判断游戏是否结束
static boolean meetWalldie = true;// 判断是否撞墙死,初始撞墙死
int isFoodAtBody = 0; // 判断食物是否在蛇身上
// int BodySum = 0;
Timer timer = new Timer(100, this);// 每100毫秒调用一次ActionPerformed
public void paint(Graphics g) {
backgrond.paintIcon(this, g, 0, 0);// 放置背景
title.paintIcon(this, g, 26, 11);// 放置主题图片
// 绘制游戏边框
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(5.0f));
g2.setColor(Color.PINK);
g2.drawRect(25, 75, 853, 582);
// 绘制主题边框
Graphics2D g3 = (Graphics2D) g;
g3.setStroke(new BasicStroke(4.0f));
g3.setColor(Color.BLACK);
g3.drawRect(24, 12, 854, 55);
up.paintIcon(this, g, snakex[0], snakey[0]);// 画蛇头
for (int i = 1; i < len; i++)// 画蛇的身体
body.paintIcon(this, g, snakex[i], snakey[i]);
// 判断如果游戏没开始显示
if (!isStarted) {
g.setColor(Color.WHITE);
g.setFont(new Font("华文琥珀", Font.BOLD, 30));
g.drawString("按空格开始/暂停", 350, 350);
}
// 判断如果游戏结束显示
if (isFailed) {
g.setColor(Color.WHITE);
g.setFont(new Font("华文琥珀", Font.BOLD, 30));
g.drawString("不服?按空格再来一次!", 300, 350);
}
// 显示食物
food.paintIcon(this, g, foodx, foody);
// 显示分数等数值
g.setColor(Color.ORANGE);
g.setFont(new Font("华文彩云", Font.BOLD, 20));
g.drawString("分数 : " + score, 650, 37);
g.drawString("长度 : " + len, 650, 57);
g.drawString("最高分 : " + maxScore, 750, 37);
g.drawString("最长长度 : " + maxLenth, 750, 57);
}
// 游戏初始化
public void setup() {
isStarted = false;
isFailed = false;
len = 3;
score = 0;
direction = "R";
snakex[0] = 100;
snakex[1] = 75;
snakex[2] = 50;
snakey[0] = 100;
snakey[1] = 100;
snakey[2] = 100;
}
// 建造画布的构造方法
public SnakePanel() {
this.setFocusable(true); // 获取焦点
this.addKeyListener(this); // 监听键盘事件
setup();
timer.start();
}
// 实现键盘响应
public void keyPressed(KeyEvent e) {
int KeyCode = e.getKeyCode();
if (KeyCode == KeyEvent.VK_SPACE) { // 敲击空格显示/消除提示信息
if (isFailed) {// 结束后经判断得到最大值
if (score > maxScore) {
maxScore = score;
maxLenth = maxScore + 3;
}
setup();
} else {
isStarted = !isStarted;
}
} else if (KeyCode == KeyEvent.VK_UP && direction != "D" && isStarted)
direction = "U";
else if (KeyCode == KeyEvent.VK_DOWN && direction != "U" && isStarted)
direction = "D";
else if (KeyCode == KeyEvent.VK_RIGHT && direction != "L" && isStarted)
direction = "R";
else if (KeyCode == KeyEvent.VK_LEFT && direction != "R" && isStarted)
direction = "L";
}
// 移动数据
public void actionPerformed(ActionEvent e) {
if (isStarted && !isFailed) {
// 移动身体
for (int i = len; i > 0; i--) {
snakex[i] = snakex[i - 1];
snakey[i] = snakey[i - 1];
}
// 移动头
if (direction.equals("R")) {
snakex[0] = snakex[0] + 25;
} else if (direction.equals("L")) {
snakex[0] = snakex[0] - 25;
} else if (direction.equals("U")) {
snakey[0] = snakey[0] - 25;
} else if (direction.equals("D")) {
snakey[0] = snakey[0] + 25;
}
if (meetWalldie) {// 判断模式
if (snakex[0] > 850 || snakex[0] < 25 || (snakey[0] < 75) || snakey[0] > 625) {
isFailed = true;
}
} else if (!meetWalldie) {
if (snakex[0] > 850)
snakex[0] = 25;
if (snakex[0] < 25)
snakex[0] = 850;
if (snakey[0] < 75)
snakey[0] = 625;
if (snakey[0] > 625)
snakey[0] = 75;
}
if (snakex[0] == foodx && snakey[0] == foody) { // 吃食物
len++;
score++;
foodx = rand.nextInt(34) * 25 + 25;
foody = rand.nextInt(23) * 25 + 75;
for (int i = 1; i < len; i++) { // 如果食物在蛇身上则重新产生
if (foodx == snakex[i] && foody == snakey[i]) {
foodx = rand.nextInt(34) * 25 + 25;
foody = rand.nextInt(23) * 25 + 75;
break;
}
}
// 不知道什么原因不能运行的循环,目的是使食物永远不会出现在蛇身上
// while (isFoodAtBody == 1) {
// foodx = rand.nextInt(34) * 25 + 25;
// foody = rand.nextInt(23) * 25 + 75;
// for (int i = 1; i < len; i++) { // 如果蛇头碰到自己的身体游戏结束
// if (foodx != snakex[i] && foody != snakey[i])
// BodySum++;
// }
// if (BodySum == len - 1) {
// isFoodAtBody = 0;
// break;
// }
// }
}
// 如果蛇头碰到自己的身体游戏结束
for (int i = 1; i < len; i++) {
if (snakex[0] == snakex[i] && snakey[0] == snakey[i]) {
isFailed = true;
}
}
}
repaint();
}
void changePattern(boolean meetWalldie) {
this.meetWalldie = meetWalldie;
}
public void keyTyped(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
}
}
图像文件:
body.png: ,food.png: ,up.png:
运行:
选项中有撞墙死和撞墙不死两种模式