版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
学习情境手机游戏的控制第一页,共四十一页,编辑于2023年,星期二能力目标能熟练实现线程、启动和停止线程以及合理控制线程的执行;使用脱屏画布实现绘制双缓冲区技术;能熟练地制作进度条;学会使用getInstance()的方法获得对象实例;能熟练地在Displayable界面中加入所需按钮,移除不需要的按钮;能在代码中使用if语句或switch语句区分不同的按钮,以实现不同的功能;完成从菜单进入相应游戏界面,再从游戏界面返回菜单的操作;正确实现游戏的开始、暂停、继续、重玩和返回功能;能快速搭建起手机游戏的制作框架。第二页,共四十一页,编辑于2023年,星期二认知目标了解多线程的概念以及线程的四种状态;理解可变图像和不可变图像的区别;识记创建脱屏画布、获取脱屏画笔的方法;了解对象池的概念,理解制作进度条的核心思想;了解MIDP框架中对事件的处理机制,熟记实现事件处理的三个步骤;识记CommandListener事件监听器的注册方法和在该监听器接口中定义的commandAction()方法;了解ItemStateListener和ItemCommandListener事件监听器的注册方法和实现方法;理解游戏状态变量在游戏控制中发挥的作用。第三页,共四十一页,编辑于2023年,星期二3.1学习情境描述在游戏开始前,通常需要完成对资源的加载操作,载入资源会出现一定的等待时间。在游戏中,通常使用进度条的方式来提示用户:“正在进行资源载入,请耐心等待!”。在从菜单进入游戏界面,以及在游戏过程中界面之间的切换、游戏进程的“开始”、“暂停”、“继续”、“返回”、“退出”等,则通常使用按钮的方式实现对用户操作的响应。在一款手机游戏中,存在很多关于游戏的控制环节。本学习情境分为四个学习单元来完成。单元一,响应菜单命令;单元二,使用线程控制游戏进程;单元三,制作游戏加载进度条;单元四,搭建手机游戏制作框架。第四页,共四十一页,编辑于2023年,星期二3.2响应菜单命令在游戏屏幕的左下角或右下角通常会有一些类似“确定”、“取消”、“退出”、“返回”等操作的提示,称之为“功能按钮”。用户通过按下键盘上的“左上”或“右上”功能键来响应这些“功能按钮”。使可视界面组件“活”起来,使之具备与用户交互的能力,成为用户与手机游戏沟通的桥梁。“功能按钮”可以是Command组件构造的,也可以是一个绘制的图片,当然也可以是直接“写”上去的提示文字。本学习单元的主要任务:在游戏界面上添加各种形式的按钮,并通过这些“功能按钮”,从菜单项进入到游戏界面,再从游戏界面返回到主菜单。第五页,共四十一页,编辑于2023年,星期二事件:一个事件描述了一个对象状态的改变。例如:点击按钮。事件源:产生事件的对象。当这个对象的内部状态改变时,事件就会产生。事件监听器:当一个事件发生时,对事件做出响应的对象。在对应的事件监听器模型中,事件源和事件监听器是通过注册联系在一起的。一个事件源必须注册一个事件监听器,这样当事件发生时,系统会自动传递事件,调用事件监听器中定义的方法来处理事件。在java.microedition.lcdui包中共定义了三种事件监听器,以接口的形式存在,分别为:CommandListener、ItemStateListener和ItemCommandListener。
CommandListener事件监听器事件源:Displayable对象(而不是Command按钮)。注册方法:setCommandListener(CommandListenerl)接口方法:publicvoidcommandAction(Commandc,Displayabled)ItemStateListener事件监听器事件源:Form类及其扩展类。注册方法:setItemStateListener(ItemStateListenerl)接口方法:publicvoiditemStateChanged(Itemitem)
ItemCommandListener事件监听器事件源:Item类的子类。注册方法:setItemCommandListener(ItemCommandListenerl)接口方法:publicvoidCommandAction(Commandcommand,Itemitem)3.2.2知识准备:事件处理总之,在MIDP框架中实现事件处理需要做如下三件事情:在类定义中加入implements子句,表示在该类中要实现接口。注册事件监听器。实现接口中的方法,完成对事件的处理。第六页,共四十一页,编辑于2023年,星期二3.2.3任务一:使用Command按钮响应菜单命令
第七页,共四十一页,编辑于2023年,星期二知识提炼:Command界面组件Command组件的构造方法如下:publicCommand(Stringlabel,intcommandType,intpriority)参数说明:label:标签字符串,表示显示在按钮或菜单上的文字。commandType:按钮类型。分别为SCREEN、BACK、CANCEL、OK、HELP、STOP、EXIT和ITEM。请注意这些类型常量仅仅提供一个标识,并不会真正实现相应功能,具体功能需要通过代码来实现。priority:优先权。值越小代表优先权越高,1代表最高优先权。如果存在多个按钮需要布局在窗体上,其布局位置根据优先权决定。但实际的布局位置由设备决定。多于两个以上的按钮将构成菜单。如果两个按钮类型相同,则优先权的取值应不同。在Displayable界面中加入Command组件的方法如下:publicvoidaddCommand(Commandcommand)参数command为事先定义好的Command组件实例。第八页,共四十一页,编辑于2023年,星期二要点提示如果一个Displayable对象注册了CommandListener事件监听器,那么,点击该Displayable界面上的所有Command按钮都会触发同一个commandAction()方法的执行,因此在该方法中通常要用if语句或switch语句来区分不同的按钮,以实现不同的功能。区分方法有多种,比如:if(command.getCommandType()==Command.EXIT){}该方法是通过在定义按钮时设定的按钮类型来区分各按钮。请注意,如果同类型按钮有多个,该法就不适用了。if(command.getLabel().equals("Exit")){}该方法是通过按钮表面的提示文字来区分各按钮。if(command==cmdExit){}该方法是通过使用事先定义好的按钮名称来区分各按钮。第九页,共四十一页,编辑于2023年,星期二3.2.4延伸任务:返回主菜单第十页,共四十一页,编辑于2023年,星期二要点提示MIDlet类实例是在手机游戏运行前,由系统构造的,在游戏运行期间是唯一的。也就是说,MIDlet类实例不能由用户构造。因此,在本任务中,通过声明一个静态的MIDlet类实例instance,并在构造方法中进行实例化。这样,就可以在其他类中直接通过MIDlet类的类名进行调用。在手机这样的资源受限设备中,要严格控制使用new方法实例化对象的次数。而且使用new方法生成的两个对象实际上是两个独立的个体,在操作上不会实现同步。因此,在本任务中,通过构造方法参数来传递返回对象,将需要返回的界面(myMenu)作为参数,传递到About类对象中。这样,在进入About界面前,和从About界面返回后,显示的是同一个菜单界面实例。这一点,可以从返回前后,当前菜单项都是“关于游戏”得到验证第十一页,共四十一页,编辑于2023年,星期二3.2.5任务二:使用图片或文字按钮响应菜单命令第十二页,共四十一页,编辑于2023年,星期二要点提示
Command组件构造的“功能按钮”可以加在所有Displayable类的子类上,包括高级界面组件和低级界面组件。响应这类按钮需要由Displayable对象注册一个CommandListener事件监听器,然后通过实现在该接口中定义的commandAction()方法进行按钮的响应。而由图片和文字构造的“功能按钮”只能加在低级界面(Canvas和GameCanvas)上。在实际的游戏开发中,设计并使用与游戏整体风格相适应的图片或文字按钮,会使游戏界面更加美观、更具个性。当用户按下键盘上的“左上”或“右上”功能键去响应这类按钮时,系统会自动响应,并调用相应的按键处理方法(比如:keyPressed()方法)进行处理。第十三页,共四十一页,编辑于2023年,星期二3.3使用线程控制游戏进程游戏有一定的帧频,需要通过线程来控制。在本学习单元中,首先,通过多闪屏的实现,来学习使用线程;然后,再对游戏时间进行倒计时的控制,进一步熟悉线程;最后,对线程进行深入使用,实现对游戏的开始、暂停、继续和重玩的控制。第十四页,共四十一页,编辑于2023年,星期二3.3.2知识准备:了解多线程多线程允许在程序中并发执行多个处理流程,每个处理流程都成为一个线程,彼此间相互独立。多线程的好处在于可以提高CPU的利用率。但也必须认识到使用多线程可能带来的不利因素,比如:线程也是程序,需要占用内存。多线程需要协调和管理,线程太多会导致控制太复杂。线程之间对共享资源的访问会产生冲突。第十五页,共四十一页,编辑于2023年,星期二3.3.3任务三:实现多闪屏第十六页,共四十一页,编辑于2023年,星期二要点提示1:线程的实现在Java中实现线程有两种途径:继承java.lang.Thread类,然后改写run()方法实现java.lang.Runnable接口,实现接口中的run()方法由于Java语言不支持多继承,所以继承java.lang.Thread类的方法有一个最大的缺点就是不能再继承其他的类。而实现java.lang.Runnable接口的方法只需在已有类的基础之上多实现一个run()方法,没有其他多余的负担。因此建议多使用该方法实现线程。第十七页,共四十一页,编辑于2023年,星期二要点提示2:线程的启动和停止启动线程:Threadt=newThread(this);t.start();停止线程:正常情况下,run()方法返回时,线程自动停止。调用stop()或destroy()方法也可使线程停止,但会产生异常,且不会释放同步资源,所以不推荐使用。第十八页,共四十一页,编辑于2023年,星期二要点提示3:线程的控制在run()方法中,线程通常使用一个while循环来控制。在循环的开始,获取一次循环的开始时间(st)。循环的最后,获取本次循环的结束时间(et)。如果结束时间和开始时间的差值(diff=et-st),小于每一帧的指定时间(rate),就让线程休眠一个(rate-diff)的差值时间。这样可以强制使每一帧运行时间固定,避免游戏产生忽快忽慢的晃动感觉。第十九页,共四十一页,编辑于2023年,星期二3.3.4任务四:实现游戏时间的倒计时第二十页,共四十一页,编辑于2023年,星期二知识提炼:脱屏画布脱屏画布其实就是通常所说的绘制双缓冲区技术,是计算机动画的一项传统技术。在动画制作中,造成屏幕闪烁的主要原因在于,画面在显示动画的同时,程序又在改变它。如何解决这个矛盾呢?通常的做法是在内存开辟一片区域作为后台画面,程序对它进行更新、修改,完成后再在屏幕上显示它。创建、使用脱屏画布的关键步骤如下:(1)创建脱屏画布Imagebuffer;buffer=Image.createImage(SCREENWIDTH,SCREENHEIGHT);(2)获取脱屏画笔GraphicsoffG=buffer.getGraphics();(3)改变脱屏画布内容offG.drawXXX();(4)将脱屏画布内容显示到屏幕上g.drawImage(buffer,0,0,g.LEFT|G.TOP);第二十一页,共四十一页,编辑于2023年,星期二3.3.4任务五:
控制游戏的开始、暂停、继续、重玩和返回游戏进行中游戏暂停游戏结束第二十二页,共四十一页,编辑于2023年,星期二要点提示游戏的运行与停止、暂停与继续,分别通过一个开关变量来控制。在程序中,使用了boolean型变量isRun表示游戏是否进行中,变量isPause表示游戏是否暂停。在run()方法中,使用isRun变量作为while循环的条件,当游戏没有暂停的时候(!isPause),实现正常的游戏功能。当按下“暂停”按钮时,设置isPause变量的值为true。此时while循环中的if(!isPause)条件就不再成立,下面的语句也就不再执行。但while循环还在继续,线程并没有结束。当按下“继续”按钮时,isPause变量的值又变为false,if(!isPause)条件成立,继续游戏。当gameTime变量小于等于0时,设置isRun变量值为false,此时while循环结束,线程也随之停止,游戏结束,显示“重玩”按钮。当按下“重玩”按钮时,调用init()方法重新初始化游戏,重新开始线程。第二十三页,共四十一页,编辑于2023年,星期二3.3.6知识拓展:了解MIDlet的生命周期
Java应用管理器(JAM)是管理Java应用的机制,它负责将MIDlet装载进来,生成一个MIDlet对象实例。该对象的生命周期完全由JAM控制。MIDlet应用程序的构造方法仅被JAM调用一次,开发人员不能通过new方法随时调用。通常将需要在程序启动时执行一次且只执行一次的操作放在构造方法中,用来初始化MIDlet状态。一个MIDle对象有三种状态:运行状态、暂停状态和终止状态。
MIDlet类中声明了三个抽象方法:
startApp():用于启动或重新启动一个MIDlet。该方法可以被系统在任何时候调用,其目的是请求或重新请求运行MIDlet所需要的资源。
pauseApp():用于暂停一个MIDlet的运行,以释放此MIDlet占用的资源而用于其他MIDlet的运行。
destroyApp():在MIDlet即将被撤消时由系统调用,也可由MIDlet自身间接调用,其目的是在MIDlet撤消前释放该MIDlet所占资源
需要说明的是,这三个方法体默认都是空的,想要实现开始、暂停和释放资源的功能,需要用户自行添加相应的功能代码。
JAM通过调用startApp()使MIDlet进入开始状态,调用pauseApp()使MIDlet进入暂停状态,调用destroyApp()使MIDlet进入终止状态。需要说明的是,这三个方法体默认都是空的,想要实现开始、暂停和释放资源的功能,需要用户自行添加相应的功能代码。
MIDlet类中还定义了notify系列函数,用于请求状态的转换。notifyPaused():MIDlet可以使用该方法通知JAM,MIDlet对象将自动进入暂停状态。resumeRequest():调用该方法可以使MIDlet对象从暂停状态重新进入激活状态。调用该方法时,应用程序一般处于暂停状态,但即使处在暂停状态的应用程序也可以处理异步事件,比如定时器timer。notifyDestroyed():该方法通知MIDlet对象已经释放了所有资源,并已将缓冲区数据保存到了永久存储记录中,已经进入中止状态。通常在调用该方法前,先调用destroyApp()方法,在该方法体中完成清除工作。第二十四页,共四十一页,编辑于2023年,星期二高品质的游戏依托于高品质的画面和音效等游戏资源,但手机毕竟属于资源受限设备,在载入这些高品质的游戏资源时,将会出现用户界面的停滞,用户会误以为程序不响应或者是死机了。此时,就需要使用某种方式来提示用户资源的载入情况。比如,可以使用进度条来提醒用户正在进行“读取数据”或“载入资源”。
在本学习单元中,首先,通过高级用户界面接口中的Gauge界面组件来制作简单的进度条;然后,再使用填充矩形框的方式,通过查询资源载入情况,来实时控制进度值。
3.4制作游戏加载进度条第二十五页,共四十一页,编辑于2023年,星期二3.4.2任务六:用Gauge界面组件制作进度条第二十六页,共四十一页,编辑于2023年,星期二知识提炼
Gauge界面组件的构造方法如下:publicGauge(Stringlabel,booleaninteractive,intmaxValue,intinitalValue)由于NoneInteractiveGauge类继承了Gauge类,因此在构造方法中,需要首先实现super()方法,以调用父类Gauge类的构造方法,语句如下:super("",false,10,0);第二十七页,共四十一页,编辑于2023年,星期二要点提示显然,交互的Gauge进度条是不能反映游戏加载情况的。而非交换的Gauge进度条,其进度值按照线程中设定的增幅和频度自动完成递增过程,不管游戏资源是否加载完毕,进度值的递增频率是不变的。这样的进度条实际上也并不能真实地反映游戏资源的加载情况。第二十八页,共四十一页,编辑于2023年,星期二3.4.3知识准备:了解对象池的概念象手机这样的资源受限设备,内存是很紧张的。如果在游戏进行过程中,还需不断地动态生成对象或载入资源,游戏就会停滞,影响体验效果。所以在程序中应尽量使用预先分配好的资源,而不是在使用时动态分配。比如,可以在游戏主程序的构造方法中,把需要动态产生的对象、资源都预先静态生成,形成一个“对象池”,再在需要的时候使用它们。这样,在游戏开始前,会产生片刻用户界面的停滞。而游戏一旦开始,就不会再出现停滞现象。如果游戏资源都是在类的构造方法中预先静态生成,那么只要资源载入没有完成,类就不会构造成功。此时,查询类的实例,就是一个空值。相反,如果类构造成功了,说明资源已经载入完毕,查询的结果也就不会是空值了。第二十九页,共四十一页,编辑于2023年,星期二3.4.4任务七:使用填充矩形框的方式制作进度条第三十页,共四十一页,编辑于2023年,星期二要点提示1:关于getInstance()方法在程序中,类的实例通常使用“New构造方法”的方式来创建。如果一个类被多个其他类调用,那么就会在程序中产生这个类的多个实例。在本任务中,采用自定义一个静态的getInstance()方法来获得类的实例。这样就可以做到在整个程序中只存在一个类的实例。因为在静态方法中,只能使用静态变量,所以在程序中,首先定义了一个静态的类变量instance,在getInstance()方法中,判断该变量是否为空,如果为空,则先使用构造方法创建实例,然后返回;如果不为空,则直接返回该变量。方法如下:privatestaticGameBodyinstance;publicstaticGameBodygetInstance(){if(instance==null){instance=newGameBody();}returninstance;}第三十一页,共四十一页,编辑于2023年,星期二要点提示2:关于进度条前进的间隔
程序在正常载入资源的状态下,进度条前进间隔按每100ms增加5的速度递增。如果进度值还没有到达100%,但资源已经加载完毕,就加大进度条前进的间隔,以加快前进速度。if(GameBody.getInstance()!=null){step+=50;}
如果进度值已经到达100%,但资源加载还没有完毕,进度值就减小1,使其处于99%的状态等待。就像大多数Windows安装程序一样,最后的1%总是要花费较长的时间等待。
if(progress>100){//如果进度值已经到了终值(100)
if(GameBody.getInstance()==null){//如果游戏还未加载完毕
progress-=1;//进度值减小1,在99%处等待。
}else{//如果游戏已经加载完毕
break;//结束while循环
}}第三十二页,共四十一页,编辑于2023年,星期二3.5搭建手机游戏制作框架
在前面的各项任务中,分别完成了闪屏、菜单、帮助、关于、进度条和游戏倒计时界面的制作。在本学习单元中,首先,把这些界面类快速地关联起来,构成一个简单的手机游戏框架;然后,再进行任务重构,通过状态变量来区分游戏进程中的各个过程,将在这些界面类中分别实现的功能,有序地合并到一个Canvas类中完成。使得代码紧凑有序,不仅提高了代码的质量,还减少了垃圾回收的负担。第三十三页,共四十一页,编辑于2023年,星期二3.5.2任务八:快速搭建手机游戏制作框架第三十四页,共四十一页,编辑于2023年,星期二3.5.3延伸任务:使用状态变量控制游戏进程菜单界面
游戏加载
关于游戏游戏帮助在本任务中,将上述各界面类合并到一个Canvas中完成。通过状态变量m_UIState来区分游戏进程中的各个过程。m_UIState变量的值和游戏进程之间的对应关系如下表所示。闪屏界面
第三十五页,共四十一页,编辑于2023年,星期二本章小结1/51.在Java中实现线程有两种途径:一种是继承java.lang.Thread类,然后改写run()方法;另一种是实现java.lang.Runnable接口的run()方法。线程通过start()方法启动,在run()方法中控制。当run()方法运行结束,线程相应终止。2.脱屏画布就是通常所说的绘制双缓冲区技术,能有效地缓解屏幕闪烁。创建、使用脱屏画布的关键步骤如下:(1)创建脱屏画布Imagebuffer;buffer=Image.createImage(SCREENWIDTH,SCREENHEIGHT);(2)获取脱屏画笔:GraphicsoffG=buffer.getGraphics();(3)改变脱屏画布内容:offG.drawXXX();(4)将脱屏画布内容显示到屏幕上:g.drawImage(buffer,0,0,g.LEFT|G.TOP);第三十六页,共四十一页,编辑于2023年,星期二本章小结2/53.Gauge界面组件是Item类的子类,是一个采用条形图代表具体取值的进度条,可以被放置在Form组件中。Gauge界面组件可以是交互的,也可以是不交互的。Gauge界面组件的构造方法如下:
publicGauge(Stringlabel,booleaninteractive,intmaxValue,intinitalValue)4.制作进度条的核心思想是:如果游戏资源都是在类的构造方法中预先静态生成,即形成一个“对象池”。那么只要资源载入没有完成,类就不会构造成功。此时,查询类的实例,就是一个空值。相反,如果类构造成功了,说明资源已经载入完毕,查询的结果也不会是空值了。在运行时,如果进度值还没有到达100%,但资源已经加载完毕,就应该加大进度条前进的间隔,以加快前进速度。如果进度值已经到达100%,但资源加载还没有完毕,应该使进度条始终处于99%的状态等待。第三十七页,共四十一页,编辑于2023年,星期二本章小结3/55.在java.microedition.lcdui包中共定义了三种事件监听器,以接口的形式存在,分别为:CommandListener、ItemStateListener和ItemCommandListener。在MIDP框架中实现事件处理需要做如下三件事情:(1)在类定义中加入implenents子句,表示在该类中要实现接口
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年中化石油广东有限公司招聘备考题库及一套完整答案详解
- 2026年常州市教育系统“优才计划”公开招聘教师备考题库及答案详解参考
- 2025年南海经济开发区人民医院招聘事业单位聘用制(编制)工作人员备考题库(第二批)参考答案详解
- 2026年广安市武胜县公证处招聘非在编公证员助理的备考题库附答案详解
- 2026年广东省广业检验检测集团有限公司面向社会招聘党群人力部(董事会办公室)董办经理备考题库及1套参考答案详解
- 2026年卢阿拉巴铜冶炼股份有限公司招聘备考题库附答案详解
- 2026年中国中医科学院望京医院公开招聘国内应届高校毕业生(提前批)备考题库及一套参考答案详解
- 2026年台州市椒江区进出口企业协会公开招聘编外工作人员备考题库及完整答案详解1套
- 2026年古田县人力资源和社会保障局关于公布古田县事业单位公开招聘紧缺急需人才26人计划的备考题库及参考答案详解
- 2026年北矿新材科技有限公司招聘备考题库及一套答案详解
- 2025马年元旦新春晚会活动策划
- 交警新警执法培训
- 骨科护理标准操作流程手册
- 产品推广专员培训
- DB65T 3119-2022 建筑消防设施管理规范
- 书黄筌画雀文言文课件
- 文体局非遗传承人评选方案
- 陪诊师医学知识培训总结课件
- 2024-2025学年江苏省苏州市高二上学期学业质量阳光指标调研数学试卷(解析版)
- 项目验收过程标准化手册
- 土地复垦项目施工组织设计方案书
评论
0/150
提交评论