Phaserjs基础教程第八节:Weapon对象

       首先,我们先来了解一下Weapon对象:Weapon对象也可以称为Weapon插件,它提供了快速创建和管理子弹池的能力。

       武器(Weapons)射击出子弹(Phaser.Bullet对象),这些子弹实际上是有一些额外属性的sprite对象,并且这些子弹还支持Arcade物理引擎,不过暂时不支持P2引擎。

       所有的子弹都被创建在一个叫Weapon.bullets的组(group)中,所以组对象支持的属性和方法,子弹组也都支持。

       子弹还可以有自己的纹理和动画,你也可以控制它的射击频率、移动速度、射击角度等等属性,甚至你还可以给它们添加重力。

       上面的内容几乎都是官网的翻译,下面我们先来看下面的代码,如果快速地创建一个会射击的小飞机:

var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render });

function preload() {
	//加载素材:子弹和飞机
    game.load.image('bullet', 'assets/sprites/bullet.png');
    game.load.image('ship', 'assets/sprites/shmup-ship.png');
}

var sprite;
var weapon;
var cursors;
var fireButton;
function create() {
    // 创建一颗子弹,使用bullet皮肤
    weapon = game.add.weapon(1, 'bullet');

    //当子弹超出窗口时自动销毁
    weapon.bulletKillType = Phaser.Weapon.KILL_WORLD_BOUNDS;

    //因为子弹的图片是横着的,所以要旋转一下角度
    weapon.bulletAngleOffset = 90;

    //子弹的速度/每秒钟位移的像素值
    weapon.bulletSpeed = 400;
	
    sprite = this.add.sprite(320, 500, 'ship');
    game.physics.arcade.enable(sprite);
    //告诉Weapon子弹的轨迹:横向14px(小飞机宽28px),纵向0px
    weapon.trackSprite(sprite, 14, 0);
	
	//启用方向键
    cursors = this.input.keyboard.createCursorKeys();
    //定义空格键为射击按键
    fireButton = this.input.keyboard.addKey(Phaser.KeyCode.SPACEBAR);
}

function update() {
	//初始化速度为0
    sprite.body.velocity.x = 0;
	//按下左方向键时速度为-200(左移),按下右方向键时速度为200(右移)
    if (cursors.left.isDown)
    {
        sprite.body.velocity.x = -200;
    }
    else if (cursors.right.isDown)
    {
        sprite.body.velocity.x = 200;
    }
	
	//按下空格键时,开火
    if (fireButton.isDown)
    {
        weapon.fire();
    }
}

function render() {
    weapon.debug();
}

       这个例子中,我们创建了一个会射击的小飞机,它只能左右移动,并且它每次只能发射一颗子弹,如果你担心它的子弹数量太少,那么修改下weapon = game.add.weapon(1, 'bullet');的数量即可,这个数量其实是子弹池的数量,同时也意味着同一时间屏幕上最多有这个数量的子弹数。

       上面的例子中,窗口中只有一颗子弹未免太单调了,不仅如此,子弹的颜色也太单一了,下面我们就再来看一个例子来熟悉weapon的各种属性:

var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render });

function preload() {
    game.load.image('ship', 'assets/sprites/thrust_ship.png');
    //这张图片长宽为320*4px,截取为4x4px一共有80个画面
    game.load.spritesheet('bullet', 'assets/sprites/rgblaser.png', 4, 4);
}

var sprite;
var weapon;
var cursors;
var fireButton;
function create() {
    //创建40颗子弹
    weapon = game.add.weapon(40, 'bullet');

    //加载时已经说过,截取图片中4x4像素为一个画面
    //第三个参数true告诉weapon类每次优先使用下一个画面,如果是false只会使用第一个画面
    //子弹发射时,80个画面全面使用完后从0开始
    weapon.setBulletFrames(0, 80, true);
    //下面这个参数相当于setBulletFrames函数的第三个参数
	//weapon.bulletFrameCycle = true;
	
	//子弹销毁方式
    weapon.bulletKillType = Phaser.Weapon.KILL_WORLD_BOUNDS;
    //weapon.bulletKillType = Phaser.Weapon.KILL_NEVER;

    //子弹速度
    weapon.bulletSpeed = 400;

    //射击频率(多少毫秒射击一次)
    weapon.fireRate = 50;

    //子弹超出边界时,会从边界的另一侧出现
    //weapon.bulletWorldWrap = true;

    sprite = this.add.sprite(400, 300, 'ship');
    sprite.anchor.set(0.5);
    game.physics.arcade.enable(sprite);
	//最大速度和减速设定
    sprite.body.drag.set(70);
    sprite.body.maxVelocity.set(200);

    //设置子弹轨迹,因为sprite.anchor已经设置为0.5,所以x方向不用位移了
    weapon.trackSprite(sprite, 0, 0, true);

    cursors = this.input.keyboard.createCursorKeys();
    fireButton = this.input.keyboard.addKey(Phaser.KeyCode.SPACEBAR);

	//自动射击
//  weapon.autofire = true;
}

function update() {
    if (cursors.up.isDown)
    {
    	//旋转加速度(先这么翻译吧,有点复杂)
        game.physics.arcade.accelerationFromRotation(sprite.rotation, 300, sprite.body.acceleration);
    }
    else
    {
    	//加速度设置为0
        sprite.body.acceleration.set(0);
    }

    if (cursors.left.isDown)
    {
    	//角速度=-300(旋转速度)
        sprite.body.angularVelocity = -300;
    }
    else if (cursors.right.isDown)
    {
        sprite.body.angularVelocity = 300;
    }
    else
    {
        sprite.body.angularVelocity = 0;
    }

    if (fireButton.isDown)
    {
        weapon.fire();
    }
	
	//是否换向显示
    game.world.wrap(sprite, 16);
}

function render() {
    weapon.debug();
}

       看过了两个例子,我们大概就知道了其中几个属性的含义了,不过还是要强调一下:

       bulletSpeed:子弹初速度(移动速度)。

       fireRate:射击频率(子弹出现的频率,单位毫秒,即多少毫秒出现一颗子弹)。

       trackSprite:上面已经说过,子弹的偏移量。

       autofire:这个简单,是否自动发射子弹。

       sprite.body.drag.set(70):API的翻译太过绕口,你直接理解成刹车速度就行,也就是停止时的速度减小量(每秒),这是一个{Phaser.Point}对象(和scale、anchor等一样),方法接收两个参数,比如这里只写了一个,其实也等于sprite.body.drag.set(70,70),之前没有讲到这个,这里补充下。

       sprite.body.maxVelocity.set(200):(小飞机)最大速度设定。

       angularVelocity:角速度,每秒旋转的角度。

       上面的代码只是发射一颗子弹,如果你想一次发射多颗子弹,也是可以的,只不过这些子弹还是直线弹道,虽然单个子弹可以设置便宜角度,但是没有办法像散弹枪一样,发射扇形的子弹(我研究了两个小时,在不修改源码的情况下没有办法实现,希望以后有这个功能吧),发射多颗子弹的代码也很简单,看下面的代码:

var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render });
function preload() {
    game.load.image('bullet', 'assets/bullets/bullet198.png');
    game.load.image('ship', 'assets/sprites/shmup-ship.png');
}

var sprite;
var weapon;
var cursors;
var fireButton;
var bulletPositions;
function create() {
    //定义48颗子弹
    weapon = game.add.weapon(6*8, 'bullet');

    weapon.bulletKillType = Phaser.Weapon.KILL_LIFESPAN;
    //子弹寿命,和上一条设定的Phaser.Weapon.KILL_LIFESPAN配合使用
    weapon.bulletLifespan = 2000;

    //子弹速度及角度(因为子弹会被横着绘制,所以需要设置角度便宜)
    weapon.bulletAngleOffset = 90;
    weapon.bulletSpeed = 400;
	
	//子弹随机角度
    // weapon.bulletAngleVariance = 20;
    sprite = this.add.sprite(320, 500, 'ship');
    game.physics.arcade.enable(sprite);
    //偏移量设置
    weapon.trackSprite(sprite, 14, 0);
    weapon.fireRate = 250;

    //开启多发
    weapon.multiFire = true;

    cursors = this.input.keyboard.createCursorKeys();
    fireButton = this.input.keyboard.addKey(Phaser.KeyCode.SPACEBAR);
    bulletPositions = [
        { x: 0, y: -32 },
        { x: -16, y: -16 },
        { x: 16, y: -16 },
        { x: -32, y: 0 },
        { x: 0, y: 0 },
        { x: 32, y: 0 }
    ];
}

function update() {
    sprite.body.velocity.x = 0;
    if (cursors.left.isDown)
    {
        sprite.body.velocity.x = -200;
    }
    else if (cursors.right.isDown)
    {
        sprite.body.velocity.x = 200;
    }
    if (fireButton.isDown)
    {
        //每次射击发射6颗子弹
        weapon.fireMany(bulletPositions);
    }
}

function render() {
    weapon.debug();
}

       步骤其实很简单,创建多颗子弹,开启多发,设定各个子弹的偏移量,然后就OK了,是不是很简单?

       还有一个属性需要了解下,就是weapon的bulletAngleVariance属性,我在上面的代码中也注释过了,它给所有的子弹提供了一个随机的发射角度,而且每次刷新都是相对于当前的位置随机的,所以会出现一条随机的弹道,只是很遗憾,我还是没有找到在不修改源代码的情况下发射扇形子弹的方法。

       好吧,这一节就这样了,教程阅读到这里,游戏页面的制作流程和方法大家也都熟悉了,那么下一节让我们进入实战吧,也是这个教程系列的最后一节,模拟经典游戏:雷电。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值