source: pycodeshooter/trunk/shooter/system.js @ 121

Revision 121, 13.4 KB checked in by atzm, 13 years ago (diff)

fixed enemy initial position

  • Property svn:keywords set to Id
Line 
1/* -*- coding: utf-8 -*-
2 *
3 * Copyright (C) 2010 by Atzm WATANABE <atzm@atzm.org>
4 *
5 *  This program is free software; you can redistribute it and/or modify it
6 *  under the terms of the GNU General Public License (version 2) as
7 *  published by the Free Software Foundation.  It is distributed in the
8 *  hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
9 *  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 *  PURPOSE.  See the GNU General Public License for more details.
11 *
12 * $Id$
13 *
14 */
15
16System = {
17    "screen": {
18        "canvas": null,
19        "ctx":    null,
20        "width":  0,
21        "height": 0
22    },
23    "sound":            {},
24    "message":          null,
25    "enemyImages":      new Array(),
26    "enemies":          new Array(),
27    "players":          new Array(),
28    "score":            {},
29    "backgroundObject": new Array(),
30    "deathPieces":      new Array(),
31    "mainIntervalId":   0
32};
33
34
35/*
36 *  Tiun Tiun Utilities
37 */
38var DeathPiece = function(sizes, colors, x, y, dir, speed) {
39    var that = new LinerBullet(sizes[0], colors[0], null,
40                               System.screen.width, System.screen.height,
41                               x, y, dir, speed);
42
43    var sizeIdx  = -1;
44    var colorIdx = -1;
45
46    that.getSize = function() {
47        if (++sizeIdx >= sizes.length)
48            sizeIdx = 0;
49        return sizes[sizeIdx];
50    };
51
52    that.getColor = function() {
53        if (++colorIdx >= colors.length)
54            colorIdx = 0;
55        return colors[colorIdx];
56    };
57
58    return that;
59};
60
61function addDeathPieces(x, y, sizes, colors, speed, way) {
62    if (way % 2)
63        way++;
64
65    var pieces = new Array();
66    var angle  = 0;
67    var delta  = 2 / way;
68
69    for(var i = 0; i < way; i++) {
70        pieces.push(new DeathPiece(sizes, colors, x, y, angle * Math.PI, speed));
71        angle += delta;
72    }
73
74    System.deathPieces.push(pieces);
75}
76
77function updateDeathPieces(ctx, width, height) {
78    var newObjs = new Array();
79
80    for (var i = 0; i < System.deathPieces.length; i++) {
81        var pieces    = System.deathPieces[i];
82        var newPieces = new Array();
83
84        for (var k = 0; k < pieces.length; k++) {
85            pieces[k].next();
86            pieces[k].draw(ctx);
87            if (!pieces[k].vanished(width, height))
88                newPieces.push(pieces[k]);
89        }
90
91        if (newPieces.length)
92            newObjs.push(newPieces);
93    }
94
95    System.deathPieces = newObjs;
96}
97
98
99/*
100 *  Utility Functions
101 */
102function setMessage(elem, msg) {
103    if (elem)
104        elem.innerHTML = msg;
105}
106
107function addMessage(elem, msg) {
108    if (elem)
109        elem.innerHTML += msg;
110}
111
112function updateBackground(ctx, width, height, size, color, max) {
113    if (System.backgroundObject.length < max) {
114        var x = Math.ceil(Math.random() * width);
115        var s = Math.ceil(Math.random() * 5);
116        System.backgroundObject.push(
117            new LinerBullet(size, color, null,
118                            System.screen.width, System.screen.height,
119                            x, 0, 0.5 * Math.PI, s));
120    }
121
122    var newObjs = new Array();
123
124    for (var i = 0; i < System.backgroundObject.length; i++) {
125        System.backgroundObject[i].next();
126        System.backgroundObject[i].draw(ctx);
127        if (!System.backgroundObject[i].vanished(width, height))
128            newObjs.push(System.backgroundObject[i]);
129    }
130
131    System.backgroundObject = newObjs;
132}
133
134function drawScreen(ctx, op, style, width, height) {
135    var c = ctx.globalCompositeOperation;
136    ctx.globalCompositeOperation = op;
137    ctx.beginPath();
138    ctx.fillStyle = style;
139    ctx.fillRect(0, 0, width, height);
140    ctx.fill();
141    ctx.closePath();
142    ctx.globalCompositeOperation = c;
143}
144
145function drawLifeGauge(ctx, op, trooper, x, y, width) {
146    var length = trooper.life;
147
148    if (length > width - 20)
149        length = width - 20;
150
151    var c = ctx.globalCompositeOperation;
152    ctx.globalCompositeOperation = op;
153    ctx.beginPath();
154    ctx.fillStyle = trooper.color;
155    ctx.fillRect(x, y, length, 10);
156    ctx.fill();
157    ctx.closePath();
158    ctx.globalCompositeOperation = c;
159
160    drawString(ctx, op, trooper.life, x + 2, y + 8, trooper.color,
161               "6pt monospace", "left");
162}
163
164function drawString(ctx, op, string, x, y, color, font, align) {
165    var a = ctx.textAlign;
166    var f = ctx.font;
167    var c = ctx.globalCompositeOperation;
168    ctx.globalCompositeOperation = op;
169    ctx.beginPath();
170    ctx.textAlign = align;
171    ctx.fillStyle = color;
172    ctx.font      = font;
173    ctx.fillText(string, x, y);
174    ctx.fill();
175    ctx.textAlign = a;
176    ctx.font      = f;
177    ctx.closePath();
178    ctx.globalCompositeOperation = c;
179}
180
181function updateTrooper(trooper, enemyKey) {
182    trooper.update(System[enemyKey]);
183
184    var aliveEnemies = new Array();
185    for (var i = 0; i < System[enemyKey].length; i++) {
186        var enemy = System[enemyKey][i];
187
188        if (enemy.isDead()) {
189            playSound("se_destroy");
190
191            addDeathPieces(
192                enemy.x, enemy.y,
193                [6, 8, 10], ["#55F", "#AAF"], 3, 8
194            );
195
196            if (System.score[trooper.name] !== undefined) {
197                System.score[trooper.name] += enemy.maxLife * 100;
198            }
199        }
200        else {
201            aliveEnemies.push(enemy);
202        }
203    }
204    System[enemyKey] = aliveEnemies;
205
206    trooper.draw(System.screen.ctx);
207}
208
209function toggleSound(val) {
210    for (var name in System.sound)
211        System.sound[name].muted = !val;
212}
213
214function registerSound(name, audio) {
215    System.sound[name] = audio;
216}
217
218function playSound(name) {
219    if (System.sound[name])
220        System.sound[name].play();
221}
222
223function numEnemies() {
224    return System.enemies.length;
225}
226
227function addEnemyImage(image) {
228    System.enemyImages.push(image);
229}
230
231function addEnemy(enemyData) {
232    var actList = EnemyActionLists[enemyData.mtime % EnemyActionLists.length];
233    var shot    = EnemyShots[enemyData.hitpoint % EnemyShots.length];
234    var numAct  = enemyData.agility       % (EnemyActions.length  - 1) + 1;
235    var numBlt  = enemyData.skills.length % (EnemyBullets.length  - 1) + 1;
236    var numBrrg = enemyData.skills.length % (EnemyBarrages.length - 1) + 1;
237    var acts    = new Array();
238    var brrgs   = new Array();
239
240    var bulletWay         = Math.ceil(enemyData.concentration / 10);
241    var bulletInterval    = Math.round(50 * 1 / Math.log(enemyData.skillpoint + 0.1));
242    var bulletSize        = Math.round(Math.log(enemyData.luck + 1));
243    var bulletFrameWidth  = (bulletSize + 5) * 2;
244    var bulletFrameHeight = (bulletSize + 5) * 4;
245    var bulletSpeed       = enemyData.strength / 15;
246
247    bulletSpeed = Math.log(bulletSpeed < 1.5 ? 1.5 : bulletSpeed);
248
249    for (var i = 0; i < numAct; i++) {
250        var idx = (enemyData.agility + i) % EnemyActions.length;
251        acts.push(new EnemyActions[idx](new shot()));
252    }
253
254    for (var i = 0; i < numBrrg; i++) {
255        var idx     = (enemyData.skillpoint + i * (enemyData.skills.length + 1)) % EnemyBarrages.length;
256        var brrgCls = EnemyBarrages[idx];
257        var frameColor;
258
259        switch(idx % 3) {
260        case 0:
261            frameColor = "rgba(128,32,32,0.7)";
262            break;
263        case 1:
264            frameColor = "rgba(32,128,32,0.7)";
265            break;
266        default:
267            frameColor = "rgba(64,64,128,0.7)";
268        }
269
270        for (var k = 0; k < numBlt; k++) {
271            var iidx = (enemyData.skills.length + i + k) % EnemyBullets.length;
272            brrgs.push(
273                new brrgCls(
274                    EnemyBullets[iidx],
275                    bulletSize,
276                    "#FF3",
277                    {"style": "rect", "color": frameColor,
278                     "width": bulletFrameWidth, "height": bulletFrameHeight},
279                    bulletInterval,
280                    bulletSpeed,
281                    bulletWay
282                )
283            );
284        }
285    }
286
287    var size  = Math.ceil((System.screen.width / 2) * (1 / enemyData.defense));
288    var enemy = new Trooper(
289        enemyData.name,
290        new actList(acts),
291        System.enemyImages[enemyData.hitpoint % System.enemyImages.length],
292        size,
293        size,
294        "#F33",
295        "#F33",
296        Math.floor(Math.random() * System.screen.width),
297        Math.floor(Math.random() * (System.screen.height / 4)),
298        System.screen.width,
299        System.screen.height,
300        Math.floor(enemyData.hitpoint / 25) + 1,
301        Math.log(enemyData.agility + 0.1) * 3,
302        0,
303        ["rgba(255,0,0,0.3)", "rgba(0,0,255,0.3)"],
304        brrgs
305    );
306    enemy.registerCallback("damaged", function() {playSound("se_damage_enemy")});
307
308    System.enemies.push(enemy);
309}
310
311
312/*
313 *  Main loop
314 */
315function mainLoop() {
316    // clear screen
317    drawScreen(
318        System.screen.ctx,
319        "source-over",
320        "rgba(8,8,8,0.8)",
321        System.screen.width,
322        System.screen.height
323    );
324
325    // update background objects
326    updateBackground(
327        System.screen.ctx,
328        System.screen.width,
329        System.screen.height,
330        1, "#CAF", 10
331    );
332
333    // draw score
334    var scoreNames = Object.keys(System.score).sort();
335    for (var i = 0; i < scoreNames.length; i++) {
336        var name = scoreNames[i];
337        drawString(
338            System.screen.ctx,
339            "source-over",
340            name + " score " + System.score[name],
341            (System.screen.width - 10),
342            i * 16 + 15,
343            "#ACF", "9pt monospace", "right"
344        );
345    }
346
347    // update/draw troopers
348    for (var i = 0; i < System.players.length; i++) {
349        var player = System.players[i];
350
351        updateTrooper(player, "enemies");
352
353        drawLifeGauge(
354            System.screen.ctx,
355            "lighter",
356            player,
357            10,
358            (System.screen.height - 20) - (i * 33),
359            System.screen.width
360        );
361
362        drawString(
363            System.screen.ctx,
364            "source-over",
365            player.name,
366            10,
367            (System.screen.height - 23) - (i * 33),
368            "#ACF", "9pt monospace", "left"
369        );
370    }
371
372    // update/draw enemies
373    for (var i = 0; i < System.enemies.length; i++) {
374        var enemy = System.enemies[i];
375
376        updateTrooper(enemy, "players");
377
378        drawLifeGauge(
379            System.screen.ctx,
380            "lighter",
381            enemy, 10, i * 33 + 10,
382            System.screen.width
383        );
384
385        drawString(
386            System.screen.ctx,
387            "source-over",
388            enemy.name, 10, i * 33 + 33,
389            "#FCA", "9pt monospace", "left"
390        );
391    }
392
393    updateDeathPieces(System.screen.ctx,
394                      System.screen.width,
395                      System.screen.height);
396
397    if (!System.players.length) {
398        drawString(
399            System.screen.ctx, "source-over",
400            "GAME OVER",
401            System.screen.width / 2,
402            System.screen.height / 2,
403            "#ACF", "24pt monospace", "center"
404        );
405    }
406}
407
408
409/*
410 *  Initializer
411 */
412function initGame(canvas, msg, playerData) {
413    System.screen.canvas = canvas;
414    System.message       = msg;
415    System.screen.ctx    = System.screen.canvas.getContext("2d");
416    System.screen.width  = System.screen.canvas.width;
417    System.screen.height = System.screen.canvas.height;
418    System.gameOver      = false;
419
420    System.screen.ctx.globalCompositeOperation = "lighter";
421
422    if (System.mainIntervalId) {
423        clearInterval(System.mainIntervalId);
424        System.mainIntervalId = 0;
425    }
426
427    drawScreen(
428        System.screen.ctx,
429        "source-over",
430        "rgba(0,0,0,1)",
431        System.screen.width,
432        System.screen.height
433    );
434
435    var trooper = new Trooper(
436        playerData.name,
437        new ActionList([new ManualAction(new ManualShot())]),
438        playerData.image,
439        playerData.size,
440        playerData.hitsize,
441        "#33F",
442        "#F33",
443        System.screen.width / 2,
444        System.screen.height - System.screen.height / 7,
445        System.screen.width,
446        System.screen.height,
447        playerData.hitpoint,
448        playerData.speed,
449        playerData.numbombs,
450        ["rgba(255,0,0,0.3)", "rgba(0,0,255,0.3)"],
451        [new LinerBarrage(YExtendBullet,
452                          playerData.shotsize,
453                          "rgba(64,64,128,0.7)",
454                          null,
455                          playerData.shotinterval,
456                          playerData.shotspeed,
457                          playerData.shotlevel,
458                          -0.5),
459         new LinerBarrage(YExtendBullet,
460                          playerData.shotsize,
461                          "rgba(64,64,128,0.7)",
462                          null,
463                          playerData.shotinterval,
464                          playerData.shotspeed,
465                          playerData.shotlevel,
466                          0.5),
467         new CircularBarrage(LinerBullet,
468                          playerData.shotsize,
469                          "rgba(64,64,128,0.7)",
470                          null,
471                          playerData.shotinterval,
472                          playerData.shotspeed,
473                          playerData.shotlevel + 2,
474                          -0.5)]
475    );
476    trooper.registerCallback("addBomb", function() {playSound("se_bomb")});
477    trooper.registerCallback("damaged", function() {playSound("se_damage_player")});
478
479    System.players.push(trooper);
480
481    for (var i = 0; i < System.players.length; i++) {
482        System.score[System.players[i].name] = 0;
483    }
484
485    System.backgroundObject = new Array();
486    System.mainIntervalId   = setInterval(mainLoop, 20);
487}
Note: See TracBrowser for help on using the repository browser.