Amazing-Python-Scripts
428 строк · 9.6 Кб
1(function(){2
3var FULL_CIRCLE = 2*Math.PI;4var HALF_CIRCLE = FULL_CIRCLE/2;5var QUARTER_CIRCLE = FULL_CIRCLE/4;6var FIFTH_CIRCLE = FULL_CIRCLE/5;7
8// Drawing positions don't change so calculate them once up front9var INNER_ROTOR_1_POS = (QUARTER_CIRCLE * 3);10var INNER_ROTOR_2_POS = QUARTER_CIRCLE;11var OUTER_ROTOR_1_POS = 0;12var OUTER_ROTOR_2_POS = HALF_CIRCLE;13
14// http://github.grumdrig.com/jsfxr/15// http://www.superflashbros.net/as3sfxr/16// var effects = window.Effects;17// effects.add('cannon', 5, [18// [0,,0.22,1,0.08,0.31,0.11,-0.4399,-0.76,,,-0.7,0.27,0.74,-0.3199,,,-0.0444,1,,,,,0.5],19// [0,,0.26,1,0.08,0.29,0.12,-0.4399,-0.76,,,-0.7,0.27,0.74,-0.3199,,,-0.0444,1,,,,,0.5]20// ]);21
22window.Ship = function(options){23var self = this;24
25options = options || {};26self.x = options.x || 0;27self.y = options.y || 0;28self.bounds = options.bounds;29
30self._rotation = 0;31self._acceleration = 0.2;32self._maxSpeed = 5;33self._motion = 0;34self._drag = 0.05;35self._lastFired = 0;36self._lastBurst = 0;37self._burst = 0;38self._bulletX = undefined;39self._bulletY = undefined;40
41// Cannon settings42self.burstLength = 3;43self.roundDelay = 90;44self.burstDelay = (self.burstLength * self.roundDelay) + 540;45self.cannonAngle = 0;46
47self.bulletsFired = 0;48
49// Change settings on the ship by applying options passed in50// to the instance. Used for cannon but could do health or speed51// etc too.52self.powerup = function(options){53extend(self, options);54self.burstDelay = (self.burstLength * self.roundDelay) + 540;55}56
57// Health is set to 3 to start, each hit removes 1 hp58self.health = 3;59
60var createParticle = function(x, y){61self.assetList.add(new Particle({62x: x,63y: y,64speed: 3,65speedVariation: 1,66angle: 5,67angleVariation: 1.5,68bounds: self.bounds,69life: 1000,70particleLength: 7,71color: [255, 132, 0]72}));73}74
75var createSmokeParticle = function(x, y){76self.assetList.add(new Particle({77x: x,78y: y,79speed: 3,80speedVariation: 1,81angle: 5,82angleVariation: 1.5,83bounds: self.bounds,84life: 2000,85radius: 60,86color: [200, 200, 200]87}));88}89
90self._particleTime = 0;91
92// Update the position of the ship based on frameTime93self.update = function(frameTime, delta){94if(self.health > 0){95self.updateRotor(delta);96self.updateMovement(delta);97self.updateCannon(delta);98
99var lastFired = self._lastFired + frameTime;100var lastBurst = self._lastBurst + frameTime;101var burst = self._burst;102
103// If the user has pressed fire then start a burst104if(Input.fire() && burst < 1 && lastBurst > self.burstDelay){105burst = self.burstLength;106lastBurst = 0;107}108
109// If there is one or more rounds in the burst then110// fire a new one if we have waited long enough between111// rounds.112if(burst > 0 && lastFired > self.roundDelay){113self.fire();114--burst;115lastFired = 0;116}117
118// Store the values for next time119self._lastFired = lastFired;120self._lastBurst = lastBurst;121self._burst = burst;122
123// Throw some particles if we're damaged124if(self.health < 3){125
126self._particleTime += frameTime;127if(self._particleTime > 100){128self._particleTime -= 100;129
130// Throw particles from the main roter if we're on 2 health131var num = self.health < 2 ? 2 : 1;132for(var i=0; i<num; ++i){133createParticle(self.x, self.y+40);134createSmokeParticle(self.x, self.y+40);135}136}137}138}139}140
141self.updateCannon = function(delta){142var mouse = Input.mouse();143var diff = {144x: mouse.x - self.x,145y: mouse.y - self.y - 10146};147
148var theta = Math.atan2(-diff.y, diff.x);149
150if(theta < 0)151theta += 2 * Math.PI;152
153self.cannonAngle = theta;154}155
156self.updateRotor = function(delta){157var rotation = self._rotation;158rotation -= (FULL_CIRCLE/30) * delta;159if(rotation < -FULL_CIRCLE){160rotation += FULL_CIRCLE;161}162self._rotation = rotation;163}164
165self.updateMovement = function(delta){166var acceleration = self._acceleration * delta;167var drag = self._drag * delta;168var maxSpeed = self._maxSpeed;// * delta;169
170var motion = self._motion;// * delta;171var bounds = self.bounds;172
173// Capture movement inputs174var userInput = false;175if(Input.right()){176motion += acceleration;177userInput = true;178}179if(Input.left()){180motion -= acceleration;181userInput = true;182}183
184// Limmit the max speed185motion = Math.max(-maxSpeed, Math.min(maxSpeed, motion));186
187// Apply drag if we're not actively moving188var stoppedByDrag = false;189if(!userInput){190
191if(motion > drag){192motion -= drag;193}else if(motion < -drag){194motion += drag;195}else{196motion = 0;197}198}199
200// Calculate the new x position201var newX = self.x + (motion * delta);202
203// Adjust the bounds by 30px to stop the ship moving half off the screen204var boundsLeft = self.bounds.left + 30;205var boundsRight = self.bounds.right - 30;206
207// Respect bounds208if(newX > boundsRight){209motion = 0;210newX = boundsRight;211}else if(newX < boundsLeft){212motion = 0;213newX = boundsLeft;214}215
216// Update the x position217self.x = newX;218
219// Store the current motion for next time220self._motion = motion;221}222
223// Draw the helicopter224self.draw = function(ctx){225var x = self.x;226var y = self.y;227
228ctx.lineWidth = 1;229ctx.strokeStyle = 'rgba(255, 255, 255, 1)';230ctx.fillStyle = 'rgba(0, 0, 0, 1)';231
232self.drawCannon(ctx);233ctx.drawImage(SHIP_SPRITE, x-21, y-1);234self.drawRoter(ctx);235}236
237self.drawCannon = function(ctx){238var x = self.x;239var y = self.y + 10;240var endX = self._bulletX = x + 20 * Math.cos(self.cannonAngle);241var endY = self._bulletY = y + 20 * -Math.sin(self.cannonAngle);242
243ctx.beginPath();244ctx.moveTo(endX, endY);245ctx.lineTo(x, y);246ctx.stroke();247}248
249self.drawRoter = function(ctx){250var x = self.x;251var y = self.y+40;252var rotation = self._rotation;253
254// Apply the rotation value to the rotor line positions255var innerRotor1Pos = INNER_ROTOR_1_POS + rotation;256var innerRotor2Pos = INNER_ROTOR_2_POS + rotation;257var outerRotor1Pos = OUTER_ROTOR_1_POS + rotation;258var outerRotor2Pos = OUTER_ROTOR_2_POS + rotation;259
260// Inner blade trail261drawArc(ctx, x, y, 23, innerRotor1Pos, innerRotor1Pos + FIFTH_CIRCLE);262drawArc(ctx, x, y, 25, innerRotor2Pos, innerRotor2Pos + FIFTH_CIRCLE);263
264// Change the radius of one of the arcs depending on damage265var innerRadius;266switch(self.health){267case 1:268innerRadius = 50;269break;270case 2:271innerRadius = 55;272break;273default:274innerRadius = 60;275}276
277// Outer blade trail278drawArc(ctx, x, y, innerRadius, outerRotor1Pos, outerRotor1Pos + FIFTH_CIRCLE);279drawArc(ctx, x, y, 60, outerRotor2Pos, outerRotor2Pos + FIFTH_CIRCLE);280}281
282self.fire = function(){283++self.bulletsFired;284
285// effects.play('cannon');286
287self.assetList.add(new Bullet({288x: self._bulletX,289y: self._bulletY,290speed: 10,291speedVariation: 1,292angle: self.cannonAngle,293angleVariation: 0.1,294bounds: self.bounds295}));296}297
298// Returns an array of rects that define hit boxes for299// the different parts of the ship. A single rect isn't300// precise enough for a complex shape like a helicopter.301self.getRects = function(){302return [303{304top: self.y,305right: self.x + 10,306bottom: self.y + 60,307left: self.x - 10308},309{310top: self.y + 30,311right: self.x + 20,312bottom: self.y + 47,313left: self.x - 20314},315{316top: self.y + 47,317right: self.x + 3,318bottom: self.y + 125,319left: self.x - 3320},321{322top: self.y + 110,323right: self.x + 15,324bottom: self.y + 116,325left: self.x - 15326}327];328}329
330// Check if the target hits the ship331self.hits = function(target){332var allRects = self.getRects();333for(var i=0; i<allRects.length; ++i){334if(intersectRect(target.getRect(), allRects[i])){335return true;336}337}338}339
340// Apply damage to the ship. Returns true if the ship341// was killed in the process, false if not.342self.damage = function(damage){343self.health -= damage;344self.explode(100 * (3-self.health));345return self.health <= 0 ? true : false;346}347
348// Make a particle explosion from the ship, particleCount is the349// number of particles to release350self.explode = function(particleCount){351if(particleCount == undefined) particleCount = 100;352for(var i=0; i<particleCount; ++i){353self.assetList.add(new Particle({354x: self.x,355y: self.y + 40,356speed: 10,357speedVariation: 8,358angle: 0,359angleVariation: 6.28,360bounds: self.bounds,361life: 500362}));363}364}365
366// Destroy the ship367self.destroy = function(options){368self.assetList.remove(self);369}370}371
372// Draw the ship sprite373
374var shipSprite = $('#shipsprite');375var ctx = shipSprite.getContext('2d');376
377ctx.lineWidth = 1;378ctx.strokeStyle = 'rgba(255, 255, 255, 1)';379ctx.fillStyle = 'rgba(0, 0, 0, 1)';380
381// ctx.fillStyle = 'rgba(0, 0, 0, 1)'382drawShape(ctx, [383// Cabin384[0, 0],385[3, 0],386[3, 4],387[5, 6],388[6, 9],389[7, 14],390[7, 38],391
392// Hardpoints393[10, 38],394[10, 30],395[14, 30],396[14, 38],397[17, 38],398[17, 30],399[20, 30],400[20, 47],401
402[12, 47],403[12, 60],404[6, 64],405[6, 58],406[3, 58],407
408[3, 64],409[3, 98],410[2, 100],411[2, 110],412
413// Tail414[15, 110],415[15, 116],416[1, 116],417[1, 125],418[0, 125]419], {420x: 21,421y: 1422}, true, true, true);423
424// Central rotor hub425drawCircle(ctx, 21, 41, 6, true, true);426
427var SHIP_SPRITE = shipSprite;428})();