返回信息流附件(3.4MB) asteroid3d.exe
..............................
......................
舍不得BUPT。
好地方啊!
这是一条镜像帖。来源:北邮人论坛 / flash / #1574同步于 2026/6/14
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Flash机器人发帖
大四滚蛋,留个作品,大家共同学习!
saizna
2026/6/14镜像同步3 回复
订阅后,新回复会通过你的通知中心匿名送达。
3 条回复
【 在 saizna 的大作中提到: 】
:
: ..............................
: ......................
: ...................
附件(3.5MB) introduce.exe
标 题
Flash 网络游戏设计
内容提要:
在本游戏中,我们所扮演的是一名太空突击队员,我们的任务是绕地球飞行,消灭有可能坠落地面并严重破坏下面居民的小行星。我们将缓慢绕整个地球飞行。飞行和驾驶通过简单的鼠标移动来实现。我们移动鼠标时,屏幕上的十字准星也跟着移动,飞船追随十字准星移动。这个游戏的整体效果是一个具有高级动作的非常平滑的,交互式的3D体验。
在本作中,首先会涉及一些有关FLASH的资料,之后依次是:脚本的制作,角色的开发以及详细代码的应用。
关键字:Flash,3D
English version
In this game, we are going to play an aero plane attacker; our mission is flying around the earth, and destroys all the asteroids which is to attack the people who lives behind on the earth. Flying and driving is realized by the movement of mouse. When we shift the mouse, the cross on the screen is moving too, the aero ship follow the cross. this game is smooth and equipped with high Tec motions, makes you fell in 3d scene.
In this passage, at first we will touch some introduce about FLASH, and then, the first plan ,character explore , and the use of all the code.
KEY WORDS:Flash 3D
Flash网络游戏设计
第一部分:Flash及其游戏概论
自问世以来,Macromedia Flash就以其开发周期短,下载迅速,良好的跨平台开发功能,易于使用和强大的处理能力的特点,颇受广大用户的青睐,并很快成为在线游戏程序开发平台中的最佳选择。目前各种各样的Flash游戏数目非常多,各种Flash game按照不同的分类,策略类、动作游戏类、冒险类、射击类、体育类、益智类和五花八门类(一些其他无法分门别类的游戏)。虽然分类不算很多,但它收集的数量却比较多而且都是一些比较好玩和经典的游戏。策略类游戏,考验用户的战略统筹能力!动作类游戏,加强手指反应能力!冒险类游戏,充满惊险与趣味!射击类游戏,刺激而震撼!体育类游戏,让你亲身体验竞技的精神!益智类游戏,考验你IQ和智慧。 ,每种游戏都是妙趣横生。一些传统的游戏,例如魂斗罗、极品飞车等都有Flash版的游戏。而且有了专门的发布Flash游戏的网站,游戏种类非常之多,少则上百个,多则上千个Flash游戏。
Flash游戏不仅种类众多,而且它操作比较简单,趣味性也比较强。Flash制作的游戏画面有趣生动,而且一般都伴有轻松滑稽的音乐,加之其操作简单,一般只需要用鼠标或者上下左右移动键就可玩游戏,因此Flash游戏受到了越来越多人的喜欢。Flash受到普遍欢迎更为重要的是此类游戏一般都是免费的,在线玩或者下载了玩都行,不需要支付任何费用,也不需要买光盘安装。茶余饭后,打开电脑,进入到Flash游戏中,想玩多长时间就玩多长时间,不需要担心点卡的费用,也不需要担心玩的时间太短升不了级。
在Flash游戏风行的时候,传统的小游戏仍然有其市场。现在比较受欢迎的是"幻想游戏",其中包括多种小游戏,有宝石游戏、泡泡龙、砖块游戏等等,另外牌类游戏也依然受欢迎。
在游戏公司任职的沈嘉表示,这类小游戏包括Flash游戏的流行主要是由于它满足了人们休闲的需要,在紧张工作之余休闲类的小游戏能够给人带来最大程度的放松。
我们大致介绍了FLASH游戏的一个简单分类,通过这个分类的介绍,我们惊讶地发现,FLASH游戏种类的丰富性与它涉及领域的广泛性。当然,我们只要在搜索引擎中加入“FLASH游戏”这几个字进行搜索的话,就会发现出来的结果中,与“小游戏”这三个字是最紧密的。也许“小巧灵活”,就是FLASH游戏的第一个特性。
一个FLASH游戏文件,小的100多K甚至几十K,大的也不过几百K。这些游戏一张软盘就可以拷下,更不要说如今已经十分普及的优盘了。或者打个包放到邮件里寄出去,
也是十分方便的事。正是因为这样,一旦有好玩的FLASH的游戏,很快就可以传播出去。
FLASH游戏的第二个优点就是不需要安装。相信喜欢玩游戏、但电脑又不太精通的朋友一听到游戏安装就会头疼。且不说那么多复杂烦琐的安装过程,有时再碰上一些操作系统不兼容、显示模式不正确的技术问题,许多人就会头大。但是到了FLASH这里来,一切就简单了,文件拷过来就可以,如果在网上,打开网页就可以玩,这种省时省力的游戏到哪里去找啊。尤其会受到最烦技术名词的MM们的喜爱。
由此我们又发现了FLASH游戏的第三个优点,就是隐蔽。这可以办公一族的最爱。互联网时代,作为老板,你可以禁止我在电脑上装游戏,但不能禁止我装浏览器,你可以禁止我开QQ聊天,但没办法不让我上网看网页。好了,能看网页就可以玩玩FLASH游戏,虽说比不上红警、CS的火爆,但是丰富多彩的FLASH游戏中总会有各人喜爱的一种的。
再说一点原本是作为FLASH游戏的缺点的,就是游戏偏小,偏简单。但对于很多人来说,这一点却往往又会成为优点。因为许多大型游戏正因为太精彩、太好玩,往往会让人入迷。而且玩一局动辄一两个小时,长则半天,容易耽误事。而小巧精致的FLASH游戏,往往会成为我们在茶余饭后的消遣项目。真正地起到了放松心情、娱乐休闲的作用,可以说是对游戏的应用起到扬善避害的效果。
第二部分:制作游戏的一些基本理念
在Macromedia Flash MX 2004中创作游戏是任何一位有抱负的或经验丰富的程序员最有价值的努力之一。无论是为了看到某个想法得以实现的感受,还是为了客户开发的特定项目,或者是纯艺术性表现自己的一种看法,其中的制作都很有价值。
对于开发FLASH游戏的,无论是处于什么样的目的,Flash都会为我们提供最理想的方法来完成这项任务。他的界面非常简单而且易于使用,编程语言不仅健壮而且功能强大,掌握起来也非常简单,使用Flash创作游戏还能让我们在几分钟内为数百万的用户配置游戏。
不可否认,制作游戏是非常有趣的,一旦我们克服了技术上的障碍,没有什么比观看自己的创作和把想法变成现实更另人愉快的了。
游戏中应该有些什么?
是哪些元素组成了一个好的游戏呢?一般说来,有以下几个方面。
技术性能。
技术性能或许是游戏中最重要的一个方面,,其中有游戏实际运行是否良好,游戏响应如何,游戏运行是否顺畅,代码的编写对于游戏的进行很重要。试想,玩家向前飞跑,遇到一个障碍,而此时的帧速从30降到了5,这会对玩家的感觉造成错误,从而使玩家跌落悬崖。
这样会使玩家对游戏造成不好的印象,甚至于拒绝游戏。
交互与控制。
交互与控制是描述使用游戏的动作的方法。他主要考虑玩家如何控制游戏中的人物的移动与射击 玩家的动作应该能产生他们所预期的效果,而且效果应该是平滑的,流畅的和逼真的。差的控制可能会使游戏性能看起来不切实际和不逼真。现实生活中我们常常会沿着曲线和弧线来移动,伴随着运动的加速度,总的说来应该遵守牛顿的运动
定律。如果游戏的设计不遵守该定律,可能玩家不知道哪里产生了问题,但是他们一定会觉得很怪异。
目标,挑战与奖赏。
所有的游戏对玩家来说都必须要有挑战性,而且克服这些挑战达到他们的目标才会使玩家有获胜的感觉。好的挑战总是能够让玩家意识到的,而且能够给玩家提供明确的指示,包括击败他的明确途径,以及最终的目标是什么。
完成挑战之后,就涉及到了奖赏问题。奖赏与玩家付出的努力必须是相称的,否则玩家可能会对做同一件事而感到厌烦,试想,各种网络游戏如果只有杀怪而没有经验上或装备上的收获,是不会有人玩的。同时一些没有目的的奖赏对玩家来说也是没有吸引力的,如“饱眼福”的舞蹈等。如果所有的艰苦工作无法实现获得某些有利于他们游戏体验的某种事物时,玩家可能会感觉到自己可能是被欺骗了。
目标,挑战和奖赏始终都应反馈到游戏中以产生更多的目标。
可重复性。
一个好的游戏应该是玩家能够多次享受游戏的乐趣。无论是什么样的游戏,都有许多不同的方式能够使得玩家反复的玩。游戏与电影不同,电影一经发布是不可能再修改的,而游戏则是交互的,而且其中固有的交互性将使得人们更有可能去重新玩。
决定要制作一个游戏,一般而言,从最初的游戏创意到最终的准备好并发布游戏,游戏的创造过程通常由若干的步骤组成:
游戏创意。
这是良好的游戏设计中的第一步,当我远离电脑,并开始为游戏设计草拟创意的时候,我首先想到的是“游戏大概将会是怎样的”在该阶段需要确定游戏的类型,也就是从总体上考虑为最终的目标用户提供一个什么样的游戏。
游戏风格。
这是非常简单的,但是又非常重要的一步。在这里要准确的决定游戏最终的风格,他将是一个象DOOM一样的第一人称的射击游戏?一个无足轻重的琐事游戏?还是一个积木组成的拼图游戏,要着眼于游戏的基本创意来决定最适合的风格。
故事的情节和要素。
在这个阶段,就可以坐下来,决定游戏都发生什么样的事情。是关于由一个邪恶的指挥官指挥下的坏士兵?或者是将会发生在水果加工厂的爆炸。
总之,我们要撰写一个有关与游戏的脚本。再某些方面这几乎象是一个电影的剧本,但是他包含的不是摄像指令,而是一个动作的一般列表,同时又包含一些交互性的细节,其中包括由玩家负责完成的一些基本活动等。
游戏设计文档。
该内容包括:
主题或情节提纲.
场景或环境列表.
地图,奖赏和难题的简要说明.
游戏中人物角色的分配,包括玩家控制的角色和计算机控制的角色,以及电脑的AI设计,他们将做什么,他们的行为,他们的外貌等。
脚本的顺序.
运动线路公式等方面的技术问题.
核心引擎
在任何游戏中,将任何故事情节和特殊效果容入代码前,必须实现一个通用的引擎。构造核心引擎的关键问题是创建一个框架,以使得游戏的其他部分能够在该框架内建立和添加到框架上。
一旦拥有了一个基本的能加载,显示敌人,运行脚本的核心引擎,再加上一些常规的碰撞和奖赏系统,那么剩下的游戏构件就是关的设计和图形设计的问题了。
以下我将就我自己的作品深入的讨论一下有关Flash游戏的制作。
第三部分:游戏的制作过程
现在,我将就以前所讲的内容将其结合到我制作的游戏:Asteroidrun(小行星运行)。
游戏概述
在本游戏中,我们所扮演的是一名太空突击队员,我们的任务是绕地球飞行,消灭有可能坠落地面并严重破坏下面居民的小行星。在摧毁小行星的同时,我们的第二个目
标是收集足够多的放射性宇宙燃料来添满自己的燃料箱。
我们将缓慢绕整个地球飞行,在飞行的时候,我们要注意,不要被飞驰而来的小行星撞到,每被撞击一次,外壳的完好程度就会减少一定的百分点。外壳的完好程度由左上的两个显示条的下边的那个来显示。当外壳的完好程度变成0的时候,游戏就以失败结束。飞行和驾驶通过简单的鼠标移动来实现。我们移动鼠标时,屏幕上的十字准星也跟着移动,飞船追随十字准星移动。
十字准星的第二个功能就是瞄准目标和发射激光。单击鼠标左键,激光向着十字准星开火。十字准星瞄准小行星,左键开火,就可以消灭小行星,这样不但可以避免和小行星碰撞,同时也能消除他们对地球的威胁。在前进过程中,我们必须尽可能多的收集绿色的放射性宇宙燃料。和小行星不同的是,对于小行星是避免和它进行碰撞,而对于
燃料则是必须飞进放射性宇宙燃料中去收集它。
但还是要小心:不要向宇宙燃料射击,否则就会破坏它。当收集到足够多的放射性宇宙燃料后,燃料储存器,就是左上两个显示条的上边的一个,将会被添满,此时,我们就会取得游戏的胜利。
这个游戏的整体效果是一个具有高级动作的非常平滑的,交互式的3D体验。游戏中包括飞船在内的所有图形都是利用3D渲染程序渲染完成的,因此他们看上去非常真实而
且具有很强的3D效果,飞船始终以30种不同角度的某一种来显示,显示的角度取决于它在屏幕上的位置。
地球本身是一个620针的循环电影,也是利用3D渲染程序完成的。电影包含一个完整的行星轨道。随着电影的播放,它将根据飞船的位置,在屏幕上缩放,旋转,移动,产生了非常有效的,动态的视差效果。
小行星同样也是用3D渲染程序渲染完成的,游戏中共有14幅不同形状的,不同大小的小行星图像。当小行星从远处接近我们的时候,对小行星本身还应用了灯光效果。它们距离我们越远,看上去越暗。但是,放射性宇宙燃料没有用灯光效果,这样有利于玩家对收集信息的把握。
角色制作
对爆炸的制作,首先在PHOTOSHOP上,刻画圆,然后再附着以蛋白和橘黄的过度色,
进行滤镜中的模糊,在其内部刻画几条线,再进行动态模糊,之后使用滤镜工具中的浮雕和锐化选项进行最后的处理。依次往复,调整大小以及色调,明度等制造一连串的爆炸效果。
对小行星的制作。主要通过3D建摸,之后进行渲染。在此,举几个事例。
飞船的制作就是对飞船的建摸处理,飞船的好坏直接决定着游戏整体风格的好坏。其多角度的视角就是飞船的虚拟模型的多角度渲染。
主时间线内包括如下几个图层:
ActionScript图层:包含游戏中的代码。
UI图层(用户界面图层):包含所有用户界面元素,包括燃料指示条。外壳指示条,以及“胜利,失败”等文本。
Ship图层(飞船图层):飞船的电影剪辑。
Crosshair图层(十字准星图层):十字准星的电影剪辑。
Earth图层(地球图层):包含一个地球动画。
用户界面(UI)图层
在UI图层中,包含两个电影剪辑。第一个是meters,第二个是textdisplays。
在meters电影剪辑中又有两个图层,顶部图层是两个彩色的轮廓线,而低部图层则是用来填充顶部图层的长方形。两个长方形分别为fuelbar和healthbar。宽度是83.8象素。
为了显示飞船外壳的完整程度(HEALTHBAR)和放射性宇宙燃料(FUELBAR),我们只需要简单的调整其中任何一个提示条的-xscale。因为xscale是表示添满面积的一个基于
100的数值,所以在游戏中,我们只需要简单的将对应的指示条的xscale严格的设置为某个数值,就能够显示的非常准确。
在UI图层内的另一个电影剪辑是textDisplays电影剪辑。textDisplays电影剪辑也有两帧,第一帧包含显示为“GAME OVER”的文本,第二帧中包含显示为“YOU WIN”的文本。
这里有stop();的代码,为了防止连续播放。
Ship(飞船)图层
主时间线上的下一图层内只包含一个电影剪辑,“ship”是电影剪辑中的一个实例。其本身长度为32,由三个图层组成:
Ship Pic图层:该图层(最底部的一个图层)内包含3D飞船的31个不同渲染的帧。电影剪辑的最后一帧,32是空白的,不包含任何图片。该帧是飞船爆炸和玩家死亡时使用的。
Gun Tips图层:此图层中包含两个电影剪辑:枪尖。飞船的机翼末端装备有激光枪,激光就是从枪尖发射出去的。然而,当飞船当前显示的帧发生改变时,枪尖的位置也会因此发生变化。因此,我们不能确定其位置,而是需要程序来确定其位置。我们必须在每帧的枪尖位置用两个空白的电影剪辑来代替,然后利用这些电影剪辑来确定激光发射位置的发射点。
Explosion图层:该电影剪辑与飞船主题的中心对齐。这是一个爆炸的动画,当玩家死亡时就播放该动画,同时爆炸的声音将同时增加到最高,飞船剪辑将移动到32。其实爆炸场景经常用得到。
对于其中的代码有:第一帧STOP();16帧有
if (_parent. name != "ship")
{
_parent.z += 10000;
_parent.dr = (Math.random() * 6) - 3;
_parent.scoff = (Math.random() * 200) + 100;
_parent.x = (Math.random() * 2000) - 1000;
_parent.y = (Math.random() * 1000) - 500;
_parent.hitting = false;
_parent.exploding = false;
_parent.gotoAndStop(Math.ceil(Math.random() * 15));
}
Crosshair图层
这或许是所有图层中最简单的一个,该图层只有一个“Crosshair”。该电影剪辑
是一个十字准星的图样,播放时将追随鼠标的周围,而鼠标本身隐藏,因此十字准线就变成了鼠标指针。
其作用是用来瞄准小行星,以及控制飞船飞行方向的控制标。
Earth图层
该图层内包含唯一一个名为“backMovie”的电影剪辑,该电影是一个长度为620帧的电影剪辑。
嵌入的电影剪辑:Asteroid
在小行星电影剪辑的前14帧的每一帧中,在舞台上完全相同的位置,都包含一个不同渲染的小行星。他们是如此多样,因此游戏中不会重复出现相同的小行星。
小行星电影剪辑的第15帧内包含一个放射性宇宙燃料的帧。
小行星电影剪辑的第16帧是空白的,这是当小行星被摧毁时用于替换的一帧,此后将播放爆炸动画。
小行星电影剪辑的第17帧包含一个放射性宇宙燃料的特殊再现,延伸到它正常宽度的200%。这样做是为了在我们抓住放射性宇宙燃料时产生特殊的效果。切换到这一帧
表示成功的拾取燃料。
代码
在游戏的ActionScript图层主时间线上的第一帧可以找到其代码。
首先是:
backMovie._xscale = 200;
backMovie._yscale = 200;
我们在这里需要完成的是立刻将地球背景放大到原始大小的200%。正如我们稍后看到的,这样做的原因是,我们使用飞船的位置在背景上“平移”,以产生视差效果。当飞船向右移动时,地球就向左移动;同样,也会做相反移动。于是产生了这样的效果:就好象在飞船后面有一架摄象机,在飞船移动时也左右移动镜头。这样就极大地增加了3D效果
在此之后,我们有如下代码:
_root.xoff = 0;
_root.yoff = 0;
_root.zoff = 0;
我们在这里设置了3D引擎的第一组变量。
接下来,有:
project = function ()
{
if ((this.z - _root.zoff) > 40)
{
我们在这里进行检测,以确保投影的对象距离玩家不小于40个单位,否则,将被视为在玩家身后。此后,我们有
this._visible = true;
var zt = 300 / (this.z - _root.zoff);
this._x = ((this.x - _root.xoff) * zt) + 275;
this._y = ((this.y - _root.yoff) * zt) + 200;
this._xscale = this._yscale = this.scoff * zt;
this.swapDepths(10000 - (this.z - _root.zoff));
我们使用一个名为SCOFF的变量来表示scale offset(缩放偏移量),而不是只使用
数值100,这样做是想让小行星的大小不同,而不是总显示为相同的大小。因此,在生成它们时就随机的设置其值。接下来的代码是:
var cperc = ((this.z - _root.zoff) / 5000) * 100;
if (this.exploding || this._currentframe == 15) cperc = 0;
if (this.hitting) cperc = -400;
这就是我们处理投影电影剪辑以使其变暗的方法。我们完成的第一件事是将变量
CPERC设置为0到100之间的某个数值,任何z距离在5000以上的对象,其CPERC将为100,对应的,任何距离在0到5000的,其值也正比到0到100。CPERC=0不会变化,而CPERC=100就是完全的黑色。
接下来我们进行检测,判断标志this.exploding是否为真,或者是this._currentframe==15是否成立。无论上述哪一种情况,我们都手动将变量CPERC从新设置为0。在第一种情况中,只有小行星被激光集中时,this.exploding才会是ture。此时我们确保对他不使用任何变换效果,这是因为他们正在发生爆炸,而爆炸会产生光亮,如果此时变暗,看起来会非常奇怪的。第二种情况中this._currentframe=15说明它是一种放射性宇宙燃料,因为它正在发光,所以也不应该是变暗的。
当this.hitting为ture时,我们将CPERC设置为400,这将使得电影剪辑产生了非常明亮的效果----几乎为白色。这就是我们用来暗示玩家飞船被击中,以及是那颗小行星击中他的方法。
之后的代码;
this.cobj.ra = this.cobj.ga = this.cobj.ba = 100 - cperc;
this.c.setTransform(this.cobj);
上述的代码只是简单地将颜色转换对象的ra,ga和ba的值设置为100-CPERC。这就意味着CPERC值为100的任何对象现在将被颜色转换设置为100-100既为0。相反的,为100。
一旦设置了颜色转换,然后就可以使用setTransform方法。之后我们用下边的方法来结束project。
}
else
{
this._visible = false;
}
}
这样,总结project,有
project = function ()
{
if ((this.z - _root.zoff) > 40)
{
this._visible = true;
var zt = 300 / (this.z - _root.zoff);
this._x = ((this.x - _root.xoff) * zt) + 275;
this._y = ((this.y - _root.yoff) * zt) + 200;
this._xscale = this._yscale = this.scoff * zt;
this.swapDepths(10000 - (this.z - _root.zoff));
var cperc = ((this.z - _root.zoff) / 5000) * 100;
if (this.exploding || this._currentframe == 15) cperc = 0;
if (this.hitting) cperc = -400;
this.cobj.ra = this.cobj.ga = this.cobj.ba = 100 - cperc;
this.c.setTransform(this.cobj);
}
else
{
this._visible = false;
}
}
在project方法之后,有如下代码:
_root.createEmptyMovieClip("asteroids", 4);
_root.createEmptyMovieClip("laser", 5);
我们在舞台内创建了两个空的电影剪辑:asteroids和laser,深度分别为4和5。两个电影剪辑默认都被设置在屏幕上的_x=0,_y=0.的位置,一旦有了上述操作,接下来,我们有:
for (var i = 0; i < 20; i++)
{
这是开始在屏幕上创建小行星电影剪辑的地方,我们在这里一共创建20个电影剪辑。为了产生非常强烈的动作游戏,这种处理是必须的。接下来有:
var nm = "ast" + i;
asteroids.attachMovie("asteroid", nm, i);
这段代码将创建嵌入到图库的asteroid电影剪辑的20个实例,他们的名字分别为ast0----ast19。然后:
asteroids[nm].project = project;
我们对每个小行星创建一个名为project的方法,并将其设置为我们刚刚创建的project方法,接下来我们有:
asteroids[nm].x = (Math.random() * 2000) - 1000;
asteroids[nm].y = (Math.random() * 1000) - 500;
asteroids[nm].z = i * 500 + 13000;
我们在小行星创建的同时设置其XYZ位置。X,Y位置分别为基于X方向-1000到+1000。Y方向-500到500范围内的某个随机数,这将使小行星的运行轨道field是宽度大于高度,但是这正是我们预期的效果----就象是小行星在围绕行星周围的一个椭圆轨道上运行。我们简单的将Z变量设为500的倍数,以变量i为乘数。这样每颗小行星将均匀的沿着Z轴分布,两两之间的距离是500个单位。我们还在每个小行星Z值的基础上+13000,以使得玩家的飞船前面没有小行星。小行星将从相当远的距离上开始出现,这样我们就有足够的时间在进入小行星轨道之间找到控制的感觉。第一个小行星将出现在Z值为13000的位
置,第二个13500,下来是14000等等。
接下来,我们有如下代码:
asteroids[nm].scoff = (Math.random() * 200) + 100;
asteroids[nm].dr = (Math.random() * 6) - 3;
在这里,我们为每个小行星创建了另外两个变量:scoff和dr。变量scoff将取值为100-300之间的某个随机数。该变量将被用来作为小行星大小的缩放比例。而产生大小不同的感觉。
变量dr的取值将为-3到+3之间的某个数,这个变量决定小行星围绕其中心旋转的角速度,因为小行星在空间不是不动的,他们往往有自转运动,变量的设置将决定它们的旋转方向该值为负为逆时针,反之,为顺时针旋转。而且,数值越大,旋转越快。之后,将是:
asteroids[nm].gotoAndStop(Math.ceil(Math.random() * 15));
这将使得新创建的小行星电影剪辑随机的转到并停止在1到15之间的某一帧,通过这种处理,就可以随机的得到15个小行星中的一个,其中包括第15个,也就是放射性宇宙燃料。
asteroids[nm].c = new Color(asteroids[nm]);
asteroids[nm].cobj = new Object();
asteroids[nm].project();
在这里,我们对小行星电影剪辑执行一次project。
asteroids[nm].onPress = function()
{
this.exploding = true;
this.gotoAndStop(16);
this.explosion.play();
}
这个是用于模拟小行星或放射性宇宙燃料毁灭的代码。当十字准星瞄准某个小行星时,如果玩家点击了左键并保持,小行星的onpress将被触发,此时,玩家就摧毁了一个小行星。之后,出发爆炸情节。
asteroids[nm].onEnterFrame = function()
{
该方法用于处理小行星所有的运动与动作。在该方法内,有:
if (!this.exploding) this.z -= flyspeed;
我们必须首先进行检查,以确认此时小行星没有发生爆炸,如果此时没有发生爆炸,那么我们就沿着Z轴将小行星移动变量flyspeed所指示的单位。如果小行星正在爆炸,那么不能移动这个小行星。,因为我们不希望小行星爆炸着飞向我们。
this.project();
调用project,在每一帧中执行,负责根据小行星的位置刷新其屏幕显示。之后有:
this._rotation += this.dr;
if (this.z < 400)
{
如果某个小行星的Z值已经低于400,说明已经被认为是足够近,足以接触到飞船的一点。那么以下有:
if (this.hitTest(ship._x, ship._y, false) && this.z > 300 && !this.exploding)
{
以上是用来判断飞船是否接触到小行星。如果,全部满足条件,既被认为是碰撞到了,此时应当判断我们撞到的是什么。
if (this._currentframe < 15)
{
如果是小行星,那么有:
this.exploding = true;
this.gotoAndStop(16);
this.explosion.play();
health-=10;
meters.healthbar._xscale = health;
将玩家的HEALTH反映到HEALTHBAR上,同时播放explosion动画。
碰撞导致玩家死亡。
就会执行以下代码:
if (health <= 0)
{
ship.gotoAndStop(32);
ship.explosion.play();
delete _root.onEnterFrame;
delete crosshair.onEnterFrame;
_root.createEmptyMovieClip("asteroids", 4);
_root.createEmptyMovieClip("laser", 5);
Mouse.show();
textDisplays._visible = true;
textDisplays.gotoAndStop(1);
}
}
飞船消失,爆炸开始。而且,在同时,“GAME OVER”的文本文档也开始运行。
}
}
else
{
energy += 5;
meters.fuelbar._xscale = energy;
this.hitting = true;
这段的含义是,飞船遇到的不是小行星,而是放射性宇宙燃料,这中情况下增加燃料的数值。控制FUELBAR的xscale增长5点。象飞船死亡一样,当燃料收集满的时候,有如下代码:
if (energy >= 100)
{
delete _root.onEnterFrame;
delete crosshair.onEnterFrame;
_root.createEmptyMovieClip("asteroids", 4);
_root.createEmptyMovieClip("laser", 5);
Mouse.show();
textDisplays._visible = true;
textDisplays.gotoAndStop(2);
}
看上去和飞船死亡很象,但是这些是胜利的代码,消除所有小行星和激光,“YOU WIN”文档开始运行。其中要补充的是,记得我们以前所说的小行星剪辑中的第17帧么?
这个时候,开始派上用场。
this.gotoAndStop(17);
}
}
这说明飞船已经成功的收集到放射性宇宙燃料。
之后的代码是:
if (this.z < 200)
{
this.z += 10000;
this.dr = (Math.random() * 6) - 3;
this.scoff = (Math.random() * 200) + 100;
this.x = (Math.random() * 2000) - 1000;
this.y = (Math.random() * 1000) - 500;
this._xscale = 0;
this.gotoAndStop(Math.ceil(Math.random() * 15));
this.hitting = false;
this.exploding = false;
this.explosion.gotoAndStop(1);
}
}
}
}
这段代码是对游戏的主体作修饰,防止不合理的小行星出现。
在此为止,所有小行星将存在于空间内,而且将向空间内向着摄象机方向移动。作为参考,以下给出小行星的完整代码。
for (var i = 0; i < 20; i++)
{
var nm = "ast" + i;
asteroids.attachMovie("asteroid", nm, i);
asteroids[nm].project = project;
asteroids[nm].x = (Math.random() * 2000) - 1000;
asteroids[nm].y = (Math.random() * 1000) - 500;
asteroids[nm].z = i * 500 + 13000;
asteroids[nm].scoff = (Math.random() * 200) + 100;
asteroids[nm].dr = (Math.random() * 6) - 3;
asteroids[nm].gotoAndStop(Math.ceil(Math.random() * 15));
asteroids[nm].c = new Color(asteroids[nm]);
asteroids[nm].cobj = new Object();
asteroids[nm].project();
asteroids[nm].onPress = function()
{
this.exploding = true;
this.gotoAndStop(16);
this.explosion.play();
}
asteroids[nm].onEnterFrame = function()
{
if (!this.exploding) this.z -= flyspeed;
this.project();
this._rotation += this.dr;
if (this.z < 400)
{
if (this.hitTest(ship._x, ship._y, false) && this.z > 300 && !this.exploding)
{
if (this._currentframe < 15)
{
this.exploding = true;
this.gotoAndStop(16);
this.explosion.play();
health-=10;
meters.healthbar._xscale = health;
if (health <= 0)
{
ship.gotoAndStop(32);
ship.explosion.play();
delete _root.onEnterFrame;
delete crosshair.onEnterFrame;
_root.createEmptyMovieClip("asteroids", 4);
_root.createEmptyMovieClip("laser", 5);
Mouse.show();
textDisplays._visible = true;
textDisplays.gotoAndStop(1);
}
}
else
{
energy += 5;
meters.fuelbar._xscale = energy;
this.hitting = true;
if (energy >= 100)
{
delete _root.onEnterFrame;
delete crosshair.onEnterFrame;
_root.createEmptyMovieClip("asteroids", 4);
_root.createEmptyMovieClip("laser", 5);
Mouse.show();
textDisplays._visible = true;
textDisplays.gotoAndStop(2);
}
this.gotoAndStop(17);
}
}
if (this.z < 200)
{
this.z += 10000;
this.dr = (Math.random() * 6) - 3;
this.scoff = (Math.random() * 200) + 100;
this.x = (Math.random() * 2000) - 1000;
this.y = (Math.random() * 1000) - 500;
this._xscale = 0;
this.gotoAndStop(Math.ceil(Math.random() * 15));
this.hitting = false;
this.exploding = false;
this.explosion.gotoAndStop(1);
}
}
}
}
接下来,我们有如下代码:
_root.onEnterFrame = function()
{
var destx = _xmouse - 275;
var desty = _ymouse - 200;
根据鼠标指针所在位置的屏幕坐标计算临时变量destx和desty,但是这两个变量是鼠标指针相对于屏幕中心的偏移量,一旦计算出来这两个偏移量,就作如下处理:
_root.xoff += (destx - _root.xoff) * .05;
_root.yoff += (desty - _root.yoff) * .05;
这样就实现了xoff和yoff是如何在每一帧内逐渐滑向其目标的。
var diffx = _xmouse - ship._x;
var tempy = ((_ymouse - 200) * 5) + 200;
if (tempy < 10) tempy = 10;
if (tempy > 390) tempy = 390;
var diffy = (tempy) - ship._y;
计算鼠标指针和飞船位置之间的差值,并将其保存在diffx的临时变量中。基本上,我们所做的是通过将飞船的位置设置成_ymouse的5倍,从而促使飞船不是位于屏幕的顶部就是屏幕的底部,通过上述处理,可以使得飞船在大部分时间内都远离屏幕的中心。我们对ship电影剪辑执行这种处理,是因为我们不希望飞船遮盖住十字准星,否则会使我们对游戏控制感到吃力。同时也会增加游戏的纵深感。
ship._rotation = diffx / 10;
var shipframe = (ship._y / 400) * 30 - (diffy / 20);
这段代码取得飞船的_rotation,它将使飞船“倾斜转弯”进入运动轨道,而且运动速度越大,倾斜也会越大,另外根据其值也可以确定倾斜的方向。
if (shipframe > 31) shipframe = 31;
if (shipframe < 1) shipframe = 1;
ship.gotoAndStop(Math.floor(shipframe));
ship._x += (diffx) * .03;
ship._y += (diffy) * .03;
将SHIP电影剪辑移动到屏幕中相应的位置。基于平稳的改变方向和从某一个位置到另一个位置的飞行,就可以产生某种非常真实的运动效果。
backMovie._x = 275 - ((ship._x - 275) / 2);
backMovie._y = 200 - ((ship._y - 200) / 2);
对backmovie电影剪辑进行处理,并根据ship电影剪辑的位置来设定其对应位置。设置backMovie电影剪辑的移动速度刚好是SHIP移动速度的一半,这将给玩家很大距离和深度的感觉。之后有
backMovie._rotation += 0.05;
这段使地球的电影剪辑自转,增加了游戏效果。
这些就是¬_root.onEnterFrame方法的全部代码.其下来的代码是
crossshair.onMouseDown = function()
targx = crosshair._x;
targy = crosshair._y;
无论何时,只要玩家单击鼠标左键,该代码都将被触发执行.首先,我们将变量targx&targy的值分别设置成crosshair电影剪辑的_x&_y位置,将startshoot设置成为ture,之后在每帧内将可见度减少40%,使的激光一旦发射出去后总是在减弱.
最后有关激光和枪尖的代码有如下:
shair.onEnterFrame = function()
{
this._x = _xmouse;
this._y = _ymouse;
var point = new Object();
point.x = ship.gun0._x;
point.y = ship.gun0._y;
ship.localToGlobal(point);
laser.clear();
laser.moveTo(point.x, point.y);
laser.lineStyle(3, 0xFF0000, 100);
laser.lineTo(targx, targy);
var point = new Object();
point.x = ship.gun1._x;
point.y = ship.gun1._y;
ship.localToGlobal(point);
laser.moveTo(point.x, point.y);
laser.lineStyle(3, 0xFF0000, 100);
laser.lineTo(targx, targy);
if (startshoot)
{
startshoot = false;
laser._alpha = 100;
}
以上是说明如何从左右枪尖发射激光的计算机绘图程序,以及适时的跟踪.到此为止,我们已经讨论了所有的有关游戏中的代码.接下来只是一些初始的设定.将能量设定为0。
生命为100,调整有关生命和能量数值到指示条的宽度.设置渲染质量,隐藏鼠标指
针.这样,我们就完成了所有的游戏设计工作.
第四部分:制作总结
计算机游戏不仅仅是闲暇时的娱乐,它们是感情的表达.探索.创造力和自我实现的一种手段,作为一名制作人员,我很高兴能够给人们带来或多或少的一些娱乐;同时经过半个学期的辛勤努力和工作,我收获了很多,付出了多少就得到多少回报.
在此,我再次感谢各位老师对我的教导.
参考文献
[1]Glen Rhods 著 《FLASH MX 2004 游戏开发》 电子工业出版社 2004.10
[2]Saizna著 《FLASH 游戏制作》 内蒙古出版社 2005.1
[3]Fire smith 著 《游戏制作工艺》 新浪网 2005.2
[4]托里司(美)著 《SUN EDUCATIONAL SERVICES》 SUN MICROSYSTEMS.INC 2003.10
[5]贾春红著 《Dreamweaver MX 网站设计》 人民邮电出版社 2003.6
[6]廖雷著 《Java程序设计教程》 中国电力出版社 2003
[7]Warton 《Java多线程编程初步》 电脑报, 2004.4.10
[8]李昭原 主编 《数据库技术新发展》 清华大学出版社,1997
[9]周龙镶编著 《数据库管理系统实现技术》 中国地质大学出版社,1990
[10]邬江兴,柴远波,《谈谈V5接口》 电信技术NO4 1997 P1
[11]天极网新技术研究室《ASP.NET完全入门》 重庆出版社, 2001
[12]Scott Worley著 《ASP.NET技术内幕》 人民邮电出版社 2002
致谢
首先和最重要的,我要感谢我的辅导老师吕美玉,为她所有的耐心和辛勤的工作,在本次的毕业设计中,我的感觉好象我在另外一个世界中。我还要感谢我的朋友张毅,他在我的工作中给了我莫大的帮助。我还要感谢我的朋友杨颖,为她在我工作中的不断激励,她的耐心和理解,使我随时拿出我最好的状态。我还要感谢所有FLASH的开发人员,正是他们不断的辛勤工作和努力并将FLASH提升到新的高度,才使得FLASH发展和成长为如此强大的一个发展平台。
我还要感谢我的父母,我的朋友们。当然还有所有教导我的老师,谢谢你们。