Javaworkers团队最终项目总结

小组成员

  1. 20145205武钰
  2. 20145222黄亚奇
  3. 20145235李涛
  4. 20145103冯文华

团队项目总结

案例提出及工程用时

本次项目由十一到十六周共计6周时间

在结合我们自身能力以及去图书馆查找相关的java项目书籍后,我们小组决定选择贪吃蛇这一项目课题,

在明确课题后,查阅了相关资料进行下一步的工作。

设计思路

贪吃蛇游戏设计与实现,我们认为主要分为以下二个模块:

游戏界面模块和游戏控制模块。

游戏界面模块:

因为我们这个项目是一个基于界面进行表达的小游戏,所以界面是我们首先要解决的设计部分,在有了界面的情况下才可以进一步定义其中的蛇和食物。

游戏控制模块:

因为本身就是一个考验操作性的小游戏,所以在控制方面的设计决定了游戏的可玩性。

项目实现情况

我们小组的项目贪吃蛇小游戏,已经完成了功能的实现,可以在界面中控制蛇进行不断吃在屏幕中随机出现的食物,获得分数,而且随着游戏时间的增加和和分数的增加,蛇的运行速度会越来越快。

窗口视图

设计的界面如下图

图一:正常游戏下

图二:咬到自己的身体

图三:撞到墙壁

项目测试

界面设计

创建界面时需要import java.awt.* ,import javax.swing.* 两个包

在设计界面时,定义了一个主函数,以下是显示界面的名称部分

package javaworkers;
import java.awt.*;
import javax.swing.*; @SuppressWarnings("serial")//注释处的所有警告都忽视 public class MainClass { ControlSnake control; Toolkit kit;//所有实际应用的抽象窗口工具包的父类 Dimension dimen;//压缩了有整数精确度的组件 public static void main(String[] args) { new MainClass("javaworkers");//显示界面名称 }

贪吃蛇的具体实现

JPanel类用于为小内容提供简单窗口,界面呈现需要

ActionListener为对象提供添加动作的方法

Random,用48bit的种子产生伪随机序列,应用到食物的随机生成

规定一个屏幕范围中的二维矩阵,在其中使用坐标定义蛇和食物,以下是部分代码

public MainClass(String s) {

        super(s);

        control = new ControlSnake();//新的ControlSnake类

        control.setFocusable(true);

        kit = Toolkit.getDefaultToolkit();

        dimen = kit.getScreenSize();//获取屏幕尺寸

        add(control);//添加control

        setLayout(new BorderLayout());

        setLocation(dimen.width / 3, dimen.height / 3);// 挪位置,dimen.width/3,dimen.height/3

        setSize(FWIDTH, FHEIGHT);//定格操作窗口大小

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        setResizable(false);

        setVisible(true);

    }

    public static final int FWIDTH = 315;

    public static final int FHEIGHT = 380;

}

蛇的坐标:x,y

食物坐标:fx,fy

分别定义参数snakeBodyspeed,来初始化蛇的初始长度和速度

蛇的初始长度和初始速度都可以通过修改对应参数的初始值进行调节

下面是设计蛇时的部分代码

    int snakeBody;

    //控制蛇的长度

    int speed;

    public ControlSnake()

    {

        snakeBody = 1;//蛇的初始长度

        str = "上下左右方向键控制 P键暂停...";

        str1 = "现在的长度为:" + snakeBody;

        key = true;

        flag = 1;

        speed = 200;//速度初始值,修改初始

        rand = new Random();//创造一个新的随机数产生器

        list = new ArrayList<Point>();//创造一个初始容量为10的数列

        listBody = new ArrayList<Point>();

        x = 5;

        y = 5;

        list.add(new Point(x, y));//在坐标空间中创建并初始化一个新的点

        listBody.add(list.get(0));//list.get(0),返回在list列中0位置的元素

食物的生成使用Random,用48bit的种子产生伪随机序列生成随机数,之后反馈到食物坐标

fx,fy上,实现食物的随机生成,食物的部分代码如下:

        fx = rand.nextInt(30) * 10 + 5;// rand.nextInt(30),返回一个在0——30内的随机数

        fy = rand.nextInt(30) * 10 + 5;// 2

控制蛇时,需要将键盘输入转换为对应的整形键码,之后使用

键盘输入时,使用抽象类KeyAdapter()将键盘输入反馈到界面中,控制蛇的运行方向和游戏暂停

addKeyListener(new KeyAdapter()

        {

        //KeyAdapter(),用于接收键盘传来的事件的抽象类

            public void keyPressed(KeyEvent e)

            {

                //KeyEvent,使键盘输入转化成对应对象
//getKeyCode(),将键盘输入转化成对应的整形键码
if (e.getKeyCode() == 37) {//左 dx = -10; dy = 0; } else if (e.getKeyCode() == 38) {//上 dx = 0; dy = -10; } else if (e.getKeyCode() == 39) {//右 dx = 10; dy = 0; } else if (e.getKeyCode() == 40) {//下 dx = 0; dy = 10; } else if (e.getKeyCode() == 80) {//暂停 if (flag % 2 == 1) { time.stop(); } if (flag % 2 == 0) { time.start(); } flag++; } } });

在设计游戏时,为了增加游戏可玩性,游戏中蛇的速度会随着吃到食物的增加而变快,速度上限为100,速度增加函数是一个开口向下的抛物线,所以说游戏会越玩难度越大。

if (x == fx && y == fy) {//即“蛇吃到果实”

            speed = (int) (speed * 0.8);// 速度增加参数

            if (speed < 200) {

                speed = 100;

            }

完整代码如下

主函数代码

package javaworkers;
import java.awt.*;
import javax.swing.*; @SuppressWarnings("serial")//注释处的所有警告都忽视 public class MainClass extends JFrame { ControlSnake control; Toolkit kit;//所有实际应用的抽象窗口工具包的父类 Dimension dimen;//压缩了有整数精确度的组件 public static void main(String[] args) { new MainClass("javaworkers");//显示界面名称 } public MainClass(String s) { super(s); control = new ControlSnake();//新的ControlSnake类 control.setFocusable(true); kit = Toolkit.getDefaultToolkit(); dimen = kit.getScreenSize();//获取屏幕尺寸 add(control);//添加control setLayout(new BorderLayout()); setLocation(dimen.width / 3, dimen.height / 3);// 挪位置,dimen.width/3,dimen.height/3 setSize(FWIDTH, FHEIGHT);//定格操作窗口大小 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setResizable(false); setVisible(true); } public static final int FWIDTH = 315; public static final int FHEIGHT = 380; }

实现贪吃蛇的代码

package javaworkers;

import java.util.*;

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import javax.swing.Timer;

import java.util.Random;

@SuppressWarnings("serial")

public class ControlSnake extends JPanel implements ActionListener {

    //JPanel类用于为小内容提供简单窗口,ActionListener为对象提供添加动作的方法

    Random rand;

    //Random,用48bit的种子产生伪随机序列

    ArrayList<Point> list, listBody;

    //ArrayList<Point>,类似于二维数组,声明了两个泛型对象

    String str, str1;

    static boolean key;

    int x, y, dx, dy, fx, fy, flag;

    int snakeBody;

    //控制蛇的长度

    int speed;

    public ControlSnake()

    {

        snakeBody = 1;//蛇的初始长度

        str = "上下左右方向键控制 P键暂停...";

        str1 = "现在的长度为:" + snakeBody;

        key = true;

        flag = 1;

        speed = 200;//速度初始值

        rand = new Random();//创造一个新的随机数产生器

        list = new ArrayList<Point>();//创造一个初始容量为10的数列

        listBody = new ArrayList<Point>();

        x = 5;

        y = 5;

        list.add(new Point(x, y));//在坐标空间中创建并初始化一个新的点

        listBody.add(list.get(0));//list.get(0),返回在list列中0位置的元素

        dx = 10;

        dy = 0;

        fx = rand.nextInt(30) * 10 + 5;// rand.nextInt(30),返回一个在0——30内的随机数

        fy = rand.nextInt(30) * 10 + 5;// 2

        setBackground(Color.WHITE);//为窗口添加背景色

        setSize(new Dimension(318, 380));//重新定义窗口的高和宽

        final Timer time = new Timer(speed, this);

        time.start();

        //timer类,在指定时间间隔触发一个或多个 ActionEvent

        addKeyListener(new KeyAdapter()

        {

        //KeyAdapter(),用于接收键盘传来的事件的抽象类

            public void keyPressed(KeyEvent e)

            {

                //KeyEvent,使键盘输入转化成对应对象

                if (e.getKeyCode() == 37) {//getKeyCode(),将键盘输入转化成对应的整形键码

                    dx = -10;

                    dy = 0;

                } else if (e.getKeyCode() == 38) {

                    dx = 0;

                    dy = -10;

                } else if (e.getKeyCode() == 39) {

                    dx = 10;

                    dy = 0;

                } else if (e.getKeyCode() == 40) {

                    dx = 0;

                    dy = 10;

                } else if (e.getKeyCode() == 80) {

                    if (flag % 2 == 1) {

                        time.stop();

                    }

                    if (flag % 2 == 0) {

                        time.start();

                    }

                    flag++;

                }

            }

        });

    }

    public void paint(Graphics g) {//Graphics,所有环境算法基础类,允许应用在已有组件上进行绘制

        g.setColor(Color.WHITE);

        g.fillRect(0, 0, 400, 400);//指定一个以setColor返回值为底色的长方形,具体参数为x,y

        g.setColor(Color.DARK_GRAY);

        g.drawLine(3, 3, 305, 3);//在点(3,3)和(305,3)之间用当前色填充一条线

        g.drawLine(3, 3, 3, 305);

        g.drawLine(305, 3, 305, 305);

        g.drawLine(3, 305, 305, 305);

        g.setColor(Color.PINK);

        for (int i = 0; i < listBody.size(); i++) {//listBody.size(),返回当前list的元素个数

            g.fillRect(listBody.get(i).x, listBody.get(i).y, 9, 9);

        }//控制蛇的长度

        g.fillRect(x, y, 9, 9);//蛇的长度最大为9

        g.setColor(Color.ORANGE);

        g.fillRect(fx, fy, 9, 9);//随机显示果实

        g.setColor(Color.DARK_GRAY);

        str1 = "现在的长度为:" + snakeBody;

        g.drawString(str, 10, 320);//在图形化界面中显示字符串

        g.drawString(str1, 10, 335);

    }

    public void actionPerformed(ActionEvent e) {

        x += dx;

        y += dy;

        if (makeOut() == false) {//见最后的函数,用于排除超出图形界面的不合法输出

            JOptionPane.showMessageDialog(null, "重新开始......");

            //跳出对话框,显示“重新开始”

            speed = 200;//重新定义蛇的速度和长度

            snakeBody = 1;

            x = 5;

            y = 5;

            list.clear();//清空数列

            list.add(new Point(x, y));//加入新元素

            listBody.clear();

            listBody.add(list.get(0));

            dx = 10;

            dy = 0;

        }

        addPoint(x, y);

        if (x == fx && y == fy) {//即“蛇吃到果实”

            speed = (int) (speed * 0.8);// 速度增加参数

            if (speed < 200) {

                speed = 100;

            }

            fx = rand.nextInt(30) * 10 + 5;// 2

            fy = rand.nextInt(30) * 10 + 5;// 2

            snakeBody++;// 2

        } // 2

        repaint();//重新进行

    }

    public void addPoint(int xx, int yy) {

        // 动态的记录最新发生的50步以内的移动过的坐标

        // 并画出最新的snakeBody

        if (list.size() < 100) {// 蛇身长度最长为100

            list.add(new Point(xx, yy));

        } else {

            list.remove(0);

            list.add(new Point(xx, yy));

        }

        if (snakeBody == 1) {

            listBody.remove(0);

            listBody.add(0, list.get(list.size() - 1));

        } else {

            listBody.clear();

            if (list.size() < snakeBody) {

                for (int i = list.size() - 1; i > 0; i--) {

                    listBody.add(list.get(i));

                }

            } else {

                for (int i = list.size() - 1; listBody.size() < snakeBody; i--) {

                    listBody.add(list.get(i));

                }

            }

        }

    }

    public boolean makeOut() {

        if ((x < 3 || y < 3) || (x > 305 || y > 305)) {

            return false;

        }

        for (int i = 0; i < listBody.size() - 1; i++) {

            for (int j = i + 1; j < listBody.size(); j++) {

                if (listBody.get(i).equals(listBody.get(j))) {

                    return false;

                }

            }

        }

        return true;

    }

}

项目实现中的问题与解决

对于项目的实现开始时,我们想到了一些问题,见第四周项目报告,连接如下:

  • Javaworkers团队第四周项目总结

    然后我们在优化的过程中解决了如上问题。

    但是对于我们来说最困难的是对于未学习知识的应用,就像在使用界面设计包import java.awt.* ,import javax.swing.* 时,开始的时候并不会,然后再网上找有关的例子,和查阅API

    文档,然后尝试的去修改代码,一步一步的试错学习得到了结果。

项目的展望与改进

贪吃蛇作为一个经典游戏,对于改进方面我认为可以穿墙吃食物,并不是非要碰到墙就死,还可以进行关卡设置,在规定时间内吃到目标数量的食物就算过关,加大难度的话就是在一定时间内没有吃到食物,就自动扣一分并且重新生成新的食物。以及在其中放置障碍物,或是有毒的食物,通过颜色进行区别,因为一段时间就会刷新食物,所以并不是每个食物都要吃,避免吃到有毒的食物会进行加分。

团队成员成绩分配

姓名 任务 分配分数
20145205武钰 项目框架设计、代码模块构思及后期代码优化 30分
20145222黄亚奇 项目bug测试以及协作代码优化 23分
20145235李涛 项目资料寻找以及协作代码编写 25分
20145103冯文华 项目推送以及博客写作以及协作代码优化 22分

总结

经过长达五周的项目制作,从初步想法到翻阅资料,从具体构思到编写代码,从项目测试到写作代码优化,这样一步步走来,不仅锻炼了我们小组成员的动手协作能力,还让我们能对java这门课程有了进一步的了解,大大激发了我们的学习热情。虽然不是所有的代码是我们小组成员亲自编写,但对于不懂的我们通过到图书馆三楼翻阅相关书籍资料、结合自己以前的学习总结博客、向学长学姐请教等途径我们终于完成了贪吃蛇游戏的项目制作。不过还是有些地方由于时间关系我们未能进行优化,例如改进使蛇能穿墙吃食物、控制蛇的速度等,但我们相信通过这次小组合作制作项目,我们小组会不断成长,越学越好!

Javaworkers团队最终项目总结的更多相关文章

  1. Javaworkers团队第四周项目总结

    本周项目进展 本周是我们的项目开发的第四周,在之前的一周,我们小组在合作的情况下基本完成了项目代码的框架编写,我们组的项目课题,小游戏--贪吃蛇以及可以运行,可以进行简单的游戏,但是我们在思考之后发现 ...

  2. “耐撕团队”部署并测试onezero团队记帐本项目

    耐撕团队 对onezero团队记帐本项目的部署并测试 测试指标参见下面给出的博客: http://www.ltesting.net/ceshi/ceshijishu/xncs/2014/1030/20 ...

  3. 第三视角团队:项目UML设计(团队)

    项目UML设计(团队) 团队信息 团队名:第三视角 各成员学号及姓名 姓名 学号 博客链接 张扬(组长) 031602345 http://www.cnblogs.com/sxZhangYang/p/ ...

  4. Javaworkers团队第五周项目总结

    本周项目进展 本周是我们项目开发的最后一周,所以接着上周未解决的问题,我们进行了认真的查阅与测试. 下面是我们本周解决的问题概述. 蛇爬行的速度控制 答:这是上周的遗留问题,经过一周的查阅与学习,我们 ...

  5. Javaworkers团队第一周项目总结

    项目名称:游戏贪吃蛇 项目介绍: 贪吃蛇是一款相当经典的小游戏,我们团队决定用我们现有的java知识来实现它. 具体设计: 对象:蛇.果实 方向键:控制蛇的运动. 空格键:暂停游戏 ESC:推出游戏( ...

  6. Javaworkers团队第三周项目总结

    第十三.十四周:按照项目设计,逐步完成各个模块的代码,初步完成项目雏形. 基础知识原理 1.TDD(Test Driven Development, 测试驱动开发),TDD的一般步骤如下: 明确当前要 ...

  7. Javaworkers团队第二周项目总结

    本周项目进展 本周我们小组成员在图书馆和网上查阅了很多资料,基本达到了预期的计划,完成了项目框架设计及代码模块设计. 设计思路 1.首先,根据用户需求合理分配代码密度,即: 用户直接操作(点击运行)的 ...

  8. CakeDC(cakephp company)Git workflow--适合于较大团队大型项目开发

    CakeDC Git workflow是一个项目开发和版本发布的工作流,在这个工作流程中开发和版本发布周期是基于几个关键阶段(key phases): Development: 所有活跃的开发活动都由 ...

  9. 《Miracle-House团队》项目需求分析改进

    (一)团队项目需求分析改进 一.<西小餐项目需求规格说明书>的不足 通过老师和其他同学的指正和建议,我们发现上次的需求规格说明书存在以下不足: 1.需求规格文档不够完整和规范: 2.系统设 ...

随机推荐

  1. 设计模式之装饰模式(Java实现)

    “怎么了,鱼哥?” “唉,别提了,网购了一件衣服,结果发现和商家描述的差太多了,有色差就算了,质量还不好,质量不好就算了,竟然大小也不行,说好的3个X,邮的却是一个X的,不说了,退货去.你先开讲吧,你 ...

  2. Java多线程详解(三)

    1)死锁 两个线程相互等待对方释放同步监视器时会出现死锁的现象,这时所有的线程都处于阻塞状态,程序无法继续向下执行. 如下就是会出现死锁的程序. 首先flag = 1,线程d1开始执行,锁住对象o1, ...

  3. Egret打包App 修改App名称和图标 (Egret4.1.0)

    图标替换位置在项目res下的drawable这些目录下,用新图标覆盖即可. 这里我用白色图片替换了白鹭默认的图片ic_launcher.png 修改App名字,在res->value->s ...

  4. 【BZOJ4101】[Usaco2015 Open]Trapped in the Haybales Silver 二分

    [BZOJ4101][Usaco2015 Open]Trapped in the Haybales (Silver) Description Farmer John has received a sh ...

  5. 【BZOJ3786】星系探索 DFS序+Splay

    [BZOJ3786]星系探索 Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球 ...

  6. Birt报表安装及制作

    一.Birt报表安装 二.Birt报表设置 1. file--> new --> Project 如下图所示创建报表工程. 输入工程名称后,创建完成. 2.创建报表 创建报表 完成创建. ...

  7. MVC视图布局页常用代码

    1.在视图 Views 中新建文件夹  Shared 2.在 Shared 中新建布局页-母版页   _Layout.cshtml @{ Layout = null; } <!DOCTYPE h ...

  8. Mssql备份失败

    Mssql备份失败出现如下提示 备份时先删除默认的备份设备,自己选择路径

  9. 全面解析Oracle等待事件的分类、发现及优化

    一.等待事件由来 大家可能有些奇怪,为什么说等待事件,先谈到了指标体系.其实,正是因为指标体系的发展,才导致等待事件的引入.总结一下,Oracle的指标体系,大致经历了下面三个阶段: · 以命中率为主 ...

  10. 【Loadrunner】性能测试:通过服务器日志获取性能需求

    性能测试:通过服务器日志获取性能需求          接触过性能测试的童鞋都知道,想要做好一个项目的性能测试,性能需求的获取至关重要~!如果公司有做过性能测试还好,大家可以拿之前的性能测试数据作为参 ...