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

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