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

Revision 108, 11.3 KB checked in by atzm, 12 years ago (diff)
  • multi enemies support
  • Property svn:keywords set to Id
RevLine 
[81]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    },
[84]23    "message":          null,
[108]24    "enemies":          new Array(),
25    "players":          new Array(),
[81]26    "backgroundObject": new Array(),
[95]27    "deathPieces":      new Array(),
[81]28    "mainIntervalId":   0
29};
30
31
32/*
[108]33 *  Tiun Tiun Utilities
[95]34 */
35var DeathPiece = function(sizes, colors, x, y, dir, speed) {
[106]36    var that = new LinerBullet(sizes[0], colors[0], null, x, y, dir, speed);
[95]37
38    var sizeIdx  = -1;
39    var colorIdx = -1;
40
41    that.getSize = function() {
42        if (++sizeIdx >= sizes.length)
43            sizeIdx = 0;
44        return sizes[sizeIdx];
45    };
46
47    that.getColor = function() {
48        if (++colorIdx >= colors.length)
49            colorIdx = 0;
50        return colors[colorIdx];
51    };
52
53    return that;
54};
55
[108]56function addDeathPieces(x, y, sizes, colors, speed, way) {
57    if (way % 2)
58        way++;
[95]59
[108]60    var pieces = new Array();
61    var angle  = 0;
62    var delta  = 2 / way;
63
64    for(var i = 0; i < way; i++) {
65        pieces.push(new DeathPiece(sizes, colors, x, y, angle * Math.PI, speed));
66        angle += delta;
67    }
68
69    System.deathPieces.push(pieces);
70}
71
72function updateDeathPieces(ctx, width, height) {
73    var newObjs = new Array();
74
75    for (var i = 0; i < System.deathPieces.length; i++) {
76        var pieces    = System.deathPieces[i];
77        var newPieces = new Array();
78
79        for (var k = 0; k < pieces.length; k++) {
80            pieces[k].next();
81            pieces[k].draw(ctx);
82            if (!pieces[k].vanished(width, height))
83                newPieces.push(pieces[k]);
84        }
85
86        if (newPieces.length)
87            newObjs.push(newPieces);
88    }
89
90    System.deathPieces = newObjs;
91}
92
93
[95]94/*
[81]95 *  Utility Functions
96 */
[108]97function setMessage(elem, msg) {
98    if (elem)
99        elem.innerHTML = msg;
100}
101
102function addMessage(elem, msg) {
103    if (elem)
104        elem.innerHTML += msg;
105}
106
[81]107function updateBackground(ctx, width, height, size, color, max) {
108    if (System.backgroundObject.length < max) {
109        var x = Math.ceil(Math.random() * width);
110        var s = Math.ceil(Math.random() * 5);
111        System.backgroundObject.push(
[106]112            new LinerBullet(size, color, null, x, 0, 0.5 * Math.PI, s));
[81]113    }
114
115    var newObjs = new Array();
[108]116
[96]117    for (var i = 0; i < System.backgroundObject.length; i++) {
[81]118        System.backgroundObject[i].next();
119        System.backgroundObject[i].draw(ctx);
120        if (!System.backgroundObject[i].vanished(width, height))
121            newObjs.push(System.backgroundObject[i]);
122    }
[108]123
[81]124    System.backgroundObject = newObjs;
125}
126
127function drawScreen(ctx, op, style, width, height) {
128    var c = ctx.globalCompositeOperation;
129    ctx.globalCompositeOperation = op;
130    ctx.beginPath();
131    ctx.fillStyle = style;
132    ctx.fillRect(0, 0, width, height);
133    ctx.fill();
134    ctx.closePath();
135    ctx.globalCompositeOperation = c;
136}
137
138function drawLifeGauge(ctx, op, trooper, x, y, width) {
139    var length = trooper.life;
140
141    if (length > width - 20)
142        length = width - 20;
143
144    var c = ctx.globalCompositeOperation;
145    ctx.globalCompositeOperation = op;
146    ctx.beginPath();
147    ctx.fillStyle = trooper.color;
148    ctx.fillRect(x, y, length, 10);
149    ctx.fill();
150    ctx.closePath();
151    ctx.globalCompositeOperation = c;
152
153    drawString(ctx, op, trooper.life, x + 2, y + 8, trooper.color,
154               "6pt monospace", "left");
155}
156
157function drawString(ctx, op, string, x, y, color, font, align) {
158    var a = ctx.textAlign;
159    var f = ctx.font;
160    var c = ctx.globalCompositeOperation;
161    ctx.globalCompositeOperation = op;
162    ctx.beginPath();
163    ctx.textAlign = align;
164    ctx.fillStyle = color;
165    ctx.font      = font;
166    ctx.fillText(string, x, y);
167    ctx.fill();
168    ctx.textAlign = a;
169    ctx.font      = f;
170    ctx.closePath();
171    ctx.globalCompositeOperation = c;
172}
173
[108]174function updateTrooper(trooper, enemyKey) {
175    trooper.update(System[enemyKey]);
[95]176
[108]177    var aliveEnemies = new Array();
178    for (var i = 0; i < System[enemyKey].length; i++) {
179        var enemy = System[enemyKey][i];
180
181        if (enemy.isDead()) {
182            addDeathPieces(
183                enemy.x, enemy.y,
184                [6, 8, 10], ["#55F", "#AAF"], 3, 8
185            );
186        }
187        else {
188            aliveEnemies.push(enemy);
189        }
[95]190    }
[108]191    System[enemyKey] = aliveEnemies;
[95]192
[108]193    trooper.draw(System.screen.ctx);
194}
195
196function addEnemy(enemyData) {
197    var actList = EnemyActionLists[enemyData.mtime % EnemyActionLists.length];
198    var shot    = EnemyShots[enemyData.hitpoint % EnemyShots.length];
199    var numAct  = enemyData.agility       % (EnemyActions.length  - 1) + 1;
200    var numBlt  = enemyData.skills.length % (EnemyBullets.length  - 1) + 1;
201    var numBrrg = enemyData.skills.length % (EnemyBarrages.length - 1) + 1;
202    var acts    = new Array();
203    var brrgs   = new Array();
204
205    var bulletWay         = Math.ceil(enemyData.concentration / 10);
206    var bulletInterval    = Math.round(50 * 1 / Math.log(enemyData.skillpoint + 0.1));
207    var bulletSize        = Math.round(Math.log(enemyData.luck + 1));
208    var bulletFrameWidth  = (bulletSize + 5) * 2;
209    var bulletFrameHeight = (bulletSize + 5) * 4;
210    var bulletSpeed       = enemyData.strength / 15;
211
212    bulletSpeed = Math.log(bulletSpeed < 1.5 ? 1.5 : bulletSpeed);
213
214    for (var i = 0; i < numAct; i++) {
215        var idx = (enemyData.agility + i) % EnemyActions.length;
216        acts.push(new EnemyActions[idx](new shot()));
[95]217    }
[108]218
219    for (var i = 0; i < numBrrg; i++) {
220        var idx     = (enemyData.skillpoint + i * (enemyData.skills.length + 1)) % EnemyBarrages.length;
221        var brrgCls = EnemyBarrages[idx];
222
223        for (var k = 0; k < numBlt; k++) {
224            var iidx = (enemyData.skills.length + i + k) % EnemyBullets.length;
225            brrgs.push(
226                new brrgCls(
227                    EnemyBullets[iidx],
228                    bulletSize,
229                    "#FF3",
230                    {"style": "rect", "color": "rgba(128,32,32,0.5)",
231                     "width": bulletFrameWidth, "height": bulletFrameHeight},
232                    bulletInterval,
233                    bulletSpeed,
234                    bulletWay
235                )
236            );
237        }
[95]238    }
239
[108]240    var size  = Math.ceil((System.screen.width / 2) * (1 / enemyData.defense));
241    var enemy = new Trooper(
242        enemyData.name,
243        new actList(acts),
244        size,
245        size,
246        "#F33",
247        "#F33",
248        System.screen.width / 2,
249        System.screen.height / 7,
250        System.screen.width,
251        System.screen.height,
252        enemyData.hitpoint,
253        Math.log(enemyData.agility + 0.1) * 3,
254        0,
255        ["rgba(255,0,0,0.3)", "rgba(0,0,255,0.3)"],
256        brrgs
257    );
[81]258
[108]259    System.enemies.push(enemy);
[84]260}
261
262
[81]263/*
264 *  Main loop
265 */
266function mainLoop() {
267    // clear screen
268    drawScreen(
269        System.screen.ctx,
270        "source-over",
[106]271        "rgba(8,8,8,0.8)",
[81]272        System.screen.width,
273        System.screen.height
274    );
275
276    // update background objects
277    updateBackground(
278        System.screen.ctx,
279        System.screen.width,
280        System.screen.height,
281        1, "#CAF", 10
282    );
283
[95]284    // update/draw troopers
[108]285    for (var i = 0; i < System.players.length; i++) {
286        var player = System.players[i];
[81]287
[108]288        updateTrooper(player, "enemies");
[81]289
[108]290        drawLifeGauge(
291            System.screen.ctx,
292            "lighter",
293            player,
294            10,
295            (System.screen.height - 20) - (i * 33),
296            System.screen.width
297        );
298
299        drawString(
300            System.screen.ctx,
301            "source-over",
302            player.name,
303            10,
304            (System.screen.height - 23) - (i * 33),
305            "#ACF", "9pt monospace", "left"
306        );
307    }
308
309    // update/draw enemies
310    for (var i = 0; i < System.enemies.length; i++) {
311        var enemy = System.enemies[i];
312
313        updateTrooper(enemy, "players");
314
315        drawLifeGauge(
316            System.screen.ctx,
317            "lighter",
318            enemy, 10, i * 33 + 10,
319            System.screen.width
320        );
321
322        drawString(
323            System.screen.ctx,
324            "source-over",
325            enemy.name, 10, i * 33 + 33,
326            "#FCA", "9pt monospace", "left"
327        );
328    }
329
330    updateDeathPieces(System.screen.ctx,
331                      System.screen.width,
332                      System.screen.height);
333
334    if (!System.players.length) {
335        drawString(
336            System.screen.ctx, "source-over",
337            "GAME OVER",
338            System.screen.width / 2,
339            System.screen.height / 2,
340            "#ACF", "24pt monospace", "center"
341        );
342    }
[81]343}
344
345
346/*
347 *  Initializer
348 */
[108]349function initGame(canvas, msg, playerData) {
[81]350    System.screen.canvas = canvas;
[84]351    System.message       = msg;
[81]352    System.screen.ctx    = System.screen.canvas.getContext("2d");
353    System.screen.width  = System.screen.canvas.width;
354    System.screen.height = System.screen.canvas.height;
[95]355    System.gameOver      = false;
[81]356
357    System.screen.ctx.globalCompositeOperation = "lighter";
358
359    if (System.mainIntervalId) {
360        clearInterval(System.mainIntervalId);
361        System.mainIntervalId = 0;
362    }
363
364    drawScreen(
365        System.screen.ctx,
366        "source-over",
367        "rgba(0,0,0,1)",
368        System.screen.width,
369        System.screen.height
370    );
371
[108]372    System.players.push(new Trooper(
[81]373        playerData.name,
374        new ActionList([new ManualAction(new ManualShot())]),
375        playerData.size,
[97]376        playerData.hitsize,
[81]377        "#33F",
[97]378        "#F33",
[81]379        System.screen.width / 2,
380        System.screen.height - System.screen.height / 7,
381        System.screen.width,
382        System.screen.height,
383        playerData.hitpoint,
384        playerData.speed,
[92]385        playerData.numbombs,
[98]386        ["rgba(255,0,0,0.3)", "rgba(0,0,255,0.3)"],
[81]387        [new LinerBarrage(YExtendBullet,
388                          playerData.shotsize,
[106]389                          "rgba(64,64,128,0.7)",
390                          null,
[81]391                          playerData.shotinterval,
392                          playerData.shotspeed,
393                          playerData.shotlevel,
394                          -0.5),
395         new LinerBarrage(YExtendBullet,
396                          playerData.shotsize,
[106]397                          "rgba(64,64,128,0.7)",
398                          null,
[81]399                          playerData.shotinterval,
400                          playerData.shotspeed,
401                          playerData.shotlevel,
402                          0.5),
403         new CircularBarrage(LinerBullet,
404                          playerData.shotsize,
[106]405                          "rgba(64,64,128,0.7)",
406                          null,
[81]407                          playerData.shotinterval,
408                          playerData.shotspeed,
409                          playerData.shotlevel + 2,
410                          -0.5)]
[108]411    ));
[81]412
413    System.backgroundObject = new Array();
414    System.mainIntervalId   = setInterval(mainLoop, 20);
415}
Note: See TracBrowser for help on using the repository browser.