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

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