|
|
- // Play class
- enyo.kind({
- name: "TankOp.Play",
- kind: enyo.Control,
- classes: "board",
- published: { level: 0 },
- components: [
- // Playing zone
- {name: "gamebox", classes: "game-box", ontap: "gameClick", components: [
- ]},
-
- // Status and score
- {classes: "status-line", components: [
- {name: "wavetext", classes: "wave-text no-select-content"},
- {name: "wave", content: "1", classes: "wave-value no-select-content"},
- {name: "scoretext", classes: "score-text no-select-content"},
- {name: "score", content: "0000", classes: "score-value no-select-content"}
- ]},
-
- // Home button
- {kind: "Image", classes: "home-button no-select-content", src: "images/gohome.png", ontap: "goHome"},
-
- // LCD counter and Keyboard
- {name: "keyboard", classes: "keyboard-set no-select-content", components: [
- {classes: "display-line", components: [
- {name: "lcd", kind: "LcdDisplay", classes: "lcd-value", size: 3, value: ""}
- ]},
- {classes: "keyboard-line", components: [
- {kind: "Image", src: "images/key_1.svg", classes: "keyboard", ontap: "virtkeyPressed"},
- {kind: "Image", src: "images/key_2.svg", classes: "keyboard", ontap: "virtkeyPressed"},
- {kind: "Image", src: "images/key_3.svg", classes: "keyboard", ontap: "virtkeyPressed"}
- ]},
- {classes: "keyboard_line", components: [
- {kind: "Image", src: "images/key_4.svg", classes: "keyboard", ontap: "virtkeyPressed"},
- {kind: "Image", src: "images/key_5.svg", classes: "keyboard", ontap: "virtkeyPressed"},
- {kind: "Image", src: "images/key_6.svg", classes: "keyboard", ontap: "virtkeyPressed"}
- ]},
- {classes: "keyboard_line", components: [
- {kind: "Image", src: "images/key_7.svg", classes: "keyboard", ontap: "virtkeyPressed"},
- {kind: "Image", src: "images/key_8.svg", classes: "keyboard", ontap: "virtkeyPressed"},
- {kind: "Image", src: "images/key_9.svg", classes: "keyboard", ontap: "virtkeyPressed"}
- ]},
- {classes: "keyboard_line", components: [
- {kind: "Image", src: "images/key_0.svg", classes: "keyboard", ontap: "virtkeyPressed"},
- {kind: "Image", src: "images/key_fire.svg", classes: "keyboard", ontap: "virtkeyPressed"}
- ]}
- ]},
-
- // Key handling
- {kind: "Signals", onkeypress: "keyPressed"},
-
- // Image cache
- {kind: "ImageCache", showing: false, onCacheLoaded: "cacheLoaded"}
- ],
-
- // Constructor
- create: function() {
- this.inherited(arguments);
- play = this;
- this.imagesToLoad++;
- this.endOfGame = false;
- this.pausedGame = true;
- this.initializedGame = false;
- this.waitForClick = false;
-
- // Init canvas
- var wsize = document.body.clientWidth;
- if (wsize <= 480) {
- this.zoom = 0.4;
- } else if (wsize <= 640) {
- this.zoom = 0.55;
- } else if (wsize <= 768) {
- this.zoom = 0.62;
- } else if (wsize <= 854) {
- this.zoom = 0.65;
- } else if (wsize <= 960) {
- this.zoom = 0.75;
- } else if (wsize <= 1024) {
- this.zoom = 0.88;
- } else {
- this.zoom = 1;
- }
-
- this.$.gamebox.setStyle("max-height: "+(this.zoom*constant.areaHeight)+"px;");
- this.canvas = this.$.gamebox.createComponent({kind: "Canvas", id: "acanvas", name: "canvas", attributes: {width: constant.areaWidth, height: constant.areaHeight}});
-
- // Start game loop
- this.loopTimer = window.setInterval(enyo.bind(this, "gameLoopTick"), constant.loopInterval);
- },
-
- // Init game
- initGame: function() {
- // Game init
- var level = this.currentlevel = preferences.levels[this.level];
- var settings_map = level.map;
- var settings_hq = level.defense[0];
- var settings_soldier = level.defense[1];
- var settings_tank = level.defense[2];
- var settings_canon = level.defense[3];
- var settings_helo = level.defense[4];
-
- // Init board
- this.initializedGame = true;
- this.game = util.createMap(preferences.gameMap(settings_map));
- this.targetpos = {x: 7, y: 4};
- this.$.wavetext.setContent(l10n.get("Wave"));
- this.$.scoretext.setContent(l10n.get("Score"));
-
- // Init units
- var width = constant.boardWidth, height = constant.boardHeight;
- var goodEngine = enyo.bind(this, "goodEngine");
- this.units = []
-
- // Set HQ
- var step = constant.boardHeight/(settings_hq+1);
- var hqs = [];
- for (var i = 0 ; i < settings_hq ; i++) {
- var hq = util.createUnit({type: "hq", color: "blue", x: 0, y: Math.floor((i+1)*step), engine: null});
- this.units.push(hq);
- hqs.push(hq);
- }
-
- // Create defending units
- var defense = [];
- for(var i = 0 ; i < settings_helo ; i++)
- defense.push({type: "helo", color: "blue", engine: goodEngine});
- for(var i = 0 ; i < settings_canon ; i++)
- defense.push({type: "canon", color: "blue", engine: goodEngine});
- for(var i = 0 ; i < settings_tank ; i++)
- defense.push({type: "tank", color: "blue", engine: goodEngine});
- for(var i = 0 ; i < settings_soldier ; i++)
- defense.push({type: "soldier", color: "blue", engine: goodEngine});
-
- // Set defense around hq
- if (defense.length > 0) {
- var hqindex = 0;
- var defenselength = Math.min(defense.length, 1+hqs.length*2);
- for (var i = 0 ; i < defenselength ; i++) {
- var position = {};
- do {
- var arounds = [{dx: 1, dy: 0}, {dx: 0, dy: -1}, {dx: 0, dy: 1}];
- for (j = 0 ; j < arounds.length ; j++) {
- position = {x: hqs[hqindex].x+arounds[j].dx, y: hqs[hqindex].y+arounds[j].dy};
- if (util.lookForUnit(position) == null)
- break;
- else
- position = {x: -1, y: -1};
- }
- hqindex = (hqindex + 1) % hqs.length;
- } while (position.x == -1);
- defense[i].x = position.x;
- defense[i].y = position.y;
- this.units.push(util.createUnit(defense[i]));
- }
- }
-
- // Prepare bad units arrival
- this.score = 0;
- this.wave = 1;
- this.enemyCount = level.attack;
- this.enemyWaveSize = constant.waveInitSize;
- this.enemyNextWaveCount = constant.waveInitSize;
- this.enemyWaveCount = 0;
- this.enemyArrivalTurn = constant.startArrival;
-
- // Let's Go !
- this.pausedGame = false;
- },
-
- // Render
- rendered: function() {
- // Init game
- if (!this.initializedGame) {
- // Init context
- this.initGame();
-
- // Set zoom
- this.canvas.hasNode().style.MozTransform = "scale("+this.zoom+")";
- this.canvas.hasNode().style.MozTransformOrigin = "0 0";
- this.canvas.hasNode().style.zoom = this.zoom;
- }
- },
-
- cacheLoaded: function() {
- },
-
- // Draw
- draw: function() {
- // Clear all
- var ctx = this.canvas.hasNode().getContext('2d');
- ctx.clearRect(0, 0, this.canvas.attributes.width, this.canvas.attributes.height);
-
- // Draw board
- var grass = document.getElementById("grass");
- var trees = document.getElementById("trees");
- var mountain = document.getElementById("mountain");
- var water = document.getElementById("water");
- for (var i = 0 ; i < constant.boardHeight ; i++ ) {
- for (var j = 0 ; j < constant.boardWidth ; j++ ) {
- ctx.save();
- ctx.translate(j*constant.tileSize, i*constant.tileSize);
- ctx.drawImage(grass, 0, 0);
- var tileType = this.game[i][j];
- if (tileType == constant.tileTrees)
- ctx.drawImage(trees, 0, 0);
- else if (tileType == constant.tileMountain)
- ctx.drawImage(mountain, 0, 0);
- else if (tileType == constant.tileWater)
- ctx.drawImage(water, 0, 0);
- ctx.restore();
- }
- }
-
- // Draw tanks
- if (!this.endOfGame) {
- for (var i = 0 ; i < this.units.length ; i++)
- this.units[i].draw(ctx);
-
- // Draw target
- var target = document.getElementById("target");
- ctx.save();
- ctx.translate(this.targetpos.x*constant.tileSize, this.targetpos.y*constant.tileSize);
- ctx.drawImage(target, 0, 0);
- ctx.restore();
- }
-
- // End of game
- else {
- // Draw end of game screen
- var endscreen = this.win ? document.getElementById("endgame_victory") : document.getElementById("endgame_defeat");
- ctx.save();
- ctx.translate((constant.areaWidth-constant.endGameWidth)/2, (constant.areaHeight-constant.endGameHeight)/2);
- ctx.drawImage(endscreen, 0, 0);
- ctx.restore();
-
- // Play end of game sound
- if (!this.waitForClick) {
- sound.play(this.win ? "audio/mission_completed" : "audio/mission_failed", true);
- this.waitForClick = true;
- }
- }
-
- },
-
- // A key was pressed
- keyPressed: function(s, e) {
- var key = e.charCode;
- if (this.endOfGame)
- return;
-
- // Digit key
- if (key >= 48 && key <= 57) {
- // Add digit to string
- var value = this.$.lcd.getValue();
- if (value.length == this.$.lcd.getSize())
- value = value.substr(1);
- value += String.fromCharCode(key);
- this.$.lcd.setValue(value);
- }
-
- // Dash key
- else if (key == 45) {
- this.$.lcd.setValue("-");
- }
-
- // Fire key
- else if (key == 32) {
- // Look for unit with the value
- var units = util.lookForValue(this.$.lcd.getValue().replace(/ /g,''));
- if (units.length != 0) {
- for (var i = 0 ; i < units.length ; i++) {
- util.processFight(null, units[i], constant.userPower);
- this.targetpos.x = units[i].x;
- this.targetpos.y = units[i].y;
- }
- }
- else
- sound.play("audio/missed");
- this.$.lcd.setValue("");
- }
- },
-
- // A virtual key is pressed
- virtkeyPressed: function(s) {
- var classes = s.getSrc().replace(".svg", "");
- var value = classes.substr("images/key_".length,classes.indexOf("key_"));
- if (value == "fire")
- this.keyPressed(null, {charCode: 32});
- else
- this.keyPressed(null, {charCode: 48+parseInt(value)});
- },
-
- goHome: function() {
- // Click at the end of game
- if (this.waitForClick) {
- this.gameClick();
- return;
- }
-
- // Stop game loop
- window.clearInterval(this.loopTimer);
-
- // Back to app
- app.init();
- app.playTheme()
- app.renderInto(document.getElementById("board"));
- },
-
- // A tap occur on the game
- gameClick: function() {
- // At end of game, quit
- if (this.endOfGame) {
- // Stop game loop
- window.clearInterval(this.loopTimer);
-
- // Set mission result
- if (this.win) {
- preferences.levels[this.level].completed = true;
- app.nextMission();
- app.save();
- }
- app.init();
-
- // Back to app
- app.renderInto(document.getElementById("board"));
- }
-
- // Compute direction
- var screen_width = document.documentElement.clientWidth;
- var screen_height = document.documentElement.clientHeight;
- var center_x = Math.floor(screen_width/2.0);
- var center_y = Math.floor((screen_height+constant.pubHeight)/2.0);
- var diffx = mouse.position.x-center_x, diffy = mouse.position.y-center_y;
- var absdiffx = Math.abs(diffx);
- var absdiffy = Math.abs(diffy);
- if (absdiffx >= 0 && absdiffx < constant.fireZoneWidth && absdiffy >= 0 && absdiffy < constant.fireZoneHeight) {
- var targetunit = util.lookForUnit(this.targetpos);
- if (targetunit != null)
- util.processFight(null, targetunit);
- return;
- } else if (absdiffx > absdiffy) {
- dx = diffx > 0 ? 1 : -1;
- dy = 0;
- } else {
- dx = 0;
- dy = diffy > 0 ? 1 : -1;
- }
-
- // Move target
- var newX = this.targetpos.x + dx;
- var newY = this.targetpos.y + dy;
- if (newX < 0 || newX == constant.boardWidth || newY < 0 || newY == constant.boardHeight)
- return;
- this.targetpos.x = newX;
- this.targetpos.y = newY;
- },
-
- // Tick for game loop
- gameLoopTick: function() {
- if (this.pausedGame)
- return;
-
- // Sanitize: clean dead units and compute victory/defeat conditions
- var alives = [];
- var hqs = [];
- var livingHq = 0;
- var livingEnemy = 0;
- for (var i = 0 ; i < this.units.length ; i++) {
- var unit = this.units[i];
- var isRed = unit.getCurrentImage().indexOf("red") != -1;
- if (unit.power > 0) {
- alives.push(unit);
- } else {
- if (isRed) {
- this.enemyNextWaveCount--;
- this.score += util.unitPowers[util.getUnitType(unit)];
- }
- continue;
- }
- if (util.getUnitType(unit) == 0) {
- hqs[livingHq++] = unit;
- }
- if (isRed)
- livingEnemy++;
- }
- this.units = alives;
- this.endOfGame = (livingHq == 0 || (livingEnemy == 0 && this.enemyCount == 0));
- this.win = (livingHq > 0);
-
- // Game play
- if (!this.endOfGame) {
- // Next wave
- if (this.enemyNextWaveCount == 0) {
- this.wave++;
- this.enemyWaveSize += 2;
- this.enemyWaveCount = 0;
- this.enemyNextWaveCount = this.enemyWaveSize;
- this.enemyArrivalTurn = constant.startArrival;
- }
-
- // Enemy arrival
- else if (this.enemyWaveCount != this.enemyWaveSize) {
- if (this.enemyArrivalTurn == 0 && this.enemyCount > 0) {
- var badEngine = enyo.bind(this, "badEngine");
- var unit = util.createUnit({
- type: util.randomUnit(this.currentlevel.stats),
- color: "red",
- heading: 0,
- engine: badEngine,
- x: constant.boardWidth-1,
- y: util.random(constant.boardHeight)
- });
- unit.value = this.currentlevel.generator();
- this.units.push(unit);
- this.enemyCount = this.enemyCount-1;
- this.enemyWaveCount++;
- this.enemyArrivalTurn = constant.startArrival;
- } else {
- this.enemyArrivalTurn = this.enemyArrivalTurn - 1;
- }
- }
-
- // Launch engine for each unit
- for (var i = 0 ; i < this.units.length ; i++) {
- var engine = this.units[i].engine;
- if (engine != null)
- engine(this.units[i], hqs);
- }
- }
-
- // Draw
- this.draw();
-
- // HACK: On Android, force redraw of canvas
- if (enyo.platform.android && document.location.protocol.substr(0,4) != "http") {
- document.getElementById('acanvas').style.display='none';
- document.getElementById('acanvas').offsetHeight;
- document.getElementById('acanvas').style.display='block';
- }
-
- // Draw score
- this.$.wave.setContent(String("0000"+this.wave).slice(-4))
- this.$.score.setContent(String("0000"+this.score).slice(-4))
- },
-
- // Engine for good tank moves
- goodEngine: function(that, hqs) {
- // Look for enemy unit
- var opponent = util.lookForOpponent(that);
- if (opponent != null) {
- // Change heading toward opponent
- that.heading = opponent.heading;
-
- // Fight
- util.processFight(that, opponent.unit);
- return;
- }
- },
-
- // Engine for bad tank moves
- badEngine: function(that, hqs) {
- // Look for enemy unit around
- var opponent = util.lookForOpponent(that);
- if (opponent != null) {
- // Change heading toward opponent
- that.heading = opponent.heading;
-
- // Fight
- util.processFight(that, opponent.unit);
- return;
- }
-
- // Change heading to go toward the nearest HQ
- var nearestHQ = util.nearestUnit(that, hqs);
- if (nearestHQ != null) {
- var dx = that.x - nearestHQ.x;
- var dy = that.y - nearestHQ.y;
- if (Math.abs(dx) > Math.abs(dy))
- that.heading = dx > 0 ? 0 : 2;
- else
- that.heading = dy > 0 ? 1 : 3;
- }
-
- // Is it a valid position ?
- var next = util.nextPositionOnHeading(that);
- while (!util.isValidPosition(next, that)) {
- // No, try a random heading
- that.heading = util.random(4);
- next = util.nextPositionOnHeading(that);
- }
- next = util.nextPositionOnHeading(that);
- that.x = next.x;
- that.y = next.y;
- }
- });
|