|
|
- // Level config
- FoodChain.buildLevels = [
- { size: 2, time: 2 }, // Level 1
- { size: 3, time: 5 }, // Level 2
- { size: 3, time: 3 }, // Level 3
- { size: 3, time: 2 }, // Level 4
- { size: 4, time: 5 }, // Level 5
- { size: 4, time: 3 }, // Level 6
- { size: 5, time: 3 } // Level 7
- ];
-
- // Build Game class
- enyo.kind({
- name: "FoodChain.BuildGame",
- kind: enyo.Control,
- published: {level: 1},
- classes: "board",
- components: [
- { name: "cards", components: [
- // Level - Score - Time bar
- { components: [
- { classes: "level-zone", components: [
- { name: "textlevel", classes: "title level-value" },
- { name: "level", content: "0", classes: "title level-value" }
- ]},
- { classes: "score-zone", components: [
- { name: "textscore", classes: "title score-text" },
- { name: "score", content: "0000", classes: "title score-value" },
- { name: "timercount", content: "0:0,0", classes: "title timer-value" }
- ]}
- ]},
-
- // Board zone
- { name: "gamebox", classes: "box", ontap: "unselect", ondrop: "drop", ondragover: "dragover", components: [] },
-
- // Buttons bar
- { name: "validate", kind: "ShadowButton", img: "validate", classes: "validate", ontap: "controlOrder" },
- { name: "play", kind: "ShadowButton", img: "play", classes: "play", ontap: "play" },
- { name: "pause", kind: "ShadowButton", img: "pause", classes: "play", ontap: "pause" },
- { name: "restart", kind: "ShadowButton", img: "restart", classes: "restart", ontap: "restart" },
- { name: "forward", kind: "ShadowButton", img: "forward", classes: "restart", ontap: "next" },
- { name: "home", kind: "ShadowButton", img: "home", classes: "home", ontap: "home" },
-
- // End of sound event
- {kind: "enyo.Signals", onEndOfSound: "endSound"}
- ]}
- ],
-
- // Constructor
- create: function() {
- this.inherited(arguments);
- this.previous = null;
- this.mixed = null;
- this.createComponent({ name: "timer", kind: "Timer", paused: true, onTriggered: "updateTimer" }, {owner: this});
- this.setLocale();
- this.$.score.setContent(String("0000"+FoodChain.context.score).slice(-4));
- FoodChain.context.game = this.kindName;
- this.levelChanged();
- },
-
- // Localization changed, update cards and string resource
- setLocale: function() {
- // Update string resources
- this.$.textlevel.setContent(__$FC("level"));
- this.$.textscore.setContent(__$FC("score"));
-
- // Update cards
- enyo.forEach(this.$.gamebox.getControls(), function(card) {
- card.setLocale();
- });
- },
-
- // Level changed, init board then start game
- levelChanged: function() {
- // Delete current cards on board
- FoodChain.context.level = this.level;
- var cards = [];
- enyo.forEach(this.$.gamebox.getControls(), function(card) {
- cards.push(card);
- });
- for (var i = 0 ; i < cards.length ; i++) {
- cards[i].destroy();
- }
-
- // Compute the start chain
- if (this.mixed == null) {
- var same;
- do {
- // Pick a random chain and ensure it's not the same that the previous one
- this.chain = FoodChain.randomChain(FoodChain.buildLevels[this.level-1].size);
- if (this.previous == null || this.previous.length != this.chain.length) {
- same = false;
- } else {
- same = true;
- for (var i = 0 ; same && i < this.chain.length ; i++ ) {
- if (this.previous[i] != this.chain[i])
- same = false;
- }
- }
- } while (same);
- this.mixed = FoodChain.mix(this.chain);
- }
-
- // Display cards
- var step = 99/this.mixed.length;
- var x = 5-this.mixed.length, y = 8;
- this.cards = [];
- for (var i = 0 ; i < this.mixed.length ; i++) {
- var autoplay = (i == 0) ? true: false;
- this.cards.push(this.$.gamebox.createComponent({ kind: "FoodChain.Card", cardname: this.mixed[i], x: x+"%", y: y, ontap: "taped", ondragstart: "dragstart", ondragfinish: "dragfinish"}, {owner: this}));
- if (i == 0) {
- FoodChain.sound.play(this.cards[i].sound);
- } else {
- this.cards[i].hide();
- }
- x = x + step;
- }
-
- // Box handling
- this.dragobject = null;
- this.selectedobject = null;
- this.zmax = 0;
- this.$.gamebox.removeClass("box-win");
- this.$.gamebox.removeClass("box-lost");
-
- // Saving context
- FoodChain.saveContext();
-
- // Button handling
- this.$.play.hide();
- this.$.pause.show();
- this.$.validate.show();
- this.$.restart.hide();
- this.$.forward.hide();
- this.$.home.hide();
-
- // Timer and level init
- this.$.level.setContent(" "+this.level);
- this.timecount = {mins:0, secs:0, tenth:0};
- this.$.timercount.removeClass("timer-overtime");
- this.displayTimer();
- this.$.timer.pause();
-
- this.render();
- },
-
- // Sound ended, play next card if any
- endSound: function(e, s) {
- // All is already displayed
- if (this.cards == null)
- return;
-
- // Display next card
- for (var i = 0 ; i < this.cards.length ; i++ ) {
- if (this.cards[i] != null && FoodChain.soundMatch(this.cards[i].sound,s.sound)) {
- this.cards[i] = null;
- if (i+1 < this.cards.length) {
- this.cards[i+1].show();
- FoodChain.sound.play(this.cards[i+1].sound);
- return;
- }
- }
- }
-
- // All card displayed, start timer
- this.cards = null;
- this.$.timer.resume();
- },
-
- // Display timer value
- displayTimer: function() {
- this.$.timercount.setContent(this.timecount.mins+":"+String("00"+this.timecount.secs).slice(-2)+","+this.timecount.tenth);
- },
-
- // Update timer
- updateTimer: function(s, e) {
- this.timecount.tenth = this.timecount.tenth + 1;
- if (this.timecount.tenth == 10) {
- this.timecount.tenth = 0;
- this.timecount.secs = this.timecount.secs + 1;
- var currentcount = this.timecount.mins * 60 + this.timecount.secs;
- if (currentcount >= FoodChain.buildLevels[this.level-1].time) {
- this.$.timercount.addClass("timer-overtime");
- }
- if (this.timecount.secs == 60) {
- this.timecount.secs = 0;
- this.timecount.mins = this.timecount.mins + 1;
- }
- }
- this.displayTimer();
- },
-
- // Play sound when card taped, set card as selected (avoid need of drag&drop)
- taped: function(s, e) {
- if (this.$.timer.paused)
- return true;
- FoodChain.log(s.cardname+" taped");
-
- // Use selection to avoid drag&drop
- if (this.selectedobject == null) {
- // No selection, set card as selected, play sound
- this.selectedobject = s;
- s.addClass("card-dragged");
- FoodChain.sound.play(s.sound);
- this.toTop(s);
- return true;
- } else if (s != this.selectedobject) {
- // A card is already selected, swap the 2 card
- var startx = this.selectedobject.getX(), starty = this.selectedobject.getY();
- var endx = s.getX(), endy = s.getY();
- this.selectedobject.moveTo(endx, endy);
- s.moveTo(startx, starty);
- this.selectedobject.removeClass("card-dragged");
- this.selectedobject = null;
- return true;
- }
- },
-
- // Tap on the board unselect current card
- unselect: function() {
- if (this.selectedobject != null) {
- this.selectedobject.removeClass("card-dragged");
- this.selectedobject = null;
- }
- },
-
- // Card drag start, change style to dragged
- dragstart: function(s, e) {
- if (this.$.timer.paused)
- return true;
- s.addClass("card-dragged");
- this.$.gamebox.addClass("box-dragging");
- FoodChain.sound.play(s.sound);
- this.dragobject = s;
- this.selectedobject = null;
- this.dragx = 0;
- this.dragy = e.clientY-s.y;
- this.toTop(this.dragobject);
- },
-
- // Card drag end, change style to not dragged
- dragfinish: function(s, e) {
- s.removeClass("card-dragged");
- this.$.gamebox.removeClass("box-dragging");
- },
-
- // Drag over the box, allow dragging
- dragover: function(s, e) {
- if (this.dragobject == null)
- return true;
- e.preventDefault();
- return false;
- },
-
- // Dropped in the box, change card parent
- drop: function(s, e) {
- if (this.dragobject == null || this.$.timer.paused)
- return true;
- e.preventDefault();
- this.dragobject.moveTo((e.clientX/window.innerWidth)*100+"%", e.clientY-this.dragy);
- this.dragobject = null;
- },
-
- // Set the card to top of the stack
- toTop: function(card) {
- this.zmax = this.zmax + 1;
- card.applyStyle("z-index", this.zmax)
- },
-
- // Validate cards order
- controlOrder: function() {
- // Stop timer
- this.$.timer.pause();
-
- // Hide button
- this.$.play.hide();
- this.$.pause.hide();
- this.$.validate.hide();
-
- // Get cards
- var cards = [];
- enyo.forEach(this.$.gamebox.getControls(), function(card) {
- cards.push(card);
- });
-
- // Sort using x card position
- cards = cards.sort(function (c1, c2) { return c1.x.replace("%","") - c2.x.replace("%",""); });
-
- // Check order
- var win = true;
- for (var i = 0 ; win && i < this.chain.length ; i++) {
- if (cards[i].cardname != this.chain[i])
- win = false;
- }
-
- // Play win or loose sound
- if (win) {
- FoodChain.sound.play("audio/applause");
- this.$.gamebox.addClass("box-win");
- this.computeScore();
- this.$.home.show();
- if (this.level != FoodChain.buildLevels.length)
- this.$.forward.show();
- }
- else {
- FoodChain.sound.play("audio/disappointed");
- this.$.gamebox.addClass("box-lost");
- this.$.home.show();
- this.$.restart.show();
- }
- },
-
- // Compute score
- computeScore: function() {
- var score = 10;
- var currentcount = this.timecount.mins * 60 + this.timecount.secs;
- if (currentcount < FoodChain.buildLevels[this.level-1].time) {
- score += (FoodChain.buildLevels[this.level-1].time - currentcount);
- }
- FoodChain.context.score += score;
- this.$.score.setContent(String("0000"+FoodChain.context.score).slice(-4));
- },
-
- // Resume game
- play: function() {
- // Show cards
- enyo.forEach(this.$.gamebox.getControls(), function(card) {
- card.show();
- });
-
- // Show pause button, hide play button
- this.$.timer.resume();
- this.$.play.hide();
- this.$.pause.show();
- this.$.home.hide();
- },
-
- // Pause game
- pause: function() {
- // Hide cards
- enyo.forEach(this.$.gamebox.getControls(), function(card) {
- card.hide();
- });
-
- // Show play button, hide pause button
- this.$.timer.pause();
- this.$.pause.hide();
- this.$.play.show();
- this.$.home.show();
- },
-
- // Restart the current level
- restart: function() {
- this.levelChanged();
- },
-
- // Go to the next level
- next: function() {
- this.level = this.level + 1;
- this.previous = this.chain;
- this.mixed = null;
- this.levelChanged();
- },
-
- // Go to the home page of the app
- home: function() {
- this.$.timer.stop();
- FoodChain.goHome();
- }
- });
|