/*
*游戏的主画布类
*/
import javax.swing.*;
import java.awt.*;
public class GameCanvas extends JPanel
{
private int rows = 30, cols = 30;
private int boxWidth, boxHeight;
private Color bgColor = Color.darkGray,
snakeColor = Color.GREEN;
private boolean [][]colorFlags;
private static GameCanvas instance = null;
/*
*构造函数私有,使用单例模式,其他类共享一个实例
*/
private GameCanvas()
{
colorFlags = new boolean[rows][cols];
for(int i = 0; i < colorFlags.length; i++)
for(int j = 0; j<colorFlags[i].length; j++)
colorFlags[i][j] = false;
}
/*
*获得GameCanvas的实例
*/
public static GameCanvas getCanvasInstance()
{
if(instance == null)
instance = new GameCanvas();
return instance;
}
/*
*设置面板画布的行数
*/
public void setRows(int rows)
{
this.rows = rows;
}
/*
*得到画布方格的行数
*/
public int getRows()
{
return rows;
}
/*
*设置画布方格的列数
*/
public void setCols(int cols)
{
this.cols = cols;
}
/*
* 得到面板方格的列数
*/
public int getCols()
{
return cols;
}
/*
*绘图类,在画布上绘图
*/
public void paintComponent(Graphics g)
{
super.paintComponent(g);
fanning();
for(int i = 0; i < colorFlags.length; i++)
for(int j = 0; j < colorFlags[i].length; j++)
{
Color color = colorFlags[i][j] ? snakeColor : bgColor;
g.setColor(color);
g.fill3DRect(j * boxWidth, i * boxHeight, boxWidth, boxHeight,true);
}
}
/*
*画布重置,恢复画布的原始状态
*/
public void reset()
{
for(int i = 0; i < colorFlags.length; i++)
for(int j = 0; j<colorFlags[i].length; j++)
colorFlags[i][j] = false;
repaint();
}
/*
*根据窗口大小调整方格的大小
*/
public void fanning()
{
boxWidth = getSize().width / cols;
boxHeight = getSize().height / rows;
}
/*
* 获取画布(row,col)位置颜色的值
*/
public boolean getColorFlag(int row, int col)
{
return colorFlags[row][col];
}
/*
* 设置画布(row,col)位置颜色的值
*/
public void setColorFlag(int row, int col, boolean colorFlag)
{
colorFlags[row][col] = colorFlag;
}
}
/*
*蛇的节点类,保存当前节点所在的(row,col)坐标值
*(同时也被用作食物类,因为食物所要保存的信息和此相同,没有再设)
*/
public class SnakeNode
{
private int row,col;
/*
*构造函数
*/
public SnakeNode(int row,int col)
{
this.row = row;
this.col = col;
}
/*
* 设置该节点所在的行
*/
public void setRow(int row)
{
this.row = row;
}
/*
* 获得该节点所在的行
*/
public int getRow()
{
return row;
}
/*
* 设置该节点所在的列
*/
public void setCol(int col)
{
this.col = col;
}
/*
* 返回该节点所在的列
*/
public int getCol()
{
return col;
}
}
/*
*游戏的主画布类
*/
import javax.swing.*;
import java.awt.*;
public class GameCanvas extends JPanel
{
private int rows = 30, cols = 30;
private int boxWidth, boxHeight;
private Color bgColor = Color.darkGray,
snakeColor = Color.GREEN;
private boolean [][]colorFlags;
private static GameCanvas instance = null;
/*
*构造函数私有,使用单例模式,其他类共享一个实例
*/
private GameCanvas()
{
colorFlags = new boolean[rows][cols];
for(int i = 0; i < colorFlags.length; i++)
for(int j = 0; j<colorFlags[i].length; j++)
colorFlags[i][j] = false;
}
/*
*获得GameCanvas的实例
*/
public static GameCanvas getCanvasInstance()
{
if(instance == null)
instance = new GameCanvas();
return instance;
}
/*
*设置面板画布的行数
*/
public void setRows(int rows)
{
this.rows = rows;
}
/*
*得到画布方格的行数
*/
public int getRows()
{
return rows;
}
/*
*设置画布方格的列数
*/
public void setCols(int cols)
{
this.cols = cols;
}
/*
* 得到面板方格的列数
*/
public int getCols()
{
return cols;
}
/*
*绘图类,在画布上绘图
*/
public void paintComponent(Graphics g)
{
super.paintComponent(g);
fanning();
for(int i = 0; i < colorFlags.length; i++)
for(int j = 0; j < colorFlags[i].length; j++)
{
Color color = colorFlags[i][j] ? snakeColor : bgColor;
g.setColor(color);
g.fill3DRect(j * boxWidth, i * boxHeight, boxWidth, boxHeight,true);
}
}
/*
*画布重置,恢复画布的原始状态
*/
public void reset()
{
for(int i = 0; i < colorFlags.length; i++)
for(int j = 0; j<colorFlags[i].length; j++)
colorFlags[i][j] = false;
repaint();
}
/*
*根据窗口大小调整方格的大小
*/
public void fanning()
{
boxWidth = getSize().width / cols;
boxHeight = getSize().height / rows;
}
/*
* 获取画布(row,col)位置颜色的值
*/
public boolean getColorFlag(int row, int col)
{
return colorFlags[row][col];
}
/*
* 设置画布(row,col)位置颜色的值
*/
public void setColorFlag(int row, int col, boolean colorFlag)
{
colorFlags[row][col] = colorFlag;
}
}
/*
*蛇身线程类,控制蛇的移动及其方向
*/
import javax.swing.*;
import java.util.*;
class SnakeBody extends Thread
{
private LinkedList snakeList;
private int iniSnakeBodyLength;
private GreedSnakeGame game;
private GameCanvas canvas;
public final static int DOWN = -1;
public final static int LEFT = -2;
public final static int UP = 1;
public final static int RIGHT = 2;
private final static int PER_LEVEL_SPEED_UP = 10;
private final static int PER_FOOD_SCORE = 10;
private final static int PER_LEVEL_SCORE = 20 *PER_FOOD_SCORE;
private int direction = LEFT;
private boolean running = true,pause = false;
private int timeInterval = 200,curLevelScore;
private ArrayList food;
/*
*构造函数
*/
public SnakeBody(final GreedSnakeGame game,int iniSnakeBodyLength)
{
this.game = game;
this.iniSnakeBodyLength = iniSnakeBodyLength;
curLevelScore = 0;
food = new ArrayList(5);
canvas = GameCanvas.getCanvasInstance();
/*
* 初始化蛇身
*/
snakeList = new LinkedList();
int rows = canvas.getRows();
int cols = canvas.getCols();
for(int i = 0; i < iniSnakeBodyLength; i++)
{
snakeList.add(new SnakeNode(rows / 2, cols / 2 + i));
canvas.setColorFlag(rows / 2, cols / 2 + i, true);
}
createFood();
canvas.repaint();
}
/*
*暂停移动
*/
public void pauseMove()
{
pause = true;
}
/*
*恢复移动
*/
public void resumeMove()
{
pause = false;
}
/*
*停止移动
*/
public void stopMove()
{
running = false;
}
/*
*每次创建食物
*/
public void createFood()
{
for(int i = 0;i < 5;i++)
{
int x = (int)(Math.random() * canvas.getCols());
int y = (int)(Math.random() * canvas.getRows());
if(canvas.getColorFlag(x,y))
i--;
else
food.add(new SnakeNode(x,y));
canvas.setColorFlag(x,y,true);
}
canvas.repaint();
}
/*
* 改变蛇的移动方向
*/
public void changeDirection(int direction)
{
this.direction = direction;
}
/*
*在没有改变方向时,控制蛇的移动,以及吃食物
*/
private boolean moveOn()
{
SnakeNode snakeHead = (SnakeNode)snakeList.getFirst();
int x = snakeHead.getRow();
int y = snakeHead.getCol();
boolean isFood = false,isBody = false;
switch(direction)
{
case LEFT: y--; break;
case RIGHT: y++; break;
case DOWN: x++; break;
case UP: x--; break;
default: break;
}
if((x >= 0 && x < canvas.getCols()) &&( y >=0 && y < canvas.getRows()))
{
int i = 0;
for(;i < food.size();i++)
if(x == ((SnakeNode)food.get(i)).getRow() && y == ((SnakeNode)food.get(i)).getCol())
{
isFood = true;
break;
}
for(int j=0;j < snakeList.size()-1 ;j++)
if(x == ((SnakeNode)snakeList.get(j)).getRow() && y == ((SnakeNode)snakeList.get(j)).getCol())
{
isBody = true;
break;
}
if(isFood)
{
int score = game.getScore();
score += PER_FOOD_SCORE;
game.setScore(score);
curLevelScore += PER_FOOD_SCORE;
snakeList.addFirst(new SnakeNode(x,y));
food.remove(i);
if(food.size() == 0)
{
if(curLevelScore >= PER_LEVEL_SCORE)
{
int level = game.getLevel();
level++;
game.setLevel(level);
curLevelScore -=PER_LEVEL_SCORE;
}
createFood();
}
}
else if(isBody)
{
JOptionPane.showMessageDialog(null,"You Failed","Game Over",
JOptionPane.INFORMATION_MESSAGE);
running = false;
}
else
{
snakeHead = new SnakeNode(x,y);
snakeList.addFirst(snakeHead);
canvas.setColorFlag(x,y,true);
SnakeNode snakeTail = (SnakeNode)snakeList.getLast();
snakeList.removeLast();
canvas.setColorFlag(snakeTail.getRow(),snakeTail.getCol(),false);
canvas.repaint();
}
return true;
}
return false;
}
/*
*run方法,控制线程运行要处理的事务
*/
public void run()
{
while(running)
{
try
{
sleep(timeInterval-game.getLevel() * PER_LEVEL_SPEED_UP);
}catch(InterruptedException e)
{
e.printStackTrace();
}
if(!pause)
{
if(!moveOn())
{
JOptionPane.showMessageDialog(null,"You Failed","Game Over",
JOptionPane.INFORMATION_MESSAGE);
running = false;
}
}
}
}
}
/*
*控制面板类
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
class ControlPanel extends JPanel
{
private JPanel infoPanel,buttonPanel;
private SnakePanel snakePanel;
private JTextField levelField;
private JTextField scoreField;
private JButton playButton, pauseButton, stopButton,
turnEasilyButton, turnHarderButton;
private Timer timer;
private GreedSnakeGame game;
private EtchedBorder border = new EtchedBorder(EtchedBorder.RAISED,Color.white,Color.lightGray);
/*
*构造函数
*/
public ControlPanel(final GreedSnakeGame game)
{
this.game = game;
setLayout(new GridLayout(3,1,0,4));
snakePanel = new SnakePanel();
snakePanel.setBorder(border);
levelField = new JTextField("0");
scoreField = new JTextField("0");
infoPanel = new JPanel(new GridLayout(4,1,0,0));
infoPanel.add(new JLabel("Level:"));
infoPanel.add(levelField);
infoPanel.add(new JLabel("Score:"));
infoPanel.add(scoreField);
infoPanel.setBorder(border);
playButton = new JButton("Play");
pauseButton = new JButton("Pause");
stopButton = new JButton("Stop");
turnEasilyButton = new JButton("Turn Easily");
turnHarderButton = new JButton("Turn Harder");
buttonPanel = new JPanel(new GridLayout(5,1,0,1));
buttonPanel.add(playButton);
buttonPanel.add(pauseButton);
buttonPanel.add(stopButton);
buttonPanel.add(turnEasilyButton);
buttonPanel.add(turnHarderButton);
buttonPanel.setBorder(border);
add(snakePanel);
add(infoPanel);
add(buttonPanel);
playButton.addActionListener(
new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
game.playGame();
requestFocus();
}
}
);
pauseButton.addActionListener(
new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
if(pauseButton.getText().equals("Pause"))
game.pauseGame();
else
game.resumeGame();
requestFocus();
}
}
);
stopButton.addActionListener(
new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
game.stopGame();
requestFocus();
}
}
);
turnHarderButton.addActionListener(
new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
int level = game.getLevel();
game.setLevel((level + 1)%9);
requestFocus();
}
});
turnEasilyButton.addActionListener(
new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
int level = game.getLevel();
if(level > 0)
{
game.setLevel(level - 1);
}
requestFocus();
}
});
timer = new Timer(500,
new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
levelField.setText(""+game.getLevel());
scoreField.setText(""+game.getScore());
}
}
);
timer.start();
addKeyListener(new ControlKeyListener());
}
/*
*设置play按钮的可用性
*/
public void setPlayButtonEnabled(boolean enable)
{
playButton.setEnabled(enable);
}
/*
*设置按钮时Pause还是Resume
*/
public void setPauseButtonLabel(boolean pause)
{
pauseButton.setText(pause ? "Pause" : "Resume");
}
/*
*重置游戏
*/
public void reset()
{
scoreField.setText("0");
levelField.setText("0");
game.setLevel(0);
game.setScore(0);
}
/*
*绘制贪吃蛇图片的面板
*/
private class SnakePanel extends JPanel
{
private ImageIcon snake = new ImageIcon("GeedSnake.jpe");
public void paintComponent(Graphics g)
{
super.paintComponent(g);
snake.paintIcon(this,g,0,0);
}
}
/*
*键盘控制类,控制蛇头的移动方向
*/
private class ControlKeyListener extends KeyAdapter {
private int direction = -2;
public void keyPressed(KeyEvent ke)
{
if (!game.isPlaying()) return;
switch (ke.getKeyCode()) {
case KeyEvent.VK_DOWN:
if(direction/SnakeBody.DOWN!=-1)
{
game.changeDirection(SnakeBody.DOWN);
direction = -1;
}
break;
case KeyEvent.VK_LEFT:
if(direction/SnakeBody.LEFT!=-1)
{
game.changeDirection(SnakeBody.LEFT);
direction = -2;
}
break;
case KeyEvent.VK_RIGHT:
if(direction/SnakeBody.RIGHT!=-1)
{
game.changeDirection(SnakeBody.RIGHT);
direction = 2;
break;
}
case KeyEvent.VK_UP:
if(direction/SnakeBody.UP!=-1)
{
game.changeDirection(SnakeBody.UP);
direction = 1;
break;
}
default:
break;
}
}
}
}