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

Revision 109, 11.5 KB checked in by atzm, 13 years ago (diff)

imaging support

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