Path: blob/main/public/games/files/garbage-collector/js/entities/laser.js
1036 views
/*jshint bitwise: false*/1/*globals define*/2define([3'box2d',4'entities/explosion',5'entities/physics-entity',6'entities/player',7'config/colors',8'config/material',9'config/settings',10'utils',11'world'12], function( Box2D, Explosion, PhysicsEntity, Player, Colors, Material, Settings, Utils, world ) {13'use strict';1415var PI2 = Utils.PI2;1617var Vec2 = Box2D.Common.Math.b2Vec2;1819function Laser( x, y, material ) {20PhysicsEntity.call( this, {21fixture: {22isSensor: true,23filter: {24categoryBits: material25}26},27body: {28position: {29x: x,30y: y31}32}33});3435this.target = null;36this.endpoint = null;37this.normal = null;38this.fraction = Number.POSITIVE_INFINITY;39}4041Laser.prototype = new PhysicsEntity();42Laser.prototype.constructor = Laser;4344Laser.prototype.update = function( dt ) {45PhysicsEntity.prototype.update.call( this, dt );4647var cos = 1,48sin = 0;4950if ( this.angle ) {51cos = Math.cos( -this.angle );52sin = Math.sin( -this.angle );53}5455this.target = null;56this.endpoint = null;57this.fraction = Number.POSITIVE_INFINITY;5859world.RayCast(60function( fixture, point, normal, fraction ) {61var target = fixture.GetBody().GetUserData();62if ( !( target.material & this.material ) ) {63return -1;64}6566if ( fraction < this.fraction ) {67this.target = target;68this.normal = normal;69this.endpoint = point;70this.fraction = fraction;71}7273return fraction;74}.bind( this ),75new Vec2( this.x + cos, this.y + sin ),76new Vec2( this.x + 1e4 * cos, this.y + 1e4 * sin )77);7879if ( !this.target ) {80return;81}8283// Delete target.84var target = this.target;85if ( target !== this &&86target.material !== Material.BIMATTER &&87!( target instanceof Player ) &&88target.game ) {89this.game.removed.push( target );9091if ( Settings.explosions ) {92var explosion, fill;93fill = Colors.Explosion[ Material.type( target.material ) ];9495if ( fill ) {96explosion = new Explosion( target.x, target.y );97explosion.fill.set( fill );98this.game.add( explosion );99}100}101}102};103104Laser.prototype.drawPath = function( ctx ) {105// Draw laser source.106ctx.beginPath();107108// The laser starts at a radius of 1.109ctx.rect( -1, -0.5, 2, 1 );110ctx.fillStyle = '#000';111ctx.fill();112113PhysicsEntity.prototype.drawPath.call( this, ctx );114};115116Laser.prototype.draw = function( ctx ) {117PhysicsEntity.prototype.draw.call( this, ctx );118119// Only render beam if there is no endpoint and target,120// or if the target has not been removed from the game.121if ( !this.endpoint || !this.target ||122( this.target && !this.target.game ) ) {123return;124}125126if ( Settings.glow ) {127ctx.globalCompositeOperation = 'lighter';128}129130var cos = Math.cos( -this.angle ),131sin = Math.sin( -this.angle );132133var x0 = this.x + cos,134y0 = this.y + sin,135x1 = this.endpoint.x,136y1 = this.endpoint.y;137138ctx.beginPath();139ctx.moveTo( x0, y0 );140ctx.lineTo( x1, y1 );141142var outerWidth = 0.4 + Math.random() * 0.2,143innerWidth = 0.1 + Math.random() * 0.1;144145// Draw beam.146var glowColor = Colors.Glow[ Material.type( this.material ) ];147148if ( glowColor ) {149ctx.lineWidth = outerWidth;150ctx.strokeStyle = glowColor;151ctx.stroke();152}153154ctx.lineWidth = innerWidth;155ctx.strokeStyle = '#fff';156ctx.stroke();157158// Draw endpoint glows.159ctx.beginPath();160ctx.arc( x0, y0, innerWidth * 2, 0, PI2 );161ctx.moveTo( x1, y1 );162ctx.arc( x1, y1, innerWidth * 2, 0, PI2 );163164if ( glowColor ) {165ctx.lineWidth = outerWidth;166ctx.strokeStyle = glowColor;167ctx.stroke();168}169170ctx.fillStyle = '#fff';171ctx.fill();172173if ( Settings.glow ) {174ctx.globalCompositeOperation = 'source-over';175}176};177178Laser.prototype.drawNormals = function( ctx ) {179if ( !this.endpoint || !this.normal ) {180return;181}182183ctx.save();184185// Counteract transofmrs in draw.186ctx.rotate( this.angle );187ctx.translate( -this.x, -this.y );188189ctx.beginPath();190ctx.moveTo( this.endpoint.x, this.endpoint.y );191ctx.lineTo( this.endpoint.x + this.normal.x, this.endpoint.y + this.normal.y );192ctx.lineWidth = 0.2;193ctx.strokeStyle = '#fff';194ctx.stroke();195196ctx.restore();197};198199Laser.prototype.aabb = function() {200var aabb;201if ( !this.endpoint ) {202aabb = PhysicsEntity.prototype.aabb();203return Utils.expandAABB( aabb, 1, 1 );204}205206var x0 = this.x,207y0 = this.y;208209var x1 = this.endpoint.x,210y1 = this.endpoint.y;211212aabb = {213xmin: Math.min( x0, x1 ),214ymin: Math.min( y0, y1 ),215xmax: Math.max( x0, x1 ),216ymax: Math.max( y0, y1 )217};218219// 1 is the pointer radius. 0.6 is the maximum glow radius.220var radius = 1.6;221return Utils.relativeExpandAABB( aabb, radius, radius );222};223224return Laser;225});226227228