1
0
Fork 0

Added weapon visual effects and sound

This commit is contained in:
Michaël Lemaire 2015-02-20 01:00:00 +01:00
parent 53fefc25b8
commit 86ff98707d
16 changed files with 161 additions and 40 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

View file

@ -1,6 +1,6 @@
/// <reference path="pixi.d.ts" />
// Type definitions for Phaser dev2.2.0 RC12 2014-12-02
// Type definitions for Phaser dev2.2.0 RC12 2015-02-01
// Project: https://github.com/photonstorm/phaser
declare class Phaser {
@ -205,7 +205,7 @@ declare module Phaser {
add(object: any): Phaser.BitmapData;
addToWorld(x?: number, y?: number, anchorX?: number, anchorY?: number, scaleX?: number, scaleY?: number): Phaser.Image;
alphaMask(source: any, mask: any, sourceRect?: Phaser.Rectangle, maskRect?: Phaser.Rectangle): Phaser.BitmapData;
alphaMask(source: any, mask?: any, sourceRect?: Phaser.Rectangle, maskRect?: Phaser.Rectangle): Phaser.BitmapData;
blendAdd(): Phaser.BitmapData;
blendColor(): Phaser.BitmapData;
blendColorBurn(): Phaser.BitmapData;
@ -235,10 +235,11 @@ declare module Phaser {
circle(x: number, y: number, radius: number, fillStyle?: string): Phaser.BitmapData;
clear(): Phaser.BitmapData;
cls(): Phaser.BitmapData;
copy(source?: any, x?: number, y?: number, width?: number, height?: number, tx?: number, ty?: number, newWidth?: number, newHeight?: number, rotate?: number, anchorX?: number, anchorY?: number, scaleX?: number, scaleY?: number, alpha?: number, blendMode?: string, roundPx?: boolean): Phaser.BitmapData;
copy(source?: any, x?: number, y?: number, width?: number, height?: number, tx?: number, ty?: number, newWidth?: number, newHeight?: number, rotate?: number, anchorX?: number, anchorY?: number, scaleX?: number, scaleY?: number, alpha?: number, blendMode?: number, roundPx?: boolean): Phaser.BitmapData;
copyPixels(source: any, area: Phaser.Rectangle, x: number, y: number, alpha?: number): void;
copyRect(source: any, area: Phaser.Rectangle, x?: number, y?: number, alpha?: number, blendMode?: string, roundPx?: boolean): Phaser.BitmapData;
draw(source: any, x?: number, y?: number, width?: number, height?: number, blendMode?: string, roundPx?: boolean): Phaser.BitmapData;
copyRect(source: any, area: Phaser.Rectangle, x?: number, y?: number, alpha?: number, blendMode?: number, roundPx?: boolean): Phaser.BitmapData;
draw(source: any, x?: number, y?: number, width?: number, height?: number, blendMode?: number, roundPx?: boolean): Phaser.BitmapData;
drawGroup(group: Phaser.Group, blendMode?: number, roundPx?: boolean): Phaser.BitmapData;
extract(destination: Phaser.BitmapData, r: number, g: number, b: number, a?: number, resize?: boolean, r2?: number, g2?: number, b2?: number): Phaser.BitmapData;
fill(r: number, g: number, b: number, a?: number): Phaser.BitmapData;
getBounds(rect?: Phaser.Rectangle): Phaser.Rectangle;
@ -599,6 +600,13 @@ declare module Phaser {
class Device {
static LITTLE_ENDIAN: boolean;
static onInitialized: Phaser.Signal;
static checkFullScreenSupport(): void;
static canPlayAudio(type: string): boolean;
static isConsoleOpen(): boolean;
static isAndroidStockBrowser(): string;
static whenReady: (callback: Function, context?: any) => void;
android: boolean;
arora: boolean;
@ -643,7 +651,6 @@ declare module Phaser {
node: boolean;
nodeWebkit: boolean;
ogg: boolean;
onInitialized: Phaser.Signal;
opera: boolean;
opus: boolean;
pixelRatio: number;
@ -669,24 +676,6 @@ declare module Phaser {
wheelEvent: string;
worker: boolean;
checkFullScreenSupport(): void;
_checkAudio(): void;
_checkBrowser(): void;
_checkCSS3D(): void;
_checkDevice(): void;
_checkFeatures(): void;
_checkFullScreenSupport(): void;
_checkInput(): void;
_checkIsLittleEndian(): void;
_checkIsUint8ClampedImageData(): boolean;
_checkOS(): void;
canPlayAudio(type: string): boolean;
_initialze(): void;
isConsoleOpen(): boolean;
isAndroidStockBrowser(): string;
_readyCheck(): void;
whenReady: (callback: Function, context?: any) => void;
}
class DOMSprite {
@ -814,6 +803,7 @@ declare module Phaser {
onKilled: Phaser.Signal;
onRevived: Phaser.Signal;
onOutOfBounds: Phaser.Signal;
onEnterBounds: Phaser.Signal;
onInputOver: Phaser.Signal;
onInputOut: Phaser.Signal;
onInputDown: Phaser.Signal;
@ -1226,7 +1216,7 @@ declare module Phaser {
filter(filter: any, ...args: any[]): Phaser.Filter;
graphics(x: number, y: number): Phaser.Graphics;
group(parent?: any, name?: string, addToStage?: boolean, enableBody?: boolean, physicsBodyType?: number): Phaser.Group;
image(x: number, y: number, key: any, frame?: any): Phaser.Image;
image(x: number, y: number, key?: any, frame?: any): Phaser.Image;
renderTexture(width?: number, height?: number, key?: any, addToCache?: boolean): Phaser.RenderTexture;
retroFont(font: string, characterWidth: number, characterHeight: number, chars: string, charsPerRow: number, xSpacing?: number, ySpacing?: number, xOffset?: number, yOffset?: number): Phaser.RetroFont;
rope(x: number, y: number, key: any, frame?: any, points?: Phaser.Point[]): Phaser.Rope;
@ -1257,7 +1247,7 @@ declare module Phaser {
filter(filter: string, ...args: any[]): Phaser.Filter;
graphics(x: number, y: number, group?: Phaser.Group): Phaser.Graphics;
group(parent?: any, name?: string, addToStage?: boolean, enableBody?: boolean, physicsBodyType?: number): Phaser.Group;
image(x: number, y: number, key: any, frame?: any, group?: Phaser.Group): Phaser.Image;
image(x: number, y: number, key?: any, frame?: any, group?: Phaser.Group): Phaser.Image;
physicsGroup(physicsBodyType: number, parent?: any, name?: string, addToStage?: boolean): Phaser.Group;
plugin(plugin: Phaser.Plugin, ...parameter: any[]): Phaser.Plugin;
renderTexture(width?: number, height?: number, key?: string, addToCache?: boolean): Phaser.RenderTexture;
@ -1480,7 +1470,7 @@ declare module Phaser {
divideAll(property: string, amount: number, checkAlive?: boolean, checkVisible?: boolean): void;
forEach(callback: Function, callbackContext: any, checkExists?: boolean, ...args: any[]): void;
forEachAlive(callback: Function, callbackContext: any, ...args: any[]): void;
forEachDead(callback: Function, callbackContext: any, ...args:any[]): void;
forEachDead(callback: Function, callbackContext: any, ...args: any[]): void;
forEachExists(callback: Function, callbackContext: any): void;
filter(predicate: Function, checkExists?: boolean): ArraySet;
getAt(index: number): any;
@ -1907,6 +1897,9 @@ declare module Phaser {
height: number;
left: number;
length: number;
normalAngle: number;
normalX: number;
normalY: number;
perpSlope: number;
right: number;
slope: number;
@ -1918,13 +1911,16 @@ declare module Phaser {
static intersectsPoints(a: Phaser.Point, b: Phaser.Point, e: Phaser.Point, f: Phaser.Point, asSegment?: boolean, result?: Phaser.Point): Phaser.Point;
static intersects(a: Phaser.Line, b: Phaser.Line, asSegment?: boolean, result?: Phaser.Point): Phaser.Point;
static reflect(a: Phaser.Line, b: Phaser.Line): number;
clone(output: Phaser.Line): Phaser.Line;
coordinatesOnLine(stepRate: number, results: any[]): any[];
fromAngle(x: number, y: number, angle: number, length: number): Phaser.Line;
fromSprite(startSprite: Phaser.Sprite, endSprite: Phaser.Sprite, useCenter?: boolean): Phaser.Line;
intersects(line: Phaser.Line, asSegment?: boolean, result?: Phaser.Point): Phaser.Point;
pointOnLine(x: number, y: number): boolean;
pointOnSegment(x: number, y: number): boolean;
reflect(line: Phaser.Line): number;
setTo(x1?: number, y1?: number, x2?: number, y2?: number): Phaser.Line;
}
@ -2251,7 +2247,7 @@ declare module Phaser {
on: boolean;
particleBringToTop: boolean;
particleSendToBack: boolean;
particleClass: Phaser.Sprite;
particleClass: typeof Phaser.Particle;
particleDrag: Phaser.Point;
position: Phaser.Point;
right: number;
@ -2269,7 +2265,7 @@ declare module Phaser {
kill(): void;
makeParticles(keys: any, frames?: any, quantity?: number, collide?: boolean, collideWorldBounds?: boolean): Phaser.Particles.Arcade.Emitter;
reset(x: number, y: number, health?: number): Phaser.Particles;
setAlpha(min?: number, max?: number, rate?: number, ease?: number, yoyo?: boolean): void;
setAlpha(min?: number, max?: number, rate?: number, ease?: (k: number) => number, yoyo?: boolean): void;
setRotation(min?: number, max?: number): void;
setScale(minX?: number, maxX?: number, minY?: number, maxY?: number, rate?: number, ease?: (k: number) => number, yoyo?: boolean): void;
setSize(width: number, height: number): void;
@ -3810,6 +3806,7 @@ declare module Phaser {
setBackgroundColor(backgroundColor: number): void;
setBackgroundColor(backgroundColor: string): void;
update(): void;
updateTransform(): void;
visibilityChange(event: any): void;
}
@ -3834,6 +3831,7 @@ declare module Phaser {
boundingParent: HTMLElement;
compatibility: {
canExpandParent: boolean;
clickTrampoline: string;
forceMinimumDocumentHeight: boolean;
noMargins: boolean;
scrollTo: Point;

View file

@ -1,4 +1,4 @@
// Type definitions for PIXI 2.2.0 dev 2014-11-02
// Type definitions for PIXI 2.2.0 dev 2014-16-12
// Project: https://github.com/GoodBoyDigital/pixi.js/
declare module PIXI {
@ -912,7 +912,7 @@ declare module PIXI {
constructor(...points: Point[]);
constructor(...points: number[]);
points: number[];
points: any[]; //number[] Point[]
clone(): Polygon;
contains(x: number, y: number): boolean;

View file

@ -9,6 +9,9 @@ module SpaceTac.Game {
// Type of slot this equipment can fit in
slot: SlotType;
// Identifiable equipment code (may be used by UI to customize visual effects)
code: string;
// Equipment name
name: string;
@ -40,9 +43,10 @@ module SpaceTac.Game {
target_effects: BaseEffect[];
// Basic constructor
constructor(slot: SlotType = null, name: string = null) {
constructor(slot: SlotType = null, code: string = null) {
this.slot = slot;
this.name = name;
this.code = code;
this.name = code;
this.requirements = [];
this.permanent_effects = [];
this.target_effects = [];

View file

@ -64,6 +64,7 @@ module SpaceTac.Game {
var result = new Equipment();
result.slot = this.slot;
result.code = Tools.getClassName(this);
result.name = this.name;
result.distance = this.distance.getProportional(power);

View file

@ -16,5 +16,10 @@ module SpaceTac.Game {
return objectCopy;
}
// Get a class name, from an instance
static getClassName(object: any): string {
return object.constructor.name;
}
}
}

View file

@ -43,6 +43,9 @@ module SpaceTac.Game {
protected customApply(battle: Battle, ship: Ship, target: Target): boolean {
if (target.ship) {
// Fire event
ship.addBattleEvent(new FireEvent(ship, this.equipment, target));
// Apply all target effects
var result = false;
this.equipment.target_effects.forEach((effect: BaseEffect) => {

View file

@ -145,14 +145,14 @@ module SpaceTac.Game.AI {
if (move.move_to) {
this.addWorkItem(() => {
move.engine.action.apply(this.battle, this.ship, move.move_to);
}, 1000);
}, 500);
}
this.addWorkItem(() => {
move.weapon.action.apply(this.fleet.battle, this.ship, Target.newFromShip(move.target));
}, 1500);
this.addWorkItem(null, 500);
this.addWorkItem(null, 1500);
}
}
}

View file

@ -188,16 +188,20 @@ module SpaceTac.Game.AI.Specs {
battle.log.clear();
ai.applyMove(move);
expect(battle.log.events.length).toBe(6);
expect(battle.log.events.length).toBe(7);
expect(battle.log.events[0]).toEqual(new MoveEvent(ship1, 2, 0));
expect(battle.log.events[1]).toEqual(new AttributeChangeEvent(ship1,
new Attribute(AttributeCode.AP, 2, 10)));
expect(battle.log.events[2]).toEqual(new AttributeChangeEvent(ship2,
new Attribute(AttributeCode.Shield, 0)));
expect(battle.log.events[2]).toEqual(new FireEvent(ship1, weapon, Target.newFromShip(ship2)));
expect(battle.log.events[3]).toEqual(new AttributeChangeEvent(ship2,
new Attribute(AttributeCode.Shield, 0)));
expect(battle.log.events[4]).toEqual(new AttributeChangeEvent(ship2,
new Attribute(AttributeCode.Hull, 5)));
expect(battle.log.events[4]).toEqual(new DamageEvent(ship2, 10, 10));
expect(battle.log.events[5]).toEqual(new AttributeChangeEvent(ship1,
expect(battle.log.events[5]).toEqual(new DamageEvent(ship2, 10, 10));
expect(battle.log.events[6]).toEqual(new AttributeChangeEvent(ship1,
new Attribute(AttributeCode.AP, 1, 10)));
});
});

View file

@ -0,0 +1,17 @@
/// <reference path="BaseLogEvent.ts"/>
module SpaceTac.Game {
"use strict";
// Event logged when a weapon is used on a target
export class FireEvent extends BaseLogEvent {
// Weapon used
weapon: Equipment;
constructor(ship: Ship, weapon: Equipment, target: Target) {
super("fire", ship, target);
this.weapon = weapon;
}
}
}

View file

@ -18,6 +18,7 @@ module SpaceTac.Game.Specs {
var equipment = template.generateFixed(0.0);
expect(equipment.slot).toEqual(SlotType.Weapon);
expect(equipment.code).toEqual("LootTemplate");
expect(equipment.name).toEqual("Bulletator");
expect(equipment.distance).toEqual(1);
expect(equipment.blast).toEqual(1);
@ -31,6 +32,7 @@ module SpaceTac.Game.Specs {
equipment = template.generateFixed(1.0);
expect(equipment.slot).toEqual(SlotType.Weapon);
expect(equipment.code).toEqual("LootTemplate");
expect(equipment.name).toEqual("Bulletator");
expect(equipment.distance).toEqual(3);
expect(equipment.blast).toEqual(1);
@ -44,6 +46,7 @@ module SpaceTac.Game.Specs {
equipment = template.generateFixed(0.5);
expect(equipment.slot).toEqual(SlotType.Weapon);
expect(equipment.code).toEqual("LootTemplate");
expect(equipment.name).toEqual("Bulletator");
expect(equipment.distance).toEqual(2);
expect(equipment.blast).toEqual(1);

View file

@ -28,6 +28,7 @@ module SpaceTac.View {
this.loadImage("battle/arena/shipspriteplaying.png");
this.loadImage("battle/ship-card.png");
this.loadImage("battle/actions/move.png");
this.loadImage("battle/weapon/bullet.png");
this.loadImage("ship/scout/sprite.png");
this.loadImage("ship/scout/portrait.png");
this.loadImage("common/standard-bar-background.png");
@ -35,6 +36,7 @@ module SpaceTac.View {
// Load sounds
this.loadSound("battle/ship-change.wav");
this.loadSound("battle/weapon-bullets.wav");
}
create() {

View file

@ -104,7 +104,9 @@ module SpaceTac.View {
}
private animateDamageText(text: Phaser.Text) {
text.alpha = 0;
var tween = this.game.tweens.create(text);
tween.to({alpha: 1}, 100, Phaser.Easing.Circular.In, false, 500);
tween.to({y: -50, alpha: 0}, 800, Phaser.Easing.Circular.In, false, 200);
tween.onComplete.addOnce(() => {
text.destroy();

View file

@ -48,6 +48,9 @@ module SpaceTac.View {
case "death":
this.processDeathEvent(<Game.DeathEvent>event);
break;
case "fire":
this.processFireEvent(<Game.FireEvent>event);
break;
}
}
@ -98,5 +101,15 @@ module SpaceTac.View {
this.view.arena.removeShip(event.ship);
this.view.ship_list.removeShip(event.ship);
}
// Weapon used
private processFireEvent(event: Game.FireEvent): void {
// TODO Handle in-space target
var source = this.view.arena.findShipSprite(event.ship);
var destination = this.view.arena.findShipSprite(event.target.ship);
var effect = new WeaponEffect(source, destination, event.weapon.code);
effect.start();
}
}
}

View file

@ -0,0 +1,69 @@
module SpaceTac.View {
"use strict";
// Particle that is rotated to always face its ongoing direction
class BulletParticle extends Phaser.Particle {
update(): void {
super.update();
this.rotation = Math.atan2(this.body.velocity.y, this.body.velocity.x);
}
}
// Renderer of visual effects for a weapon fire
export class WeaponEffect {
// Firing ship
private source: ArenaShip;
// Targetted ship
private destination: ArenaShip;
// Weapon class code (e.g. GatlingGun, ...)
private weapon: string;
// Effect in use
private effect: Function;
constructor(source: ArenaShip, destination: ArenaShip, weapon: string) {
this.source = source;
this.destination = destination;
this.weapon = weapon;
this.effect = this.getEffectForWeapon(weapon);
}
// Start the visual effect
start(): void {
if (this.effect) {
this.effect.call(this);
}
}
// Get the function that will be called to start the visual effect
getEffectForWeapon(weapon: string): Function {
return this.defaultEffect;
}
// Default firing effect (bullets)
private defaultEffect(): void {
this.source.game.sound.play("battle-weapon-bullets");
var source = this.source.sprite.toGlobal(new PIXI.Point(0, 0));
var destination = this.destination.sprite.toGlobal(new PIXI.Point(0, 0));
var dx = destination.x - source.x;
var dy = destination.y - source.y;
var angle = Math.atan2(dy, dx);
var distance = Math.sqrt(dx * dx + dy * dy);
var emitter = new Phaser.Particles.Arcade.Emitter(this.source.game, source.x, source.y, 10);
var speed = 5000;
var scale = 0.1;
emitter.particleClass = BulletParticle;
emitter.gravity = 0;
emitter.setRotation(0, 0);
emitter.minParticleSpeed.set(Math.cos(angle) * speed, Math.sin(angle) * speed);
emitter.maxParticleSpeed.set(Math.cos(angle) * speed, Math.sin(angle) * speed);
emitter.minParticleScale = scale;
emitter.maxParticleScale = scale;
emitter.makeParticles(["battle-weapon-bullet"]);
emitter.start(false, 1000 * distance / speed, 50, 10);
}
}
}