java貪吃蛇游戲代碼
思路 :主要是模擬蛇的運動。只要對蛇頭進行操作,然后讓前一種狀態先的蛇頭位置復制給現在蛇身的第二個部分,讓前一狀態的蛇的第二個部分的位置復制給現在蛇身的第三個部分......以此類推,從而達到模擬蛇運動的狀態。
//貪吃蛇圖形界面
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Observable;
import java.util.Observer;import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;public class GluttonousSnake extends JFrame implements ActionListener {
private JButton upButton, downButton, leftButton, rightButton;//控制方向按鈕
private JTextField score;//分數
private SnakeCanvas snake;//蛇的模型public GluttonousSnake() { super("貪吃蛇");//設置標題 this.setSize(725, 515);//設置大小 this.setDefaultCloseOperation(EXIT_ON_CLOSE);//設置退出按鍵 this.setLocationRelativeTo(null);//設置窗口居中 JPanel p = new JPanel();//控制按鈕和顯示分數面板 p.setBorder(new TitledBorder("控制和顯示區"));//設置這個面板的標題 this.getContentPane().add(p, "East");//設置此面板的位置 p.setLayout(new GridLayout(4, 1));//設置此面板的布局方式,為網格布局方式 JPanel p2 = new JPanel();//在此面板中添加顯示分數的面板 p2.setLayout(new FlowLayout());//設置為流布局方式 p2.add(new JLabel("得分:")); score = new JTextField("0"); score.setEditable(false); p2.add(score); p.add(p2); //添加按鈕,有圖片的并添加事件監聽 upButton = new JButton("", new ImageIcon("up.png")); upButton.setActionCommand("up"); upButton.addActionListener(this); downButton = new JButton("", new ImageIcon("down.png")); downButton.setActionCommand("down"); downButton.addActionListener(this); leftButton = new JButton("", new ImageIcon("left.png")); leftButton.setActionCommand("left"); leftButton.addActionListener(this); rightButton = new JButton("", new ImageIcon("right.png")); rightButton.setActionCommand("right"); rightButton.addActionListener(this); p.add(upButton); JPanel p1 = new JPanel(); p1.setLayout(new GridLayout(1, 2)); p1.add(leftButton); p1.add(rightButton); p.add(p1); p.add(downButton); addMenu();//添加菜單 start(); this.setResizable(false); this.setVisible(true); } private void start() { snake = new SnakeCanvas(); this.getContentPane().add(snake); } private void addMenu() { JMenuBar menubar = new JMenuBar(); this.setJMenuBar(menubar); JMenu game = new JMenu("游戲"); JMenu help = new JMenu("幫助"); JMenuItem jitemNew = new JMenuItem("新游戲"); jitemNew.setActionCommand("new"); jitemNew.addActionListener(this); JMenuItem jitemPause = new JMenuItem("暫停"); jitemPause.setActionCommand("pause"); jitemPause.addActionListener(this); JMenuItem jitemExit = new JMenuItem("退出"); jitemExit.setActionCommand("exit"); jitemExit.addActionListener(this); game.add(jitemNew); game.add(jitemPause); game.addSeparator();//菜單里設置分隔線 game.add(jitemExit); menubar.add(game); menubar.add(help); } public static void main(String[] args) { new GluttonousSnake(); } public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equalsIgnoreCase("exit")) { System.exit(EXIT_ON_CLOSE); } if (e.getSource() instanceof JButton) { if (e.getActionCommand().equalsIgnoreCase("up")) {//響應向上按鈕按下事件 snake.setDirect(1);//設置蛇頭運動方向 snake.repaint();//對蛇模型重新畫 snake.timer.start();//定時器開始 return; } if (e.getActionCommand().equalsIgnoreCase("down")) { snake.setDirect(2); snake.repaint(); snake.timer.start(); return; } if (e.getActionCommand().equalsIgnoreCase("left")) { snake.setDirect(3); snake.repaint(); snake.timer.start(); return; } if (e.getActionCommand().equalsIgnoreCase("right")) { snake.setDirect(4); snake.repaint(); snake.timer.start(); return; } } if (e.getSource() instanceof JMenuItem) { if (e.getActionCommand().equalsIgnoreCase("new")) { //this.getContentPane().remove(snake); snake.init(); snake.repaint(); snake.timer.start(); } if (e.getActionCommand().equalsIgnoreCase("pause")) { snake.timer.stop(); JOptionPane.showMessageDialog(this, "繼續請按“確定”"); snake.timer.start(); } } }
} </pre>
MapCanvas.javaimport java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
//蛇運行的地圖
public class MapCanvas extends Canvas{public void paint(Graphics g) { g.setColor(Color.red); for(int i=30;i<=450;i+=30){ g.drawLine(0,i,450,i); } for(int i=30;i<=450;i+=30){ g.drawLine(i,0,i,450); } g.drawLine(0, 0, 450, 0); g.drawLine(0, 450, 450, 450); g.drawLine(0, 0, 0, 450); g.drawLine(450, 0, 450, 450); }
} </pre>
SnakeCanvas.javaimport java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;import javax.swing.JOptionPane;
import javax.swing.Timer;
//蛇模型
public class SnakeCanvas extends MapCanvas implements ActionListener {
private int number = 5;//蛇身的初始長度
public Timer timer;//定時器
private Body[] bodys;//蛇身
private Body food;//食物
public int score=0;//分數
private int speed=250;//定時器延時事件
int direct = 3;//蛇頭初始方向
private int[][] mapflag = new int[455][455];//地圖標記
//初始化
public void init(){
this.direct=3;
this.number=5;
this.bodys = new Body[this.number];
mapflag = new int[455][455];
for (int i = 0, x = 300; i < this.number; i++, x += 30) {
bodys[i] = new Body(x, 180);
mapflag[bodys[i].x][bodys[i].y] = 2;//如果是蛇體 設標記為2
}
food = creatFood();//創建食物} public SnakeCanvas() { init(); timer = new Timer(speed, this);//創建定時器對象 timer.start();//定時器啟動 } private class Body {//蛇頭成員 int x, y; Body(int x, int y) { this.x = x; this.y = y; } } public void paint(Graphics g) {//畫圖 super.paint(g); if(bodys==null){ return ; } for (int i = 0; i < this.number; i++) { if(i==0){//設置蛇頭顏色不同 g.setColor(Color.blue); }else{ g.setColor(Color.black); } mapflag[bodys[i].x][bodys[i].y] = 2; g.fillOval(bodys[i].x, bodys[i].y, 30, 30);//畫蛇體 } g.setColor(Color.red); g.fillOval(food.x, food.y, 30, 30);//畫食物 } public Body creatFood() { int x = 0, y = 0; do {//隨機生成食物位置 Random r = new Random();//創建隨機數對象 x = r.nextInt(450);//在0到所給的數中隨機產生一個偽隨機數 y = r.nextInt(450); //System.out.println(mapflag[x][y]+"!"); } while (x % 30 != 0 || y % 30 != 0 || mapflag[x][y]==2 );//保證位置不是蛇身的部分,并且確保整齊性 //System.out.println(x + " " + y); mapflag[x][y] = 1;//將食物標記為1,下面就可以通過標記的不同來判斷是吃到食物還是自身,從而進行不同的操作 return new Body(x, y); } public void actionPerformed(ActionEvent e) { if(bodys==null){ return ; } if(!isMove()){//如果移動失敗,游戲結束 JOptionPane.showMessageDialog(this, "Game Over !"); bodys=null; timer.stop(); return ; } repaint(); } //蛇移動,原理:僅需對蛇頭進行操作,然后將蛇頭之前的位置賦值給現在蛇身的第二個部分, //讓之前的第二個部分復制個現在的第三個部分。。。。以此類推,模擬蛇運動(這是關鍵) public void move(int x,int y) { Body[] b=new Body[bodys.length]; for(int i=0;i<this.number;i++){ b[i]=new Body(bodys[i].x,bodys[i].y); } this.bodys[0].x=x; this.bodys[0].y=y; for(int i=1;i<this.number;i++){ this.bodys[i]=b[i-1]; } setMapflag(); } private void setMapflag() {//地圖標記的刷新 mapflag=new int[455][455]; mapflag[food.x][food.y]=1; for(int i=0;i<this.number;i++){ mapflag[bodys[i].x][bodys[i].y]=2; } } //判斷是否移動成功 public boolean isMove() { if(bodys==null){ return false; } int x=bodys[0].x; int y=bodys[0].y; switch (this.direct) {//通過方向的不同對蛇頭進行不同的操作 case 1: y -= 30; break; case 2: y += 30; break; case 3: x -= 30; break; case 4: x += 30; break; } if(x<0||y>=450||x>=450||y<0){//越界問題 return false; } if(mapflag[x][y]==1){//標記為1 ,則為蛇頭,要添加蛇身長度 this.number++; addSnake(x,y);//添加蛇長
// System.out.println("*");
return true;
}else if(mapflag[x][y]==2){//標記為2,則為蛇體,即自己吃到自己,游戲結束
// System.out.println("^");
return false;
}else{
// System.out.println("%");
move(x,y);
return true;
}
}
//添加蛇身,類似move();
private void addSnake(int x, int y) {
this.score++;
Body[] b=new Body[bodys.length];
for(int i=0;i<this.number-1;i++){
b[i]=new Body(bodys[i].x,bodys[i].y);
}
bodys=new Body[this.number];
this.bodys[0]=new Body(x,y);
for(int i=1;i<this.number;i++){
this.bodys[i]=b[i-1];
}
setMapflag();
food = creatFood();
}public void setDirect(int i) {//設置蛇頭方向 this.direct = i; }
} </pre>
來自:http://blog.csdn.net/u011479875/article/details/46355905