您的位置: 首页 > 技术文档 > 多媒体制作 > Flash 区块游戏开发
Flash MX 2004 pro 帮助 CHM 版 回到列表 如何防止SWF文件被反编译
 Flash 区块游戏开发

作者:qhwa 时间: 2004-05-22 文档类型:原创 来自:蓝色理想

第 1 页 欢迎
第 2 页 为什么用方块?
第 3 页 地图
第 4 页 关于地图的东西
第 5 页 创建方块
第 6 页 再谈谈区块原型的定义
第 7 页 英雄/主角
第 8 页 键盘控制的移动
第 9 页 碰撞检测
第 10 页 芝麻开门-地图切换
第 11 页 跳跃
第 12 页 腾云驾雾
第 13 页 梯子
第 14 页 愚蠢的敌人
第 15 页 更多关于敌人的东西
第 16 页 射击
第 17 页 拾取物品
第 18 页 浮动区块
第 19 页 卷屏
第 20 页 未完待续 | coming soon

射击

你可以用很多方法杀死敌人。你可以通过刀剑、枪或者其他的东西。让我们来看看我们怎样向敌人射击(使用shift键射击)。

当我说到“子弹”的时候,我的意思是那些从英雄处飞出来的、看起来要去杀死敌人的东西。它可以是球、箭头、冰激凌、企鹅等等。

首先,我们还是应该考虑一下,射击应该是怎样的过程,子弹是怎样运动。一旦shift键被按下,首先,子弹对象、子弹剪辑被创建,子弹剪辑的位置应该是英雄所在的位置。而且子弹应该朝英雄面对的方向运动。如果子弹遇到墙或者敌人,它应该自动消失。如果它碰到的是敌人,那么敌人也要消失。

子弹的速度应当比英雄的速度大,除非你准备让英雄可以用某种方式阻挡飞行的子弹。通常那些傻乎乎的敌人不会看到飞行的子弹,但是你也可以创建会躲避子弹的敌人。你也可以做一些能朝英雄射击的敌人。

准备射击

画一个子弹的mc,然后做一个linkage,ID是bullet,以便用AS复制到舞台中。子弹MC中的图像应该居中对齐。

让我们声明一下子弹对象:

game.Bullet= function () {};
game.Bullet.prototype.speed=5;
game.Bullet.prototype.dirx=0;
game.Bullet.prototype.diry=-1;
game.Bullet.prototype.width=2;
game.Bullet.prototype.height=2;

子弹每步移动的距离是5,高度和宽度都是2象素,这已经足够杀死敌人了。

dirx/diry属性确定了子弹移动的方向。实际上我们还是通过moveChar函数移动子弹。如果dirx=1,子弹向右移动,diry=-1则向上移动。我可以从英雄(或敌人)对象中得到方向参数,设定dirx/diry的值,但是在游戏刚开始的时候,英雄还没有移动,这时候玩家如果要射击,就用上面这个默认的方向(dirx=0,diry=-1,朝上移动)。

给game对象添加两个新的属性:

game={tileW:30, tileH:30, currentMap:1, bulletcounter:0};
game.bullets= new Array();

bulletcounter属性用来记录子弹的数目,以便我们给新产生的子弹取不重复的名称。游戏里第一发子弹名称是bullet0,然后是bullet1、bullet2……最多是bullet100,接下来返回到bullet0。我们可以让数目无限增长,但是谁也不能保证到最后会发生什么。

game.bullets数组用来放置舞台上的子弹对象。一开始的时候它是一个空的数组。

然后给角色对象加上一个shootspeed属性,设置每次发弹的最小时间间隔:

char={xtile:2, ytile:1, speed:4, shootspeed:1000};

更高的shootspeed值代表更长的间隔、更慢的射击速度,单位是毫秒。

敌人死亡后,我们还要把他们从game对象中删除。改变buildMap函数的创建敌人的部分:

game.currentEnemies = [];
for (var i = 0; i<enemies.length; ++i) {
  var name = "enemy"+i;
  game[name]= new game["Enemy"+enemies[i][0]];
  game[name].id=i;
  game.currentEnemies.push(game[name]);

然后在enemyBrain函数中,把这句:

var name = "enemy"+i;
换成 :var name = "enemy"+game.currentEnemies[i].id;

我通过currentEnemies数组来放置舞台上活动的敌人。一旦敌人被杀死,我们就会把它从currentEnemies数组中删除。新的属性“id”帮助我们找到敌人在enemies数组中的位置。

在detectKeys函数检查完按键后添加代码:

if (Key.isDown(Key.SHIFT) and getTimer()>ob.lastshot+ob.shootspeed) {
  _root.shoot(ob);
}

如果SHIFT键被按下,而且时间间隔足够长,调用shoot函数。

在moveChar函数的开头添加两行代码,用来保存当前对象的方向:

ob.dirx=dirx;
ob.diry=diry;

我们可以用这个来指定子弹运行的方向。


开枪

为了成功的让子弹按照我们预定的想法飞行,我们要写一个新的函数shoot:

function shoot (ob) {
  ob.lastshot=getTimer();
  game.bulletcounter++;
  if (game.bulletcounter>100) {
    game.bulletcounter=0;
  }
  var name = "bullet"+game.bulletcounter;
  game[name]= new game.Bullet;
  game[name].id=game.bulletcounter;
  game.bullets.push(game[name]);
  if (ob.dirx or ob.diry) {
    game[name].dirx= ob.dirx;
    game[name].diry= ob.diry;
  }
  game[name].xtile= ob.xtile;
  game[name].ytile= ob.ytile;
  game.clip.attachMovie("bullet", name, 10100+game.bulletcounter);
  game[name].clip=game.clip[name];
  game[name].x = (ob.x+game[name].dirx*ob.width);
  game[name].y = (ob.y+game[name].diry*ob.height);
  game.clip[name]._x = game[name].x;
  game.clip[name]._y = game[name].y;
}

首先我们传递了一个obj对象给函数。如果开枪的是英雄,这个obj就是英雄;如果是敌人射击,obj就是敌人对象。

我们通过getTimer()函数把当前的时间保存到lastshot属性中。

接着给game.bulletcounter属性增加1,如果它大于100,我们就让他回到0。

现在用bulletcounter产生一个新的子弹名字,创建一个子弹对象,然后把这个数字存到该对象中,把这个对象的地址放入game.bullets数组中。

下面的if判断用来检测角色对象是否移动过(dirx/diry有值),如果是,则把这两个方向属性传递给新建的子弹对象。否则子弹会有默认的运行方向。

为了让子弹从角色处出现,我们把角色的xtile和ytile属性复制给子弹对象。

代码的最后部分创建了新的子弹剪辑,计算坐标,最后显示到该位置。有趣的地方在于如何计算子弹的象素坐标:

game[name].x = (ob.x+game[name].dirx*ob.width);

首先我们得到角色的位置(ob.x),这是角色的中心坐标。通常子弹并不是从角色的正中心发出,我们给他加上了角色的宽度。这个地方的巧妙之处在于乘了子弹的dirx属性,dirx取-1,0,1都能适合。当dirx为0的时候,子弹的x坐标就是角色的中心,不过这时候子弹是竖直运动的,出现在角色的正上方或正下方。


杀死敌人!

在detectKeys函数的结尾添加一行,调用一个新的函数来移动子弹,并且检查是不是打到了什么东西。

_root.moveBullets();

moveBullets函数:

function moveBullets () {
  for (var i = 0; i<game.bullets.length; ++i) {
    var ob=game.bullets[i];
    getMyCorners (ob.x+ob.speed*ob.dirx, ob.y+ob.speed*ob.diry, ob);
    if (ob.downleft and ob.upleft and ob.downright and ob.upright) {
      moveChar(ob, ob.dirx, ob.diry);
    } else {
      ob.clip.removeMovieClip();
      delete game["bullet"+game.bullets[i].id];
      game.bullets.splice(i,1);
    }
    for (var j = 0; j<game.currentEnemies.length; ++j) {
      var name = "enemy"+game.currentEnemies[j].id;
      var obenemy = game[name];
      var xdist = ob.x - obenemy.x;
      var ydist = ob.y - obenemy.y;
      if (Math.sqrt(xdist*xdist+ydist*ydist) < ob.width+obenemy.width) {
        obenemy.clip.removeMovieClip();
        delete game["enemy"+game.currentEnemies[j].id];
        game.currentEnemies.splice(j,1);
        ob.clip.removeMovieClip();
        delete game["bullet"+game.bullets[i].id];
        game.bullets.splice(i,1);
      }
    }
  }
}

这个函数通过循环来操作放在bullets数组中的每一个子弹对象。

使用getMyCorners函数我们得知子弹下一步是不是打在了障碍物上。如果不是,我们就调用moveChar函数移动子弹。

如果子弹确实击中了障碍物,我们就要删除它了。有3样事情要做:
删除子弹mc (使用removeMovieClip)
删除子弹对象 (使用delete函数)
从子弹数组中删除当前的子弹

尽管我们可以只删除子弹mc而留下子弹对象,这样做不会有大问题。因为子弹mc已经不存在,对它的所有的操作不能被执行。但是这样做会降低效率,子弹数组越来越大,而且里面全是垃圾数据。

当移动了子弹而且子弹没有撞上障碍物,我们开始检查它是不是击中了敌人。循环currentEnemies数组,计算出子弹和敌人的距离。如果他们离得太近,我们就删除他们——子弹和敌人都消失。

如果你要永久清楚这个被杀的敌人(当你再一次进入这个房间的时候,它不会再出现),在这里再添加一行:
myEnemies[game.currentMap][obenemy.id]=0;

你也可以让射击变得更加丰富多彩:

+限制子弹的总数。你可以设置一个变量,每次创建一个子弹,变量就减1,只有这个变量值大于0才能创建对象。
+限制舞台上只有1颗子弹。当子弹数组长度>0时不创建子弹。
+让敌人也能发弹。让敌人射击也很容易做到,方法和他们改变移动方向一样。
+创建不同的武器。你可以声明多种子弹模板,规定不同的伤害值,你可以得到更强的武器,更快的杀死敌人。

玩的开心 :-)

下载上例的源文件

在侧视图中射击:

下载本例的源文件

出处:蓝色理想
责任编辑:qhwa

上一页 更多关于敌人的东西 下一页 拾取物品

◎进入论坛Flash专栏版块参加讨论

相关文章 更多相关链接
Flash 酷站猎手
中文ID3乱码问题MX解决方案
用AS2解决中文ID3的乱码
Flash常用效果-移动模糊效果
Flash MX 2005 制作环境预览
作者文章 更多作者文章
中文ID3乱码问题MX解决方案
Flash 区块游戏开发
Flash 中如何显示清晰的字体
JavaScript 和 Flash 的通信
在 ListBox 组件中应用 HTML
热门搜索:CSS Fireworks 设计比赛 网页制作 web标准 用户体验 UE photoshop Dreamweaver Studio8 Flash 手绘 CG
站点最新 站点最新列表
全兼容的纯CSS级联菜单要点浅析
CSS Sprites 图片整合技术
雅安,一场中式旅行
热烈祝贺"醒狮杯"圆满结束
菊花宝典大赏大奖教程《阳台》
交互设计师怎样和产品团队合作
Photoshop打造个性潮流音乐海报
简单解读面包屑
CSS盒模型
Apple与Microsoft网站可用性研究
栏目最新 栏目最新列表
safari 4 新特性
Photoshop制作精美高光流线字
IE下img多余5像素空白解决方法
XHTML1.0与HTML兼容指引16条
JavaScript优化细节
全兼容的纯CSS级联菜单要点浅析
CSS Sprites 图片整合技术
Photoshop打造个性潮流音乐海报
CSS盒模型
45度地图编辑器及游戏开发心得
>> 分页 首页 前页 后页 尾页 页次:16/201个记录/页 转到 页 共20个记录

蓝色理想版权申明:除部分特别声明不要转载,或者授权我站独家播发的文章外,大家可以自由转载我站点的原创文章,但原作者和来自我站的链接必须保留(非我站原创的,按照原来自一节,自行链接)。文章版权归我站和作者共有。

转载要求:转载之图片、文件,链接请不要盗链到本站,且不准打上各自站点的水印,亦不能抹去我站点水印。

特别注意:本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有,文章若有侵犯作者版权,请与我们联系,我们将立即删除修改。

本文总共有 28 条评论,现在显示最新的 5 条。评分:- llllllllllllllllllll + 评分人数: 7 ,平均分: 5.00


autodesker Publish at 2009-2-23 16:24:22
又一年过去了……还是没有下文呀~~
ye2325875 Publish at 2008-1-1 18:06:00
求求站长了,把后面的都翻译过来吧,谢谢了。
-----------------------------------------
支持``
ghyh22 Publish at 2006-7-25 0:42:03 评分5
支持,强烈支持
太感谢了
像得到宝一样高兴
hack86 Publish at 2006-7-16 22:18:18 评分5
求求站长了,把后面的都翻译过来吧,谢谢了。
qhwa Publish at 2006-1-12 22:55:57
回复:oring
Math.floor((y+ob.height-1)/game.tileH 有-1和没有-1算出来是不同的方块了


oring Publish at 2005-6-7 10:49:37 评分5 删除评论
请问:
ob.downY = Math.floor((y+ob.height-1)/game.tileH);
ob.rightX = Math.floor((x+ob.width-1)/game.tileW);
为什么 “y+ob.height-1“和“x+ob.width-1“ 这边要减1?
---
我有试过如果把-1去掉,差别就出来了。 始终想不出这微妙的-1是什么意思?

查看全部评论

您的评论
用户名:  口令:
说明:输入正确的用户名和密码才能参与评论。如果您不是本站会员,你可以注册 为本站会员。
注意:文章中的链接、内容等需要修改的错误,请用报告错误,以利文档及时修改。
不评分 1 2 3 4 5
注意:请不要在评论中含与内容无关的广告链接,违者封ID
请您注意:
·不良评论请用报告管理员,以利管理员及时删除。
·尊重网上道德,遵守中华人民共和国的各项有关法律法规
·承担一切因您的行为而直接或间接导致的民事或刑事法律责任
·本站评论管理人员有权保留或删除其管辖评论中的任意内容
·您在本站发表的作品,本站有权在网站内转载或引用
·参与本评论即表明您已经阅读并接受上述条款
推荐文档 | 打印文档 | 评论文档 | 报告错误  
专业书推荐 更多内容
《Web标准设计》
《美工神话》
《Flash短片轻松学》
Illustrator CS3质感绘画表现技法
大师之路--Photoshop 完全解析
《用户体验要素》
HTML与CSS入门经典(第7版)
作品集 更多内容

毕业设计。 华贸提案 一个专题 GenNext网站 GenNext网站 毕业设计。 毕业设计。 华硕(Asus)手机 Zt23