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

Revision 111, 11.6 KB checked in by atzm, 13 years ago (diff)

modified, parameter adjustment

  • 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 numEnemies() {
198    return System.enemies.length;
199}
200
201function addEnemyImage(image) {
202    System.enemyImages.push(image);
203}
204
205function addEnemy(enemyData) {
206    var actList = EnemyActionLists[enemyData.mtime % EnemyActionLists.length];
207    var shot    = EnemyShots[enemyData.hitpoint % EnemyShots.length];
208    var numAct  = enemyData.agility       % (EnemyActions.length  - 1) + 1;
209    var numBlt  = enemyData.skills.length % (EnemyBullets.length  - 1) + 1;
210    var numBrrg = enemyData.skills.length % (EnemyBarrages.length - 1) + 1;
211    var acts    = new Array();
212    var brrgs   = new Array();
213
214    var bulletWay         = Math.ceil(enemyData.concentration / 10);
215    var bulletInterval    = Math.round(50 * 1 / Math.log(enemyData.skillpoint + 0.1));
216    var bulletSize        = Math.round(Math.log(enemyData.luck + 1));
217    var bulletFrameWidth  = (bulletSize + 5) * 2;
218    var bulletFrameHeight = (bulletSize + 5) * 4;
219    var bulletSpeed       = enemyData.strength / 15;
220
221    bulletSpeed = Math.log(bulletSpeed < 1.5 ? 1.5 : bulletSpeed);
222
223    for (var i = 0; i < numAct; i++) {
224        var idx = (enemyData.agility + i) % EnemyActions.length;
225        acts.push(new EnemyActions[idx](new shot()));
226    }
227
228    for (var i = 0; i < numBrrg; i++) {
229        var idx     = (enemyData.skillpoint + i * (enemyData.skills.length + 1)) % EnemyBarrages.length;
230        var brrgCls = EnemyBarrages[idx];
231
232        for (var k = 0; k < numBlt; k++) {
233            var iidx = (enemyData.skills.length + i + k) % EnemyBullets.length;
234            brrgs.push(
235                new brrgCls(
236                    EnemyBullets[iidx],
237                    bulletSize,
238                    "#FF3",
239                    {"style": "rect", "color": "rgba(128,32,32,0.5)",
240                     "width": bulletFrameWidth, "height": bulletFrameHeight},
241                    bulletInterval,
242                    bulletSpeed,
243                    bulletWay
244                )
245            );
246        }
247    }
248
249    var size  = Math.ceil((System.screen.width / 2) * (1 / enemyData.defense));
250    var enemy = new Trooper(
251        enemyData.name,
252        new actList(acts),
253        System.enemyImages[enemyData.hitpoint % System.enemyImages.length],
254        size,
255        size,
256        "#F33",
257        "#F33",
258        System.screen.width / 2,
259        System.screen.height / 7,
260        System.screen.width,
261        System.screen.height,
262        Math.floor(enemyData.hitpoint / 25) + 1,
263        Math.log(enemyData.agility + 0.1) * 3,
264        0,
265        ["rgba(255,0,0,0.3)", "rgba(0,0,255,0.3)"],
266        brrgs
267    );
268
269    System.enemies.push(enemy);
270}
271
272
273/*
274 *  Main loop
275 */
276function mainLoop() {
277    // clear screen
278    drawScreen(
279        System.screen.ctx,
280        "source-over",
281        "rgba(8,8,8,0.8)",
282        System.screen.width,
283        System.screen.height
284    );
285
286    // update background objects
287    updateBackground(
288        System.screen.ctx,
289        System.screen.width,
290        System.screen.height,
291        1, "#CAF", 10
292    );
293
294    // update/draw troopers
295    for (var i = 0; i < System.players.length; i++) {
296        var player = System.players[i];
297
298        updateTrooper(player, "enemies");
299
300        drawLifeGauge(
301            System.screen.ctx,
302            "lighter",
303            player,
304            10,
305            (System.screen.height - 20) - (i * 33),
306            System.screen.width
307        );
308
309        drawString(
310            System.screen.ctx,
311            "source-over",
312            player.name,
313            10,
314            (System.screen.height - 23) - (i * 33),
315            "#ACF", "9pt monospace", "left"
316        );
317    }
318
319    // update/draw enemies
320    for (var i = 0; i < System.enemies.length; i++) {
321        var enemy = System.enemies[i];
322
323        updateTrooper(enemy, "players");
324
325        drawLifeGauge(
326            System.screen.ctx,
327            "lighter",
328            enemy, 10, i * 33 + 10,
329            System.screen.width
330        );
331
332        drawString(
333            System.screen.ctx,
334            "source-over",
335            enemy.name, 10, i * 33 + 33,
336            "#FCA", "9pt monospace", "left"
337        );
338    }
339
340    updateDeathPieces(System.screen.ctx,
341                      System.screen.width,
342                      System.screen.height);
343
344    if (!System.players.length) {
345        drawString(
346            System.screen.ctx, "source-over",
347            "GAME OVER",
348            System.screen.width / 2,
349            System.screen.height / 2,
350            "#ACF", "24pt monospace", "center"
351        );
352    }
353}
354
355
356/*
357 *  Initializer
358 */
359function initGame(canvas, msg, playerData) {
360    System.screen.canvas = canvas;
361    System.message       = msg;
362    System.screen.ctx    = System.screen.canvas.getContext("2d");
363    System.screen.width  = System.screen.canvas.width;
364    System.screen.height = System.screen.canvas.height;
365    System.gameOver      = false;
366
367    System.screen.ctx.globalCompositeOperation = "lighter";
368
369    if (System.mainIntervalId) {
370        clearInterval(System.mainIntervalId);
371        System.mainIntervalId = 0;
372    }
373
374    drawScreen(
375        System.screen.ctx,
376        "source-over",
377        "rgba(0,0,0,1)",
378        System.screen.width,
379        System.screen.height
380    );
381
382    System.players.push(new Trooper(
383        playerData.name,
384        new ActionList([new ManualAction(new ManualShot())]),
385        playerData.image,
386        playerData.size,
387        playerData.hitsize,
388        "#33F",
389        "#F33",
390        System.screen.width / 2,
391        System.screen.height - System.screen.height / 7,
392        System.screen.width,
393        System.screen.height,
394        playerData.hitpoint,
395        playerData.speed,
396        playerData.numbombs,
397        ["rgba(255,0,0,0.3)", "rgba(0,0,255,0.3)"],
398        [new LinerBarrage(YExtendBullet,
399                          playerData.shotsize,
400                          "rgba(64,64,128,0.7)",
401                          null,
402                          playerData.shotinterval,
403                          playerData.shotspeed,
404                          playerData.shotlevel,
405                          -0.5),
406         new LinerBarrage(YExtendBullet,
407                          playerData.shotsize,
408                          "rgba(64,64,128,0.7)",
409                          null,
410                          playerData.shotinterval,
411                          playerData.shotspeed,
412                          playerData.shotlevel,
413                          0.5),
414         new CircularBarrage(LinerBullet,
415                          playerData.shotsize,
416                          "rgba(64,64,128,0.7)",
417                          null,
418                          playerData.shotinterval,
419                          playerData.shotspeed,
420                          playerData.shotlevel + 2,
421                          -0.5)]
422    ));
423
424    System.backgroundObject = new Array();
425    System.mainIntervalId   = setInterval(mainLoop, 20);
426}
Note: See TracBrowser for help on using the repository browser.