Path: blob/main/public/games/files/garbage-collector/js/entities/emitter.js
1036 views
/*jshint bitwise: false*/1/*globals define*/2define([3'entities/physics-entity',4'entities/trash',5'geometry/geometry-factory',6'config/colors',7'config/material',8'config/settings',9'utils'10], function( PhysicsEntity, Trash, GeometryFactory, Colors, Material, Settings, Utils ) {11'use strict';1213var defaults = {14aspectRatio: 0.1,1516portalRadiusRatio: 0.6,17coneRadiusRatio: 1.5,18coneLengthRatio: 2,1920speed: 0,2122// Both are in seconds.23rate: 0,24lifeTime: 025};2627function Emitter( x, y, options ) {28PhysicsEntity.call( this, {29fixture: {30isSensor: true31},32body: {33position: {34x: x,35y: y36}37}38});3940Utils.defaults( this, options, defaults );4142this.spawnArea = null;43this.particle = null;44// Any custom particle physics properties go here.45this.properties = {};4647this.time = 0;48this.firing = false;49}5051Emitter.prototype = new PhysicsEntity();52Emitter.prototype.constructor = Emitter;5354Emitter.prototype.update = function( dt ) {55PhysicsEntity.prototype.update.call( this, dt );5657if ( !this.firing ) {58return;59}6061this.time += dt;62if ( this.time > this.rate ) {63this.time = 0;64this.fire();65}66};6768Emitter.prototype.fire = function() {69if ( !this.particle || !this.game ) {70return;71}7273// Initial state of a random point.74var state = this.random();7576// Create entities with the properties of the initial state.77var entity = new Trash( this.properties, this.lifeTime );7879entity.x = state.x;80entity.y = state.y;81entity.accelerate( state.vx, state.vy );8283// Add any specified shapes.84var particleJSON = JSON.stringify( this.particle );85entity.add( GeometryFactory.create( particleJSON ) );8687this.game.add( entity );88};8990/**91* Get the initial position and acceleration of particle.92*/93Emitter.prototype.random = function() {94var x = this.x,95y = this.y;9697var cos = 1,98sin = 0;99100if ( this.angle ) {101cos = Math.cos( -this.angle );102sin = Math.sin( -this.angle );103}104105// Spawn inside an area (rect, circle, segment).106var point;107if ( this.spawnArea ) {108point = this.spawnArea.random();109point = this.toWorld( point.x, point.y );110x = point.x;111y = point.y;112}113114return {115x: x,116y: y,117vx: cos * this.speed,118vy: sin * this.speed119};120};121122Emitter.prototype.start = function( when ) {123when = when || 0;124125setTimeout(function() {126this.firing = true;127this.time = 0;128}.bind( this ), when );129};130131Emitter.prototype.stop = function( when ) {132when = when || 0;133134setTimeout(function() {135this.firing = false;136}.bind( this ), when );137};138139Emitter.prototype.drawPath = function( ctx ) {140var material = this.properties.fixture.filter.categoryBits;141142// The radius of the portal opening.143var portalRadius = this.portalRadius;144145var coneRadius = portalRadius * this.coneRadiusRatio,146coneLength = portalRadius * this.coneLengthRatio;147148var glowColor = Colors.Glow[ Material.type( material ) ];149150ctx.save();151ctx.scale( this.aspectRatio, 1 );152ctx.beginPath();153154// Draw warp hole.155ctx.arc( 0, 0, portalRadius, 0, 2 * Math.PI );156ctx.restore();157158ctx.fillStyle = '#000';159ctx.fill();160161// Draw ring.162if ( Settings.glow ) {163ctx.globalCompositeOperation = 'lighter';164}165166if ( glowColor ) {167ctx.strokeStyle = glowColor;168ctx.lineWidth = 0.3 + Math.random() * 0.2;169ctx.stroke();170}171172ctx.strokeStyle = '#fff';173ctx.lineWidth = 0.1;174ctx.stroke();175176if ( Settings.gradients && glowColor ) {177var grad = ctx.createLinearGradient( 0, 0, coneLength, 0 );178grad.addColorStop( 0, glowColor );179grad.addColorStop( 1, 'transparent' );180181ctx.fillStyle = grad;182ctx.beginPath();183ctx.moveTo( 0, -portalRadius );184ctx.lineTo( coneLength, -coneRadius );185ctx.lineTo( coneLength, coneRadius );186ctx.lineTo( 0, portalRadius );187ctx.fill();188}189190if ( Settings.glow ) {191ctx.globalCompositeOperation = 'source-over';192}193194PhysicsEntity.prototype.drawPath.call( this, ctx );195};196197Emitter.prototype.aabb = function() {198return null;199};200201Object.defineProperty( Emitter.prototype, 'portalRadius', {202get: function() {203return this.spawnArea.height * this.portalRadiusRatio;204}205});206207return Emitter;208});209210211