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

Revision 112, 12.3 KB checked in by atzm, 12 years ago (diff)

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