Flixel横板游戏制作教程(三)— AddingWeapons

发布时间:2025-12-09 20:15:06 浏览次数:5

from: http://bbs.9ria.com/thread-77302-1-1.html

 

演示程序

http://www.adamatomic.com/canabalt/

http://www.flixel.org/mode/

 

Flixel横板游戏制作教程(三)— AddingWeapons

现在我们给 player 加入 weapon 武器。
首先是 子弹 Bullet 类:

 

 

package {import org.flixel.FlxObject;import org.flixel.FlxSprite;/*** ...* @author zb*/public class Bullet extends FlxSprite {[Embed(source = 'media/bullet.png')]protected var bulImg:Class;public function Bullet():void {//记得每个FlxSprite的子类构造方法这里 都顺手写一个这个哦super(0, 0);//加载子弹的素材loadGraphic(bulImg, true, false, 8, 8);//设置子弹的动画//向上发射addAnimation('shootUp', [0]);//向下addAnimation('shootDown', [1]);//向左addAnimation('shootLeft', [2]);//向右addAnimation('shootRight', [3]);//爆炸动画,最后一个参数设置false,表示动画播不会循环播放addAnimation('BulBoom', [4, 5, 6, 7], 50, false);//exists,是所有flxObject的一个属性,表示该object是否存在//false,说明改物体不存在,flixel不会对他进行任何操作(碰撞检测等)//true,则说明改物体存在//当子弹没有发射出去的时候,自然不需要检测碰撞,所以设置 falseexists = false;}/*** 这个是子弹的发射方法* @param sPosX 子弹发射时的初始 x 坐标* @param sPosY 子弹发射时的初始 y 坐标* @param velX 设置子弹发射的 x轴 速度* @param velY 设置子弹发射的 y轴 速度*/public function shoot(sPosX:Number,sPosY:Number,velX:Number,velY:Number):void {//reset方法,是将该object的一些属性重置//重置 exist 为 true ,dead(是否死亡)为 false//参数1:要将该object 重置到的 x坐标//参数2:要将该object 重置到的 y坐标reset(sPosX, sPosY);//将参数中的速度赋值给 子弹velocity.x = velX;velocity.y = velY;//根据速度判断子弹需要 播放哪个方向的动画if (velY < 0) {//y速度小于 0,向上发射play('shootUp');}else if (velY > 0) {//y速度大于 0,向下发射play('shootDown');}else if (velX < 0) {//x速度小于0,向左发射play('shootLeft');}else if (velX > 0) {//x速度大于0,向右发射play('shootRight');}}//当发射出去的子弹碰到障碍物之后,就会爆炸//所以重写碰撞方位的方法,加上hurt 方法,//这样碰到障碍物后,子弹会触发hurt方法,hurt是指本object受到伤害。/*** 重写的 碰撞 物体 左边 和 右边 的方法* @param Contact 碰撞的对象,也就是 与 谁 发生了碰撞* @param Velocity 发生碰撞后,本 objcet 获得的一个 速度*/override public function hitSide(Contact:FlxObject, Velocity:Number):void {//参数:该object 受到的伤害值,注意是本objcet,从 health值上减少//受到0点伤害,因为默认的health(生命值) 是1,所以填 0 子弹就不会受到伤害,//因为 health <= 0 的时候,就会触发 kill 方法,//而kill方法会设置 exist 会设置为 false,那么子弹就会马上消失//这不是我们想看到的,因为 子弹 爆炸的动画还没播放呢。。hurt(0); //别忘了 重写以后 要 加上。。。super.hitSide(Contact,Velocity);}//这个是重写 碰到本object 上方时的方法override public function hitTop(Contact:FlxObject, Velocity:Number):void {hurt(0);super.hitTop(Contact,Velocity);}//重写 碰到本object底部时的方法override public function hitBottom(Contact:FlxObject, Velocity:Number):void {hurt(0);super.hitBottom(Contact, Velocity);}//重写一下 hurt 方法,因为需要在 碰到障碍物的时候要设置些东东//比如 子弹速度 以及 播放爆炸的动画//参数:本objcet 所受到的 伤害值override public function hurt(Damage:Number):void {//如果子弹已经dead了,那么就不在做 hurt 的操作//为什么不是 判断 exist ,因为 exist为 false 已经消失,不会受到任何渲染//而 dead 为 true时,虽然是死亡了,但是 仍然 被渲染,//我们需要的是,子弹 虽然 已经 死亡,但 仍然 可以看到 爆炸动画if (dead) {return;}//子弹被碰一次直接设置dead为true,否则会不停调用该方法//同时也是为了在GameState中检测子弹与敌人触碰(不是碰撞检测,而是叠加检测)不发生连续伤害dead = true;//速度设置为0,因为碰撞后子弹爆炸是在 原地的//所以不需要移动了,当然如果你喜欢继续移动的爆炸的话。。。velocity.x = 0;velocity.y = 0;//播放爆炸动画了play('BulBoom');//至于为什么 不用 使用 super的 hurt 方法//因为本教程的子弹 碰撞后 是受到 0 伤害的//只要 完成 上面的几个语句就足够了//当然 加上也无妨,同学们可以看看 super 的hurt 方法的内容//就知道为什么这里可以不加了//super.hurt(Damage);}override public function update():void {//使用 dead 是判断子弹是否碰到障碍物而'死掉',//使用 finish 是为了判断子弹的爆炸动画是否完成,//2个一起 就说明子弹完成动画并且'死掉',这样子弹就消失了//至于为什么 super的update 只放在 else 里面//因为 子弹消失后 没必要再 update 了,还能省点CPU资源....//还是那句话,要也无妨。。。if (dead && finished) {exists = false;}else {super.update();}}}}

 下面是 Player 类中需要加入的:

 

package {import org.flixel.FlxG;import org.flixel.FlxGroup;import org.flixel.FlxSprite;/*** ...* @author zb*/public class Player extends FlxSprite {/********* 教程(二)中所声明的 ***********///....我省略掉了,参考源文件即可//看新加入部分即可//子弹组//flxGroup 就是一种 组,有数组的储存,用于flixel的各种控制检测//用flxGroup 将多个 object 添加进 组,方便管理public var bullets:FlxGroup;//当前可以发射的子弹索引private var currentBul:uint = 0;public function Player(startX:Number=100,startY:Number=50):void {//********* 教程(二)中在构造方法里已经写的内容 ********/}public override function update():void{//********* 教程(二)中在update里已经写的内容 ********///子弹发射设置//为了让教程的顺序比较好写,这里加了个判断//这样 子弹 就不需要在Player构造的时候必须存在了if (bullets!=null) {//按 C 键 发射子弹吧if (FlxG.keys.justPressed('C')) {//按 上 的时候 向上 发射子弹if (FlxG.keys.UP) {//member 是 Array 类型,//存放在 bullets中的元素都可以通过 members 找到//shoot 的时候 将 player 的 x y 坐标作为初始点来调整bullets.members[currentBul].shoot(x, y-4, 0, -250);}else if (FlxG.keys.DOWN) {//按下的时候向下 发射子弹bullets.members[currentBul].shoot(x, y+4, 0, 250);}else if (facing==LEFT) {//人物面向左的时候 向左发射子弹//为什么不用 按下 左的时候呢//因为 不按按钮的时候 仍然需要可以发射子弹呢。。。bullets.members[currentBul].shoot(x-4, y, -250, 0);}else if(facing==RIGHT){//人物面向右的时候 向右发射子弹bullets.members[currentBul].shoot(x+4, y, 250, 0);}//子弹已经发射,索引变成下一个的currentBul++;//求余数的运算,这样 索引就会 循环了currentBul %= bullets.members.length;/** 注意 **///目前对 子弹 是否可以 发射,没有设置相应的属性 来进行判断//因此 当 按键够快,同时 子弹移动的速度 比较慢时//就可以明显的看到 发射出去的子弹 还没有消失//就被 马上 拉回来 重新发射出去//请同学们 自行 加入相应的判断,给个提示//比如给Bullet 加入一个 isShooting 的boolean 属性}}/*** 切记 ***///这个语句一定要加上去,只要重写了update,就一定要调用 super的update//否则不会刷新动画。。也不会响应你在这里所设置的控制super.update();}}}

 运行看看效果吧,嘿嘿~

 

 

 

需要做网站?需要网络推广?欢迎咨询客户经理 13272073477