Browse Source

Implement base game logic

Thomas Dy 7 years ago
parent
commit
ddfa9c4629
5 changed files with 142 additions and 31 deletions
  1. 44 0
      dist/jugemu.json
  2. 69 20
      src/display.ts
  3. 6 3
      src/index.ts
  4. 3 8
      src/kana.ts
  5. 20 0
      src/level.ts

+ 44 - 0
dist/jugemu.json

@@ -0,0 +1,44 @@
+{
+  "lines": [
+    {
+      "kanji": "寿限無、寿限無",
+      "kana": "じゅげむじゅげむ"
+    },
+    {
+      "kanji": "五劫の擦り切れ",
+      "kana": "ごこうのすりきれ"
+    },
+    {
+      "kanji": "海砂利水魚の",
+      "kana": "かいじゃりすいぎょうの"
+    },
+    {
+      "kanji": "水行末 雲来末 風来末",
+      "kana": "すいぎょうまつうんらいまつふうらいまつ"
+    },
+    {
+      "kanji": "食う寝る処に住む処",
+      "kana": "くうねるところにすむところ"
+    },
+    {
+      "kanji": "やぶら小路の藪柑子",
+      "kana": "やぶらこうじのぶらこうじ"
+    },
+    {
+      "kanji": "パイポパイポ パイポのシューリンガン",
+      "kana": "ぱいぽぱいぽぱいぽのしゅうりんがん"
+    },
+    {
+      "kanji": "シューリンガンのグーリンダイ",
+      "kana": "しゅうりんがんのぐうりんだい"
+    },
+    {
+      "kanji": "グーリンダイのポンポコピーのポンポコナーの",
+      "kana": "ぐうりんだいのぽんぽこぴいのぽんぽこなあの"
+    },
+    {
+      "kanji": "長久命の長助",
+      "kana": "ちょうきゅうめいのちょうすけ"
+    }
+  ]
+}

+ 69 - 20
src/display.ts

@@ -59,6 +59,7 @@ namespace display {
     }
 
     setInputState(inputState: InputState) {
+      this.clearChildren();
       if (inputState == null) {
         this.children = [];
       } else {
@@ -71,8 +72,8 @@ namespace display {
 
     private clearChildren(): void {
       this.children.forEach(child => {
-        child.destroy();
         this.element.removeChild(child.element);
+        child.destroy();
       });
     }
 
@@ -147,7 +148,7 @@ namespace display {
     }
   }
 
-  export class MainAreaController implements Component{
+  class MainAreaController implements Component {
     element: HTMLElement;
     inputState: InputState | null;
     kanaController: KanaDisplayController;
@@ -163,36 +164,84 @@ namespace display {
       this.element.appendChild(this.kanaController.element);
       this.element.appendChild(this.kanjiHTMLElement);
       this.element.appendChild(this.romajiController.element);
+    }
+
+    setData(kanji: string, kana: InputState) {
+      this.kanjiHTMLElement.textContent = kanji;
+      this.kanaController.setInputState(kana);
+      this.romajiController.setInputState(kana);
+    }
+
+    destroy(): void {
+      this.kanaController.destroy();
+      this.romajiController.destroy();
+      this.element.removeChild(this.kanaController.element);
+      this.element.removeChild(this.kanjiHTMLElement);
+      this.element.removeChild(this.romajiController.element);
+    }
+  }
+
+  export class LevelController implements Component {
+    element: HTMLElement;
+    level: level.Level;
+    currentLine: number;
+    inputState: InputState | null;
+    mainAreaController: MainAreaController;
+    listener: (event: KeyboardEvent) => void;
 
-      document.addEventListener('keydown', event => {
-        if (this.inputState !== null) {
-          this.inputState.handleInput(event.key);
+    constructor(level: level.Level) {
+      this.element = document.createElement('div');
+      this.level = level;
+      this.currentLine = -1;
+      this.inputState = null;
+      this.mainAreaController = new MainAreaController();
+      this.listener = event => this.handleInput(event.key);
+
+      this.nextLine();
+
+      document.addEventListener('keydown', this.listener);
+      this.element.appendChild(this.mainAreaController.element);
+    }
+
+    handleInput(key: string): void {
+      if (this.inputState !== null) {
+        if (this.inputState.handleInput(key)) {
+          this.nextLine();
         }
-      });
+      } else {
+        this.nextLine();
+      }
+    }
+
+    nextLine(): void {
+      if (this.currentLine + 1 < this.level.lines.length) {
+        this.currentLine += 1;
+        this.setLine(this.level.lines[this.currentLine]);
+      } else {
+        this.setLine({ kanji: '@', kana: '@' });
+      }
     }
 
-    setData(kanji: string, kana: string) {
-      if (kanji === '@') {
-        this.kanjiHTMLElement.textContent = '';
+    setLine(line: level.Line): void {
+      let kanji, inputState;
+      if (line.kanji === '@') {
+        kanji = '';
       } else {
-        this.kanjiHTMLElement.textContent = kanji;
+        kanji = line.kanji;
       }
 
-      if (kana === '@') {
-        this.inputState = null;
+      if (line.kana === '@') {
+        inputState = null;
       } else {
-        this.inputState = new InputState(kana);
+        inputState = new InputState(line.kana);
       }
-      this.kanaController.setInputState(this.inputState);
-      this.romajiController.setInputState(this.inputState);
+
+      this.inputState = inputState;
+      this.mainAreaController.setData(kanji, inputState);
     }
 
     destroy(): void {
-      this.kanaController.destroy();
-      this.romajiController.destroy();
-      this.element.removeChild(this.kanaController.element);
-      this.element.removeChild(this.kanjiHTMLElement);
-      this.element.removeChild(this.romajiController.element);
+      document.removeEventListener('keydown', this.listener);
     }
   }
 }

+ 6 - 3
src/index.ts

@@ -1,6 +1,9 @@
 /// <reference path="display.ts" />
+/// <reference path="level.ts" />
 
 let container = document.querySelector('#container');
-let controller = new display.MainAreaController();
-container.appendChild(controller.element);
-controller.setData('大丈夫ですか', 'だいじょうぶですか');
+
+level.loadFromJson('jugemu.json').then(level => {
+  let controller = new display.LevelController(level);
+  container.appendChild(controller.element);
+});

+ 3 - 8
src/kana.ts

@@ -300,15 +300,10 @@ namespace kana {
 
       let currentMachine = this.stateMachines[this.currentIndex];
       let result = currentMachine.transition(input);
-      switch (result) {
-        case TransitionResult.FAILED:
-          return false;
-        case TransitionResult.SUCCESS:
-          return true;
-        case TransitionResult.FINISHED:
-          this.currentIndex += 1;
-          return true;
+      if (result === TransitionResult.FINISHED) {
+        this.currentIndex += 1;
       }
+      return this.currentIndex >= this.stateMachines.length;
     }
 
     getRemainingInput(): string {

+ 20 - 0
src/level.ts

@@ -0,0 +1,20 @@
+/**
+ * This module represents the levels for the game. Each level consists of lines
+ * that you have to complete. Each line has the kanji of the line, which is used
+ * solely for display and the kana of the line which the input is based.
+ */
+namespace level {
+  export interface Line {
+    kanji: string,
+    kana: string
+  }
+
+  export interface Level {
+    lines: Line[]
+  }
+
+  export function loadFromJson(url: string): Promise<Level> {
+    return window.fetch(url)
+      .then(response => response.json())
+  }
+}