2 Комити ff9b635e62 ... c83509d7a3

Аутор SHA1 Порука Датум
  Pedro Tonini Rosenberg Schneider c83509d7a3 ✨ Make Valise 2 tutorial пре 3 година
  Pedro Tonini Rosenberg Schneider 288a534424 ✨ Make valise 2 normal levels work пре 3 година

+ 11 - 0
index.html

@@ -53,6 +53,17 @@
     <script type="text/javascript" src="src/elements/earth/valise1/tutorial/Valise1Tutorial.js"></script>
     <script type="text/javascript" src="src/elements/earth/valise1/level_selector/Valise1LevelButton.js"></script>
     <script type="text/javascript" src="src/elements/earth/valise1/level_selector/Valise1LevelSelector.js"></script>
+    <!-- Valise 2 -->
+    <script type="text/javascript" src="src/elements/earth/valise2/Valise2Levels.js"></script>
+    <script type="text/javascript" src="src/elements/earth/valise2/game/Valise2CardVisualEffect.js"></script>
+    <script type="text/javascript" src="src/elements/earth/valise2/game/Valise2OptionCard.js"></script>
+    <script type="text/javascript" src="src/elements/earth/valise2/game/Valise2QuestionCard.js"></script>
+    <script type="text/javascript" src="src/elements/earth/valise2/game/Valise2GameDialogue.js"></script>
+    <script type="text/javascript" src="src/elements/earth/valise2/game/Valise2Game.js"></script>
+    <script type="text/javascript" src="src/elements/earth/valise2/tutorial/Valise2TutorialDialogue.js"></script>
+    <script type="text/javascript" src="src/elements/earth/valise2/tutorial/Valise2Tutorial.js"></script>
+    <script type="text/javascript" src="src/elements/earth/valise2/level_selector/Valise2LevelButton.js"></script>
+    <script type="text/javascript" src="src/elements/earth/valise2/level_selector/Valise2LevelSelector.js"></script>
     <!-- Rébus -->
     <script type="text/javascript" src="src/elements/earth/rebus/RebusLevels.js"></script>
     <script type="text/javascript" src="src/elements/earth/rebus/level_selector/RebusLevelButton.js"></script>

+ 6 - 0
src/elements/earth/valise1/game/Valise1Game.js

@@ -62,6 +62,11 @@ class Valise1Game extends Object2D
     _draw( /** @type {Number} */ delta, /** @type {p5.Graphics} */ db)
     {
         background(52);
+
+        // db.fill(255);
+        // db.textSize(70);
+        // db.textAlign(CENTER, CENTER);
+        // db.text(`Nível ${this.levelData}`, 1920 / 2, 100);
     }
 
     _onCardSelected( /** @type {Boolean} */ isAnswer)
@@ -69,6 +74,7 @@ class Valise1Game extends Object2D
         if (!isAnswer) this.points--;
         else
         {
+            this.backButton.hide();
             this.gameFinished = true;
             for (let i = 0; i < 4; i++)
                 this.optionCards.children[i].selectable = false;

src/elements/earth/valise1/acrofonyleveldata.txt → src/elements/earth/valise1/valise1leveldata.txt


+ 173 - 0
src/elements/earth/valise2/Valise2Levels.js

@@ -0,0 +1,173 @@
+const VALISE2_LEVELS = {
+    tutorial:
+    {
+        questionCard:
+        {
+            name: "Cana",
+        },
+
+        optionCards: [
+        {
+            name: "Ana",
+            isAnswer: true,
+        },
+        {
+            name: "Cama",
+            isAnswer: false,
+        },
+        {
+            name: "Pera",
+            isAnswer: false,
+        }, ],
+
+        tip: "É o nome de uma pessoa que está escondido na palavra CANA."
+    },
+
+    level1:
+    {
+        questionCard:
+        {
+            name: "Irmão",
+        },
+
+        optionCards: [
+        {
+            name: "Mão",
+            isAnswer: true,
+        },
+        {
+            name: "Corrimão",
+            isAnswer: false,
+        },
+        {
+            name: "Cão",
+            isAnswer: false,
+        }, ],
+
+        tip: "É o nome de uma parte do corpo que está escondido na palavra IRMÃO."
+    },
+
+    level2:
+    {
+        questionCard:
+        {
+            name: "Cebolinha",
+        },
+
+        optionCards: [
+        {
+            name: "Bolinha",
+            isAnswer: true,
+        },
+        {
+            name: "Linha",
+            isAnswer: true,
+        },
+        {
+            name: "Salsinha",
+            isAnswer: false,
+        },
+        {
+            name: "Comida",
+            isAnswer: false,
+        }, ],
+
+        tip: "É o nome de um objeto usado para costurar que está escondido na palavra CEBOLINHA. Agora a outra dica: é redondo esse brinquedo escondido na palavra CEBOLINHA."
+    },
+
+    level3:
+    {
+        questionCard:
+        {
+            name: "Salsinha",
+        },
+
+        optionCards: [
+        {
+            name: "Sal",
+            isAnswer: true,
+        },
+        {
+            name: "Linha",
+            isAnswer: false,
+        },
+        {
+            name: "Unha",
+            isAnswer: false,
+        }, ],
+
+        tip: "É o nome de um tempero que está escondido na palavra SALSINHA."
+    },
+
+    level4:
+    {
+        questionCard:
+        {
+            name: "Banana",
+        },
+
+        optionCards: [
+        {
+            name: "Ana",
+            isAnswer: true,
+        },
+        {
+            name: "Bala",
+            isAnswer: false,
+        },
+        {
+            name: "Maçã",
+            isAnswer: false,
+        }, ],
+
+        tip: "É o nome de uma pessoa que está escondido na palavra BANANA."
+    },
+
+    level5:
+    {
+        questionCard:
+        {
+            name: "Alface",
+        },
+
+        optionCards: [
+        {
+            name: "Face",
+            isAnswer: true,
+        },
+        {
+            name: "Tomate",
+            isAnswer: false,
+        },
+        {
+            name: "Fada",
+            isAnswer: false,
+        }, ],
+
+        tip: "É o nome de uma parte do corpo que está escondido na palavra ALFACE."
+    },
+
+    level6:
+    {
+        questionCard:
+        {
+            name: "Pimenta",
+        },
+
+        optionCards: [
+        {
+            name: "Menta",
+            isAnswer: true,
+        },
+        {
+            name: "Pepino",
+            isAnswer: false,
+        },
+        {
+            name: "Anta",
+            isAnswer: false,
+        }, ],
+
+        tip: "É uma erva que está escondida na palavra PIMENTA."
+    },
+}

+ 36 - 0
src/elements/earth/valise2/game/Valise2CardVisualEffect.js

@@ -0,0 +1,36 @@
+class Valise2CardVisualEffect extends Object2D
+{
+    constructor(name)
+    {
+        super(name);
+
+        /** @type {number} */
+        this.glowIterations = 7;
+        /** @type {number} */
+        this.glowAmount = 0;
+    }
+
+    _draw( /** @type {number} */ delta, /** @type {p5.Graphics} */ db)
+    {
+        db.rectMode(CENTER);
+        if (this.parent.selected)
+        {
+            if (!this.parent.isAnswer)
+            {
+                db.fill(0, 80);
+                db.rect(0, 0, 275, 275, 10, 10);
+            }
+            else
+            {
+                db.noFill();
+                this.glowAmount = min(1.0, this.glowAmount + 0.03);
+                for (let i = 0; i < this.glowIterations; i++)
+                {
+                    db.stroke(255, 255, 100, this.glowAmount * 200 / (this.glowIterations + 1 - i));
+                    db.strokeWeight((this.glowIterations - i) * 6);
+                    db.rect(0, 0, 275, 275, 10);
+                }
+            }
+        }
+    }
+}

+ 101 - 0
src/elements/earth/valise2/game/Valise2Game.js

@@ -0,0 +1,101 @@
+class Valise2Game extends Object2D
+{
+    constructor(name)
+    {
+        super(name);
+
+        /** @type {Object} */
+        this.levelData = null;
+        /** @type {Valise2QuestionCard} */
+        this.questionCard = null;
+        /** @type {Object2D} */
+        this.optionCards = null;
+        /** @type {Button} */
+        this.backButton = null;
+        /** @type {Valise2GameDialogue} */
+        this.dialogue = null;
+
+        /** @type {Number} */
+        this.points = 3;
+        /** @type {Boolean} */
+        this.gameFinished = false;
+        /** @type {Number} */
+        this.numAnswers = 0;
+    }
+
+    _setup()
+    {
+        this.backButton = new Button("BackButton");
+        this.backButton.setLabel("Voltar");
+        this.backButton.setFontSize(30);
+        this.backButton.setPosition(20, 20);
+        this.backButton.setSize(110, 75);
+        this.backButton.connect("mouseClicked", this, "_onBackClicked");
+        this.addChild(this.backButton);
+
+        this.questionCard = new Valise2QuestionCard("QuestionCard");
+        this.questionCard.str = this.levelData.questionCard.name + "\n🗢";
+        this.questionCard.setPosition(1920 / 2, 300);
+        this.addChild(this.questionCard);
+
+        this.optionCards = new Object2D("OptionCards");
+        this.addChild(this.optionCards);
+        var idx = [];
+        for (let i = 0; i < this.levelData.optionCards.length; i++)
+            idx.push(i);
+        randomSeed(Date.now());
+        idx = shuffle(idx);
+        for (let i = 0; i < this.levelData.optionCards.length; i++)
+        {
+            var newCard = new Valise2OptionCard(`OptionCard${i}`);
+            newCard.setPosition((i + 1) * 1920 / (this.levelData.optionCards.length + 1), 800);
+            newCard.isAnswer = this.levelData.optionCards[idx[i]].isAnswer;
+            newCard.connect("selected", this, "_onCardSelected");
+            newCard.str = this.levelData.optionCards[idx[i]].name + "\n🗢";
+            this.levelData.optionCards[idx[i]].isAnswer ? this.numAnswers++ : 0;
+            this.optionCards.addChild(newCard);
+        }
+        console.log(this.numAnswers)
+
+        this.dialogue = new Valise2GameDialogue("GameDialogue");
+        this.dialogue.connect("endGame", this, "_onDialogueEndGame");
+        this.addChild(this.dialogue);
+    }
+
+    _draw( /** @type {Number} */ delta, /** @type {p5.Graphics} */ db)
+    {
+        background(52);
+
+        // db.fill(255);
+        // db.textSize(70);
+        // db.textAlign(CENTER, CENTER);
+        // db.text(`Nível ${this.levelData}`, 1920 / 2, 100);
+    }
+
+    _onCardSelected( /** @type {Boolean} */ isAnswer)
+    {
+        if (!isAnswer) this.points--;
+        else
+        {
+            this.numAnswers--;
+            if (this.numAnswers != 0) return;
+            this.backButton.hide();
+            this.gameFinished = true;
+            for (let i = 0; i < this.optionCards.children.length; i++)
+                this.optionCards.children[i].selectable = false;
+        }
+    }
+
+    _onDialogueEndGame()
+    {
+        this._onBackClicked();
+    }
+
+    _onBackClicked()
+    {
+        var vls = new Valise2LevelSelector("Valise2LevelSelector");
+        GameHandler.addRootObject(vls);
+        AssetHandler.clearTextureCache();
+        this.queueFree();
+    }
+}

+ 65 - 0
src/elements/earth/valise2/game/Valise2GameDialogue.js

@@ -0,0 +1,65 @@
+class Valise2GameDialogue extends Object2D
+{
+    constructor(name)
+    {
+        super(name);
+
+        /** @type {Button} */
+        this.continueButton = null;
+        /** @type {Timer} */
+        this.timer;
+
+        /** @type {String} */
+        this.suffix = "";
+        /** @type {number} */
+        this.bgOpacity = 0;
+        /** @type {number} */
+        this.textOpacity = 0;
+    }
+
+    _initSignals()
+    {
+        this.addSignal("endGame");
+    }
+
+    _setup()
+    {
+        this.timer = new Timer("Timer", 2, false, true);
+        this.timer.connect("timeout", this, "_onTimerTimeout");
+        this.addChild(this.timer);
+
+        this.continueButton = new Button("ContinueButton", "Continuar");
+        this.continueButton.setFontSize(40);
+        this.continueButton.setPosition(1920 / 2 - this.continueButton.getSize().x / 2, 600);
+        this.continueButton.connect("mouseClicked", this, "_onContinueButtonClicked");
+        this.addChild(this.continueButton);
+        this.continueButton.hide();
+    }
+
+    _draw( /** @type {number} */ delta, /** @type {p5.Graphics} */ db)
+    {
+        if (this.parent.gameFinished)
+        {
+            this.timer.start();
+            db.noStroke();
+            db.fill(0, min(this.bgOpacity += 75 * delta, 200));
+            db.rectMode(CENTER);
+            db.rect(db.width / 2, db.height / 2, 1800, 600, 40, 40);
+            db.textAlign(CENTER, CENTER);
+            db.fill(255, min(this.textOpacity += 80 * delta, 255));
+            db.textSize(40);
+            this.parent.points > 1 ? this.suffix = "S" : this.suffix = "";
+            db.text(`PARABÉNS, NÍVEL CONCLUÍDO\n\nVOCÊ GANHOU ${this.parent.points} PONTO${this.suffix}!`, db.width / 2, db.height / 2 - 100);
+        }
+    }
+
+    _onTimerTimeout()
+    {
+        this.continueButton.show();
+    }
+
+    _onContinueButtonClicked()
+    {
+        this.emitSignal("endGame");
+    }
+}

+ 120 - 0
src/elements/earth/valise2/game/Valise2OptionCard.js

@@ -0,0 +1,120 @@
+class Valise2OptionCard extends Object2D
+{
+    constructor(name)
+    {
+        super(name);
+
+        /** @type {String} */
+        this.str = "";
+        /** @type {Boolean} */
+        this.isAnswer = false;
+        /** @type {Boolean} */
+        this.selected = false;
+        /** @type {Boolean} */
+        this.selectable = true;
+        /** @type {Boolean} */
+        this.mouseOver = false;
+        /** @type  {Boolean} */
+        this.mousePress = false;
+
+        /** @type {TextureRes} */
+        this.thumb = null;
+        /** @type {Color} */
+        this.fillColor = new Color(200, 200, 200);
+        /** @type {Boolean} */
+        this.tweenStarted = false;
+        /** @type {Tween} */
+        this.tween = null;
+        /** @type {Timer} */
+        this.timer = null;
+    }
+
+    _initSignals()
+    {
+        this.addSignal("selected");
+    }
+
+    _setup()
+    {
+        var area = new Area2D("area", SHAPES.RECT, new Rect(275, 275), true);
+        area.connect("mouseEntered", this, "_onMouseEntered");
+        area.connect("mouseExited", this, "_onMouseExited");
+        this.addChild(area);
+
+        this.addChild(new Valise2CardVisualEffect("CardVfx"));
+
+        this.tween = new Tween("Tween");
+        this.tween.interpolateProperty(this, "scale", PROPERTY_TYPE.VECTOR2, Vector2.ZERO(), Vector2.ONE(), 2, TRANS_TYPE.ELASTIC, EASE_TYPE.OUT);
+        this.addChild(this.tween);
+        this.setScale(0, 0);
+
+        this.timer = new Timer("Timer", 1, false, true);
+        this.timer.connect("timeout", this, "_onTimerTimeout");
+        this.addChild(this.timer);
+    }
+
+    _update( /** @type {Number} */ delta)
+    {
+        if (this.visible && !this.tweenStarted)
+        {
+            this.timer.start();
+            this.tween.startAll();
+            this.tweenStarted = true;
+        }
+
+        if (this.selectable && this.mouseOver)
+        {
+            if (InputHandler.mouseIsClicked)
+            {
+                this.selected = true;
+                this.selectable = false;
+                this.emitSignal("selected", this.isAnswer);
+
+            }
+
+            if (InputHandler.mouseIsPressed)
+            {
+                this.scale.x = max(this.scale.x - 3.0 * delta, 0.95);
+                this.scale.y = max(this.scale.y - 3.0 * delta, 0.95);
+            }
+            else
+            {
+                this.scale.x = min(this.scale.x + 2.0 * delta, 1.2);
+                this.scale.y = min(this.scale.y + 2.0 * delta, 1.2);
+            }
+        }
+
+        else
+        {
+            this.scale.x = max(this.scale.x - 2.0 * delta, 1);
+            this.scale.y = max(this.scale.y - 2.0 * delta, 1);
+        }
+    }
+
+    _draw( /** @type {Number} */ delta, /** @type {p5.Graphics} */ db)
+    {
+        db.rectMode(CENTER);
+        db.fill(this.fillColor.getP5Color());
+        db.rect(0, 0, 275, 275, 10, 10);
+        db.textAlign(CENTER, CENTER);
+        db.fill(0);
+        db.textSize(40);
+        db.text(this.str, 0, 0);
+    }
+
+    _onMouseEntered()
+    {
+        this.mouseOver = true;
+        console.log(this.str);
+    }
+
+    _onMouseExited()
+    {
+        this.mouseOver = false;
+    }
+
+    _onTimerTimeout()
+    {
+        this.tween.stopAll();
+    }
+}

+ 39 - 0
src/elements/earth/valise2/game/Valise2QuestionCard.js

@@ -0,0 +1,39 @@
+class Valise2QuestionCard extends Object2D
+{
+    constructor(name)
+    {
+        super(name);
+
+        /** @type {String} */
+        this.str = "";
+
+        /** @type {Color} */
+        this.fillColor = new Color(200, 200, 200);
+        /** @type {Tween} */
+        this.tween = null;
+    }
+
+    _setup()
+    {
+        this.tween = new Tween("Tween");
+        this.tween.interpolateProperty(this, "scale", PROPERTY_TYPE.VECTOR2, Vector2.ZERO(), Vector2.ONE(), 2, TRANS_TYPE.ELASTIC, EASE_TYPE.OUT);
+        this.addChild(this.tween);
+    }
+
+    _update( /** @type {Number} */ delta)
+    {
+        if (this.visible) this.tween.startAll();
+    }
+
+    _draw( /** @type {Number} */ delta, /** @type {p5.Graphics} */ db)
+    {
+        db.strokeWeight(10);
+        db.rectMode(CENTER);
+        db.fill(this.fillColor.getP5Color());
+        db.rect(0, 0, 275, 275, 10, 10);
+        db.textAlign(CENTER, CENTER);
+        db.fill(0);
+        db.textSize(40);
+        db.text(this.str, 0, 0);
+    }
+}

+ 20 - 0
src/elements/earth/valise2/level_selector/Valise2LevelButton.js

@@ -0,0 +1,20 @@
+class Valise2LevelButton extends Button
+{
+    constructor(name)
+    {
+        super(name);
+
+        /** @type {Object} */
+        this.levelData = null;
+    }
+
+    _initSignals()
+    {
+        this.addSignal("levelSelected");
+    }
+
+    _onMouseClicked()
+    {
+        this.emitSignal("levelSelected", this.levelData);
+    }
+}

+ 87 - 0
src/elements/earth/valise2/level_selector/Valise2LevelSelector.js

@@ -0,0 +1,87 @@
+class Valise2LevelSelector extends Object2D
+{
+    constructor(name)
+    {
+        super(name);
+
+        /** @type {Object} */
+        this.gridMargins = {
+            left: 0,
+            right: 0,
+            up: 500,
+            down: 0
+        };
+
+        /** @type {number} */
+        this.gridCols = 4;
+    }
+
+    _setup()
+    {
+        var b = new RebusLevelButton("Tutorial");
+        b.levelData = VALISE2_LEVELS.tutorial;
+        b.setLabel("Tutorial");
+        b.setFontSize(40);
+        this.addChild(b);
+        b.setSize(200, 100);
+        b.setPosition((1920 - b.getSize().x) / 2, 300);
+        b.connect("levelSelected", this, "_onTutorialSelected");
+
+        var i = 1;
+        while (VALISE2_LEVELS[`level${i}`])
+        {
+            var b = new Valise2LevelButton(`level${i}`);
+            b.levelData = VALISE2_LEVELS[`level${i}`];
+            b.setLabel(`${i}`);
+            b.setFontSize(40);
+            this.addChild(b);
+            b.setSize(100, 100);
+            b.setPosition((((i - 1) % this.gridCols) + 1) * 1920 / (this.gridCols + 1) - b.getSize().x / 2, this.gridMargins.up + 200 * int((i - 1) / this.gridCols));
+            b.connect("levelSelected", this, "_onLevelSelected");
+            i++;
+        }
+
+        this.backButton = new Button("BackButton");
+        this.backButton.setLabel("Voltar");
+        this.backButton.setFontSize(30);
+        this.backButton.setPosition(20, 20);
+        this.backButton.setSize(110, 75);
+        this.backButton.connect("mouseClicked", this, "_onBackClicked");
+        this.addChild(this.backButton);
+    }
+
+    _draw( /** @type {number} */ delta, /** @type {p5.Graphics} */ db)
+    {
+        background(52);
+
+        db.textAlign(CENTER, CENTER);
+        db.fill(255);
+        db.textSize(100);
+        db.text("PALAVRA VALISE 2", 1920 / 2, 125);
+        db.textSize(40);
+        db.text("Escolha o nível", 1920 / 2, 200);
+    }
+
+    _onTutorialSelected( /** @type {Object} */ levelData)
+    {
+        var vt = new Valise2Tutorial("Valise2Tutorial");
+        vt.levelData = levelData;
+        GameHandler.addRootObject(vt);
+        this.queueFree();
+    }
+
+    _onLevelSelected( /** @type {Object} */ levelData)
+    {
+        var vg = new Valise2Game("Valise2Game");
+        vg.levelData = levelData;
+        GameHandler.addRootObject(vg);
+        this.queueFree();
+    }
+
+    _onBackClicked()
+    {
+        var ems = new EarthMinigameSelector("EarthMinigameSelector");
+        GameHandler.addRootObject(ems);
+        this.queueFree();
+    }
+}

+ 160 - 0
src/elements/earth/valise2/tutorial/Valise2Tutorial.js

@@ -0,0 +1,160 @@
+class Valise2Tutorial extends Object2D
+{
+    constructor(name)
+    {
+        super(name);
+
+        /** @type {Object} */
+        this.levelData = null;
+        /** @type {Valise2QuestionCard} */
+        this.questionCard = null;
+        /** @type {Object2D} */
+        this.optionCards = null;
+        /** @type {Button} */
+        this.backButton = null;
+        /** @type {Valise2TutorialDialogue} */
+        this.dialogue = null;
+        /** @type {Timer} */
+        this.timer = null;
+
+        /** @type {Number} */
+        this.points = 3;
+        /** @type {Boolean} */
+        this.gameFinished = false;
+        /** @type {Number} */
+        this.tutorialStep = 0;
+    }
+
+    _setup()
+    {
+        this.backButton = new Button("BackButton");
+        this.backButton.setLabel("Voltar");
+        this.backButton.setFontSize(30);
+        this.backButton.setPosition(20, 20);
+        this.backButton.setSize(110, 75);
+        this.backButton.connect("mouseClicked", this, "_onBackClicked");
+        this.addChild(this.backButton);
+
+        this.questionCard = new Valise2QuestionCard("QuestionCard");
+        this.questionCard.str = this.levelData.questionCard.name + "\n🗢";
+        this.questionCard.setPosition(1920 / 2, 300);
+        this.addChild(this.questionCard);
+
+        this.optionCards = new Object2D("OptionCards");
+        this.addChild(this.optionCards);
+        var idx = [];
+        for (let i = 0; i < this.levelData.optionCards.length; i++)
+            idx.push(i);
+        randomSeed(Date.now());
+        idx = shuffle(idx);
+        for (let i = 0; i < this.levelData.optionCards.length; i++)
+        {
+            var newCard = new Valise2OptionCard(`OptionCard${i}`);
+            newCard.setPosition((i + 1) * 1920 / (this.levelData.optionCards.length + 1), 800);
+            newCard.isAnswer = idx[i] == 0;
+            newCard.connect("selected", this, "_onCardSelected");
+            newCard.str = this.levelData.optionCards[idx[i]].name + "\n🗢";
+            newCard.selectable = false;
+            this.optionCards.addChild(newCard);
+        }
+
+        this.dialogue = new Valise2TutorialDialogue("TutorialDialogue");
+        this.dialogue.connect("continue", this, "_onTutorialContinue");
+        this.addChild(this.dialogue);
+
+        this.timer = new Timer("Timer", 2, false, true);
+        this.timer.connect("timeout", this, "_onTimerTimeout");
+        this.addChild(this.timer);
+        this.timer.start();
+    }
+
+    _draw( /** @type {Number} */ delta, /** @type {p5.Graphics} */ db)
+    {
+        background(52);
+    }
+
+    _onCardSelected( /** @type {Boolean} */ isAnswer)
+    {
+        if (!isAnswer) this.points--;
+        else
+        {
+            this.gameFinished = true;
+            for (let i = 0; i < 4; i++)
+                this.optionCards.children[i].selectable = false;
+        }
+    }
+
+    _onTutorialContinue()
+    {
+        this.tutorialStep++;
+
+        switch (this.tutorialStep)
+        {
+            case 2:
+                this.timer.start(2);
+                break;
+            case 9:
+                this._onBackClicked();
+                break;
+        }
+    }
+
+    _onTimerTimeout()
+    {
+        this.tutorialStep++;
+
+        switch (this.tutorialStep)
+        {
+            case 3:
+                this.optionCards.children[0].selectable = true;
+                this.optionCards.children[0].mouseOver = true;
+                this.optionCards.children[1].selectable = false;
+                this.optionCards.children[1].mouseOver = false;
+                this.optionCards.children[2].selectable = false;
+                this.optionCards.children[2].mouseOver = false;
+                this.timer.start(0.5);
+                break;
+            case 4:
+                this.optionCards.children[0].selectable = false;
+                this.optionCards.children[0].mouseOver = false;
+                this.optionCards.children[1].selectable = true;
+                this.optionCards.children[1].mouseOver = true;
+                this.optionCards.children[2].selectable = false;
+                this.optionCards.children[2].mouseOver = false;
+                this.timer.start(0.5);
+                break;
+            case 5:
+                this.optionCards.children[0].selectable = false;
+                this.optionCards.children[0].mouseOver = false;
+                this.optionCards.children[1].selectable = false;
+                this.optionCards.children[1].mouseOver = false;
+                this.optionCards.children[2].selectable = true;
+                this.optionCards.children[2].mouseOver = true;
+                this.timer.start(0.5);
+                break;
+            case 6:
+                this.optionCards.children[0].selectable = false;
+                this.optionCards.children[0].mouseOver = false;
+                this.optionCards.children[1].selectable = false;
+                this.optionCards.children[1].mouseOver = false;
+                this.optionCards.children[2].selectable = false;
+                this.optionCards.children[2].mouseOver = false;
+                this.timer.start(2);
+                break;
+            case 7:
+                this.optionCards.children[0].selected = true;
+                this.optionCards.children[1].selected = true;
+                this.optionCards.children[2].selected = true;
+                this.timer.start(1);
+                break;
+        }
+    }
+
+    _onBackClicked()
+    {
+        var vls = new Valise2LevelSelector("Valise2LevelSelector");
+        GameHandler.addRootObject(vls);
+        AssetHandler.clearTextureCache();
+        this.queueFree();
+    }
+}

+ 81 - 0
src/elements/earth/valise2/tutorial/Valise2TutorialDialogue.js

@@ -0,0 +1,81 @@
+class Valise2TutorialDialogue extends Object2D
+{
+    constructor(name)
+    {
+        super(name);
+
+        /** @type {Button} */
+        this.continueButton = null;
+        /** @type {Timer} */
+        this.timer;
+
+        /** @type {String} */
+        this.text = "";
+        /** @type {number} */
+        this.bgOpacity = 0;
+        /** @type {number} */
+        this.textOpacity = 0;
+    }
+
+    _initSignals()
+    {
+        this.addSignal("continue");
+    }
+
+    _setup()
+    {
+        this.continueButton = new Button("ContinueButton", "Continuar");
+        this.continueButton.connect("mouseClicked", this, "_onContinueButtonMouseClicked");
+        this.continueButton.hide();
+        this.continueButton.setFontSize(40);
+        this.continueButton.setPosition(1920 / 2 - this.continueButton.getSize().x / 2, 600);
+        this.addChild(this.continueButton);
+    }
+
+    _draw( /** @type {number} */ delta, /** @type {p5.Graphics} */ db)
+    {
+        switch (this.parent.tutorialStep)
+        {
+            case 0:
+                this.bgOpacity = 0;
+                this.textOpacity = 0;
+                break;
+            case 1:
+                this.bgOpacity = min(this.bgOpacity + 150 * delta, 200);
+                this.textOpacity = min(this.textOpacity + 150 * delta, 255);
+                this.text = "Qual é a palavra escondida em CANA?"
+                if (this.textOpacity == 255) this.continueButton.show();
+                break;
+            case 2:
+                this.continueButton.hide();
+                this.bgOpacity = max(this.bgOpacity - 150 * delta, 0);
+                this.textOpacity = max(this.textOpacity - 150 * delta, 0);
+                this.text = "Qual é a palavra escondida em CANA?"
+                break;
+            case 3:
+                this.bgOpacity = 0;
+                this.textOpacity = 0;
+                break;
+            case 8:
+                this.bgOpacity = min(this.bgOpacity + 150 * delta, 200);
+                this.textOpacity = min(this.textOpacity + 150 * delta, 255);
+                this.text = "A palavra escondida em CANA é ANA.\n\nAgora é sua vez!"
+                if (this.textOpacity == 255) this.continueButton.show();
+                break;
+        }
+
+        db.noStroke();
+        db.fill(0, this.bgOpacity);
+        db.rectMode(CENTER);
+        db.rect(db.width / 2, db.height / 2, 1800, 600, 40, 40);
+        db.textAlign(CENTER, CENTER);
+        db.fill(255, this.textOpacity);
+        db.textSize(40);
+        db.text(this.text, db.width / 2, db.height / 2 - 100);
+    }
+
+    _onContinueButtonMouseClicked()
+    {
+        this.emitSignal("continue");
+    }
+}

+ 20 - 0
src/elements/earth/valise2/valise2leveldata.txt

@@ -0,0 +1,20 @@
+Cana        Ana, Cama, Pera
+É o nome de uma pessoa que está escondido na palavra CANA.
+
+Irmão       Mão, Corrimão, Cão
+É o nome de uma parte do corpo que está escondido na palavra IRMÃO.
+
+Cebolinha   Bolinha Linha Salsinha Comida
+É o nome de um objeto usado para costurar que está escondido na palavra CEBOLINHA. Agora a outra dica: é redondo esse brinquedo escondido na palavra CEBOLINHA.
+
+Salsinha    Sal, Linha, Unha
+É o nome de um tempero que está escondido na palavra SALSINHA.
+
+Banana      Ana, Bala, Maçã
+É o nome de uma pessoa que está escondido na palavra BANANA.
+
+Alface      Face, Tomate, Fada
+É o nome de uma parte do corpo que está escondido na palavra ALFACE.
+
+Pimenta     Menta, Pepino, Anta
+É uma erva que está escondida na palavra PIMENTA.

+ 1 - 1
src/main.js

@@ -30,7 +30,7 @@ GameHandler._setup = function()
     GameHandler.drawDebugBufferBounds(true);
     textFont("Lato");
 
-    var vg = new Valise1LevelSelector("Valise1Game");
+    var vg = new Valise2LevelSelector("Valise2Game");
     GameHandler.addRootObject(vg);
 
     // var menu = new EelementSelector("ElementSelector");