代碼一:
package Snake;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Observable;
import java.util.Random;
import javax.swing.JOptionPane;
public class SnakeModel extends Observable implements Runnable{
public static final int UP=2;
public static final int DOWN=4;
public static final int LEFT=1;
public static final int RIGHT=3;
private boolean[][] matrix;
private LinkedList nodeArray=new LinkedList();
private Node food;
private int maxX;
private int maxY;
private int direction=UP;
private boolean running=false;
private int timeInterval=200;
private double speedChangeRate=0.75;
private boolean paused=false;
private int score=0;
private int countMove=0;
public SnakeModel(int maxX,int maxY){
this.maxX=maxX;
this.maxY=maxY;
reset();
}
public void reset(){
direction=SnakeModel.UP;
timeInterval=200;
paused=false;
score=0;
countMove=0;
matrix=new boolean[maxX][maxY];
for(int i=0;i<maxX;i++){
matrix[i]=new boolean[maxY];
Arrays.fill(matrix[i], false);
}
int initArrayLength=maxX>20?10:maxX/2;
nodeArray.clear();
int x=maxX/2;
int y=maxY/2;
for(int i=0;i<initArrayLength;i++){
nodeArray.addLast(new Node(x,y));
matrix[x][y]=true;
x++;
}
food=createFood();
matrix[food.x][food.y]=true;
}
public void changeDirection(int newDirection){
if(direction%2!=newDirection%2){
direction=newDirection;
}
}
public boolean moveOn(){
Node head=(Node)nodeArray.getFirst();
int headX=head.x;
int headY=head.y;
switch(direction){
case UP:
headY--;
break;
case DOWN:
headY++;
break;
case LEFT:
headX--;
break;
case RIGHT:
headX++;
break;
}
if((0<=headX&&headX<maxX)&&(0<=headY&&headY<maxY)){
if(matrix[headX][headY]){
if(headX==food.x&&headY==food.y){
nodeArray.addFirst(food);
int scoreGet=(10000-200*countMove)/timeInterval;
score+=scoreGet>0?scoreGet:10;
countMove=0;
food=createFood();
matrix[food.x][food.y]=true;
return false;
}else{
return false;
}
}else{
nodeArray.addFirst(new Node(headX,headY));
matrix[headX][headY]=true;
head=(Node)nodeArray.removeLast();
matrix[head.x][head.y]=false;
countMove++;
return true;
}
}
return false;
}
@Override
public void run() {
// TODO Auto-generated method stub
running=true;
while(running){
try{
Thread.sleep(timeInterval);
}catch(Exception e){
break;
}
if(!paused){
if(moveOn()){
setChanged();
notifyObservers();
}else{
JOptionPane.showMessageDialog(null,"you failed","Game Over",JOptionPane.INFORMATION_MESSAGE);
break;
}
}
}
if(!running){
JOptionPane.showMessageDialog(null,"you stoped the game","Game Over",JOptionPane.INFORMATION_MESSAGE);
}
}
private Node createFood(){
int x=0;
int y=0;
do{
Random r=new Random();
x=r.nextInt(maxX);
y=r.nextInt(maxY);
}while(matrix[x][y]);
return new Node(x,y);
}
public void speedUp(){
timeInterval*=speedChangeRate;
}
public void speedDwon(){
timeInterval/=speedChangeRate;
}
public void speedPauseState(){
paused=!paused;
}
public boolean isRunning(){
return running;
}
public void setRunning(boolean running){
this.running=running;
}
public LinkedList getNodeArray(){
return nodeArray;
}
public Node getFood(){
return food;
}
public int getScore(){
return score;
}
public String toString(){
String result="";
for(int i=0;i<nodeArray.size();++i){
Node n=(Node)nodeArray.get(i);
result +="["+n.x+","+n.y+"]";
}
return result;
}
}
class Node{
int x;
int y;
Node(int x,int y){
this.x=x;
this.y=y;
}
}
代碼二:
package Snake;
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class SnakeView extends JFrame implements Observer{
public static final int nodeWidth=10;
public static final int nodeHeight=10;
private int CanvasWidth;
private int CanvasHeight;
private int startX=0;
private int startY=0;
JLabel labelScore;
Canvas paintCanvas;
public SnakeView(){
this(30,40,0,0);
}
public SnakeView(int maxX,int maxY){
this(maxX,maxY,0,0);
}
public SnakeView(int maxX,int maxY,int startX,int startY){
this.CanvasWidth=maxX*nodeWidth;
this.CanvasHeight=maxY*nodeHeight;
this.startX=startX;
this.startY=startY;
init();
}
private void init(){
this.setName("貪喫蛇");
this.setLocation(startX,startY);
Container cp=this.getContentPane();
labelScore=new JLabel("Score:");
cp.add(labelScore,BorderLayout.NORTH);
paintCanvas=new Canvas();
paintCanvas.setSize(CanvasWidth+1,CanvasHeight+1);
cp.add(paintCanvas,BorderLayout.CENTER);
JPanel panelBottom=new JPanel();
panelBottom.setLayout(new BorderLayout());
JLabel labelHelp;
labelHelp=new JLabel("PageUp,PageDown for speed;",JLabel.CENTER);
panelBottom.add(labelHelp,BorderLayout.NORTH);
labelHelp=new JLabel("PageUp,PageDown for speed;",JLabel.CENTER);
panelBottom.add(labelHelp,BorderLayout.WEST);
labelHelp=new JLabel("SPACE or P for pause",JLabel.CENTER);
panelBottom.add(labelHelp,BorderLayout.SOUTH);
labelHelp=new JLabel("q for stop",JLabel.CENTER);
panelBottom.add(labelHelp,BorderLayout.EAST);
cp.add(panelBottom,BorderLayout.SOUTH);
this.pack();
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
@Override
public void update(Observable o, Object arg) {
// TODO Auto-generated method stub
SnakeModel model=(SnakeModel)o;
Graphics g=paintCanvas.getGraphics();
g.setColor(Color.white);
g.fillRect(0,0,CanvasWidth,CanvasHeight);
g.setColor(Color.BLACK);
LinkedList na=model.getNodeArray();
Iterator it=na.iterator();
while(it.hasNext()){
Node n=(model.getFood());
drawNode(g,n);
this.updateScore(model.getScore());
}
}
private void updateScore(int score) {
// TODO Auto-generated method stub
String s="Score:"+score;
labelScore.setText(s);
}
private void drawNode(Graphics g, Node n) {
// TODO Auto-generated method stub
g.fillRect(n.x*nodeWidth, n.y*nodeHeight, nodeWidth-1, nodeHeight-1);
}
}
代碼三:
package Snake;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class SnakeControl implements KeyListener {
private SnakeModel model;
private SnakeView view;
private int district_maxX;
private int district_maxY;
public SnakeControl(){
this.district_maxX=30;
this.district_maxY=40;
}
public SnakeControl(int maxX,int maxY){
this();
if((10<maxX)&&(maxX<200)&&(10<maxY)&&(maxY<200)){
this.district_maxX=maxX;
this.district_maxY=maxY;
}else{
System.out.println("初始化參數錯誤,用默認參數構造對象");
}
init();
}
private void init(){
this.model=new SnakeModel(district_maxX,district_maxY);
this.view=new SnakeView(district_maxX,district_maxY,500,200);
this.model.addObserver(this.view);
this.view.addKeyListener(this);
(new Thread(this.model)).start();
}
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
int keyCode=e.getKeyCode();
if(model.isRunning()){
switch(keyCode){
case KeyEvent.VK_UP:
model.changeDirection(SnakeModel.UP);
break;
case KeyEvent.VK_DOWN:
model.changeDirection(SnakeModel.DOWN);
break;
case KeyEvent.VK_LEFT:
model.changeDirection(SnakeModel.LEFT);
break;
case KeyEvent.VK_RIGHT:
model.changeDirection(SnakeModel.RIGHT);
break;
case KeyEvent.VK_SPACE:
case KeyEvent.VK_P:
//這裏有問題
model.speedPauseState();
break;
default:
}
}
if(keyCode==KeyEvent.VK_R||keyCode==KeyEvent.VK_S||keyCode==KeyEvent.VK_ENTER){
model.reset();
}
if(keyCode==KeyEvent.VK_Q){
model.setRunning(false);
}
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
}
代碼四:
package Snake;
public class GreedSnakeMain {
public static void main(String[] args){
SnakeControl control=new SnakeControl(30,30);
}
}