Java游戏程序设计教程第13章-游戏设计案例详课件_第1页
Java游戏程序设计教程第13章-游戏设计案例详课件_第2页
Java游戏程序设计教程第13章-游戏设计案例详课件_第3页
Java游戏程序设计教程第13章-游戏设计案例详课件_第4页
Java游戏程序设计教程第13章-游戏设计案例详课件_第5页
已阅读5页,还剩33页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第13章游戏设计案例详解模拟钢琴游戏太空射击游戏点灯游戏案例一:模拟钢琴游戏钢琴游戏的类结构接下来要做的是:在木纹图像上画出一个个的琴键;然后给每个琴键编写一个演奏的play()方法。实例化一个琴键对象

在Piano类的构造方法Piano()中添加:Keykey_g=newKey();

addObject(key_g,300,180);为什么?实现琴键的动画效果

打开Key类的act()方法,在其中添加相应的琴键动画效果代码。给琴键添加声音效果

按下G键,发出“哆”的声音准备声音文件“3a.wav”在key类的act()方法中添加如下代码:publicvoidact(){if(Greenfoot.isKeyDown("g")){ //如果按下g键

Greenfoot.playSound("3a.wav"); //演奏声音文件“3a.wav”

setImage("white-key-down.png"); //显示键被按下的效果图片

}else{

setImage("white-key.png"); //显示键被松开的效果图片

}}完善琴键的声音效果如果一直按住G键,琴键对应的声音文件连续播放现实中的钢琴演奏是按下一个琴键,钢琴奏出一个音符,这个音符的长度不受琴键被按下的时间长短所控制。解决办法是先声明一个变量,用这个变量记录下某个琴键是否被按下的状态,然后在if条件判断时考虑这个状态变量的情况。通常人们将这种记录某个对象的状态值的变量称为标记变量,大多数情况下,标记变量是个boolean类型的变量,它只有true或false两种状态。编写多个琴键每个琴键对象对应一个电脑键盘按键和一个声音文件。钢琴有几十个键,需要在Key类的act()方法里面用几十组if语句来为每个琴键对象指定其电脑按键和声音文件,势必act()方法的代码会很长很复杂,有很多的代码重复。能不能在实例化生成每个琴键对象时,就指定这个琴键对象的电脑按键和声音文件呢?即编写一个通用的Key()构造器,使它能够将电脑按键和声音文件作为参数传入到构造器中,如Key(String

keyName,StringsoundFile),这样在创建每个琴键对象时就为其指定了电脑按键和声音文件。用循环添加多个琴键实现了通用的琴键Key构造器,就可实现多个琴键了inti=0;while(i<12){Keykey=newKey(“g”,“3a.wav);

addObject(key,54+(i*63),140); //每隔63个像素绘制一个琴键

i=i+1;}用数组来完善钢琴游戏目前为止,所有的琴键都是G键如何生成每个都不一样的琴键呢?即前面的循环语句中,如何向Key构造器中传入不同的键名和声音文件Keykey=newKey(“键名”,“声音文件);最好的办法是数组循环中需要每次循环传入不同的值,最好的办法是数组因为把数组的下标作为循环变量,就使得数组和循环二者结合起来了绘制黑色琴键黑色琴键是对应白色琴键的升半调音符设计一个黑色键名数组和一个黑色键音符文件名数组与白色键一样,黑色键也有两张图像在生成琴键对象的时候,就将琴键所对应的效果图片传入到其构造器中不用担心要在Key类的act()方法中使用麻烦的if语句来区分是黑色还是白色琴键使得Key类的act()方法更具通用性,使得程序更加易于扩展,如容易继续添加其它类型的按键案例二:太空射击游戏太空射击游戏中的类太空射击游戏对象关系图太空射击游戏类关系图源代码比较Ship、Enemy和Laser三个类三者的代码重复部分都有用setLocation(intx,inty)实现从一个位置坐标到另一个位置坐标的匀速直线运动Ship类和Enemy类之间,以及Enemy类与Laser之间的碰撞检测碰撞发生后有爆炸效果和战果记分的相关代码大部分是相同的,只有少许差异由此可能带来的问题setLocation(intx,inty)中的坐标从int型改成double型(这样就可以处理比较精确的小数了),这样的修改在三个类中都得修改程序扩展比较困难,如增加一个飞碟类Saucer飞碟Saucer类的代码与Ship类和Enemy类的基本相同哪个类中的代码有点问题,其它所有类都得同步修改代码重复问题解决最好办法:继承

继承是一种解决重复问题的机制首先,将Ship、Enemy和Laser三个类的共同部分抽取出来,单独地做成一个Sprite类然后,分别声明Ship、Enemy和Laser是这个Sprite类的子类最后再分别在Ship类里加上Ship自己独有的部分,在Enemy类里加上Enemy独有的部分,Laser也是如此Ship、Enemy和Laser三个类都继承Sprite类,它们都是Sprite类的子类三个类中共同的属性只需描述一次就够了子类的设计变得简单了,只需考虑自己的特有部分就行了,再也不用操心如何与其它类的代码保持一致的难题继承程序结构的类图运用继承后的游戏类图用抽象类来优化程序结构程序结构的进一步分析Ship、Enemy类的act()方法,发现两个类中都有关于碰撞检测、对象重新生成和游戏记分的功能代码与下面的伪代码是一致的,只是实现代码不同。如何优化?能否将它们抽象出来,归入Sprite类呢?Ship类和Enemy类中相同功能的实现代码不一样不能简单地将它们移植到超类中应该在更高的层次上将二者的雷同部分抽象出来然后归入到超类Sprite中解决办法——抽象类为两个类中的功能相同部分的代码设计一个名为处理碰撞的handleShotCollision()方法但是Ship类和Enemy类对于handleShotCollision()方法的具体实现代码可以不同。解决这个问题,需要用到Java中抽象类的技术案例三:点灯游戏需要考虑的问题牌桌上有两组扣起来的牌鼠标点任一张牌牌正面翻过来鼠标连续翻开两张牌灯泡阵列如何生成

翻开的牌不同牌自动扣起来牌桌上有两组扣起来的牌鼠标点任一张牌牌正面翻过来鼠标连续翻开两张牌灯泡的明暗转换

过关场景转换的问题

关卡的设计问题

灯泡对象的创建

怎样改变周围灯的明暗状态关卡的设计问题关卡设计游戏各个关卡的场景是一组灯泡阵列,因此将每一关的场景用一个三维整数数组bulb[][][]来表示。数组最外面一维(第一维)用整数0~4分别表示第一关~第五关,当然如果关卡数多,就用更多的数字。过关场景转换文字信息提示是过关场景转换的标志从最开始到进入第一关、从前一关进入后一关,以及游戏全部结束等几个状态的转换。几个状态转换时都应该给游戏者一些文字提示信息,表明现在是游戏开始,还是中间第几关,或者是游戏全部结束。

游戏根据游戏者的鼠标动作来决定游戏进程的流转

if(游戏界面上显示了文字){ if(游戏者用鼠标点击游戏面板){

进入下一关

}}//游戏者在玩游戏else{ if(面板上的等全部是亮的){

在面板上显示“过关”或“游戏全部结束”的文字信息

}}灯泡对象的创建游戏面板上的每一盏灯都是一个Light对象初始时,根据所处的关卡,每个Light对象预置其初始的明暗状态值。即Light类应该有一个boolean型的字段isON用来记录当前此Light对象的明暗状态。另外,准备两张表示灯泡明暗的图片,保存到项目文件夹中的images子文件夹。同时在Light类中设计两个GreenfootImage图片对象指向那两张图片。Light构造器需要传入创建这个Light灯泡对象时它应该的明暗状态值。publicLight(boolean

isOn){……}灯泡的明暗转换运行过程中,Light对象时刻捕捉当前游戏者的鼠标是否点击了此Light对象这个可以使用Greenfoot的静态方法mouseClicked(Objecto)来实现。当捕捉到鼠标对此Light对象的点击后,用代码将此Light对象的明暗状态进行切换。publicvoidswitchOnOff(){ //切换灯泡的明暗状态的方法

if(isOn){

isOn=false;

setImage(offImage);}else{

isOn=true;

setImage(onImage);}}灯泡阵列生成灯泡阵列的生成是:将三维数组bulb中的灯泡二维(4x4)阵列元素位置上的“1”或“-1”转换成灯泡对应的明暗状态图片,并显示在场景面板上。一个重要的问题:

bulb数组中灯泡二维阵列元素数值的坐标系该如何转换成游戏场景面板上的灯泡图片坐标系改变周围灯的明暗状态鼠标点击了面板上的一盏灯这盏灯周围的灯(包括它自己)的状态都要被切换也就是要找出这盏灯周围的所有灯Greenfoot中Actor有一个getNeighbours(1,false,Light.class)方法可以帮助编程者获取这盏灯周围距离为一个单元格范围内的所有Light对象的集合。需要设计一个List集合来保存这些找到的Light对象点灯游戏的对象关系图灯泡Light类的设计Light类的成员字段:保存灯泡明暗状态的boolean型的isOn属性字段两个GreenfootImage型的灯泡明暗图片对象onImage与offImage

面板Table对象中要检查面板上的所有灯泡是否全部被点亮所以Table对象要修改Light对象的isOn属性那么Light类中的isOn属性应该设计成public否则就设计专门的成员方法来实现从Light对象的外部来对Light成员属性的修改面板Table类的设计Tabel类的作用游戏各关卡场景的生成关卡状态的转换各关卡场景的生成每一关场景中的灯泡阵列由一个整型的三维数组决定三维数组是游戏设计者按照难易程度递增的原则制订出来的Table类Table的属性字段level——表示游戏关卡的第几关,游戏开始之前它的初值为0isEnded——用来判断游戏是否全部结束,其初值应该是falseTable的成员方法

游戏关卡状态判断点灯游戏各关卡之间的状态:检查游戏面板界面上是显示说明信息还是显示灯泡阵列。当显示说明文字时用鼠标点击面板界面,游戏进入灯泡阵列的界面,即进入下一关;当面板上的灯泡全部被点亮游戏又进入游戏的等待状态,即显示说明信息阶段。Table面板上灯泡全点亮如何判定Table上的灯泡全部被点亮遍历一堆的灯泡对象,显然需要用到本章学习的List集合。Greenfoot的World类提供了一个getObjects(java.lang.Class

cls)方法可以获得场景World中一个类的所有对象。Table类是继承World类的,所以Table对象可以调用这个getObjects(…)方法。在Table类的act()方法中完成灯泡全亮的检查先创建一个包括面板上所有Light对象的集合lights,然后用for循环遍历集合lights,检查每一盏灯泡是否全部被点亮。List<Light>lights=getObjects(Light.class);for(Lightlight:lights){

isAllOn=isAllOn&light.isOn;//遍历检查每一盏灯泡,看是否完成关卡}游戏文字信息类Text的设计Text负责向游戏面板上显示该显示的文字说明信息Green

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论