Amazing-Python-Scripts

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

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.