Java课程设计——贪吃蛇小游戏

一.项目简介
二.项目构架图
三.团队成员以及任务简介
四.代码和git链接
五.项目运行图片

一.项目简介:设计目标及完成功能本软件是针对贪吃蛇小游戏的JAVA程序,利用上、下、左、右方向键来改变蛇的运动方向,在随机的地方产生食物,吃到食物就变成新的蛇体,碰自身则游戏结束,否则正常进行游戏。

二.项目构架图

 三.团队成员任务简介

队长:张德群

任务:贪吃蛇游戏界面,贪吃蛇图像的引用,团队博客以及git的书写,以及贪吃蛇的移动;

队员:李连崧

任务:贪吃蛇长度的增加以及食物的生成,以及贪吃蛇的死亡条件。

四.代码。

1.Startgame类

import javax.swing.*;

public class Startgame {
    public static void main(String[] args) {
        /*
        绘制一个静态窗口
         */
        JFrame frame = new JFrame("贪吃蛇by张德群,李连崧");//创建一个窗口,参数是窗口标题显示的文字
        frame.setBounds(430, 180, 900, 720);//设置一个窗口的大小
        frame.setResizable(false);//窗口大小不可以改变
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置窗口可以关闭,此处填写参数3可以
   
        frame.add(new GamePanel());//添加组件
        frame.setVisible(true);//打开窗口
    }
}

import javax.swing.*;

2.date类

public class date {
    /*
    此类用于存储图片信息
    image和src是同一个级别的文件夹
     */ 
    public static ImageIcon right = new ImageIcon("image/right.png");
    public static ImageIcon body = new ImageIcon("image/body.png");
    public static ImageIcon down = new ImageIcon("image/down.png");
    public static ImageIcon food = new ImageIcon("image/food.png");
    public static ImageIcon up = new ImageIcon("image/up.png");
    public static ImageIcon left = new ImageIcon("image/left.png");


}

3.GamePanel类

 

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

public class GamePanel extends JPanel implements KeyListener, ActionListener {//集成画板类,实现键盘监听方法

    public GamePanel() {
        init();
        this.setFocusable(true);//让这个组件获取到焦点
        this.addKeyListener(this);
        /*
       用于接收键盘事件(击键)的侦听器接口。
                使用组件的 addKeyListener 方法将从该类所创建的侦听器对象向该组件注册。按下、释放或键入键时生成键盘事件。
            然后调用侦听器对象中的相关方法并将该 KeyEvent 传递给它。
         */
        timer.start();//计时器打开
    }

    Timer timer = new Timer(160, this);//每160毫秒刷新一次,保证动画动起来
    int lenth;
    int foodx = 0;//设置食物的横坐标
    int foody = 0;//设置食物的纵坐标
    boolean isfood = false;//设置当前是否有食物变量,默认为假
    boolean start = false;//设置当前游戏是否开始变量,默认为假
    boolean iskilled=false;
    String fx = "R";//R 向右 L向左 U向上 D向下
    int[] snakex = new int[999];
    int[] snakey = new int[999];
    Random Ran = new Random();//创建随机数对象,给食物的坐标生成随机数并且赋值

    public void init() {//初始化方法,当本类被构造的时候被执行一次
        fx = "R";
        lenth = 9;//设置蛇的输出长度
        snakex[0] = 200;
        snakey[0] = 100;//头部坐标
        snakex[1] = 200;
        snakey[1] = 100;
        snakex[2] = 179;
        snakey[2] = 100;//第一节坐标
        for (int i = 2; i < lenth; i++) {
            /*
            其他节坐标以此赋值,因为第一节身体坐标与头部一样,
            所以从第二节开始输出
             */
            snakex[i + 1] = snakex[i] - 19;
            snakey[i + 1] = snakey[i];
        }
    }

    @Override
    protected void paintComponent(Graphics g) {//重写这个方法
        super.paintComponent(g);//清屏的作用,Graphics g 画笔
        this.setBackground(Color.lightGray);//设置画板背景颜色
        g.fillRect(0, 0, 884, 681);//添加组件,绘制游戏区域
        if (fx.equals("R"))//判断方向是哪个,输出对应的方向图标
            date.right.paintIcon(this, g, snakex[0], snakey[0]);
        else if (fx.equals("L"))
            date.left.paintIcon(this, g, snakex[0], snakey[0]);
        else if (fx.equals("U"))
            date.up.paintIcon(this, g, snakex[0], snakey[0]);
        else if (fx.equals("D"))
            date.down.paintIcon(this, g, snakex[0], snakey[0]);
        for (int i = 2; i < lenth; i++) {//循环输出多少个身体
            date.body.paintIcon(this, g, snakex[i], snakey[i]);
        }
        date.food.paintIcon(this, g, foodx, foody);//输出食物
        g.setColor(Color.WHITE);//设置画笔的颜色
        g.setFont(new Font("宋体", Font.BOLD, 20));//设置画笔的大小,字体,
        g.drawString("当前得分:" + (lenth - 9), 750, 50);//画笔输出对应的分数
        if (start == false) {//游戏是否开始,如果没有开始利用画笔在画板内写一句话
            g.setFont(new Font("宋体", Font.BOLD, 40));
            g.drawString("按下空格键进行游戏!", 250, 300);
        }
        /*
        用循环不断检查蛇头坐标与身体坐标是否相等,如果相等,定时器终止,则提示游戏结束
         */
        for (int i = 3; i < lenth; i++) {
            if (snakey[0] == snakey[i] && snakex[0] == snakex[i]) {
                System.out.println("游戏结束!");
                timer.stop();//游戏画面暂停
                iskilled=true;//死亡 状态变为真
                g.setFont(new Font("宋体", Font.BOLD, 40));
                g.drawString("游戏结束!按空格键重新开始游戏", 120, 300);
            }
        }

    }

    @Override
    public void keyPressed(KeyEvent e) {//键盘按下,未释放操作
        int keycode = e.getKeyCode();//定义一个变量用来接收键盘的数据
        if (keycode == 32)  //如果按下空格键(数字32),用来启动或者暂停
        {
          if (iskilled==true){//如果死亡状态为真,初始化全部参数,进行下一次游戏
                init();
            timer.start();
         }
            iskilled=false;
            start = !start;
            repaint();//刷新界面
        }
        /*
        为了防止向左运动的时候,方向键给予一个向右的命令造成死亡,所以设置了在向一个方向运动的时候,
        相反方向的命令不能够被运行。
        方法是当键盘接收到一个方向指令以后,判断是不是当前方向与获取的指令是否相反,相反则不允许更改
        当前方向
         */
        else if (keycode == 38 && fx != "D") {
            fx = "U";
        } else if (keycode == 40 && fx != "U") {
            fx = "D";
        } else if (keycode == 37 && fx != "R") {
            fx = "L";
        } else if (keycode == 39 && fx != "L") {
            fx = "R";
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {//执行定时操作
        if (start == true) {//游戏开始以后,让小蛇动起来
            if (fx.equals("R")) {
                if (snakex[0] > 884) {//超出边界就把坐标变成初始值
                    snakex[0] = 19;
                }
                snakex[0] = snakex[0] + 20;
                for (int i = lenth - 1; i > 0; i--) {//输出右移时候的身子
                    snakex[i] = snakex[i - 1];
                    snakey[i] = snakey[i - 1];
                }
            } else if (fx.equals("L")) {
                if (snakex[0] < 0) {
                    snakex[0] = 885;
                }
                snakex[0] = snakex[0] - 20;

                for (int i = lenth - 1; i > 0; i--) {//输出左移时候的身子
                    snakex[i] = snakex[i - 1];
                    snakey[i] = snakey[i - 1];
                }
            } else if (fx.equals("U")) {
                snakey[0] = snakey[0] - 20;

                if (snakey[0] <10) {
                    snakey[0] = 680;
                }
                for (int i = lenth - 1; i > 0; i--) {//输出上移时候的身子
                    snakex[i] = snakex[i - 1];
                    snakey[i] = snakey[i - 1];
                }
            } else if (fx.equals("D")) {
                snakey[0] = snakey[0] + 20;//每次行走的单位
                if (snakey[0] > 685) {//判断边界值
                    snakey[0] = 1;
                }
                for (int i = lenth - 1; i > 0; i--) {//输出下移时候的身子
                    snakex[i] = snakex[i - 1];
                    snakey[i] = snakey[i - 1];
                }
            }

        }
        if (!isfood) {//判断地图是否存在食物,如果没有,就会进行一次绘图,把食物绘图在地图上
//                      食物的坐标通过Random置随机种子完成

            foodx = Ran.nextInt(600);
            foody = Ran.nextInt(600);
            System.out.println(foodx);//输出食物的横坐标
            System.out.println(foody);//输出食物的纵坐标
            isfood = !isfood;
        }
           /*
        判断食物是否被吃,因为蛇的单位是每20个单位进行行走,如果判断头的坐标和食物坐标完全相等时不现实的,所以就利用蛇与食物的
        绝对值相差19(蛇每走一步是20单位)以下认为吃到了食物!
        也可以在1-20置随机数,得到的随机数乘以20,保证是20的倍数,这样就存在与小蛇坐标相等的情况
         */
        if (Math.abs(snakex[0] - foodx) < 19 && Math.abs(snakey[0] - foody) < 19) {
            isfood = !isfood;//把状态取反
            lenth++;//蛇的长度自加
        }
        repaint();//清屏
        timer.start();//定时器开始

    }
  

    @Override
    public void keyReleased(KeyEvent e) {//释放某个键操作

    }

    @Override
    public void keyTyped(KeyEvent e) {//键盘按下弹起操作
    }
}
git链接:“提交项目” · 93dda78 · zdq/zdq - Gitee.com

五.代码运行结果截图。

 退出

点击右上角的X,将关闭所有程序窗口。

 六.总结反思

课程设计就快结束了,我们自己认为自己学java没学好,而在整个新技术专题中我觉得贪吃蛇的游戏应该是最简单的。
通过这次课程设计,我对java又有了更深刻的认识。也有了更深- -步的喜爱,决定一-定要努力学好java,并能更好的应用于以后的工作中。
这次贪吃蛇的设计,俺做的不是很完美,也没想象中的那么好,但也获得了许多宝贵的经验:
1)在设计程序之前,务必要对自己所要设计的题目和内容有一个系统的,大概的了解,知道所设计的题目和内容
包含哪些资源。
2)设计程序采用什么编程语言并不是非常重要,关键是要有一个清晰的思路和一个完整的软件流程图,所有要
先把设计原理与思路搞清楚,再把流程图画出来,这样设计起来就简单多了。
3)在设计程序时,不能妄想一次就将整个程序设计好,“ 反复修改,不断改进”是程序设计的必经之路,发现错误也是取得成绩及成绩的一种必经之路。
4)要养成注释程序的好习惯,一个程序的完美与否不仅仅是实现功能,而
应该让人一看就能明白自己的思路,这样也为资料的保存和交流提供了方便。
在以后的工作中,我希望我能把这些经验应用起来。为以后的工作顺利进行,也让自己获得一定的能力,能够拥有一份好的工作。

  • 5
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值