【项目二 贪吃蛇游戏开发】

一、实验要求

1.实现贪吃蛇游戏基本功能,屏幕上随机出现一个“食物”,称为豆子,上下左右控制“蛇”的移动,吃到“豆子”以后“蛇”的身体加长一点。
2.“蛇”碰到边界或蛇头与蛇身相撞,蛇死亡,游戏结束。
3.为游戏设计友好的交互界面;例如欢迎界面,游戏界面,游戏结束界面。要有开始键、暂停键和停止退出的选项。
4.对蛇吃到豆子进行分值计算,可以设置游戏速度,游戏音乐等拓展元素。

二、实验分析

注意点:
A.新豆子的生成规则为:
①不能超出游戏区域
②不能在蛇身上
B.游戏结束时的检测规则为:
①蛇是否超出游戏区域
②蛇头是否撞到自己身上

三、实现语言

Java

四、软件代码

SnakeGame类:

package mwy;

import java.awt.Color;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class SnakeGame extends JFrame implements Runnable {
    private static final long serialVersionUID = -6497735513679547494L;
    SnakeBorder panel;
    JPanel jp;
    JLabel lab;
    JLabel labScore;
    JLabel labRecorde;
    JButton btnStart;
    JButton btnRestart;
    private int bestRecorde = 0;

    public SnakeGame() {
        super("Sanke Game");
        this.setSize(1000, 780);
        this.saveData();
        this.labScore = new JLabel("当前分数:0");
        this.labRecorde = new JLabel("   当前最佳纪录:" + this.bestRecorde);
        this.panel = new SnakeBorder();
        int x = (int)Toolkit.getDefaultToolkit().getScreenSize().getWidth();
        int y = (int)Toolkit.getDefaultToolkit().getScreenSize().getHeight();
        this.setLocation((x - this.getWidth()) / 2, (y - this.getHeight()) / 2);
        this.lab = new JLabel("提示:按↑、↓、←、→控制方向     ");
        this.jp = new JPanel();
        this.btnStart = new JButton("点击开始");
        this.btnStart.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (e.getSource() == SnakeGame.this.btnStart && !SnakeGame.this.panel.supe) {
                    SnakeGame.this.btnStart.setText("点击暂停");
                    SnakeGame.this.panel.resume();
                } else if (e.getSource() == SnakeGame.this.btnStart && SnakeGame.this.panel.supe) {
                    SnakeGame.this.btnStart.setText("点击继续");
                    SnakeGame.this.panel.supe = false;
                }

            }
        });
        this.btnRestart = new JButton("重新开始");
        this.btnRestart.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (e.getSource() == SnakeGame.this.btnRestart) {
                    SnakeGame.this.panel.init();
                    SnakeGame.this.panel.resume();
                }

            }
        });
        this.jp.setSize(1000, 25);
        this.jp.setBackground(Color.cyan);
        this.jp.add(this.lab);
        this.jp.add(this.btnStart);
        this.jp.add(this.btnRestart);
        this.jp.add(this.labScore);
        this.jp.add(this.labRecorde);
        this.add(this.jp, "North");
        this.add(this.panel);
        this.btnStart.addKeyListener(this.panel);
        this.btnRestart.addKeyListener(this.panel);
        this.panel.addKeyListener(this.panel);
        this.addKeyListener(this.panel);
        this.setDefaultCloseOperation(3);
        this.setVisible(true);
        Thread t = new Thread(this.panel);
        t.start();
        Thread s = new Thread(this);
        s.start();
    }

    public static void main(String[] args) {
        new SnakeGame();
    }

    public void run() {
        while(true) {
            this.labScore.setText("当前分数:" + this.panel.score);
            if (this.bestRecorde < this.panel.score) {
                this.saveData();
            }
        }
    }

    public void saveData() {
        try {
            BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream("Data.txt")));
            String str = "";
            str = in.readLine();
            this.bestRecorde = Integer.parseInt(str);
            if (this.bestRecorde <= this.panel.score) {
                FileOutputStream fos = new FileOutputStream("Data.txt");
                PrintWriter pw = new PrintWriter(fos);
                pw.write("" + this.panel.score);
                pw.flush();
                pw.close();
            }

            in.close();
        } catch (Exception var6) {
            try {
                FileOutputStream fos1 = new FileOutputStream("Data.txt");
                PrintWriter pw1 = new PrintWriter(fos1);
                pw1.write("" + this.bestRecorde);
                pw1.flush();
                pw1.close();
            } catch (FileNotFoundException var5) {
                var5.printStackTrace();
            }
        }

    }
}

Snake类:


package mwy;

import java.awt.Image;

public class Snake {
    public Image image;
    public int x;
    public int y;
    public int dir = 4;

    public Snake() {
    }
}

SnakeBorder类:

package mwy;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.ImageObserver;
import java.util.ArrayList;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class SnakeBorder extends JPanel implements Runnable, KeyListener {
    private static final long serialVersionUID = 1L;
    private Snake[] images = new Snake[151];
    int score;
    Image grey;
    Image head;
    Image body;
    Image food;
    private int location = 29;
    ArrayList<Snake> snake = new ArrayList();
    Snake snakeHead;
    Snake snakeFood;
    Snake snakeBody;
    boolean supe;
    long time;
    boolean gameover;

    public SnakeBorder() {
        this.init();
    }

    public void init() {
        this.score = 1;
        this.time = 500L;
        this.supe = false;
        this.gameover = false;
        this.snake.clear();
        this.grey = (new ImageIcon("pictures/grey.png")).getImage();
        this.head = (new ImageIcon("pictures/head_right.png")).getImage();
        this.body = (new ImageIcon("pictures/body.png")).getImage();
        this.food = (new ImageIcon("pictures/food.png")).getImage();

        int k;
        for(k = 0; k < 151; ++k) {
            this.images[k] = new Snake();
        }

        k = 1;

        for(int i = 30; i < 605; i += 60) {
            for(int j = 40; j < 940; j += 60) {
                this.images[k].x = j;
                this.images[k].y = i;
                this.images[k].dir = 4;
                ++k;
            }
        }

        while(this.location % 15 >= 6 || this.location % 15 < 2 || this.location > 90) {
            this.location = (int)(Math.random() * 150.0D);
        }

        this.snakeHead = new Snake();
        this.snakeHead.x = this.images[this.location].x;
        this.snakeHead.y = this.images[this.location].y;
        this.snakeHead.dir = this.images[this.location].dir;
        this.snakeHead.image = this.head;
        this.snake.add(this.snakeHead);
        this.produceFood();
    }

    public void paint(Graphics g) {
        super.paint(g);

        int i;
        for(i = 1; i < 151; ++i) {
            g.drawImage(this.grey, this.images[i].x, this.images[i].y, (ImageObserver)null);
        }

        for(i = 0; i < this.snake.size(); ++i) {
            g.drawImage(((Snake)this.snake.get(i)).image, ((Snake)this.snake.get(i)).x, ((Snake)this.snake.get(i)).y, (ImageObserver)null);
        }

        g.drawImage(this.snakeFood.image, this.snakeFood.x, this.snakeFood.y, (ImageObserver)null);
    }

    private void produceFood() {
        boolean judge = false;

        while(true) {
            while(this.location == 1 || this.location == 15 || this.location == 135 || this.location == 150 || !judge) {
                this.location = (int)(Math.random() * 149.0D + 1.0D);

                for(int i = 0; i < this.snake.size(); ++i) {
                    if (this.images[this.location].x == ((Snake)this.snake.get(i)).x && this.images[this.location].y == ((Snake)this.snake.get(i)).y) {
                        judge = false;
                        break;
                    }

                    judge = true;
                }
            }

            this.snakeFood = new Snake();
            this.snakeFood.x = this.images[this.location].x;
            this.snakeFood.y = this.images[this.location].y;
            this.snakeFood.image = this.food;
            return;
        }
    }

    private void eatFood() {
        int x = ((Snake)this.snake.get(0)).x;
        int y = ((Snake)this.snake.get(0)).y;
        if (x < this.snakeFood.x + 20 && x > this.snakeFood.x - 20 && y < this.snakeFood.y + 20 && y > this.snakeFood.y - 20) {
            this.snakeBody = new Snake();
            if (((Snake)this.snake.get(this.snake.size() - 1)).dir == 1) {
                this.snakeBody.x = ((Snake)this.snake.get(this.snake.size() - 1)).x;
                this.snakeBody.y = ((Snake)this.snake.get(this.snake.size() - 1)).y + 60;
            } else if (((Snake)this.snake.get(this.snake.size() - 1)).dir == 2) {
                this.snakeBody.x = ((Snake)this.snake.get(this.snake.size() - 1)).x;
                this.snakeBody.y = ((Snake)this.snake.get(this.snake.size() - 1)).y - 60;
            } else if (((Snake)this.snake.get(this.snake.size() - 1)).dir == 3) {
                this.snakeBody.x = ((Snake)this.snake.get(this.snake.size() - 1)).x + 60;
                this.snakeBody.y = ((Snake)this.snake.get(this.snake.size() - 1)).y;
            } else if (((Snake)this.snake.get(this.snake.size() - 1)).dir == 4) {
                this.snakeBody.x = ((Snake)this.snake.get(this.snake.size() - 1)).x - 60;
                this.snakeBody.y = ((Snake)this.snake.get(this.snake.size() - 1)).y;
            }

            this.snakeBody.image = this.body;
            this.snakeBody.dir = ((Snake)this.snake.get(this.snake.size() - 1)).dir;
            this.snake.add(this.snakeBody);
            ++this.score;
            if (this.time >= 200L) {
                this.time -= 30L;
            }

            this.produceFood();
            this.repaint();
        }

    }

    private void moved() {
        int k;
        for(k = 0; k < this.snake.size(); ++k) {
            if (((Snake)this.snake.get(k)).dir == 1) {
                ((Snake)this.snake.get(k)).y -= 60;
            } else if (((Snake)this.snake.get(k)).dir == 2) {
                ((Snake)this.snake.get(k)).y += 60;
            } else if (((Snake)this.snake.get(k)).dir == 3) {
                ((Snake)this.snake.get(k)).x -= 60;
            } else if (((Snake)this.snake.get(k)).dir == 4) {
                ((Snake)this.snake.get(k)).x += 60;
            }
        }

        this.eatFood();

        for(k = this.snake.size() - 1; k > 0; --k) {
            if (((Snake)this.snake.get(k)).dir != ((Snake)this.snake.get(k - 1)).dir) {
                ((Snake)this.snake.get(k)).dir = ((Snake)this.snake.get(k - 1)).dir;
            }
        }

    }

    private void isGameOver() {
        int choice;
        if (((Snake)this.snake.get(0)).x <= 880 && ((Snake)this.snake.get(0)).x >= 40 && ((Snake)this.snake.get(0)).y >= 30 && ((Snake)this.snake.get(0)).y <= 570) {
            for(choice = 1; choice < this.snake.size(); ++choice) {
                if (((Snake)this.snake.get(0)).x == ((Snake)this.snake.get(choice)).x && ((Snake)this.snake.get(0)).y == ((Snake)this.snake.get(choice)).y) {
                    this.gameover = true;
                    break;
                }
            }
        } else {
            this.gameover = true;
        }

        if (this.gameover) {
            choice = JOptionPane.showConfirmDialog(this, "你输了!是否再来一局?", (String)null, 0);
            if (choice == 0) {
                this.init();
                this.resume();
                this.repaint();
            } else {
                System.exit(0);
            }
        }

    }

    public void run() {
        while(true) {
            try {
                while(true) {
                    Thread.sleep(this.time);
                    synchronized(this) {
                        while(!this.supe) {
                            this.wait();
                        }

                        this.moved();
                        this.isGameOver();
                        if (!this.gameover) {
                            this.repaint();
                        }
                    }
                }
            } catch (Exception var3) {
                var3.printStackTrace();
            }
        }
    }

    synchronized void resume() {
        this.supe = true;
        this.notify();
    }

    public void keyTyped(KeyEvent e) {
    }

    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == 40 && ((Snake)this.snake.get(0)).dir != 1) {
            ((Snake)this.snake.get(0)).dir = 2;
            ((Snake)this.snake.get(0)).image = (new ImageIcon("pictures/head_down.png")).getImage();
        }

        if (e.getKeyCode() == 38 && ((Snake)this.snake.get(0)).dir != 2) {
            ((Snake)this.snake.get(0)).dir = 1;
            ((Snake)this.snake.get(0)).image = (new ImageIcon("pictures/head_up.png")).getImage();
        }

        if (e.getKeyCode() == 37 && ((Snake)this.snake.get(0)).dir != 4) {
            ((Snake)this.snake.get(0)).dir = 3;
            ((Snake)this.snake.get(0)).image = (new ImageIcon("pictures/head_left.png")).getImage();
        }

        if (e.getKeyCode() == 39 && ((Snake)this.snake.get(0)).dir != 3) {
            ((Snake)this.snake.get(0)).dir = 4;
            ((Snake)this.snake.get(0)).image = (new ImageIcon("pictures/head_right.png")).getImage();
        }

    }

    public void keyReleased(KeyEvent e) {
    }
}

图片合集包pictures:
链接:https://pan.baidu.com/s/1eGva9F0xDm4Hq-r-oU-UvA
提取码:1234

五、运行界面

正常游戏:
在这里插入图片描述
碰到边界——游戏结束:
在这里插入图片描述
撞到自身——游戏结束:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值