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

Revision 106, 11.6 KB checked in by atzm, 13 years ago (diff)
  • fixed small bug
  • add bullet frame
  • parameter adjust
  • 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], 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
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, null, 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.8)",
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        playerData.hitsize,
290        "#33F",
291        "#F33",
292        System.screen.width / 2,
293        System.screen.height - System.screen.height / 7,
294        System.screen.width,
295        System.screen.height,
296        playerData.hitpoint,
297        playerData.speed,
298        playerData.numbombs,
299        ["rgba(255,0,0,0.3)", "rgba(0,0,255,0.3)"],
300        [new LinerBarrage(YExtendBullet,
301                          playerData.shotsize,
302                          "rgba(64,64,128,0.7)",
303                          null,
304                          playerData.shotinterval,
305                          playerData.shotspeed,
306                          playerData.shotlevel,
307                          -0.5),
308         new LinerBarrage(YExtendBullet,
309                          playerData.shotsize,
310                          "rgba(64,64,128,0.7)",
311                          null,
312                          playerData.shotinterval,
313                          playerData.shotspeed,
314                          playerData.shotlevel,
315                          0.5),
316         new CircularBarrage(LinerBullet,
317                          playerData.shotsize,
318                          "rgba(64,64,128,0.7)",
319                          null,
320                          playerData.shotinterval,
321                          playerData.shotspeed,
322                          playerData.shotlevel + 2,
323                          -0.5)]
324    );
325
326    var actList = EnemyActionLists[bossData.mtime % EnemyActionLists.length];
327    var shot    = EnemyShots[bossData.hitpoint % EnemyShots.length];
328    var numAct  = bossData.agility       % (EnemyActions.length  - 1) + 1;
329    var numBlt  = bossData.skills.length % (EnemyBullets.length  - 1) + 1;
330    var numBrrg = bossData.skills.length % (EnemyBarrages.length - 1) + 1;
331    var acts    = new Array();
332    var brrgs   = new Array();
333
334    var bulletWay         = Math.ceil(bossData.concentration / 10);
335    var bulletInterval    = Math.round(50 * 1 / Math.log(bossData.skillpoint + 0.1));
336    var bulletSize        = Math.round(Math.log(bossData.luck + 1));
337    var bulletFrameWidth  = (bulletSize + 5) * 2;
338    var bulletFrameHeight = (bulletSize + 5) * 4;
339    var bulletSpeed       = bossData.strength / 15;
340    bulletSpeed = Math.log(bulletSpeed < 1.5 ? 1.5 : bulletSpeed);
341
342    setMessage(System.message, "");
343    addMessage(System.message, " bulletWay:" + String(bulletWay) + "<br>");
344    addMessage(System.message, " bulletInterval:" + String(bulletInterval) + "<br>");
345    addMessage(System.message, " bulletSize:" + String(bulletSize) + "<br>");
346    addMessage(System.message, " bulletSpeed:" + String(bulletSpeed) + "<br>");
347
348    addMessage(System.message, "ActionsIdx:");
349
350    for (var i = 0; i < numAct; i++) {
351        var idx = (bossData.agility + i) % EnemyActions.length;
352        acts.push(new EnemyActions[idx](new shot()));
353
354        addMessage(System.message, String(idx) + "(" +
355                   String(bossData.hitpoint % EnemyShots.length) + "),");
356    }
357
358    addMessage(System.message, "<br>");
359
360    for (var i = 0; i < numBrrg; i++) {
361        var idx     = (bossData.skillpoint + i * (bossData.skills.length + 1)) % EnemyBarrages.length;
362        var brrgCls = EnemyBarrages[idx];
363
364        addMessage(System.message,
365                   "BarragesIdx:" + String(idx) + " / BulletsIdx:");
366
367        for (var k = 0; k < numBlt; k++) {
368            var iidx = (bossData.skills.length + i + k) % EnemyBullets.length;
369            brrgs.push(
370                new brrgCls(
371                    EnemyBullets[iidx],
372                    bulletSize,
373                    "#FF3",
374                    {"style": "rect", "color": "rgba(128,32,32,0.5)",
375                     "width": bulletFrameWidth, "height": bulletFrameHeight},
376                    bulletInterval,
377                    bulletSpeed,
378                    bulletWay
379                )
380            );
381
382            addMessage(System.message, String(iidx) + ",");
383        }
384
385        addMessage(System.message, "<br>");
386    }
387
388    var size = Math.ceil((System.screen.width / 2) * (1 / bossData.defense));
389    size = size < playerData.size ? playerData.size : size;
390    System.boss = new Trooper(
391        bossData.name,
392        new actList(acts),
393        size,
394        size,
395        "#F33",
396        "#F33",
397        System.screen.width / 2,
398        System.screen.height / 7,
399        System.screen.width,
400        System.screen.height,
401        bossData.hitpoint,
402        Math.log(bossData.agility + 0.1) * 3,
403        0,
404        ["rgba(255,0,0,0.3)", "rgba(0,0,255,0.3)"],
405        brrgs
406    );
407
408    System.backgroundObject = new Array();
409    System.mainIntervalId   = setInterval(mainLoop, 20);
410}
Note: See TracBrowser for help on using the repository browser.