学习情境4MIDP2.0游戏开发.ppt

上传人:xin****828 文档编号:7212202 上传时间:2020-03-16 格式:PPT 页数:60 大小:5.28MB
返回 下载 相关 举报
学习情境4MIDP2.0游戏开发.ppt_第1页
第1页 / 共60页
学习情境4MIDP2.0游戏开发.ppt_第2页
第2页 / 共60页
学习情境4MIDP2.0游戏开发.ppt_第3页
第3页 / 共60页
点击查看更多>>
资源描述
学习情境4MIDP2 0游戏开发 能力目标 学会使用GameCvanvas类的按键响应方法 会熟练构造精灵类 学会使用精灵实现动画的自动播放 能熟练设置精灵出现的位置 显示帧 切换帧和绘制帧的方法 学会使用Vector类创建子弹 移动子弹和绘制子弹 学会自定义对象类的方法 构造一个游戏对象 学会使用变量来模拟计数器功能 实现游戏对象以不同的频率运动 熟练掌握使用setTransform 方法 实现精灵对象的旋转 熟练掌握使用精灵类提供的方法进行碰撞的检测 认知目标 认识游戏的屏幕GameCanvas类 了解GameCanvas类和Canvas类的区别 了解GameCvanvas类的自动双缓冲区和脱屏画笔 学习精灵类中常用方法的语法格式 并理解其中参数的含义 了解Vector类中的常用方法 并理解各参数的含义 理解计数器在游戏程序中的使用方法和重要性 理解setTransform 方法中参数rotating的8个取值的含义认知collidesWith 方法的语法格式 并理解其参数的含义 理解区域级和像素级碰撞区别 理解播放帧序列中的帧号码和帧序号的区别 4 1学习情景描述 除棋牌类游戏之外 一款手机游戏 通常在一个特定的场景下展开 这个特定的场景 就是游戏的背景 根据需要 游戏背景还可以滚动 在游戏背景下 通常有若干个游戏的对象 其中可以由玩家通过按键来控制的游戏对象 称为游戏的 主角 其余不能由玩家来控制的角色称为 NPC 即非玩家控制角色 或系统控制角色 这些游戏对象可以进行移动 跳跃 投掷 发射子弹 攻击等各种动作 并通过对这些游戏对象和动作进行HP 生命值 MP 经验值 攻击力等等的数值设计 来判断游戏的胜利或者失败 本学习情境分为五个学习单元来完成 单元一 游戏主角设计 单元二 子弹设计 单元三 NPC 非玩家控制角色 设计 单元四 游戏背景设计 单元五 滚屏设计 游戏主角是由玩家来控制的游戏对象 可以是一架飞机 一辆坦克 一个人物等 玩家通过手机键盘上的按键 可以控制游戏主角在手机屏幕上进行移动 跳跃 投掷 格斗等各种动作 在本学习单元中 首先 通过控制一架飞机在屏幕上的移动 来认识GameCanvas 并学习在GameCanvas中的键盘处理 然后 通过在移动时 改变飞机的形状 初识精灵类 最后 通过控制一个主角人物在屏幕上的行走 来深入地学习精灵类的使用 4 2游戏主角设计 4 2 2知识准备 了解GameCanvas类 MIDP有1 0和2 0版本之分 在MIDP2 0中 新增加了一个javax microedition lcdui game包 这个包中定义了专门用于游戏开发的5个新类 GameCanvas Layer LayerManager Sprite和TiledLayer 这些类主要针对游戏开发的特点 提供了用于提高游戏性能的独立功能 其中 GameCanvas类继承自MIDP1 0中的Canvas类 为游戏提供了基本的 屏幕 功能 除了完全具备Canvas类的功能外 这个类还提供了游戏专用的功能 这些功能简化了游戏开发并提高了运行性能 比如 提供双缓冲绘制机制 能直接获得设备键盘的物理状态等等 4 2 3任务一 控制主角飞机在屏幕上移动 任务准备 1 声明变量 2 在构造方法中实现初始化 3 绘制屏幕 4 响应键盘 5 启动线程 6 控制线程 7 测试运行 1 新建MIDlet工程 工程名为 Ch4 Unit1 2 新建MIDlet类 类名为 Ch4 Unit1 MIDlet 3 新建GameCanvas类 4 将主角飞机图片资源文件plane png 拷贝到工程的 res 文件夹下 实现过程 知识提炼 MIDP2 0中的键盘处理 在MIDP2 0中 不需要等待键盘事件发生后才能获取键盘状态信息 通过调用GameCanvas类上定义的的getKeyStates 方法 可以随时获取键盘状态信息 并且可以获取多个按键状态信息 getKeyStates 方法的语法如下 publicintgetKeyStates 该方法返回一个int型数据 其中每一位代表一个按键的状态 如果某个按键被按下 则对应的数据位为1 否则 数据位为0 MIDP2 0在GameCanvas类上定义了九个静态属性常量来表示游戏按键状态码 分别为 UP PRESSED上功能键或数字2键DOWN PRESSED下功能键或数字8键LEFT PRESSED左功能键或数字4键RIGHT PRESSED右功能键或数字6键FIRE PRESSED开火功能键或数字5键GAME A PRESSED数字1键GAME B PRESSED数字3键GAME C PRESSED数字7键GAME D PRESSED数字9键 检测按键状态方法 intkeyCode this getKeyStates 获取键盘状态if keyCode GameCanvas UP PRESSED 假如是按上键 elseif keyCode GameCanvas DOWN PRESSED 假如是按下键 elseif keyCode GameCanvas LEFT PRESSED 假如是按左键 elseif keyCode GameCanvas RIGHT PRESSED 假如是按右键 当然 也可以使用位 与 的方法进行判断 intkeyCode this getKeyStates 获取键盘状态if keyCode GameCanvas UP PRESSED 0 假如是按向上键 elseif keyCode GameCanvas DOWN PRESSED 0 假如是按下键 elseif keyCode GameCanvas LEFT PRESSED 0 假如是按向左键 elseif keyCode GameCanvas RIGHT PRESSED 0 假如是按向右键 使用上述两种方法 都只能判断一个按键被按下的情况 无法判断多个按键被同时按下的情况 原因是 比如 当同时按下 上 和 右 按键的时候 得到的值既不是UP PRESSED也不是RIGHT PRESSED 改进方法如下 if keyCode GameCanvas UP PRESSED 0 keyCode GameCanvas LEFT PRESSED 0 左 上两个按键被同时按下 elseif keyCode GameCanvas UP PRESSED 0 keyCode GameCanvas RIGHT PRESSED 0 右 上两个按键被同时按下 elseif keyCode GameCanvas LEFT PRESSED 0 左键被按下 elseif keyCode GameCanvas RIGHT PRESSED 0 右键被按下 小提示 由于使用的是elseif判断 因此对多按键被同时按下的判断应放在单按键被按下的判断之前 比如 当同时按下左 上按键时 会有如下三个条件同时成立 keyCode GameCanvas UP PRESSED 0 keyCode GameCanvas LEFT PRESSED 0 keyCode GameCanvas UP PRESSED 0 keyCode GameCanvas LEFT PRESSED 0 如果单按键被按下的判断放在前面 那么后面的多按键被按下的情况就不再判断了 protectedGameCanvas booleansuppressKeyEvents 参数suppressKeyEvents用于指定是否支持MIDP1 0中的键盘响应事件 当参数取值为true时 指明不支持键盘响应事件 当用户操作键盘时 不会引起keyPressed keyReleased 和keyRepeated 这三个事件方法被调用 这样可以提高速度和性能 如果参数取值为false 那么一旦按键被按下 就会调用上述三个传统的键盘事件处理方法 在GameCanvas类中定义的九个表示按键状态码的静态属性常量中 并不包含键盘左上角的 左软键 和键盘右上角的 右软键 而这两个按键通常被用来响应 返回 暂停 退出 确定 等与用户交互的功能按钮 因此 在MIDP2 0中保留了对MIDP1 0中的按键响应机制 通常用于对 左软键 和 右软键 的响应 要点提示1 GameCanvas类的构造方法 要点提示1 绘制双缓冲区 1 在MIDP2 0中 GameCanvas类为每个实例对象提供唯一的图形缓冲区 缓冲区的大小与屏幕大小一样 每一个GameCanvas对象所拥有的缓冲区都是独立的 因此最好在游戏中仅创建一个GameCanvas类对象 并且重复利用 2 调用GameCanvas类的getGraphics 方法 可以获得绘制缓冲区的Graphics对象 3 调用GameCanvas类的flushGraphics 方法 可以将缓冲区中的内容绘制到屏幕上 4 2 4任务二 飞机移动时 实现形状的改变 知识准备 了解精灵类 精灵类 Sprite 被定义在javax microedition lcdui game包中 专门用来代表游戏中的动画角色 可以显示一帧或多帧的连续图像 但所有的帧都必须大小相同 并且由一个Image对象提供 比如 飞机在飞行时有三种不同的形状 正向飞行 向左侧飞行和向右侧飞行 将这三个形状不同 但大小相同 25 24 的小图片合成到一个Image对象中 每个小图片为一帧 帧的序号从0开始 并且按从左到右 从上到下的顺序依次排列 通过精灵类 Sprite 对象 可以任意显示其中某一帧的静态图像 或者连续地 循环显示任意顺序的某几帧 以实现动画效果 精灵类 Sprite 还提供了许多变换模式 翻转和旋转 以及碰撞检测的方法 能大大简化游戏逻辑的实现 知识提炼 精灵类构造方法 1 publicSprite Imageimage 说明 通过图像创建一个只含有一帧图像的非动画Sprite类对象 即只能显示一幅静态图像 利用该方法创建精灵类对象的目的 主要是利用Sprite类提供的方法 实现图像各种角度的翻转 碰撞检测等功能 参数 image为只含有一帧的图像 2 publicSprite Imageimage intframeWidth intframeHeight 说明 通过图像创建一个指定每帧图像大小的动画精灵类对象 该方法是最常用的 参数 image为包含多帧的图像 frameWidth和frameHeight分别为每一帧的宽度和高度 3 publicSprite Spritesprite 说明 通过一个精灵类对象创建一个新的精灵类对象 参数 sprite是一个已创建好的精灵类 要点提示 1 单帧图像处理publicvoidsetFrame intindex 其中 参数index为当前精灵类对象某一帧的序号 2 设置精灵位置并绘制精灵 publicvoidsetPosition intx inty 说明 将精灵类对象定位到屏幕上的任意位置 参数 x为横坐标 y为纵坐标 publicvoidpaint Graphicsg 说明 绘制精灵类对象的当前帧 参数 g为绘制上下文 4 2 5任务三 设计主角人物在屏幕上行走 任务准备 1 声明变量 2 在构造方法中实现初始化 3 绘制屏幕 4 响应键盘 5 启动线程 6 控制线程 7 测试运行 1 新建MIDlet类 类名为 Ch4 Unit1 MIDlet2 2 新建GameCanvas类 类名为 Ch4 Unit1 GameCanvas2 3 将主角人物图片资源文件man png 拷贝到工程的 res 文件夹下 实现过程 要点提示 1 多帧动画处理publicvoidsetFrameSequence int sequence publicvoidnextFrame publicvoidprevFrame 小提示 使用getFrame 方法可以获取动画播放帧序列中当前正在播放的图像帧序号 在实际应用中 可以使用该方法判断某一次动画的播放帧是否已经播放完毕 比如 爆炸效果 2 精灵的移动publicvoidmove intdx intdy 小提示 当多次使用move 方法移动精灵后 其在屏幕上的确切位置就有些模糊了 此时可以使用精灵类提供的getX 和getY 方法 来获取精灵的当前坐标位置 以此判断精灵是否移出了屏幕 即进行边界的处理 要点提示 int sequence 6 7 8 0 1 2 3 4 5 9 10 11 上 下 左 右播放帧序列 intdirection 1 行走方向0 上1 下2 左3 右 1 无方向 4 2 6延伸任务 控制主角人物 按键行走 释放站立 privatevoidcontrolFrame intdirection if frameIndex sequence direction length 1 frameCounter if frameCounter 0 frameIndex frameCounter 3 else frameIndex 1 跳过0帧 站立帧 spMan setFrame sequence direction frameIndex 设置帧 4 3子弹设计 在射击类游戏中 除主角和NPC之外 子弹是一个很重要的游戏元素 他可以自动地 源源不断地发射 或者按键触发后发射 其实 子弹只是一个特殊的游戏元素 使用与设计子弹同样的方法 可以设计任何形状的 与游戏角色相关的游戏元素 比如 潜水艇扔下的水雷 武士发出的暗器 天上飘落的雪花 大富翁游戏中掉落的金子等等 在本学习单元中 首先 通过Vector类进行子弹的设计 然后 通过自定义类的方法设计子弹 并指出两种设计方法在实现手段和执行效率及执行效果上的差别 最后 通过实现散弹 进一步学习精灵类对象在运行过程 进行图片的动态转换和对象的旋转 4 3 2使用Vector类设计子弹 知识准备 了解Vector类 Vector类位于java util包中 在J2MEMIDP2 0中 保留了J2SE中的Vector类 该类对用户隐藏了内存分配的细节问题 使用Vector可以作为需要动态生成对象的容器 而游戏中的子弹则是动态生成的最好例子 Vector有 矢量 媒介 载体 的含义 很多书上称之为 向量 但把他看成一个 容器 也许更形象一些 因为他能够像容器一样存放各种类型的对象 而且这个 容器 随着存放对象的多少 其长度可以动态地变化 从这个角度来说 Vector就是一个能够存放任意类型对象的动态数组 任务准备 1 声明子弹相关变量 2 在构造方法中加载图片 3 自定义创建子弹的方 4 自定义移动子弹的方法 5 自定义绘制子弹的方 6 在绘制屏幕的show 方法中 添加对上述三个方法的调用语句 实现对子弹的绘制 7 测试运行 1 新建MIDlet工程 工程名为 Ch4 Unit2 2 新建MIDlet类 类名为 Ch4 Unit2 MIDlet 3 新建GameCanvas类 类名为 Ch4 Unit2 GameCanvas 4 将飞机图片文件plane2 png 和子弹图片文件bullet png 拷贝到工程的 res 文件夹下 实现过程 知识提炼 Vector类的常用方法 1 构造方法 publicVector intinitialCapacity intcapacityIncrement 说明 通过参数构造一个Vector的动态数组 能设置动态数组的初始容量和递增增量 参数 initialCapacity为Vector动态数组的初始容量 capacityIncrement为Vector动态数的递增增量 publicVector intinitialCapacity 说明 通过参数构造一个Vector的动态数组 只能设置动态数组的初始容量 一般是增长目前大小的一倍 参数 initialCapacity为Vector动态数组的初始容量 publicVector 说明 构造一个Vector动态数组 参数 无 2 size方法语法 publicintsize 说明 返回当前Vector动态数组中的元素个数 参数 无 3 addElement方法 语法 publicvoidaddElement Objectobj 说明 把组件加到向量尾部 同时大小加1 向量容量比以前大1 参数 Objectobj是向动态数组中添加的对象 4 removeElementAt方法 语法 publicvoidremoveElementAt inti 说明 把第i个元素移出动态数组 同时 动态数组的大小减1 参数 inti为要移除的动态数组的第i个元素 5 ElementAt方法 语法 publicObjectElementAt inti 说明 返回Vector动态数组中的第i个对象 参数 inti为返回动态数组的第i个元素 返回值 返回Vector动态数组中的对象 注意 返回的对象要强制转换为自己所需要的类型 要点提示 privatevoidcreateBullet if distance 0 SpritespBullet newSprite imgBullet spBullet setPosition spPlane getX 10 spPlane getY vecBullet addElement spBullet distance 6 4 3 3任务五 使用自定义子弹 Bullet 类的方法设计子弹 任务四和任务五 采用不同的方法 实现了同样的效果 但要注意区别两者在实现方法和执行效率及执行效果上的差别 Vector类使用方便 但其对内存的频繁动态分配 在一定程度上会影响执行效率 并且放入Vector中的对象 一般都具有相同的属性和行为 比如 都按同一轨迹运行 而自定义子弹类的方法 则比较灵活 可以通过给定不同的子弹图片 定义各种不同形状的子弹 可以设计多种运行轨迹 使得不同的子弹可以按不同的轨迹运行 需要注意的是 Bullet类只是一个普通的JAVA类 并没有继承自精灵类 主要原因是精灵类占用内存空间比较大一些 而且运行起来比较慢 因此 在本任务中只声明了一个子弹精灵spBullet 而不是十五个 并该子弹精灵看成是一个 精灵图章 当需要显示15颗子弹中的某一颗时 只需在相应的位置上 盖 上对应的 精灵图章 即可 这样既节省了内存 又提高了运行效率 4 3 4延伸任务 实现散弹 知识提炼 2 精灵对象的旋转使用setTransform 方法可以实现精灵对象的旋转 语法格式如下 publicviodsetTransform introtating 其中 参数Rotating是由8个静态属性常量来表示 TRANS NONE 保持图像的原始位置 TRANS ROT90 顺时针旋转90度 TRANS ROT180 顺时针旋转180度 TRANS ROT270 顺时针旋转270度 TRANS MIRROR 沿着图片垂直Y轴翻转 TRANS MIRROR ROT90 沿着图片垂直Y轴翻转后 再顺时针旋转90度 TRANS MIRROR ROT180 沿着图片垂直Y轴翻转后 再顺时针旋转180度 TRANS MIRROR ROT270 沿着图片垂直Y轴翻转后 再顺时针旋转270度 1 精灵图片的动态转换使用setImage 方法可以在运行时 实现精灵图片的动态转换 语法格式如下 publicvoidsetImage Imageimg intframeWidth intframeHeight 其中 参数img表示要动态改变的图片对象 frameWidth和frameHeight是图片帧的宽度和高度 4 4NPC 非玩家控制的角色 设计 NPC 即非玩家控制的角色 比如 射击类游戏中的敌机 NPC的设计通常包括 形象设计 出现的时机 出现方式 运行轨迹 碰撞检测 生命值和得分等简单的数值设计 以及简单的AI设计等等 在本学习单元中 以射击类游戏中的敌机为NCP的特例 首先 对其的出现方式和运行轨迹进行设计 然后 通过添加时间轴 对其的出现时机进行了统一的安排和设计 接着 进行主角子弹和敌机的碰撞检测 最后 通过出现BOSS 进行简单的数值设计和AI设计 4 4 2任务六 出现敌机 队列 要点提示 敌机队形的设计 在本任务中 设计了四种队形 但实现方法都是类似的 要点是首先定位第一架敌机 后面的敌机位置分别是前一架敌机在x位置或y位置上间隔一定的距离 比如 斜线排列的队形 首先 定位第一架敌机的位置是 18 10 然后 后面的敌机分别在前一架敌机的右上侧 x方向上距离36像素 y方向上距离35像素 代码如下 spNpc1 0 setPosition 18 10 设置队列中第一架敌机出现的位置for inti 1 i spNpc1 length i spNpc1 i setPosition spNpc1 i 1 getX 36 spNpc1 i 1 getY 35 水平排列和垂直排列的方法与此类似 根据这个方法还可以设计出很多其他的队形 4 4 3延伸任务 添加时间轴 安排游戏情节 timing if timing 20 1 timing 20 7 npcPlane setNpc0Position spNpc0 screenWidth elseif timing 20 3 timing 20 9 npcPlane setNpcQueue1 spNpc1 elseif timing 20 4 timing 20 14 npcPlane setNpcQueue2 spNpc2 screenWidth screenHeight elseif timing 20 5 timing 20 15 npcPlane setNpcQueue3 spNpc3 screenWidth elseif timing 20 6 timing 20 18 npcPlane setNpcQueue4 spNpc4 要点提示 时间轴 在射击类游戏中 敌机的出现都应该是事先安排好的 在什么时刻出现什么敌机 什么时刻出现什么状态 例如 在本任务中 游戏开始1秒钟后 出现第一架敌机 过3秒钟后 出现敌机队列1 过4秒钟后 出现敌机队列2 这类似于游戏的脚本 从游戏的开始到结束 都贯穿着时间轴的概念 在时间轴的设计中 使用了记录时间的一个长整型变量timing 在每个线程周期中 该变量值就会增加1 因为每个线程周期为50毫秒 当timing的值为20 1时 就意味着过了50 20 1毫秒 即1秒钟 依次类推 当tming的值为20 2时 就意味着游戏开始后2秒钟 时间轴的实现方法 可以使用如任务中的if elseif结构 当然 也可以使用swtich结构 不管是什么游戏 都会有条 主线 例如 对于射击游戏 主线就是时间 对于RPG 角色扮演类 游戏 主线可能就是游戏的故事情节 而对于益智类游戏来说 主线则显得不是很明朗 例如五子棋游戏 那么他的主线就是根据玩家下的每一步棋子 来判断下一步应该怎么操作 4 4 4任务七 实现主角子弹和敌机的碰撞检测 要点提示 关于爆炸效果 程序中 每一架敌机都对应地定义了一个爆炸精灵 这是因为爆炸帧的播放需要一个过程 因此两架甚至多架敌机的爆炸效果可能会同时出现在屏幕上 所以爆炸精灵一般不共用 爆炸效果的绘制是一个逐帧绘制的过程 当最后一帧绘制完毕的时候 就应该停止 否则 爆炸效果会反复出现 精灵类提供的getFrame 方法 可以获取当前正在播放的帧索引号 当帧索引号再次变为0的时候 表示帧序列已经播放完毕 此时 应该再次设置当前的爆炸精灵为不可见 代码如下 if spExplosion getFrame 0 如果帧序列播放完毕 重新开始下一循环序列了 spExplosion setVisible false 知识提炼 publicfinalbooleancollidesWith Sprites booleanpixelLevel publicfinalbooleancollidesWith Imageimage intx inty booleanpixelLevel publicfinalbooleancollidesWith TiledLayert booleanpixelLevel 每种碰撞的检测都存在两种级别的检测模式 区域级模式和像素级模式 4 4 5任务八 出现BOSS 要点提示 1 数值设计在本任务中 设计Boss的初始生命值为100 被子弹击中一次 生命值就减2 直至为0 Boss爆炸 在玩家得分的设计上 击中一架敌机 得分加10 当Boss被击爆时 得分加100 2 Boss的AI设计在Boss完全移入屏幕之前 子弹击中Boss 其生命值是不减的 当Boss作水平移动时 碰到左右边界 会自动折返 当被子弹击中时 显示闪烁效果 并且移动速度变慢 4 5游戏背景设计 游戏背景设计是游戏的一个亮点所在 当拿到一款游戏的时候 这款游戏是否吸引人 由两个方面所决定 游戏的控制和游戏的背景设计 在MIDP1 0中没有提供专门负责背景设计的类 而在MIDP2 0中提供了一个TiledLayer类 该类专门负责对游戏背景进行管理和操作 由于移动设备的存储资源有限 因此不可能装载过大的图片来作为游戏的背景 本学习单元中 首先 通过一个图块 瓷片 铺设 单一的游戏背景 然后 使用由一块一块图块 瓷片 合成的图片 来 铺设 丰富的游戏背景 最后 学习使用地图编辑器 进行大型地图的设计 并显示在手机屏幕上 4 5 2任务九 使用一个图块 铺设 单一的游戏背景 知识提炼 TiledLayer类被定义在javax microedition lcdui game包中 该类代表一个背景图层 将背景所占区域分成大小相等的一系列单元格 每个单元格可被一个图块填充 最终构成一个组合成的大图块背景 1 背景的初步规划根据手机屏幕的大小 以及图块的宽 高 设计使用该图块铺满整个屏幕 横着需要多少个图块 竖着需要多少个图块 使用TiledLayer类的构造方法可以进行游戏背景的初步规划 TiledLayer类的构造方法语法如下 publicTiledLayer intcolumns introws Imageimage inttileWidth inttileHeight 2 背景的铺设为了形成背景 必须将图块填充到单元格中 通过调用setCell 方法可以为单元格设置引用的图块 语法如下 publicvoidsetCell intcol introw inttileIndex 3 背景的绘制背景形成后 需要通过paint Graphicsg 方法绘制出TiledLayer实例 要点提示 在本任务中 water png文件中只有一个图块 该图块的大小为30 30 整个屏幕都使用同一个图块进行填充 类似这种使用同一个图块填充一片连续区域的情况 也可以使用fillCells 方法来完成 语法如下 publicvoidfillCells intcol introw intnumCols intnumRows inttileIndex 因此 程序中如下的相关代码 for inti 0 i backCols i for intj 0 j backRows j tlgBackground setCell i j 1 可以使用如下这条语句进行替代 tlgBackground fillCells 0 0 backCols backRows 1 4 5 3任务十 使用合成图块 铺设 丰富的游戏背景 要点提示 本任务中 使用了由一个一个图块合成的图片文件进行地图的铺设 这些图块必须拥有相同的宽度和高度 每个图块按从左到右 从上到下的顺序分配一个索引号 索引号从1开始 小提示 如果使用索引为0去填充单元格 则表示该区域不填充 绘制任何东西 4 5 4任务十一 使用地图编辑器 设计大型地图 对于飞行射击类 角色扮演类等手机游戏 在设计游戏背景的时候 通常比手机屏幕要大很多 并且在游戏过程中 背景会自动地滚动 或者随着游戏主角的移动而移动 以增加游戏的动感 这样大的一个游戏背景 全凭想象来设计二维的地图数据 显然是不可行的 因此 在本任务中 通过借助于第三方开发的地图编辑器 来设计大型地图 将大大简化工作量和工作难度 比较常用的手机游戏地图编辑器有Mappy mapwin Tiled TILESTUDIO等等 这些地图编辑工具可以到相关网站免费下载 2 在手机屏幕上显示地图首先 将导出并修改的 map1 png 文件拷贝到 Ch4 Unit4 工程的 res 文件夹下 在 Ch4 Unit4 工程中新建类 类名为 Map1 打开 Map1 类 声明一个二维数组 并把map1 txt文件中的二维数组 map1 map0 的值拷贝过来 将原先声明的二维数组 mapData 删除 并将代码中所有引用该二维数组的地方 全部用 Map1 map1Data 替代 1 使用mapwin编辑地图新建地图导入图块铺设地图保存地图文件导出地图数据 实现过程 小提示 单击菜单 MapTools RemoveUnusedorDuplicate 可以在导出的图块文件中移除那些在编辑地图过程中没有用到的图块 4 5 5延伸任务 铺设多层地图 4 6滚屏设计 4 5 4的任务十一和4 5 5的延伸任务中 铺设的地图都比手机屏幕大许多 默认情况下 手机屏幕上显示的仅仅是地图的左上角部分 其余部分由于位于屏幕之外 而无法显示 如果能让屏幕 滚动 起来 不仅能逐渐展示完整的地图 丰富玩家的视觉效果 而且还可以根据游戏情节需要 切换游戏场景 增加游戏的动感 在本学习单元中 首先 实现游戏屏幕的自动滚动 了解实现滚屏的基本原理 然后 与任务八中完成的成果相结合 实现一个简单的滚屏飞行射击游戏 最后 实现RPG游戏中的滚屏效果 即屏幕随着游戏主角的移动而移动 4 6 2知识准备 了解层管理器 事实上 Sprite类和TiledLayer类的父类均是定义在javax microedition lcdui game包中的Layer类 Layer类是一个抽象类 表示游戏中的一个可视元素 图层 图层是可以在游戏画布中单独绘制并能够移动的对象 每个Layer类实例都有一定的位置 宽度 高度和是否可见的状态 Layer类的子类必须实现一个piant Graphics 方法 使得它们能够被绘制在屏幕上 游戏中不止一个图层存在 每个加入LayerManager中的图层都会被分配一个索引值 索引值从0开始顺序分配 就想排队一样 先加入的排在前面 后加入的排在后面 但需要注意的是 图层的绘制过程却是相反的 排后面的 即索引值大的 先绘制 排前面的 即索引值小的 后绘制 显然 后绘制的图层将覆盖先绘制的图层 另外 LayerManager中的图层索引号永远是连续的 如果一个图层从LayerManager中被移除 那么后面图层的索引号都将相应地作调整 以便使得图层索引号保持连续性 4 6 3任务十二 实现游戏屏幕的自动滚动 实现滚屏的原理 只需要在线程周期中不断改变可视窗口的x坐标 实现横向滚动 或者改变y坐标 实现纵向滚动 然后 将改变坐标位置后的可视窗口重新绘制在手机屏幕上即可 知识提炼 LayerManager类其他常用方法 1 LayerManager类构造方法 2 append方法 3 remove方法 4 getLayerAt方法 5 getSize方法 小提示 综合使用上述三个方法 可以实现将加入图层管理器对象中的图层全部清空的功能 清空图层管理器对象在RPG游戏的场景转换中非常有用 参考代码如下 publicvoidclearLayerManager if lm null while lm getSize 0 lm remove lm getLayerAt 0 System gc 垃圾回收 4 6 4延伸任务 实现滚动背景下的飞行射击效果 4 6 5任务十三 根据主角人物的位置 重置地图视角 要点提示 1 重置地图视角所谓 重置地图视角 就是根据主角的位置 重新设置可视窗口的位置 设置可视窗口的代码如下 lm setViewWindow viewX viewY screenWidth screenHeight 其中 参数viewX和viewY是可视窗口在地图层中的左上角坐标 这个坐标是根据主角行走时 在地图层中的位置来确定的 并保证主角在屏幕的正中间 就像舞台上的追光灯一样 追着舞台上的主角 使得主角始终位于灯光的中间 viewX spPlayer getX spPlayer getWidth 2 screenWidth 2 viewY spPlayer getY spPlayer getHeight 2 screenHeight 2 当然 如果主角的位置距离屏幕的上 下 左 右边缘小于屏幕高度和宽度的一半时 当主角继续按原方向行走时 屏幕就不再移动了 这时 viewX和viewY的值就始终是可视窗口在地图层中的边界值 viewX 0 左边界值viewX backCols 16 screenWidth 右边界值viewY 0 上边界值viewY backRows 16 screenHeight 下边界值 2 精灵与地图层的碰撞在本任务中 使用的地图有两层 0层是行走层 1层是碰撞层 主角在走动过程中 需要检测是否和碰撞层发生了碰撞 如果碰撞 则回退并站立 精灵和地图层的碰撞检测方法语法如下 publicfinalbooleancollidesWith TiledLayert booleanpixelLevel 在碰撞检测过程中 为了使效果更逼真一些 可以自定义精灵对象的碰撞区域 默认情况下 精灵对象的碰撞检测区定位在左上角 0 0 并与精灵对象的大小相同 自定义碰撞检测区域方法的语法如下 publicvoiddefineCollisionRectangle intx inty intwidth intheight 比如 本任务中 在进行主角和地图碰撞层的碰撞检测之前 首先自定义了主角精灵的碰撞检测区域 代码如下 spPlayer defineCollisionRectangle 0 spPlayer getHeight 2 spPlayer getWidth spPlayer getHeight 2 这样 就将主角精灵的碰撞检测区域定位在了下半身 当主角精灵的上半身和碰撞层中的房屋 数木 石头等发生重叠的时候 不会产生回退和站立的效果 使得主角在地图中行走的效果更加逼真 本章小结 通过完成本章任务 学习到了如何编写一个简单的游戏程序 知道了游戏的基本组成 和编程原理 1 GameCanvas类一款游戏首先要有一个画布GameCanvas 他有一下常用方法 GameCanvas booleansuppressionKeyEvents 方法用于创造一个指定相应按键事件模式的GameCanvas对象 protectedGraphicsgetGraphics 得到画布中脱机屏幕上用于绘制的Graphics对象 就是得到脱机画笔 flushGraphics 要求刷新屏幕 这时将脱机屏幕上的图像会被绘制到真实屏幕上 flushGraphics intx inty intwidth intheight 要求刷新屏幕上指定区域 这时脱机屏幕上指定区域的图像会被绘制到真实屏幕上 getKeyStates 得到当前按键状态 Sprite精灵类精灵类是在MIDP2 0中是非常重要的 为游戏人物 主角 NPC的实现提供了遍历 Sprite Imageimage 通过图像创造一个精灵Sprite对象 只是一个帧 Sprite Imageimage intframeWidth intframeHeight 通过图像创造一个精灵Sprite对象 这个对象通过对frameWidth和frameHeight值进行计算 得到一共多少帧 Sprite Spritesprite 通过另一个精灵类创建一个新的Sprite对象 setFrame intindex 设置当精灵类显示为指定的序号图像 Sprite精灵类setPosition intx inty 将精灵移动到x y点 print GraphicsG 将精灵的当前帧绘制到Graphics上 collidesWth Sprites booleanpixelLevel 判断当前精灵和另外s精灵是否发生碰撞 collidesWth TiledLayert booleanpixelLevel 判断当前精灵和一个tiledLayer类实例之间是否发生碰撞 collidesWth Imageimg intx inty booleanpixelLevel 判断当前精灵和一个Image类实例之间是否发生碰撞 TiledLayer瓷片类TiledLayer瓷片类为游戏背景设计带来了不仅是方便 而且还节省了系统资源 TiledLayer intcolumns introws Imageimage inttileWidth inttileHeight 该方法用于创造一个代表背景的瓷片类对象 setCell intcol introw inttileIndex 该方法用于为每个单元设定静态小图片fillCells intcol introw intnumCols intnumRows inttileIndex 使用特定的小图片填充特定区域中的单元格createAnimatedTile intstaticTileIndex 将一个静态索引创建一个动态索引号setAnimatedTile intanimatedTileIndex intstaticTileIndex 动态图块索引号与静态图块索引号建立关联层管理器LayerManager将所有相关的显示对象实例联系到一起 课后实训1 1 实现一只小鸟在蓝天白云间展翅飞翔的动画效果 小鸟出现的位置是随机的 在黑色的背景下 站着一个准备战斗的武士 按左键 武士出拳 按右键 武士踢腿 按下键 武士躺倒 3 实现飞机撞云的效果 在蓝天白云的背景下 绘制四朵云 飞机可以通过上 下 左 右按键控制移动 如果和云发生碰撞 则产生爆炸的效果 4 小人在一个滚动的背景上 从左向右行走 当走到背景的最右端时 自动转身 从右向左行走 课后实训2 综合调试 将 3 5 3延伸任务 和 4 6 4延伸任务 的成果进行综合调试 形成一款相对比较完善的射击类手机游戏作品 有闪屏 菜单 帮助 关于 加载进度条和飞行射击的游戏界面 进入游戏界面后 可以 暂停 继续 和 返回 主菜单界面 当BOSS爆炸后 出现 胜利 界面 6 在 综合调试 的基础之上 设计敌机和BOSS的子弹 并实现敌机 敌机的子弹和主角的碰撞检测及处理 敌机和BOSS的子弹在外形和运行轨迹上可以变化多样 提示 课后实训中的图片资源可以自行设计或从网上寻找 课后实训参看效果图
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!