java贪吃蛇游戏代码详解编程语言

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();   
            }   
        }   
    }   
   
       
   
   
}  

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);   
    }   
   
}  

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;   
    }   
   
}  

来自:http://blog.csdn.net/u011479875/article/details/46355905

原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/10153.html

(0)
上一篇 2021年7月19日 10:00
下一篇 2021年7月19日 10:00

相关推荐

发表回复

登录后才能评论