package snake;
import java.awt.*;
public class Snake {
//构造方法
public Snake(){
//构造并显示主窗体
MainFrame frame = new MainFrame();
frame.setTitle("贪吃蛇游戏");
frame.setSize(760,584);
frame.setResizable(false); //不允许改变窗口的大小
frame.setLocationRelativeTo(null); //设置窗口居中显示
//将主窗体居中显示
// Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
// Dimension frameSize = frame.getSize();
// if(frameSize.height > screenSize.height){
// frameSize.height = screenSize.height;
// }
// if(frameSize.width > screenSize.width){
// frameSize.width = screenSize.width;
// }
// frame.setLocation((screenSize.width - frameSize.width)/2,(screenSize.height - frameSize.height)/2);
frame.setVisible(true);
frame.setDefaultCloseOperation(3);
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO 自动生成方法存根
new Snake();
}
}
package snake;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JToolBar;
public class MainFrame extends JFrame {
// 菜单相关属性
private JMenuBar menuBar1 = new JMenuBar(); // 菜单栏-菜单项-菜单
private JMenu mLevel = new JMenu("难度");
private JRadioButtonMenuItem miBegin = new JRadioButtonMenuItem("初级");
private JRadioButtonMenuItem miMiddle = new JRadioButtonMenuItem("中级");
private JRadioButtonMenuItem miHard = new JRadioButtonMenuItem("高级");
private JMenu mColor = new JMenu("背景颜色");
private JRadioButtonMenuItem mibrown = new JRadioButtonMenuItem("棕色");
private JRadioButtonMenuItem miblue = new JRadioButtonMenuItem("蓝色");
private JRadioButtonMenuItem mired = new JRadioButtonMenuItem("红色");
// 控制面板相关属性
private JToolBar toolBar = new JToolBar(); // 工具栏
private JButton jStart = new JButton("开始");
private JButton jPause = new JButton("暂停");
private JButton jStop = new JButton("结束");
private JButton jHelp = new JButton("帮助");
private boolean isPause = false; // 游戏是否处于暂停
private boolean isEnd = true; // 游戏是否处于停止
public int speed = 300; // 游戏速度
private PlayPanel playPane = new PlayPanel();
SnakeThread thread = new SnakeThread();
public static final int BEGINNER = 1, MIDDLE = 2, EXPERT = 3;
private int level = BEGINNER; // 当前游戏级别
// 构造方法,主窗体的初始构造
public MainFrame() {
// 构造等级设定菜单
this.setJMenuBar(menuBar1); // 把菜单栏放到容器中
menuBar1.add(mLevel); // 把菜单 放入菜单栏中
ButtonGroup group1 = new ButtonGroup(); // 只针对单选按钮菜单项,
group1.add(miBegin);
group1.add(miMiddle);
group1.add(miHard);
mLevel.add(miBegin);
mLevel.add(miMiddle);
mLevel.add(miHard);
miBegin.setSelected(true); // 初级选项被选中
// 构造颜色设定菜单
// this.setJMenuBar(menuBar2);
menuBar1.add(mColor);
ButtonGroup group2 = new ButtonGroup();
group2.add(mibrown);
group2.add(miblue);
group2.add(mired);
mColor.add(mibrown);
mColor.add(miblue);
mColor.add(mired);
mibrown.setSelected(true);
// 构造游戏控制工具栏
Container contentPane = this.getContentPane(); // 添加内容窗格
contentPane.add(toolBar, BorderLayout.NORTH); // 把工具栏放到了最上边
toolBar.add(jStart); // 往工具栏里放按钮
toolBar.add(jPause);
toolBar.add(jStop);
toolBar.add(jHelp);
contentPane.add(playPane, BorderLayout.CENTER);
// 设置按钮初始状态
jPause.setEnabled(false); // 按钮初始化是灰色的,无法使用
jStop.setEnabled(false);
// 创建动作时间的监听对象
MainFrameActionListener actionListener = new MainFrameActionListener();
// 开始按钮 注册监听器
jStart.addActionListener(actionListener);
jPause.addActionListener(actionListener);
jStop.addActionListener(actionListener);
jHelp.addActionListener(actionListener);
// 创建键盘时间的监听器对象
jStart.setFocusable(false);
jPause.setFocusable(false);
jStop.setFocusable(false);
jHelp.setFocusable(false);
MainFrameKeyListener keyListener = new MainFrameKeyListener();
// 将监听器注册给主窗体
this.addKeyListener(keyListener);
// 为级别设定按钮注册监听器
miBegin.addActionListener(actionListener);
miMiddle.addActionListener(actionListener);
miHard.addActionListener(actionListener);
}
class MainFrameActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
if (e.getSource() == jStart) {
isPause = false;
isEnd = false;
// 创建 蛇
playPane.createSnake();
// 创建食物
playPane.createFood();
// 创建障碍物
playPane.createbarrier();
// 启动蛇移动的线程
try {
thread.start();
} catch (Exception ex) {
}
jStart.setEnabled(false);
jPause.setEnabled(true);
jStop.setEnabled(true);
} else if (e.getSource() == jPause) {
if (isPause == true) {
jPause.setText("暂停");
isPause = false;
} else if (isPause == false) {
jPause.setText("继续");
isPause = true;
}
} else if (e.getSource() == jStop) {
playPane.clear(); // 清空游戏区
isPause = false;
isEnd = true;
jStart.setEnabled(true);
jPause.setEnabled(false);
jStop.setEnabled(false);
jPause.setText("暂停");
} else if (e.getSource() == jHelp) {
JOptionPane.showMessageDialog(null,"游戏说明:/n1:方向键控制蛇的移动方向/n2:按开始键开始游戏/n3:按暂停键可以暂停游戏,再按暂停键可以继续游戏/n4:黄色为普通食物,吃一个得100分/n5:蓝色为穿身宝物,吃一个得100分,该宝物允许玩家穿过蛇身一次/n6:红色为穿身宝物,吃一个得100分,该宝物允许玩家穿过墙壁一次/n7:暂停的快捷键为“空格”");
}
if (e.getSource() == miBegin) {
speed = 200;
} else if (e.getSource() == miMiddle) {
speed = 100;
} else if (e.getSource() == miHard) {
speed = 50;
}
}
}
// 定义一个内部类 用于做监听类
class MainFrameKeyListener extends KeyAdapter { // KeyAdapter 直接继承这个适配器
public void keyPressed(KeyEvent e) {
if (e.getKeyCode()==KeyEvent.VK_SPACE){
if (isPause == true) {
jPause.setText("暂停");
isPause = false;
} else if (isPause == false) {
jPause.setText("继续");
isPause = true;
}
}
if (!isEnd && !isPause) {
// 判断游戏状态
if (e.getKeyCode() == KeyEvent.VK_UP) {
playPane.setDirection(PlayPanel.UP);
} else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
playPane.setDirection(PlayPanel.DOWN);
} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
playPane.setDirection(PlayPanel.LEFT);
} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
playPane.setDirection(PlayPanel.RIGHT);
}
// 根据用户按键,设置蛇运动方向
}
}
}
class SnakeThread extends Thread {
public void run() {
while (true) {
try {
// 停顿
Thread.sleep(speed);
// 当游戏处于正常运行状态,则移动蛇身
if (!isEnd && !isPause) {
if (playPane.isLost()) {
isEnd = true;
JOptionPane.showMessageDialog(null, "游戏结束");
isPause = false;
playPane.clear();
jStart.setEnabled(true);
jPause.setText("暂停");
jPause.setEnabled(false);
jStop.setEnabled(false);
}
else{
int score = playPane.getScore();
if(score<300){
speed=200;
}
else if(score<1000){
speed=100;
}else{
speed=50;
}
playPane.moveSnake();
}
}
} catch (Exception ex) {
}
}
}
}
}
package snake;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class PlayPanel extends JPanel {
// 状态栏相关属性
private JLabel j1Score = new JLabel("0");
private JLabel j1ThroughBody = new JLabel("0");
private JLabel j1ThroughWall = new JLabel("0");
public int score = 0; // 当前得分
private int throughBody = 0;
private int throughWall = 0;
// 定义游戏去相关属性
private static final int ROWS = 30; // 游戏去行数
private static final int COLS = 50; // 游戏去列数
private JButton[][] playBlocks; // 游戏去的所有方格
// 蛇身相关属性
private int length = 3; // 蛇身的初始长度
private int[] rows = new int[ROWS * COLS]; // 记录蛇身每个方块的行号
private int[] columes = new int[ROWS * COLS]; // 记录蛇身的每个方格
public static final int UP = 1, LEFT = 2, DOWN = 3, RIGHT = 4;// 蛇运动方向
private int direction = RIGHT; // 用户按键的方向
private int lastdirection = RIGHT; // 蛇当前正在运动的方向
private boolean lost = false;
private int speed = 300;
// 创建蛇身
public void createSnake() {
length = 3; // 蛇身初始长度
score = 0; // 当前得分
throughBody = 0; // 穿身宝物数
throughWall = 0; // 穿墙宝物数
lost = false; // 游戏结束标志
direction = RIGHT; // 蛇身运动方向
lastdirection = RIGHT; // 蛇身在改变运动方向前的运动方向
// 初始化蛇身位置
for (int i = 0; i <= length; i++) {
rows[i] = 1;
columes[i] = length - i;
}
// 显示蛇身
for (int i = 0; i <= length; i++) {
playBlocks[rows[i]][columes[i]].setBackground(Color.green);
playBlocks[rows[i]][columes[i]].setVisible(true);
}
}
// 在游戏去内随机放置食物
public void createFood() {
int x = 0; // 食物行号
int y = 0; // 食物列号
// 随机生成食物位置,如果新位置是蛇身时,重新生成食物位置
do {
// 随机生成食物的行
x = (int) (Math.random() * ROWS);
// 随机生成食物的列
y = (int) (Math.random() * COLS);
} while (playBlocks[x][y].isVisible());
// 生成随机数,用于决定食物的类型
int random = (int) (Math.random() * 10);
// 当随机数小于7时,生成普通食物
if (random < 7) {
playBlocks[x][y].setBackground(Color.yellow);
}
// 当随机数介于7-9之间时,生成穿身宝物
else if (random < 9) {
playBlocks[x][y].setBackground(Color.blue);
} else {
playBlocks[x][y].setBackground(Color.red);
}
playBlocks[x][y].setVisible(true);
}
// 创建障碍物
public void createbarrier() {
int p = 0; // 障碍物的行号
int q = 0; // 障碍物的列号
// 随机生成障碍物位置,如果新位置是蛇身时,重新生成障碍物位置
for (int j = 0; j < 4; j++) {
do {
// 随机生成障碍物的行
p = (int) (Math.random() * ROWS);
q = (int) (Math.random() * COLS);
} while (playBlocks[p][q].isVisible());
for (int i = 0; i < 5; i++) {
playBlocks[p][q + i].setBackground(Color.black);
playBlocks[p][q + i].setVisible(true);
}
}
}
// 移动蛇
public void moveSnake() {
// 去掉蛇尾
playBlocks[rows[length]][columes[length]].setVisible(false);
playBlocks[rows[length]][columes[length]]
.setBackground(Color.lightGray);
// 显示除蛇头外蛇身
// 移动除蛇头外蛇身,记录新的蛇身的位置
for (int i = length; i > 0; i--) {
rows[i] = rows[i - 1];
columes[i] = columes[i - 1];
}
// 根据蛇身运动方向,决定蛇头位置
switch (direction) {
case UP: {
if (lastdirection == DOWN) {
rows[0] += 1;
} else {
rows[0] -= 1;
lastdirection = UP;
}
break;
}
case LEFT: {
if (lastdirection == RIGHT) {
columes[0] += 1;
} else {
columes[0] -= 1;
lastdirection = LEFT;
}
break;
}
case DOWN: {
if (lastdirection == UP) {
rows[0] -= 1;
} else {
rows[0] += 1;
lastdirection = DOWN;
}
break;
}
case RIGHT: {
if (lastdirection == LEFT) {
columes[0] -= 1;
} else {
columes[0] += 1;
lastdirection = RIGHT;
}
break;
}
}
// 处理蛇头碰到墙壁时操作
if (rows[0] >= ROWS || rows[0] < 0 || columes[0] >= COLS
|| columes[0] < 0) {
// 处理有穿墙宝物时的穿墙操作
if (throughWall != 0) {
// 更改穿墙宝物数,并更新状态栏
throughWall--;
j1ThroughWall.setText(Integer.toString(throughWall));
// 当蛇头碰到右侧墙壁时,蛇头从左侧墙壁重新进入
if (rows[0] >= ROWS) {
rows[0] = 0;
}
// 当蛇头碰到左侧墙壁时,蛇头从右侧墙壁重新进入
else if (rows[0] < 0) {
rows[0] = ROWS - 1;
}
// 当蛇头碰到低侧墙壁时,蛇头从顶部墙壁重新进入
else if (columes[0] >= COLS) {
columes[0] = 0;
}
// 当蛇头碰到顶部墙壁是,蛇头从底部墙壁重新进入
else if (columes[0] < 0) {
columes[0] = COLS - 1;
}
}
// 当没有穿墙宝物时,游戏结束
else {
lost = true;
return;
}
}
// 蛇头碰到蛇身时的处理操作
if (playBlocks[rows[0]][columes[0]].getBackground().equals(Color.green)) {
if (throughBody != 0) {
throughBody--;
j1ThroughBody.setText(Integer.toString(throughBody));
} else {
lost = true;
return;
}
}
// 蛇头碰到障碍物时的处理操作
if (playBlocks[rows[0]][columes[0]].getBackground().equals(Color.black)) {
if (throughWall != 0) {
throughWall--;
j1ThroughWall.setText(Integer.toString(throughWall));
} else {
lost = true;
return;
}
}
// 蛇头吃完食物后,蛇身加长,并随即显示下一个食物或者宝物
if (playBlocks[rows[0]][columes[0]].getBackground()
.equals(Color.yellow)
|| playBlocks[rows[0]][columes[0]].getBackground().equals(
Color.blue)
|| playBlocks[rows[0]][columes[0]].getBackground().equals(
Color.red)) {
length++;
createFood();
// 更新状态栏
score += 100;
j1Score.setText(Integer.toString(score));
// 获得穿身宝物时的操作
if (playBlocks[rows[0]][columes[0]].getBackground().equals(
Color.blue)) {
throughBody++;
j1ThroughBody.setText(Integer.toString(throughBody));
}
// 获得穿墙宝物时的操作
if (playBlocks[rows[0]][columes[0]].getBackground().equals(
Color.red)) {
throughWall++;
j1ThroughWall.setText(Integer.toString(throughWall));
}
}
// 显示蛇头
playBlocks[rows[0]][columes[0]].setBackground(Color.green);
playBlocks[rows[0]][columes[0]].setVisible(true);
}
// 清空游戏区
public void clear() {
score = 0;
throughBody = 0;
throughWall = 0;
j1ThroughBody.setText("0");
j1ThroughWall.setText("0");
j1Score.setText("0");
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
playBlocks[i][j].setBackground(Color.LIGHT_GRAY);
playBlocks[i][j].setVisible(false);
}
}
}
// 获取游戏状态
public boolean isLost() {
// TODO 自动生成方法存根
return lost;
}
// 设置蛇的运行方向
public void setDirection(int direction) {
this.direction = direction;
}
// 构造方法
public PlayPanel() {
JPanel statusPane = new JPanel(); // 状态栏面板
statusPane.add(new JLabel("得分:"));
statusPane.add(j1Score);
statusPane.add(new JLabel("穿身宝物:"));
statusPane.add(j1ThroughBody);
statusPane.add(new JLabel("穿墙宝物:"));
statusPane.add(j1ThroughWall);
// 构造游戏区面板
JPanel showPane = new JPanel(); // 显示蛇身运动的游戏区面板
showPane.setLayout(new GridLayout(ROWS, COLS, 0, 0));
// 设置边框
showPane.setBorder(BorderFactory.createEtchedBorder());
// 创建并初始化游戏区方块
playBlocks = new JButton[ROWS][COLS];
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
playBlocks[i][j] = new JButton(); // 把所有的格格都弄成JButton
playBlocks[i][j].setBackground(Color.LIGHT_GRAY); // 把所有的按钮都设成
// 亮灰色
playBlocks[i][j].setVisible(false); //
playBlocks[i][j].setEnabled(false);
showPane.add(playBlocks[i][j]);
}
}
this.setLayout(new BorderLayout());
this.add(statusPane, BorderLayout.NORTH);
this.add(showPane, BorderLayout.CENTER);
this.createSnake();
// this.createFood();
// this.createbarrier();
}
public int getScore() {
// TODO 自动生成方法存根
return 0;
}
}