• 领导讲话
  • 自我介绍
  • 党会党课
  • 文秘知识
  • 转正申请
  • 问题清单
  • 动员大会
  • 年终总结
  • 工作总结
  • 思想汇报
  • 实践报告
  • 工作汇报
  • 心得体会
  • 研讨交流
  • 述职报告
  • 工作方案
  • 政府报告
  • 调研报告
  • 自查报告
  • 实验报告
  • 计划规划
  • 申报材料
  • 当前位置: 勤学考试网 > 公文文档 > 研讨交流 > 正文

    我Java实验报告

    时间:2020-10-30 12:37:27 来源:勤学考试网 本文已影响 勤学考试网手机站

    我的Java实验报告

    刘方然 学号:200103100311

    本实验报告分为以下部分:

    1:项目目标:

    2:名词与概念:

    3:系统总体分析。

    3:类的功能划分及相互关系:

    4:技术重点攻关几主要算法分析:

    5:部分类的具体实现:

    6:拓展:

    1:项目目标:

    这次我要实现的是一个游戏界面的框架及简单的游戏操作。

    游戏界面大体上有一个观察窗,一张小地图(MiniMap),两个按钮与相邻帧的间隔时间组成。在大地图上有一些可控制的单位(Unit)。

    完成的效果如下:

    单位 U

    单位 Unit

    观察窗

    小地图

    MiniMap

    退出按钮

    作者信息按钮

    观察窗在小地图中的视野框

    单位在小地图中的微缩代表

    玩家可进行地图视野移动,视野选定,单位选定,选定单位移动目的地,查寻作者信息,退出游戏等操作。

    2:名词与概念:

    1)游戏界面框架元素:

    1观察窗:显示单位及其他框架元素的载体。

    2 小地图:微缩显示地图。

    3 退出按钮:点击退出。

    4 作者信息按钮:点击显示作者信息。

    5 单位:操作的对象,可移动。

    7 单位在小地图中的微缩代表:指示单位在地图中的相对位置。

    8 观察窗在小地图中的视野框:指示观察窗在地图中的相对位置。

    2) 简单的游戏操作:

    1选定单位:

    a.集体选定:单击鼠标左键,拖动鼠标产生一个选择框,释放鼠标,则在选择框内的单位就被集体选定。

    b.单个选定:单击某一单位,则该单位就被选中。当该位置有多个单位时,随机选定其中一单位。

    2选定目的地:

    c.在观察窗中选定:在选定单位后,在观察窗中单击鼠标右键于目的地,则目的地被选定。

    d.在小地图中选定:在选定单位后,在小地图中单击鼠标右键于目的地,则目的地被选定。

    3改变视野:

    a.移动视野:将鼠标移至观察窗边界,则视野会向相应方向移动,直至视野到达地图边界。

    b.直接选定视野:鼠标左键单击小地图,视野直接移至相应位置。

    4显示作者信息:鼠标左键单击作者信息按钮,则跳出作者信息。

    5退出游戏:鼠标左键单击退出按钮。

    3: 系统总体分析。

    1)组成要素:

    1单位:

    a.单位运动(Movement)

    b.单位管理(Management)

    c.单位控制(Control)

    d.单位显示(Show)

    2界面:

    a.界面显示管理

    b.界面鼠标响应管理

    c.按钮响应

    3视频:

    a.分辨率调整

    b.全屏显示

    c.重绘管理(Repaint Management)

    2)要素关系:

    由于关系复杂,用下图表示:

    界面控制重绘管理

    视频

    视频

    全屏设置

    分辨率调整

    界面

    界面鼠标响应管理

    按钮响应

    单位

    单位运动

    界面

    通过

    控制 界面

    管理 显示

    单位

    3)运行框架

    设置视频

    设置视频

    取得视频环境

    取得视频设备

    保存原有视频模式

    界面初始化

    1. 添加单位

    满足退出条件

    结束

    恢复视频模式

    推出全屏显示

    主过程

    单位管理更新

    视野坐标更新

    取得绘图区

    绘制绘图区

    鼠标响应

    Yes

    影响

    主过程

    No

    4:技术重点攻关及主要算法分析:

    1)关于视频

    1如何实现全屏:

    使用如下框架:

    GraphicsEnvironment graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment ();

    GraphicsDevicegraphics Device = graphicsEnvironment.getDefaultScreenDevice();

    DisplayMode originalDisplayMode = graphicsDevice.getDisplayMode();

    try {

    graphicsDevice.setFullScreenWindow(helk); // Set the full screen

    //: Anything I want to do is written here.

    } finally {

    graphicsDevice.setDisplayMode(originalDisplayMode);

    graphicsDevice.setFullScreenWindow(null); // Set off.

    }

    System.exit(0);

    }

    2如何改变分辨率

    if(graphicsDevice.isDisplayChangeSupported()) {

    graphicsDevice.setDisplayMode(displayMode);

    }

    在本程序中分辨率为 640 * 480。

    2)关于单位

    1 单位如何运动:

    a.在本项目中使用了基于浮点的体系(区别与基于网格的体系)。

    基于浮点的体系

    位置(Position)P(1.234, 5.678)

    方向(Direction)All direction

    位移(Displacement)D(0.0343, 0.5443)

    基于浮点的体系 基于网格的体系

    位置(Position)P(2,4)

    方向(Dirction)Four or Eight directions

    位移(Displacement)D(1,0)

    b.如何运动

    原有位置 (curPosX, curPosY)

    目标位置 (desPosX, desPosY)

    运动速率 (vel);

    有了以上参数就可以实现对下一位置的计算

    double sclX, sclY;

    double distance = distanceBetween(curPos, desPos);

    sclX = (desPos.x - curPos.x) / distance;

    sclY = (desPos.y - curPos.y) / distance;

    curPos.x += vel * sclX;

    curPos.y += vel * sclY;

    c. 如何确定已到达目标

    如果只使用以上代码则会出现无法停止或distance == 0造成除零的危险。

    解决的方法是在距离目标位置很短的范围内(rngStop)停下来。

    即当distance < rngStop时停下。

    而且速率应当略小于这个范围,既 vel < rngStop,避免有除零的危险。

    代码修正如下:

    if(!isMove) {

    return;

    }

    double distance = distanceBetween(curPos, desPos);

    if(distance < rngStop) {

    isMove = false;

    return;

    }

    sclX = (desPos.x - curPos.x) / distance;

    sclY = (desPos.y - curPos.y) / distance;

    curPos.x += vel * sclX;

    curPos.y += vel * sclY;

    2单位如何绘制

    为了简化程序而又明晰物体的运动方向绘制效果如下:

    选定圈方向条

    选定圈

    方向条

    普通(Normal) 选定(Selected)

    具体代码如下:

    // Draw the Unit

    g.drawOval((int)(curPos.x - sizeDraw.width / 2) - p.x, (int)(curPos.y - sizeDraw.height / 2) - p.y, sizeDraw.width, sizeDraw.height);

    // Draw the Dirction Bar

    g.drawLine((int)(curPos.x) - p.x, (int)(curPos.y) - p.y, (int)(sizeDraw.width * sclX / 2 + curPos.x) - p.x, (int)(sizeDraw.height * sclY / 2 + curPos.y) - p.y);

    // If selected, draw the Selected Bar

    if (isSlct) {

    g.setColor(Color.GREEN);

    g.drawOval((int)(curPos.x - size.width / 2) - p.x, (int)(curPos.y - size.height / 2) - p.y, size.width, size.height);

    }

    由于在程序的开始,sclX, sclY(运动方向分量比例)均为零,则时会出现无方向条的现象。为弥补此不足将绘方向条代码修改如下。

    // Draw the Dirction Bar

    if (sclX == sclY && sclX == 0) {

    g.drawLine((int)(curPos.x) - p.x, (int)(curPos.y) - p.y, (int)(sizeDraw.width / 2 + curPos.x) - p.x, (int)(curPos.y) - p.y);

    } else {

    g.drawLine((int)(curPos.x) - p.x, (int)(curPos.y) - p.y, (int)(sizeDraw.width * sclX / 2 + curPos.x) - p.x, (int)(sizeDraw.height * sclY / 2 + curPos.y) - p.y);

    }

    3单位如何被驱动的

    单位有一个executeCommand(Command cmd) 函数 可以通过执行Command的对象来改变自身状态。可移动单位(MobileUnit)可以执行MoveCommand来驱动它向目的地运动.代码如下:

    public void executeCommand(Command cmd) {

    if(cmd instanceof MoveCommand) {

    gotoDestination(((MoveCommand)cmd).getPosition());

    }

    }

    如果还想单位执行其它操作,也使用如上框架:如

    if(cmd instanceof Command1) {

    //Act 1

    } else if(cmd instanceof Command2) {

    //Act 2

    } else if...

    2)关于鼠标响应

    1如何拖框(Drag a Selective frame): 当鼠标左键按下时,记录坐标P1(startX, startY)同时使P2(endX, endY)与P1重合,当鼠标拖动时更新P2至鼠标当前位置。有了P1,P2点的坐标就可以确定一个矩形,绘出此矩形便得到拖框效果。但当startX > endX 或 startY > endY 时矩形的边长是负值,不能画框,因此要稍作处理。交换startX 与 endX 或是startY 与endY。

    2如何实现单位集体选中

    拖动鼠标产生如上矩形,遍历所以单位,当单位在矩形内时将此单位设置成选中状态(isSlct = true)既可

    3如何实现单位单个选中

    单击鼠标左键,遍历所以单位,当点击位置与某一单位的距离小于单位的一半尺寸时,该单位便被选中。

    4如何实现目的地选定

    单击鼠标右键,点击位置即被确定为目的地位置。

    4)关于单位的管理与控制

    1单位的管理

    任何一个单位生成后,都应向单位管理器(UnitManager)注册,由管理器管理。管理器负责对所有单位(在视野内)进行显示,微缩显示与更新。

    public void createUnit(Unit unit) { // 单个单位向管理器注册

    units.add(unit);

    }

    public void addUnitGroup(LinkedList list) { // 单位组向管理器注册

    units.addAll(list);

    }

    public void updateAll() { // 对所有单位进行更新

    ListIterator lit = units.listIterator();

    Unit u;

    while (lit.hasNext()) {

    (u = (Unit)lit.next()).update();

    }

    }

    public int showAll(Graphics g, Rectangle r) {

    // 对所有单位(在视野内)进行显示

    ListIterator lit = units.listIterator();

    Unit u;

    int i = 0;

    while (lit.hasNext()) {

    u = (Unit)lit.next();

    if (r.contains((int)(u.getX()), (int)(u.getY()))) {

    u.show(g, r.getLocation());

    if(u.isSelected()) {

    i++;

    }

    }

    }

    return i;

    }

    public void miniShowAll(Graphics g, Point p, int scale) {

    // 对所有单位微缩显示

    ListIterator lit = units.listIterator();

    while (lit.hasNext()) {

    // 调用所有单位的miniShow();

    ((Unit)(lit.next())).miniShow(g, p, scale);

    }

    }

    2单位的控制

    所有选中的单位都在单位控制器(UnitControler)中注册。实际上所有的鼠标对单位的控制都是通过单位控制器完成的。

    public void addUnit(Unit unit) { // 添加单位

    units.add(unit);

    unit.setSelected(true);

    }

    public void removeUnit(Unit unit) { // 注销单位

    if(units.remove(unit)) {

    unit.setSelected(false);

    }

    }

    public void removeAll() { // 清空控制器

    ListIterator lit = units.listIterator();

    while(lit.hasNext()) {

    ((Unit)(lit.next())).setSelected(false);

    lit.remove();

    }

    }

    public void setUnitGroup(LinkedList units) { // 重置控制器

    removeAll(); // 先清空

    ListIterator lit = units.listIterator();

    this.units = units;

    lit = units.listIterator();

    Unit u;

    while(lit.hasNext()) {

    ((Unit)(lit.next())).setSelected(true);

    }

    }

    public void executeCommand(Command cmd) { // 对选定单位发布命令

    ListIterator lit = units.listIterator();

    while(lit.hasNext()) {

    ((Unit)lit.next()).executeCommand(cmd);

    }

    }

    5)总体协调

    1刷新率(画面的更新速度)的调整

    我发现绘图是有很大开销的,当视野内的单位超过150 个时速度会变得很慢(500Mhz,64M条件下)。我通过调整睡眠时间(Sleep)来使动画平滑.

    在UnitManager 中 showAll()不仅显示所有在视野内的单位而且还返回一个放映绘图量的整数 drawCounter;

    将线程的睡眠时间设定为 Math.max(5,100 - drawCounter / 2);

    则效果较好

    2关于最大处理能力

    为了使动画不致太慢,单位数应少于200(500Mhz,64M条件下)。

    5:类的功能划分及相互关系:

    1)自编类一览

    Command 命令接口

    ExitableJFrame 关闭后自动退出的Frame类

    Helkcraft 主类

    MiniMap 小地图

    MobileUnit 可移动单位

    MoveCommand 移动命令

    Position 浮点型坐标类

    Unit 单位接口

    UnitControler 单位控制器

    UnitLayout 单位排版器

    UnitManager 单位管理器

    2)相互关系

    JFrame

    JFrame

    Helkcraft

    MiniMap

    Position

    UnitControler

    UnitLayout

    UnitManager

    MoveCommand

    Command

    MobileUnit

    Unit

    LinkedList

    ExitableJFrame

    ExitableJFrame

    A B B使用 A

    A B B继承 A

    6: 部分类的具体实现:

    对于关键类UnitManager 和 UnitControler 上面已经介绍过了,这里不在赘述。

    接下来讲讲UnitLayout 和 主类 Helkcraft.

    UnitLayout

    为了方便单位在地图上的摆放,我设计了UnitLayout 这个辅助类。

    实际上它只有一个square()函数。这个函数在地图某个位置摆上单位的N x N 的方阵。

    它的返回值可以交给UnitManager来管理。具体代码如下:

    static public LinkedList square(int n, Position p, int interval) {

    Position pos = new Position(p);

    LinkedList list = new LinkedList();

    for(int i = 0; i < n; i++) {

    pos.x = p.x;

    for(int j = 0; j < n; j++) {

    list.add(new MobileUnit(pos));

    pos.x += interval;

    }

    pos.y += interval;

    }

    return list;

    }

    UnitLayout 还可以有任何摆单位的函数如

    line(), random(), triangle() 等等。这样就能摆出各种各样的阵型。由于精力所

    限, 我没有去拓展。

    square

    Line

    Ramdon

    Rriangle

    Helkcraft

    作为主类的Helkcrart在报告的一开始就已涉及到。在这里着重讲一讲它的鼠标监听部分。

    Helkcraft 有两个监听器,一个MouseListener 一个 mouseMotionListener。

    它们相互配合对鼠标进行监听并做出相应反应。

     

    MouseListener 的

    MouseListener 的方法伪代码

    MousePressed()

    if(LeftButtonDown) {

    SetSelectedRectangleInvisible

    If(PressInMiniMap) {

    ControlerExecuteCommandInMiniMapWay

    } else {

    ControlerExecuteCommand

    }

    } else if (RightButtonDown){

    if(PressQuitButton) {

    QuitTheGame

    Return

    }else if(PressInfoButton) {

    TriggleTheInfoShown

    Return

    }else if(PressMiniMap) {

    MoveMiniMap

    Return

    } else if(PressUnit) {

    SetUnitSelected

    Return

    }

    RecordPressLocation

    SetSingleSelectedTrue

    }

    mouseReleased

    if(isSingleSelected) {

    SetSingleSetlectedFalse

    Return

    }

    if(LeftButtonUp) {

    NormalizeSelectedRectangle

    SetTheSelectedUnit

    SetTheSelectRectShownFalse

    }

    MouseMotionListener 的

    MouseMotionListener 的方法伪代码

    MouseDragged()

    if(isShowSelectRect) {

    ShowSelectRect

    Return

    }

    if(LeftButtonUp) {

    NormalizeSelectedRectangle

    SetTheSelectedUnit

    SetTheSelectRectShownFalse

    }

    mouseMoved

    GetCurrentLocation

    7:拓展:

    如果有时间与精力我会再添一个单位信息框和一个控制板。效果应该向下面那样:

    单位信息框

    单位信息框

    控制板

    控制按钮

    如果还有时间与精力我会解决单位重叠的问题。

    如果还有时间与精力我会使单位可已互相开仗。

    如果还有时间与精力我会。。。

    就写到这吧,再见。

    • 考试时间
    • 范文大全
    • 作文大全
    • 课程
    • 试题
    • 招聘
    • 文档大全

    推荐访问