package com.lyl.util;
public class Global {
public static final int CELL_SIZE = 18;
public static final int WIDTH = 25;
public static final int HEIGHT = 25;
}
entity包
Food
package com.lyl.entity;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import com.lyl.util.Global;
public class Food extends Point{
/**
*
*/
private static final long serialVersionUID = 1L;
private Color foodColor;
public void setFoodColor(Color foodColor) {
this.foodColor = foodColor;
}
public Color getFoodColor() {
return foodColor;
}
public void newFood(Point p) {
setLocation(p);
}
public boolean isFoodEated(Snake snake) {
return this.equals(snake.getHead());
}
public void drawMe(Graphics g) {
if(foodColor==null) {
g.setColor(Color.RED);
}else {
g.setColor(foodColor);
}
g.fill3DRect(x*Global.CELL_SIZE, y*Global.CELL_SIZE, Global.CELL_SIZE, Global.CELL_SIZE, true);
}
}
Ground
package com.lyl.entity;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.Random;
import com.lyl.util.Global;
public class Ground {
private boolean [][] rocks = new boolean[Global.WIDTH][Global.HEIGHT];
private int mapType = 1;
public int getMapType() {
return mapType;
}
public void setMapType(int mapType) {
this.mapType = mapType;
}
//初始化地面(清空石头)
public void clear() {
for (int x = 0; x < Global.WIDTH; x++)
for (int y = 0; y < Global.HEIGHT; y++)
rocks[x][y] = false;
}
/**
* 产生石头, 可以覆盖这个方法改变石头在地面上的布局
*/
public void generateRocks1() {
for (int x = 0; x < Global.WIDTH; x++)
rocks[x][0] = rocks[x][Global.HEIGHT - 1] = true;
for (int y = 0; y < Global.HEIGHT; y++)
rocks[0][y] = rocks[Global.WIDTH - 1][y] = true;
}
public void generateRocks2() {
for (int y = 0; y < 6; y++) {
rocks[0][y] = true;
rocks[Global.WIDTH - 1][y] = true;
rocks[0][Global.HEIGHT - 1 - y] = true;
rocks[Global.WIDTH - 1][Global.HEIGHT - 1 - y] = true;
}
for (int y = 6; y < Global.HEIGHT - 6; y++) {
rocks[6][y] = true;
rocks[Global.WIDTH - 7][y] = true;
}
}
public void generateRocks3() {
for(int x=4;x<14;x++)
rocks[x][5] = true;
for(int j=5;j<15;j++)
rocks[21][j] = true;
for(int y=13;y<20;y++)
rocks[14][y] = true;
for(int x=2;x<10;x++)
rocks[x][17] = true;
for(int i=10;i<Global.WIDTH-3;i++)
rocks[i][Global.HEIGHT-3] = true;
}
//蛇是否吃到了石头
public boolean isGroundEated(Snake snake) {
for(int x=0; x<Global.WIDTH;x++) {
for(int y=0; y<Global.HEIGHT;y++) {
if(rocks[x][y] == true &&
(x==snake.getHead().x &&y==snake.getHead().y)) {
return true;
}
}
}
return false;
}
public Point getPoint() {
Random random = new Random();
int x=0,y=0;
do {
x = random.nextInt(Global.WIDTH);
y = random.nextInt(Global.HEIGHT);
} while (rocks[x][y]==true);
return new Point(x,y);
}
//显示方法
public void drawMe(Graphics g) {
g.setColor(Color.DARK_GRAY);
for(int x=0; x<Global.WIDTH;x++) {
for(int y=0; y<Global.HEIGHT;y++) {
if(rocks[x][y] == true) {
g.fill3DRect(x*Global.CELL_SIZE, y*Global.CELL_SIZE,
Global.CELL_SIZE,Global.CELL_SIZE, true);
}
}
}
}
}
Snake
package com.lyl.entity;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
import com.lyl.listener.SnakeListener;
import com.lyl.util.Global;
public class Snake {
// 代表方向的常量
public static final int UP = 1;
public static final int DOWN = -1;
public static final int LEFT = 2;
public static final int RIGHT = -2;
// 监听器组
private Set<SnakeListener> listeners = new HashSet<SnakeListener>();
// 存储蛇的链表结构
private LinkedList<Point> body = new LinkedList<Point>();
private boolean life; // 是否活着
private boolean pause; // 是否暂停游戏
private int oldDirection, newDirection; // 新,旧方向的引入(避免一次移动时间内的无效方向)
private Point oldTail; // 旧的尾巴(在吃掉食物的时候使用)
private int foodCount = 0; // 吃掉食物的数量
private Color headColor;
private Color bodyColor;
private int sleepTime;
public boolean isLife() {
return life;
}
public int getSleepTime() {
return sleepTime;
}
public void setSleepTime(int sleepTime) {
this.sleepTime = sleepTime;
}
public void setHeadColor(Color headColor) {
this.headColor = headColor;
}
public void setBodyColor(Color bodyColor) {
this.bodyColor = bodyColor;
}
public void init() {
int x = Global.WIDTH / 2;
int y = Global.HEIGHT / 2;
for (int i = 0; i < 3; i++) {
body.addLast(new Point(x--, y));
}
oldDirection = newDirection = RIGHT;
foodCount = 0;
life = true;
pause = false;
if (sleepTime == 0) {
sleepTime = 300;
}
}
// 清空蛇的节点的方法(用来开始一次新的游戏)
public void clear() {
body.clear();
}
public void setLife(boolean life) {
this.life = life;
}
public boolean getPause() {
return pause;
}
public void setPause(boolean pause) {
this.pause = pause;
}
// 用来改变pause常量的状态
public void changePause() {
pause = !pause;
}
// 蛇死掉的方法
public void die() {
life = false;
}
// 蛇移动的方法
public void move() {
if (!(oldDirection + newDirection == 0)) {
oldDirection = newDirection;
}
// 去尾
oldTail = body.removeLast();
int x = body.getFirst().x;
int y = body.getFirst().y;
switch (oldDirection) {
case UP:
y--;
if (y < 0) {
y = Global.HEIGHT - 1;
}
break;
case DOWN:
y++;
if (y >= Global.HEIGHT) {
y = 0;
}
break;
case LEFT:
x--;
if (x < 0) {
x = Global.WIDTH - 1;
}
break;
case RIGHT:
x++;
if (x >= Global.WIDTH) {
x = 0;
}
break;
}
Point newHead = new Point(x, y);
// 加头
body.addFirst(newHead);
}
// 改变方向
public void changeDirection(int direction) {
newDirection = direction;
}
// 吃食物
public void eatFood() {
body.addLast(oldTail);
foodCount++;
}
// 获取吃到的食物数量
public int getFoodCount() {
return foodCount;
}
// 蛇是否吃到了自己的身体
public boolean isEatBody() {
for (int i = 1; i < body.size(); i++) {
if (body.get(i).equals(this.getHead()))
return true;
}
return false;
}
// 获取代表蛇头的节点
public Point getHead() {
return body.getFirst();
}
// 显示自己
public void drawMe(Graphics g) {
if (bodyColor == null) {
g.setColor(new Color(0x3333FF));
} else {
g.setColor(bodyColor);
}
for (Point p : body) {
g.fillRoundRect(p.x * Global.CELL_SIZE, p.y * Global.CELL_SIZE, Global.CELL_SIZE, Global.CELL_SIZE, 15, 12);
}
drawHead(g);
}
// 画蛇头
public void drawHead(Graphics g) {
if (headColor == null)
g.setColor(Color.YELLOW);
else {
g.setColor(headColor);
}
g.fillRoundRect(getHead().x * Global.CELL_SIZE, getHead().y * Global.CELL_SIZE, Global.CELL_SIZE,
Global.CELL_SIZE, 15, 12);
}
// 控制蛇移动的线程内部类
private class SnakeDriver implements Runnable {
public void run() {
while (life) {
if (pause == false) {
move();
for (SnakeListener l : listeners)
l.snakeMoved(Snake.this);
}
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
// 启动线程的方法
public void begin() {
new Thread(new SnakeDriver()).start();
}
// 添加监听器
public void addSnakeListener(SnakeListener l) {
if (l != null) {
listeners.add(l);
}
}
// 加速
public void speedUp() {
if (sleepTime > 50) {
sleepTime -= 20;
}
}
// 减速
public void speedDown() {
if (sleepTime < 700) {
sleepTime += 20;
}
}
}
listener包
SnakeListener
package com.lyl.listener;
import com.lyl.entity.Snake;
public interface SnakeListener {
void snakeMoved(Snake snake);
}
view包
BottonPanel
package com.lyl.view;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class BottonPanel extends JPanel{
private static final long serialVersionUID = 1L;
private JButton startButton;
private JButton pauseButton;
private JButton endButton;
private JLabel scoreLabel;
private int score;
public BottonPanel() {
//setFocusable(false);
setLayout(null);
setBounds(455, 0, 235, 450);
startButton = new JButton("开始游戏");
startButton.setBounds(10,20, 100, 25);
add(startButton);
pauseButton = new JButton("暂停游戏");
pauseButton.setBounds(10, 60, 100, 25);
add(pauseButton);
endButton = new JButton("结束游戏");
endButton.setBounds(10,100, 100, 25);
add(endButton);
scoreLabel = new JLabel("Score:");
scoreLabel.setFont(new Font("Serif",Font.BOLD,18));
scoreLabel.setBounds(30, 140, 100, 30);
add(scoreLabel);
/*
scorePanel = new JPanel();
scorePanel.setBounds(30, 180, 150, 100);
//scorePanel.setBackground(Color.BLUE);
add(scorePanel);*/
Color c= new Color(0, 250,154);
this.setBackground(c);
this.setFocusable(true);
}
public JButton getStartButton() {
return startButton;
}
public JButton getPauseButton() {
return pauseButton;
}
public JButton getEndButton() {
return endButton;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.PINK);
g.setFont(new Font("Serif",Font.BOLD,50));
g.drawString(score+"", 40, 230);
}
}
GameMenu
package com.lyl.view;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
public class GameMenu extends JMenuBar{
/**
*
*/
private static final long serialVersionUID = 1L;
private JMenu colorMenu,speeceMenu,mapMenu,abortMenu;
private JMenuItem item1,item2,item3,item4;
private JMenuItem spItem1,spItem2,spItem3,spItem4;
private JMenuItem mapItem1,mapItem2,mapItem3;
private JMenuItem abItem;
public JMenu getColorMenu() {
return colorMenu;
}
public JMenu getSpeeceMenu() {
return speeceMenu;
}
public JMenu getMapMenu() {
return mapMenu;
}
public JMenu getAbortMenu() {
return abortMenu;
}
public JMenuItem getItem1() {
return item1;
}
public JMenuItem getItem2() {
return item2;
}
public JMenuItem getItem3() {
return item3;
}
public JMenuItem getItem4() {
return item4;
}
public JMenuItem getSpItem1() {
return spItem1;
}
public JMenuItem getSpItem2() {
return spItem2;
}
public JMenuItem getSpItem3() {
return spItem3;
}
public JMenuItem getSpItem4() {
return spItem4;
}
public JMenuItem getMapItem1() {
return mapItem1;
}
public JMenuItem getMapItem2() {
return mapItem2;
}
public JMenuItem getMapItem3() {
return mapItem3;
}
public JMenuItem getAbItem() {
return abItem;
}
public GameMenu() {
colorMenu = new JMenu("设置颜色");
add(colorMenu);
speeceMenu = new JMenu("设置速度");
add(speeceMenu);
mapMenu = new JMenu("地图");
add(mapMenu);
abortMenu = new JMenu("帮助");
add(abortMenu);
item1 = new JMenuItem("背景颜色");
item2 = new JMenuItem("食物颜色");
item3 = new JMenuItem("蛇头颜色");
item4 = new JMenuItem("蛇身颜色");
colorMenu.add(item1);
colorMenu.add(item2);
colorMenu.add(item3);
colorMenu.add(item3);
colorMenu.add(item4);
spItem1 = new JMenuItem("散步");
spItem2 = new JMenuItem("行走");
spItem3 = new JMenuItem("奔跑");
spItem4 = new JMenuItem("疯狂");
speeceMenu.add(spItem1);
speeceMenu.add(spItem2);
speeceMenu.add(spItem3);
speeceMenu.add(spItem4);
mapItem1 = new JMenuItem("地图一");
mapItem2 = new JMenuItem("地图二");
mapItem3 = new JMenuItem("地图三");
mapMenu.add(mapItem1);
mapMenu.add(mapItem2);
mapMenu.add(mapItem3);
//String s = "huowolf开发http://blog.csdn.net/huolang_vip";
abItem = new JMenuItem("使用说明");
abortMenu.add(abItem);
}
}
GamePanel
package com.lyl.view;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.JPanel;
import javax.swing.border.EtchedBorder;
import com.lyl.entity.Food;
import com.lyl.entity.Ground;
import com.lyl.entity.Snake;
import com.lyl.util.Global;
public class GamePanel extends JPanel{
private static final long serialVersionUID = 1L;
private Snake snake;
private Food food;
private Ground ground;
public Color backgroundColor;
public GamePanel() {
setLocation(0, 0);
/* 设置大小和布局 */
this.setSize(Global.WIDTH * Global.CELL_SIZE, Global.HEIGHT
* Global.CELL_SIZE);
this.setBorder(new EtchedBorder(EtchedBorder.LOWERED));
this.setFocusable(true);
}
public void display(Snake snake,Food food,Ground ground) {
this.snake = snake;
this.food = food;
this.ground = ground;
repaint();
}
//清空游戏面板(擦除效果)
public void clearDraw(Graphics g) {
if(backgroundColor==null) {
g.setColor(new Color(0x00FFFF));
}
else {
g.setColor(backgroundColor);
}
g.fillRect(0, 0, Global.WIDTH*Global.CELL_SIZE, Global.HEIGHT*Global.CELL_SIZE);
}
@Override
public void paint(Graphics g) {
clearDraw(g);
//重新显示
if(ground != null && snake != null && food != null) {
ground.drawMe(g);
food.drawMe(g);
snake.drawMe(g);
}
if(snake!=null && snake.isLife()==false) {
recover(g);
}
}
//恢复工作
public void recover(Graphics g) {
clearDraw(g);
//在游戏主面板区绘制“game over”
g.setColor(Color.GREEN);
g.setFont(new Font("Serif",Font.BOLD,50));
g.drawString("Game Over", 130, 210);
}
}
controller包
Controller
package com.lyl.controller;
//控制器负责处理各组件的变化
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JColorChooser;
import javax.swing.JOptionPane;
import com.lyl.entity.Food;
import com.lyl.entity.Ground;
import com.lyl.entity.Snake;
import com.lyl.listener.SnakeListener;
import com.lyl.view.BottonPanel;
import com.lyl.view.GameMenu;
import com.lyl.view.GamePanel;
public class Controller extends KeyAdapter implements SnakeListener{
private Snake snake;
private Food food;
private Ground ground;
private GamePanel gamePanel;
private GameMenu gameMenu;
private BottonPanel bottonPanel;
public Controller(Snake snake, Food food, Ground ground,GamePanel gamePanel,GameMenu gameMenu,BottonPanel bottonPanel) {
this.snake = snake;
this.food = food;
this.ground = ground;
this.gamePanel = gamePanel;
this.gameMenu = gameMenu;
this.bottonPanel = bottonPanel;
init();
}
//控制器的初始化,主要初始化对控件的监听
public void init() {
bottonPanel.getStartButton().addActionListener(new startHandler());
bottonPanel.getPauseButton().addActionListener(new pauseHandler());
bottonPanel.getEndButton().addActionListener(new endHandler());
gameMenu.getItem1().addActionListener(new Item1Handler());
gameMenu.getItem2().addActionListener(new Item2Handler());
gameMenu.getItem3().addActionListener(new Item3Handler());
gameMenu.getItem4().addActionListener(new Item4Handler());
gameMenu.getSpItem1().addActionListener(new spItem1Handler());
gameMenu.getSpItem2().addActionListener(new spItem2Handler());
gameMenu.getSpItem3().addActionListener(new spItem3Handler());
gameMenu.getSpItem4().addActionListener(new spItem4Handler());
gameMenu.getMapItem1().addActionListener(new mapItem1Handler());
gameMenu.getMapItem2().addActionListener(new mapItem2Handler());
gameMenu.getMapItem3().addActionListener(new mapItem3Handler());
gameMenu.getAbItem().addActionListener(new abortItemHandler());
bottonPanel.getStartButton().setEnabled(true);
}
//获取各对象
public Snake getSnake() {
return snake;
}
public Ground getGround() {
return ground;
}
public GamePanel getGamePanel() {
return gamePanel;
}
public GameMenu getGameMenu() {
return gameMenu;
}
public BottonPanel getBottonPanel() {
return bottonPanel;
}
//键盘按键的监听
@Override
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
snake.changeDirection(Snake.UP);
break;
case KeyEvent.VK_DOWN:
snake.changeDirection(Snake.DOWN);
break;
case KeyEvent.VK_LEFT:
snake.changeDirection(Snake.LEFT);
break;
case KeyEvent.VK_RIGHT:
snake.changeDirection(Snake.RIGHT);
break;
case KeyEvent.VK_W:
snake.speedUp();
break;
case KeyEvent.VK_S:
snake.speedDown();
break;
default:
break;
}
}
//实现蛇移动的接口,处理蛇移动过程发生的各种事情
@Override
public void snakeMoved(Snake snake) {
//每移动一次,就更新一次面板
gamePanel.display(snake, food, ground);
if(food.isFoodEated(snake)) {
snake.eatFood();
food.newFood(ground.getPoint());
//更新得分显示面板
bottonPanel.repaint();
setScore();
}
if(ground.isGroundEated(snake)) {
snake.die();
bottonPanel.getStartButton().setEnabled(true);
}
if(snake.isEatBody()) {
snake.die();
bottonPanel.getStartButton().setEnabled(true);
}
}
//
public void setScore() {
int score = snake.getFoodCount() ;
bottonPanel.setScore(score);
}
// 开始一个新游戏
public void newGame() {
ground.clear();
switch (ground.getMapType()) {
case 1:
ground.generateRocks1();
break;
case 2:
ground.generateRocks2();
break;
case 3:
ground.generateRocks3();
break;
}
food.newFood(ground.getPoint());
bottonPanel.setScore(0);
bottonPanel.repaint();
}
//开始游戏按钮的监听
class startHandler implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
gamePanel.requestFocus(true); //!!使游戏面板区获得焦点
snake.clear();
snake.init();
snake.begin();
newGame();
bottonPanel.getStartButton().setEnabled(false);
}
}
//暂停按钮的监听
class pauseHandler implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
gamePanel.requestFocus(true);
snake.changePause();
if(e.getActionCommand()=="暂停游戏")
bottonPanel.getPauseButton().setText("继续游戏");
else {
bottonPanel.getPauseButton().setText("暂停游戏");
}
}
}
//结束游戏按钮的监听
class endHandler implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
snake.die();
bottonPanel.getStartButton().setEnabled(true);
}
}
//菜单栏各按钮的监听
class Item1Handler implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
Color color = JColorChooser.showDialog(gamePanel, "请选择颜色", Color.BLACK);
gamePanel.backgroundColor = color;
}
}
class Item2Handler implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
Color color = JColorChooser.showDialog(gamePanel, "请选择颜色", Color.BLACK);
food.setFoodColor(color);
}
}
class Item3Handler implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
Color color = JColorChooser.showDialog(gamePanel, "请选择颜色", Color.BLACK);
snake.setHeadColor(color);
}
}
class Item4Handler implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
Color color = JColorChooser.showDialog(gamePanel, "请选择颜色", Color.BLACK);
snake.setBodyColor(color);
}
}
class spItem1Handler implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
snake.setSleepTime(600);
}
}
class spItem2Handler implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
snake.setSleepTime(350);
}
}
class spItem3Handler implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
snake.setSleepTime(150);
}
}
class spItem4Handler implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
snake.setSleepTime(80);
}
}
class mapItem1Handler implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
ground.setMapType(1);
}
}
class mapItem2Handler implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
ground.setMapType(2);
}
}
class mapItem3Handler implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
ground.setMapType(3);
}
}
class abortItemHandler implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
StringBuffer sb= new StringBuffer();
sb.append("方向键控制方向\n");
sb.append("w键、s键分别控制使其加速、减速\n");
String message = sb.toString();
JOptionPane.showMessageDialog(null, message, "使用说明",JOptionPane.INFORMATION_MESSAGE);
}
}
}
game包
GameFrame(运行这个类)
package com.lyl.game;
import java.awt.Container;
import javax.swing.JFrame;
import javax.swing.JPanel;
import com.lyl.controller.Controller;
import com.lyl.entity.Food;
import com.lyl.entity.Ground;
import com.lyl.entity.Snake;
import com.lyl.util.Global;
import com.lyl.view.BottonPanel;
import com.lyl.view.GameMenu;
import com.lyl.view.GamePanel;
public class GameFrame extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
public static void main(String[] args) {
new GameFrame(new Controller(new Snake(), new Food(), new Ground(),
new GamePanel(), new GameMenu(),new BottonPanel()));
}
//各对象
private GamePanel gamePanel;
private GameMenu gameMenu;
private Snake snake;
//private Food food;
//private Ground ground;
private Controller controller;
private JPanel buttonPanel;
public GameFrame(Controller c) {
this.controller = c;
snake = controller.getSnake();
gameMenu = controller.getGameMenu();
gamePanel = controller.getGamePanel();
buttonPanel = controller.getBottonPanel();
setTitle("我的贪吃蛇");
setBounds(300,100,Global.WIDTH*Global.CELL_SIZE+250,Global.HEIGHT*Global.CELL_SIZE+60);
setLayout(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container contentPane = this.getContentPane();
this.setJMenuBar(gameMenu);
contentPane.add(gamePanel);
contentPane.add(buttonPanel);
setResizable(false);
setVisible(true);
/* 让窗口居中 */
this.setLocation(this.getToolkit().getScreenSize().width / 2
- this.getWidth() / 2, this.getToolkit().getScreenSize().height
/ 2 - this.getHeight() / 2);
gamePanel.addKeyListener(controller);
snake.addSnakeListener(controller);
controller.newGame();
}
}