java貪吃蛇游戲代碼

jopen 9年前發布 | 4K 次閱讀 Java



思路  :主要是模擬蛇的運動。只要對蛇頭進行操作,然后讓前一種狀態先的蛇頭位置復制給現在蛇身的第二個部分,讓前一狀態的蛇的第二個部分的位置復制給現在蛇身的第三個部分......以此類推,從而達到模擬蛇運動的狀態。


GluttonousSnake.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.java

import 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.java

import 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

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!