錬金術系ゲームを考える

ayumegu(プログラマー)
よろしくお願いします。

おはようございます、あゆめぐです。
錬金術系のレシピの管理のしかたについて考えてみた。

錬金術系ゲームといえばシンプルに浮かんだのが2パターン

  • レシピを選択→素材が選ばれる。
  • 素材を選択→素材があっていれば成功

上のパターンは気合で実装できると思うのですが、下のパターン、DBなどを使えば簡単ですが、使わない場合、簡単に実装できる方法がないか考えてみた。

今回つくりたいな〜と思うのはお寿司ゲーム。Youda Sushi Che○っていうアプリ。
私このゲームがすごい好き。

機能

  • 素材は9つまで選択可能
  • 同じ素材も選べるものとする
  • 素材がレシピと一致しない場合失敗とする

素材:

のり ごはん いくら きゅうり たまご コーン サーモン まぐろ えび 

レシピ例

  • のり+ごはん=おにぎり
  • のり+ごはん+いくら = いくらの巻きずし
  • のり+ごはん+いくら+いくら=いくらの軍艦

みたいなの

まずレシピをどう管理するか。というか今回はこれしかやらないけどね。
11 = おにぎり 見たいな感じ。1の位がのり、10の位がごはん見たいな感じで。
111 = いくらの巻きずし
211 = いくらの軍艦
こうすることで連想配列から簡単になにができたか取得できる

適当に実装

はい。後は実装するだけ。
とにかくシンプルに実装してみました。
レシピは上記3つしかありません!このサンプル作った時点で朝4時とかだったのですw
こんな感じ

はいっ。シンプル!
同じ素材が選べないという仕様ならば二進数にすればより多くの素材が使用可能!
Unityで二進数あつかえるのかしら?
int型だと9個ぐらいまでしか桁数的にいけないのが問題ですがそうなったら文字列にしてしまえばいいかなと。
文字列の○番目を取得して数字に変換。値を足してもとの位置に戻す。
コレでいけるかと思います。文字列なら100種類ぐらいは余裕でしょ。

はい、あとは作りこめばゲームになりますね。
今回は手短にここまで〜。

最初から文字列で初期化時に00000000000にしてしまうと楽だな~

ソース

ソースすごい短いけど

ButtonObject.js

各ボタンにアタッチ。クリックしたら素材の数字がわたる仕組み。
2dtoolkit なのでこれだけでクリックイベント完了なのです!

1
2
3
4
5
6
7
8
9
10
11
12
13
var manger:Manager;
var materialValue:int;
function Start () {

}

function Update () {

}

function ClickBtn(){
  manger.MaterialClick(materialValue);
}

Manager.js

はい、ここ実装部分。
短いね。説明することないよ。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
var MAX_MATERIAL_COUNT:int = 9;
var material:int;
var materialCount:int;
var materialText:TextMesh;
var materialValueText:TextMesh;
var recipe:Hashtable; // UnityのJavascriptでは連想配列がないため

function Start () {
  init();
  
  // 好きに追加してね
  recipe = new Hashtable();
  recipe[11] = "おにぎり";
  recipe[111] = "いくらの手巻きずし";
  recipe[211] = "いくらの軍艦";   
}

function Update () {

}

function init(){
  material = 0;
  materialCount = 0;
  materialText.text = "";
  materialValueText.text = "";
}

function MaterialClick(materialValue:int){
  if(materialCount == 0){
      init();
  }
  // 最大合成数を超えてなければ追加
  if(materialCount < MAX_MATERIAL_COUNT){
      material += materialValue;
      materialCount++;
      materialValueText.text = material + "";
      
      // TODO 手っ取り早くべた書き
      if(materialValue == 1){
          materialText.text += "のり\n";
      }else if(materialValue == 10){
          materialText.text += "ごはん\n";
      }else if(materialValue == 100){
          materialText.text += "いくら\n";
      }else if(materialValue == 1000){
          materialText.text += "きゅうり\n";
      }else if(materialValue == 10000){
          materialText.text += "たまご\n";
      }else if(materialValue == 100000){
          materialText.text += "コーン\n";
      }else if(materialValue == 1000000){
          materialText.text += "サーモン\n";
      }else if(materialValue == 10000000){
          materialText.text += "まぐろ\n";
      }else if(materialValue == 100000000){
          materialText.text += "えび\n";
      }
      return true;
  }else{
      return false;
  }
}

function OkClick(){
  if(recipe.ContainsKey(material)){
      materialText.text = recipe[material] + "\nができました";
  }else{
      materialText.text = "失敗";
  }
  material = 0;
  materialCount = 0;
}

function ResetClick(){
  init();
}

プラスα

はい、これをカスタマイズすれば、牧場物○の料理のようなこともできます。 すで、煮る、焼く、ゆでるなどを1の位などに設定してしまえばOKな訳です また、水+水=川みたいなエレメントの合成みたいなのも作れますね。

また、この素材で作れるレシピ一覧を取得したい〜なんてときは配列のキーをループで回して〜、 その桁数の数字を取得してif分岐でいける。

今回の感想

ゲームがどうやって実装されているかを考えるのがとても楽しい。
昔、桃太郎電○のゴールまで残り○マスという計算をどう出しているのかが不思議で仕方がなかった。   現在は解決法が脳内で組み上がってはいるので時間があるときに実装してみたいなと思う。  今回は文章ばかりですがこの辺で。