Path: blob/main/public/games/files/garbage-collector/js/entities/player.js
1036 views
/*jshint bitwise: false*/1/*globals define*/2define([3'box2d',4'entities/physics-entity',5'config/colors',6'config/material',7'config/settings',8'utils'9], function( Box2D, PhysicsEntity, Colors, Material, Settings, Utils ) {10'use strict';1112var PI2 = Utils.PI2;1314var Emotion = {15NORMAL: 0,16HIT: 117};1819function Player( x, y ) {20PhysicsEntity.call( this, {21shape: 'circle',22radius: 3,23fixture: {24density: 0.25,25friction: 0.5,26restitution: 0.2,27filter: {28categoryBits: Material.MATTER29}30},31body: {32position: {33x: x,34y: y35},36linearDamping: 2,37angularDamping: 0.1,38type: 'dynamic'39}40});4142this.emotion = Emotion.NORMAL;43this.emotionTimeout = null;44}4546Player.Emotion = Emotion;4748Player.prototype = new PhysicsEntity();49Player.prototype.constructor = Player;5051Player.prototype.draw = function( ctx ) {52// 0.4 compensates for the difference between the drawn and fixture radii.53// The drawn ring is at a radius of 0.35 with a maximum lineWidth of 0.18.54// This results in a total relative width of (0.35 + 0.09) * 2 = 0.88.55// 0.88 * 3 (physical radius) = 2.64 (draw radius).56// Whereas:57// 0.88 * (3 + 0.4) = 2.992, which gives some spacing.58var radius = this.fixture.GetShape().GetRadius() + 0.4;5960var width = 2 * radius,61height = 2 * radius;6263ctx.save();64ctx.translate( this.x, this.y );65if ( this.angle ) {66ctx.rotate( this.angle );67}6869// Draw casing.70ctx.lineWidth = 0.05 * width;7172// Top left.73ctx.beginPath();74ctx.arc( 0, 0, 0.22 * width, -Math.PI, -0.5 * Math.PI );75ctx.strokeStyle = '#fef';76ctx.stroke();7778// Top right.79ctx.beginPath();80ctx.arc( 0, 0, 0.22 * width, -0.5 * Math.PI, 0 );81ctx.strokeStyle = '#cbe';82ctx.stroke();8384// Bottom right.85ctx.beginPath();86ctx.arc( 0, 0, 0.22 * width, 0, 0.5 * Math.PI );87ctx.strokeStyle = '#98b';88ctx.stroke();8990// Bottom left.91ctx.beginPath();92ctx.arc( 0, 0, 0.22 * width, 0.5 * Math.PI, Math.PI );93ctx.strokeStyle = '#658';94ctx.stroke();9596// Draw main body.97ctx.beginPath();98ctx.arc( 0, 0, 0.2 * width, 0, PI2 );99ctx.fillStyle = '#ecf';100ctx.fill();101102// Strokes.103ctx.lineWidth = 0.02 * width;104ctx.strokeStyle = 'rgba(0, 0, 0, 0.5)';105ctx.stroke();106107ctx.beginPath();108ctx.arc( 0, 0, 0.18 * width, 0, PI2 );109ctx.strokeStyle = '#fff';110ctx.stroke();111112if ( this.angle ) {113ctx.save();114ctx.rotate( -this.angle - this.game.camera.angle );115}116117this.drawFace( ctx, width, height );118119if ( this.angle ) {120ctx.restore();121}122123this.drawRing( ctx, width );124};125126Player.prototype.drawFace = function( ctx, width, height ) {127var faceColor = Colors.Face;128129// Determine direction of movement.130var dx = Utils.inverseLerp( Math.abs( this.vx ), 0, 20 ),131dy = Utils.inverseLerp( Math.abs( this.vy ), 0, 20 );132133dx = Utils.clamp( dx, 0, 1 );134dy = Utils.clamp( dy, 0, 1 );135136dx *= this.vx < 0 ? -1 : 1;137dy *= this.vy < 0 ? -1 : 1;138139dx *= 0.05 * width;140dy *= 0.05 * width;141142dx += this.game.camera.x;143dy += this.game.camera.y;144145var d = this.game.camera.toLocal( dx, dy );146dx = d.x;147dy = d.y;148149if ( this.emotion === Emotion.NORMAL ) {150// Draw eyes.151ctx.beginPath();152153ctx.save();154ctx.scale( 0.6, 1 );155156// // Draw left eye.157ctx.arc( -0.12 * width + dx, dy, 0.07 * width, 0, PI2 );158// // Draw right eye.159ctx.arc( 0.12 * width + dx, dy, 0.07 * width, 0, PI2 );160161ctx.fillStyle = faceColor;162ctx.fill();163ctx.restore();164} else if ( this.emotion === Emotion.HIT ) {165// Draw X.166ctx.beginPath();167ctx.lineCap = 'round';168169// Smaller eye movements.170dx *= 0.5;171dy *= 0.5;172173// Left diagonal.174ctx.moveTo( -0.08 * width + dx, -0.07 * height + dy );175ctx.lineTo( 0.08 * width + dx, 0.07 * height + dy );176// Right diagonal.177ctx.moveTo( -0.08 * width + dx, 0.07 * height + dy );178ctx.lineTo( 0.08 * width + dx, -0.07 * height + dy );179180ctx.lineWidth = 0.04 * width;181ctx.strokeStyle = faceColor;182ctx.stroke();183184ctx.lineCap = 'butt';185}186};187188Player.prototype.drawRing = function( ctx, width ) {189if ( Settings.glow ) {190ctx.globalCompositeOperation = 'lighter';191}192193ctx.beginPath();194ctx.arc( 0, 0, 0.35 * width, 0, PI2 );195196var glowColor = Colors.Glow[ Material.type( this.material ) ];197198if ( glowColor ) {199ctx.lineWidth = ( 0.1 + Math.random() * 0.08 ) * width;200ctx.strokeStyle = glowColor;201ctx.stroke();202}203204ctx.lineWidth = 0.07 * width;205ctx.strokeStyle = '#fff';206ctx.stroke();207208if ( Settings.glow ) {209ctx.globalCompositeOperation = 'source-over';210}211212ctx.restore();213};214215Player.prototype.toggleMaterial = function() {216this.material = this.material ^ ( Material.MATTER | Material.ANTIMATTER );217};218219return Player;220});221222223