Results for tag "enchant-js"

node.jsとsocket.ioとenchant.jsで作ったMMORPG風チャットをheruokuと9leapにデプロイしよう


node+socket.io+enchant.jsでチャットゲーを作る9leapで動くように修正してみた。
 
ソースコードはgithubにあげている
https://github.com/SimtterCom/enchat-9leap-client
 
サーバー側ソースコードもgithubにあげている。
https://github.com/SimtterCom/enchat-9leap
 
サーバーはherokuにデプロイしている。
http://enchat-9leap.herokuapp.com/
 
なお、ベースとなるソースコードは有限会社ジーワークス 佐藤潔 氏によって作成されました。


0

EnchantCityチュートリアル


SimCityにタワーディフェンスの要素を加えた街作りシュミレーションゲーム。

12月1日から始まり、クリスマスを迎えるまで、道路や住宅地、商業地を建設して住民を住まわせ、
工業地を建設してモンスターを倒してお金を稼いで街を発展させよう。
人口100人達成してクリスマスを迎えると何かが起こる!

上記リンクからゲームを開始できるが、最初何をしたら良いかさっぱり分からないと思うので、手順(チュートリアル)を説明する。

まず画面構成から説明します。

enchantcity.01.00.statusmenu
画面の一番上にあるのがステータスメニューです。
enchantcity.01.01.date
ステータスメニューの一番左が日付を表します。
12月1日から始まり、ゲーム内独自の時間でリアルタイムに進んでいきます。
時間を止めることはできません。

enchantcity.01.02.population
次に右が人口を表します。
このゲームの目的は、人口を増やすことなので、一番重要なパラメータです。
最初は0人で、後述する住宅地を建てると人口が増えます。
しかし、人がモンスターに殺されたり、住宅地がモンスターに壊されるか、ユーザー自らに壊されると人口も減ります。

enchantcity.01.03.cash
次に右がお金を表します。
お金は最初50から始まり、
建物を建設するとお金が減り、モンスターを倒すとお金が増えます。
建物の建設費とモンスターを倒したときに貰える額は以下の通り。
道路:2減
住宅地:5減
商業地:10減
工業地:10減
モンスターを倒すと1増

enchantcity.01.04.bgm
次に右がBGMボタンです。
BGMをオン/オフできます。
最初はオンになっている。
※現在、IEではBGMが再生されないバグあり。

enchantcity.01.05.end
一番右が終了ボタンです。
終了ボタンを押すとダイアログが表示されて本当に終了するか聞いてくるので、
「はい」を押すとゲーム終了。
このゲームはユーザー自ら終了しない限り、永遠と動き続けます。

enchantcity.02.00.mainmenu
次に一段下がってメインメニューを説明します。

enchantcity.02.01.road
一番左が道路建設ボタンです。
道路建設ボタンを押してチェックにした状態で、フィールドをクリックすると道路を建設できます。
ただし、道路は後述する高速道路に繋がっていないと建設できません。
また、海にも建設できません。
草原、森林、砂漠は建設でき、どれに建設しても効果は同じです。
道路を建設するためには、お金が2かかります。

enchantcity.02.02.region
次に右が区画ボタンです。
区画ボタンを押すと下段に区画メニューが表示され、住宅地、商業地、工業地を建設できます。
区画メニューについては、後ほど説明します。

enchantcity.02.03.destroy
次に右が破壊ボタンです。
破壊ボタンを押してチェックにした状態で、建物をクリックすると破壊できます。
ただし、高速道路と他の建物を切断する破壊はできません。
道路を破壊したいときは、高速道路から一番遠い道路から順番に破壊してください。

enchantcity.02.04.cursor
一番右がカーソルボタンです。
破壊ボタンを押してチェックにした状態で、建物をクリックすると建物ダイアログが表示され、建物に入っている人の種類と数が分かります。
建物ダイアログについては、後ほど説明します。

enchantcity.03.00.regionmenu
メインメニューで区画ボタンを押すと区画メニューが表示されます。
区画メニューについて説明します。

enchantcity.03.01.town
一番左が住宅地ボタンです。
住宅地ボタンを押してチェックにした状態で、フィールドをクリックすると住宅地が建設できます。
ただし、道路に隣接した場所にしか建設できません。
また、海にも建設できません。
草原、森林、砂漠に建設でき、どれに建設しても効果は同じです。
住宅地を建設するためには、お金が5かかります。
住宅地を建設すると高速道路から家族(労働者1人、買い物客1人、学生2人の計4人)が引っ越してきます。
住宅地はモンスターに入居されると、破壊されます。
住宅地は労働者が12時間以上、家賃を支払わないと、倒産します。
住宅地が破壊された場合、その住宅地に入居中の家族も消滅します。
住宅地に怪我をした家族が入居していると、救急車マークが表示されます。

enchantcity.03.02.castle
次に右が商業地ボタンです。
商業地ボタンを押してチェックにした状態で、フィールドをクリックすると商業地が建設できます。
ただし、道路に隣接した場所にしか建設できません。
また、海にも建設できません。
草原、森林、砂漠に建設でき、どれに建設しても効果は同じです。
商業地を建設するためには、お金が10かかります。
商業地は買い物客が食べ物を買うために必要です。
商業地には、買い物客が同時に5人まで入ることができます。
買い物客について後ほど説明します。
商業地はモンスターに入居されると、破壊されます。
商業地は買い物客が12時間以上、買い物に来ないと、倒産します。

enchantcity.03.03.dungeon
一番右が工業地ボタンです。
工業地ボタンを押してチェックにした状態で、フィールドをクリックすると工業地が建設できます。
ただし、道路に隣接した場所にしか建設できません。
また、海にも建設できません。
草原、森林、砂漠に建設でき、どれに建設しても効果は同じです。
工業地を建設するためには、お金が10かかります。
工業地を建設するとゲーム内時間で30分おきにモンスターが出現します。
工業地ダイアログからモンスターの出現を一時停止できます。
モンスターについて後ほど説明します。

次にフィールドについて説明する。
enchantcity.04.01.highway
これは高速道路です。
高速道路は街の入り口となるため、非常に重要です。
道路は高速道路に繋がっていないと建設できません。
また、住宅地を建設した場合、高速道路から家族が引っ越してきます。
高速道路は建設できないし、破壊もできません。

enchantcity.04.02.sea
これは海です。
海には建物を建設できません。

enchantcity.04.03.grass
enchantcity.04.04.desert
enchantcity.04.05.forest
上から順に草原、砂漠、森林です。
これらに建物を建設できます。
また、効果も同じで、見た目以外の違いはありません。

以上で画面の説明は終わりです。
次は手順(チュートリアル)を説明します。

enchantcity.05.01.tutorial
手順1.
まずは、上記のスクリーンショットの通り、高速道路の隣に道路を2つ建設しましょう。

enchantcity.05.02.tutorial
手順2.
次に、上記のスクリーンショットの通り、道路を囲むように住宅地を3つ建設しましょう。
住宅地を建設すると、高速道路からそれぞれの住宅地に家族が引っ越してきますよ。

enchantcity.05.03.tutorial
手順3.
次に、上記のスクリーンショットの通り、商業地を1つ建設しましょう。
商業地を建設すると、住宅地から買い物客が商業地へ買い物に行きますよ。

enchantcity.05.04.tutorial
手順4.
次に、上記のスクリーンショットの通り、縦に道路を5つ建設しましょう。

enchantcity.05.05.tutorial
手順5.
次に、上記のスクリーンショットの通り、道路の端に工業地1つ建設しましょう。
工業地を建設してからゲーム時間内で30分経つと、工場地からモンスターが出てきます。
さらに、労働者がモンスターを倒しに住宅地から出てきますよ。
労働者がモンスターを倒すと、お金が1増えます。
こうして、街の住人の生活が始まりました。

チュートリアルで示した配置は言わば定石で、この配置では順調にお金が増えていきます。
ここからさらに街を発展させるのはプレイヤーの腕次第。
人口100人達成してクリスマスを迎えると何かが起こる特典付きです。

次はキャラクターについて説明します。

worker worker.02
これは労働者です。
住宅地1つに付き、1人入居できます。
工業地からモンスターが出現した場合、労働者の体力が1以上の場合、労働者はモンスターを倒しに出勤します。
ただし、労働者の行動範囲は10マスです。
モンスターが住宅地の10マス以内に来ないと労働者は出勤しません。
体力が1以上の場合にモンスターに接触すると、モンスターを倒せます。
体力が0の場合にモンスターに接触すると、怪我をします。
怪我をすると紫色に変色し、住宅地から出れなくなります。
モンスターを倒すとモンスター1匹に付き、体力が1減り、お金1と家賃1が増えます。
体力が0になると住宅地に戻ります。
労動者の家賃が1以上の場合、労働者は住宅地に家賃を支払います。
労働者は最初街に引っ越してきたときは、体力0、家賃0です。
体力は買い物客から食べ物をもうらことで、食べ物1つに付き、体力が1回復できます。

shopper shopper.02
これは買い物客です。
住宅地1つに付き、1人入居できます。
同じ住宅地に労働者が入居していて、かつ、労働者の体力が0の場合、買い物客は労働者に食べ物を与えます。
食べ物が0の場合、商業地へ食べ物を買いに行きます。
ただし、買い物客の行動範囲は10マスです。
商業地が住宅地の10マス以内にないと買い物へ行きません。
食べ物を買うのにお金はかからりません。
買い物客1人に付き、食べ物は1つしか持てません。
モンスターに接触すると怪我をします。
怪我をすると紫色に変色し、住宅地から出れなくなります。

student2student student0.02student1.02
これは学生です。
住宅地1つに付き、2人入居できます。
今のところ学生に役割はありません。
モンスターに接触すると怪我をします。
怪我をすると紫色に変色し、住宅地から出れなくなります。

monster
これはモンスターです。
工業地からゲーム時間内で30分間隔で出現します。
モンスターは住宅地と商業地を目指して、襲ってきます。
襲う建物が無い場合は高速道路を目指します。
モンスターは労働者と接触した場合、労働者の体力が1以上ある場合、倒されて、労働者にお金1と家賃1を与えます。
労働者の体力が0の場合、労働者に怪我をさせて、モンスター自身は死にます。この場合は、何も与えません。
モンスターは買い物客と接触した場合、買い物客に怪我をさせて、モンスター自身は死にます。
モンスターは学生と接触した場合、学生に怪我をさせて、モンスター自身は死にます。
モンスターは住宅地に入居した場合、住宅地を破壊して、モンスター自身は死にます。
モンスターは商業地に入居した場合、商業地を破壊して、モンスター自身は死にます。
 
次はエフェクトについて説明します。
 
enchantcity.07.01.destroy
これは建物が破壊された場合に表示されるエフェクトです。
ユーザー自ら破壊した場合、モンスターによって破壊された場合に表示されます。
建物が破壊されると、その土地は更地に戻ります。
 
enchantcity.07.02.liquidate
これは住宅地の賃貸が支払われなった場合、商業地に買い物客が来ない場合に建物が倒産する場合に表示されるエフェクトです。
建物が倒産すると、その土地は更地に戻ります。
 
enchantcity.07.05enchantcity.07.06
これは工業地を稼動停止した場合に表示されるエフェクトです。
工業地を稼動停止した場合は、工業地に停止マークが赤く点滅します。
 
enchantcity.07.03enchantcity.07.04
これは住宅地に怪我をした家族が入居している場合に表示されるエフェクトです。
住宅地に怪我をした家族が入居している場合は、住宅地に救急車マークが紫色に点滅します。
 
次は建物ダイアログについて説明します。
 
enchantcity.08.01enchantcity.08.02
これは住宅地ダイアログです。
W, Sp, Stの文字は下記の意味を持ちます。
W: 労働者の怪我人数 / 労働者の住居人数
Sp: 買い物客の怪我人数 / 買い物客の住居人数
St: 学生の怪我人数 / 学生の住居人数
また、救急車マークのボタンは治療ボタンです。
住宅地に怪我人が全く居ないときは白くなり、1人でもいると赤くなります。
治療ボタンを押すとその住宅地の怪我人を全員治療します。
治療には1人に付きお金2がかかります。
お金が足りない場合は治療できません。
 
enchantcity.08.03
これは商業地ダイアログです。
W, Sp, Stの文字は下記の意味を持ちます。
W: 商業地に訪れいてる労働者数
Sp: 商業地に訪れいてる買い物客数
St: 商業地に訪れいてる学生数
 
enchantcity.08.04enchantcity.08.05
これは工業地ダイアログです。
工業地が稼動している場合は稼働中が表示され、停止している場合は停止中がが表示されます。
また、再生ボタン/停止ボタンを押すことで、稼動/停止を切り替えられます。
 
次はゲーム内の生活サイクルについて説明します。
1.住宅地が建設されると、家族が入居します。
 新規入居時点の家族は、労働者の体力0、家賃0、買い物客の食べ物0です。
2.商業地が建設されると、買い物客が商業地へ食べ物を買い物に行きます。
3.買い物客が買い物した商業地は、12時間倒産しません。
4.買い物を終えた買い物客は住宅地へ戻ります。
5.住宅地に戻った買い物客は労働者に食べ物を与えます。
6.食べ物を与えられた労働者は体力が回復します。
7.食べ物が無くなった買い物客は、また商業地へ買い物へ行きます。
8.工業地が建設されると、モンスターが出現します。
9.体力の回復した労働者は、モンスターを倒しに行きます。
10.モンスターと接触した労働者は、体力が0になる代わりに、モンスターを倒して家賃を1得ます(このとき、ユーザーはお金を1得ます)
11.モンスターを倒した労働者は住宅地へ戻ります。
12.住宅地に戻った労働者は、住宅地に家賃を支払います。
13.家賃が支払われた住宅地は12時間倒産しません。
14.買い物客は体力0の労働者に食べ物を与えます。
15.以下、上記の生活サイクルの繰り返しです。

ただし、上記の生活サイクルが崩れるケースがあります。
そのケースは以下の通り。
A.モンスターが住宅地に入居した場合、住宅地が破壊され、その住宅地に入居している家族も消滅します。
B.モンスターが商業地に入居した場合、商業地が破壊され、その商業地で買い物している買い物客も消滅します。
C.モンスターが体力0の労働者と接触した場合、その労働者に怪我をさせます。
D.モンスターが買い物客と接触した場合、その買い物客に怪我をさせます。
E.モンスターが学生と接触した場合、その学生に怪我をさせます。
F.12時間家賃が支払われなかった住宅地は倒産し、その住宅地に入居している家族も消滅します。
G.12時間買い物客が買い物しなかった商業地は倒産します。

※なお、BGM、効果音は魔王魂様のサイトから拝借しました。
音楽素材/魔王魂

※キャラクターグラフィックはESPRI様より拝借しています。
espri-Q


0

SimCityもどきはEnchantCityと名づけよう

構想一ヶ月前、本格的に着手したのは、ゴールデンウィーク明けなので、はや3週間ぐらいでしょうか。
とりあえず、3割ぐらいはできた。
街に労働者が来て、住居に住み、工場(ダンジョン)に働きに行く。までができた。
といっても、賃金の計上やら、労働者が少ないダンジョンからはモンスターが現れるとかの処理はできてない。
買い物客や学生もできてないけど、これは労働者のアルゴリズムの応用でできるので、あまり問題視してない。
それよりも、問題ありそうなのが、処理が重いことと、建物の破壊と建設を繰り返すと徐々にメモリが増えていくことだ。
ブラウザの対応状況では、
IE: 完全動作
Chrome: BGMがまともに再生されない。(それ以外は動く)
firefox:処理がめちゃくちゃ重い。ボタンの動作がおかしい。
Safari: 読み込みで止まる(オーディオ系のファイルに問題があるみたい)
とIE以外は問題あり。
これから、リファクタリングなどの大改造を施すかも知れないので、とりあえず、現状を中間報告としてアップしておく。
http://9leap.net/games/3339
※前述の通り、問題多々有りなので、動作保証はできません。
※ゲーム内時間で18時になると、労働者が街にやってきて、住居に住みます。そして、翌日6時に工場へ働きに行く。
※道路、住商工の建設&破壊可能。
※なお、BGM、効果音は魔王魂様のサイトから拝借しました。
音楽素材/魔王魂


0

enchant.js Safariでsound.clone()を実行するとメモリリーク

バグっぽいのを見つけたので、enchant.js本家にバグ報告した。
https://github.com/wise9/enchant.js/issues/210

一応、このブログでも報告しておく。
javascirptのメモリ管理を知りたかったので、タクスマネージャーを眺めていたら、とてつもなくメモリ食っていることに気づき、
調べたら、sound.clone()でメモリリークしているっぽい。
効果音鳴らすゲームなら、簡単に100MB、200MBと食っていくので注意。
ただし、Safariでしか発生しないので、ブラウザのバグなのか、enchant.jsのバグなのか微妙なところ。
以下、本家への報告コピペ。

[環境]
OS: Windows7 64bit
ブラウザ:Safari 5.1.7
enchant.js v0.7.0 (v0.6.3でも同様の現象が発生する)

[発生手順]
●手順1
1.サンプルの examples/expert/action/index.html をサファリで実行する
2.Windows タスクマネージャーを実行し、プロセスタブのWebKit2WebProcess.exeに注目
3.サンプルのhtmlに戻りゲームスタート。上キーを押し続けて、ジャンプし続ける
4.タスクマネージャーのWebKit2WebProcess.exeのメモリが4MBぐらいの単位で増え続ける。
5.サンプルのhtmlの上キーを離してジャンプを止めても、メモリが減らない。

●手順2
examples/expert/action/game.js の92行目の
game.assets[‘jump.wav’].clone().play();
の箇所を
game.assets[‘jump.wav’].play();
に変更して、手順1を実行すると、メモリリークの量が減る。(それでもメモリが僅かに増え続けるので他にもメモリリークしているのかも?)

[コメント]
以上のことから、sound.clone()を実行するとメモリリークが発生するものと思われます。
ただし、この現象はSafariでしか発生せず、firefoxやchromeでは問題ありませんでした。


0

enchant.js用プラグイン exntendMapについて解説する

enchantMapEditorでマップ拡張を有効にして吐き出したコードはenchant.js用プラグインexntendMap (ExMap)で読み込む必要がある。

以下がExMapの使い方である。

window.onload = function() {
	var core = new Core(320, 320);
	core.preload('map0.gif');
	core.onload = function() {
		var backgroundMap = new ExMap(16, 16);
		backgroundMap.image = core.assets['map0.gif'];
		backgroundMap.loadData([
		    [39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39],
		    //...マップデータの定義
		    [107,107,107,38,4,22,22,22,22,23,107,107,107,107,107,107,107,107,107,107]
		]);
		backgroundMap.collisionData = [
		    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
		    //...当り判定の定義
		    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
		];
		core.rootScene.addChild(backgroundMap);
	}
}

map0
(上の画像がmap0.gif)

このコードでマップデータで定義されたマップが画面に表示される。
ここで疑問なのは、マップデータの39や107などの数字は何を示しているのか?
この数字はマップのチップ番号を示していて、左上を0として右へ16ドット単位で0,1,2,3と連番を振り一番右まで行ったら改行して、さらに2行目3行目・・・と連番を振ったものだ。
だた、読み込んだ画像ファイル(map0.gif)そのものを使っているのではなく、加工を加えた画像を使っている。

		backgroundMap.image = core.assets['map0.gif'];

imageプロパティ内で、加工を加えている。
exmap0
上の画像が加工を加えた結果だ。

この加工のルールは、
元の画像ファイルのうち、左側の縦横96×256をマップのフィールド画像と仮定して、
さらに48×60の単位でフィールドのタイプとして仮定して、
それぞれの他のフィールドとの境界線のバリエーションを生成している。
この加工された画像は縦横サイズ276×512に拡張されている。
よって、チップ番号は0~551までの連番になる。
要は元の画像を元にしたチップ番号ではなく、加工した画像を元にしたチップ番号であることに注意すること。

また、このフィールドのタイプ知ることもできる。

	var type = backgroundMap._typeData[0][0];

上記は座標(0,0)のタイプを取得するコードだ。
最初のマップデータの例では、typeには0が入ってくる。
typeの数字はマップのフィールドのうち、左上から1行目1列目を0、1行目2列目を1、2行目1列目を2・・・4行目2列目を7とした0~7までの数字である。
map0_no


0

enchant.js用マップエディタenchant.js Map EditorをjQuery UIに置き換えてみた

勉強がてら、enchant.jsの公式マップエディタenchantMapEditorjQuery UIに置き換えてみた。

jQuery UI版enchant.js Map Editor
http://9leap.net/games/3338/

機能は公式とほぼ一緒だが、公式はsafariでしか動かなかったが、こちらはIE,chrome,safariで動く。
※firefoxではレイヤーが切り替えられないバグがある。
※上記のフレームをクリックするとMap Editorを操作できるが、フレームが狭すぎてまともに使えないので、こちらから開くことをおススメする。

画面構成を解説します。
[画面]
Create Mapボタン:
起動したらまず最初にこのボタンを押して、横のチップ数、縦のチップ数などを指定してマップを作成する。

Import Mapボタン:
すでに作成済みのMapデータをインポートする。エクスポートと同じ書式のコードから読み込む。

Undo:
アンドゥ(履歴は1回しか覚えていない)

Tool bar:
ドローツール。pen(ペン),fill(塗りつぶし),straight(線),rect(矩形)がある。

selected chip:
パレットから選択したチップを表示

eraser chip:
消しゴムチップ

palette:
マップに配置したいチップをクリックして選択する。選択したチップはselected chipに表示される。

Export Mapボタン:
作成したマップのコードを表示する。ユーザーはこのコードをコピーして自分のプログラミングにペーストして反映させる。

Add Layerボタン:
マップのレイヤーを追加する。
※現在レイヤー追加は未対応。UIは実装したが、内部処理を実装していない。

collision detectionタブ:
当り判定を配置するレイヤー

Layer 0タブ:
チップを配置するレイヤー(ベースとなるフィールドを配置)

Layer 1タブ:
チップを配置するレイヤー(フィールドの上に建つ建物などを配置)

enchant-stage:
マップにチップを配置する。Create Mapボタンで作られる。

使い方を順を追って解説します。(チュートリアル)
enchantMapEditor01
1.まずenchantMapEditorを開いたら、
Create Mapボタンを押して、マップ作成ダイアログを開きます。

enchantMapEditor02
2.マップ作成ダイアログを開いたら、
Number of chips for width: マップの幅のチップ数(チップのサイズは16ドット固定ですのでマップの幅はチップ数*16になります。デフォルトでは20個になっています。これは20*16=320でマップ幅は320ドットになります。)
Number of chips for height: マップの高さのチップ数(チップのサイズは16ドット固定です。デフォルトでは20個になっている)
Image: マップの画像ファイルの種類を指定します。RPG用と2Dスクロール用が用意されています。RPGを指定するとhtmlファイルを同じディレクトリにあるmap0.gifを読み込み、2Dスクロールを指定するとmap1.gifを読み込みます。画像ファイルは置き換えることも可能ですが、256×256のサイズを想定しています。
Enable MAP EXTENTION:マップ拡張と言う機能を有効するか指定します。マップ拡張とはRPGのフィールドマップを作成する場合に、海岸線や森と平原の境目を自動補間する機能です。主にRPG(map0.gif)用の機能になりますので、2Dスクロールの場合はチェックを外してください。
以上を設定して、Create a new mapボタンを押してください。

enchantMapEditor03
3.マップ作成ダイアログの設定にしたがって、パレットにマップ画像ファイルが読み込まれ、enchant-stageに指定したサイズのマップが作られます。

enchantMapEditor04
4.paletteのどこかをクリックすると、描画したいチップを選択できます。この例では草原あたりをクリックします。
マップ拡張を有効にしていると、パレットの左側96×256をそれぞれ48×64を同一のタイプとして認識(例では海、草原、石造物、砂漠、床、森、ダンジョンの床、穴)し、そのタイプを選択したことになります。(例えば、海の海岸線チップは選択できず、海岸線はenchant-stageへ描くときに自動補間され書き込まれる)
マップ拡張を無効にしていると、タイプとして認識せず、選択したチップをそのまま認識します。

enchantMapEditor05
5.ツールバーでペンを選択し、enchant-stage内で適当にドラッグすると選択したチップが描き込まれます。

enchantMapEditor06
6.さらに、ツールバーでfill(塗りつぶし)を選択し、パレットで海タイプを選択し、enchant-stage内の空白部分を適当にクリックすると、空白を海で塗りつぶせます。草原との境界はマップ拡張機能により自動補間されます。

enchantMapEditor07
7.当り判定も設定してみましょう。
ツールをペンに変え、collision detection(当り判定)をクリックし、enchant-stage内の海岸線に沿ってクリックすると、当り判定を設定できます。
当り判定は初期値0になっており、設定した箇所は1が入ります。ゲーム上で当り判定1の場合はプレイヤーがそこを通れないといった処理に使えます。

enchantMapEditor14
8.レイヤーは2つ使えます。
レイヤー0ではフィールドを設定し、レイヤー1では建物を設定するのに適しています。
建物を建ててみましょう。
パレットから建物(この例ではダンジョン)をクリックし、Layer 1をクリックしてレイヤーを切り替え、enchant-stageの草原をクリックすると、建物が建てれます。

enchantMapEditor09
9.ここまで作ったら、作成したマップをエクスポートしてみましょう。
Export Mapボタンを押します。

enchantMapEditor10
10.するとエクスポートダイアログが開きます。

enchantMapEditor11
11.テキスト内をドラッグ&ドロップで選択し、Ctrl+Cでテキストをコピーし、自分のゲームのソースコード内に貼り付けてください。

以上でチュートリアルは終わりですが、その他の機能についても説明しましょう。
enchantMapEditor12
12.インポート機能について説明しましょう。
インポート機能とは、エクスポートでコピーしたマップのソースコードを貼り付けて、再編集するときに使います。
また、現在編集中のマップをソースコードレベルで編集したいときにも使えます。
では、手順を説明します。
Import Mapボタンを押してください。

enchantMapEditor13
13.インポートダイアログが開きます。
テキスト内には、エクスポートで表示されるソースコードを同じソースコードが表示されています。

enchantMapEditor14
14.この例では現在編集中のマップをソースコードレベルで編集してみましょう。
スクリーンショットの赤丸で囲っている部分の数字がマップのレイヤー0のx:0,y:0のチップ番号になります。
これを別のチップ番号に変えてみましょう。(例ではダンジョンのチップ番号を指定している)
変え終わったら、Import a crated mapボタンを押します。

enchantMapEditor15
15.すると、左上x:0,y:0がダンジョンに置き換わっています。

enchantMapEditor16
16.レイヤーの追加について説明します。
ただし、現在レイヤー追加機能は正しく動きませんので、予備知識ぐらいに考えておいてください。
UIとしては機能しているのですが、内部の機能を実装していません。
と言うのも、ほとんどのマップは2レイヤーで収まってしまうと思うので、作る必要が無いかなと思って作ってません。
必要だよと言う方がいたら作りますので、コメント等々いただければと思います。
では、説明します。
まず、Add Layerボタンを押してください。

enchantMapEditor17
17.Layer 2が追加されます。

enchantMapEditor18
18.レイヤーは削除するこも可能です。
Layer 2の隣のバツボタンを押すと削除できます。

enchantMapEditor19
19.Layer 2が削除されました。

以上で、スクリーンショットを使った解説を終了します。

せっかくなので、ファイル構成も解説しておきます。

index.html
公式のmapeditor.htmlをindex.htmlに名前を変更したうえで大幅変更。
公式ではhtmlにはenchant-stageタグとeditタグしか存在せず、その他のタグはjavascriptで生成していたが、こちらはタグ構成をすべてhtmlに書いてある。
jQuery UIのサンプルを参考に書いた。

main.js
公式の同名ファイルから大幅変更。
enchantの初期化とjQuery UIのスクリプトが書いてある。
今回の変更の大半はこのファイルをjQuery UIのスクリプトに置き換える作業になった。

mapeditor.js
公式の同名ファイルから多少変更。
ehchantのcoreの初期化とenchant-stageタグのタッチイベントハンドラが記述してある。
タッチイベント(マウスクリックイベント)でマウス位置が正しく入ってきてなかったり、イベント自体が発生しなかったりなどのバグっぽい動きを修正した。

drawing.js
公式の同名ファイルからほとんど変更なし。
plugins/extendMap.enchant.js を更に拡張してドローツールのpen,fillなどの機能が記述されている。
Export Mapで吐き出す文字列をgame.からcore.に変更したぐらいで、ほとんど変更なし。

enchant.min.js
いわずと知れたehchant.jsの本体。
公式はv0.3と古いバージョンが使われていたが、jQuery UIとの相性が悪くinputタグが動かなかったので、最新版v0.6.3に変更した。

plugins/extendMap.enchant.js
enchant.jsのマップ拡張プラグイン
これもv0.3からv0.6.3へ変更した。

jsディレクトリ
jQueryとjQuery UIの本体が入っている。

css/main.css
スタイルシートまわりを個別ファイルとして新規追加した。
jQuery UIのサンプルを参考に書いた。

css/imagesディレクトリ
ツールバーや消しゴムチップ、アンドゥのアイコンのpngファイルが入っている。
main.cssで参照している。

css/ui-lightnessディレクトリ
jQuery UIの公式スタイルシート。
ui-lightnessというテーマを使っている。

[今後対応したいこと]
1.パレット用の画像ファイルを読み込めるように。
 今は画像固定、画像を変えたければツールをダウンロードして、ローカルで差し替える必要がある。
2.Create Mapをしたあともう一度Createすると、落ちるのを直す。
 今は再度Createしたい場合は、ページを読み直す必要がある
3.firefoxでもレイヤーが切り替わるように。(原因不明、firefoxか、jQuery UIのバグか?)
4.レイヤーの追加・削除の内部処理に対応
5.Import Mapでレイヤーが追加された場合にGUIに反映させる。


2

Map Editorにenchant.js v0.6.3を適用すると正常動作しない問題の解決法

enchant.js用マップエディタenchantMapEditorをjQuery UIに置き換えてみた
http://blog.chat.ac/?p=157
上記の作業中に発生した問題の解決法を備忘録として記す。

enchant.js公式のマップエディタ
https://github.com/wise9/enchantMapEditor
ですが、
これに使われているenchant.js はv0.3と非常に古いバージョンが使われている。
古いバージョンが使われていること自体は問題ないが、
プログラミングの勉強がてらjQuery UIを使ってUIを作り直していたら、
htmlのinputフォームが正常動作しない(inputをクリックしてもアクティブにならない)問題が発生。
原因は良く分からないが、enchant.js v0.6.3を使ったら問題解決した。
しかし、enchant.js v0.6.3を使うと、今度はMap Editorでチップが配置できない(enchant-stageをクリックしてもチップが置かれない)問題が発生。
この問題解決にコードをいじったので、修正箇所を記す。

mapeditor.jsの処理をのぞくと以下の処理を行っていた。
mapeditor.js 116行目

		var editScene = new Scene();
		this.sx = 0;
		this.sy = 0;
		editScene.addEventListener('touchstart', function(e) {

mapeditor.js 163行目

		editScene.addEventListener('touchmove', function(e) {

mapeditor.js 206行目

		game.pushScene(editScene);

このeditSceneはタッチイベントのためだけに作られたシーンのようだ。
これが問題のようで、enchant.js v0.6.3では内部処理が変わったのか、editSceneにはチップがロードされていないのに、editSceneに対してチップを描画しようとして、描画できなくなっていた。
それならば、実際チップを持っているgame.rootSceneにイベントをハンドルすることで解決。
具体的には以下のコードに修正する。
mapeditor.js 116行目

		//var editScene = new Scene();
		this.sx = 0;
		this.sy = 0;
		game.rootScene.addEventListener('touchstart', function(e) {

mapeditor.js 163行目

		game.rootScene.addEventListener('touchmove', function(e) {

mapeditor.js 206行目

		//game.pushScene(editScene);

0

enchant.jsでマウスの相対位置を取得する

enchant.js用マップエディタenchantMapEditorをjQuery UIに置き換えてみた
http://blog.chat.ac/?p=157
上記の作業中に発生した問題の解決法を備忘録として記す。

enchant.jsでehcnaht-stageの位置が(0,0)以外の場合、
マウスイベント(タッチイベント)のマウス位置(localX,localY)に正しい値が入ってこないようだ。
正しいマウス位置を取る方法を備忘録として残しておく。

enchant.jsのマウスイベント(タッチイベント)の中をのぞいてみると、
こんな処理をしていた。
enchant.js v.0.6.2 内1173行目付近

                stage.addEventListener('mousedown', function(e) {
                    var core = enchant.Core.instance;
                    var evt = new enchant.Event(enchant.Event.TOUCH_START);
                    evt._initPosition(e.pageX, e.pageY);
                    var target = core.currentScene._determineEventTarget(evt);
                    core._touchEventTarget[core._mousedownID] = target;
                    target.dispatchEvent(evt);
                }, false);

e.pageX,e.pageYがマウスの絶対位置を示す。
この値を_initPosition()で以下の計算をしてから、localX,localYを設定している。

enchant.js v.0.6.2 内469行目付近

    _initPosition: function(pageX, pageY) {
        var core = enchant.Core.instance;
        this.x = this.localX = (pageX - core._pageX) / core.scale;
        this.y = this.localY = (pageY - core._pageY) / core.scale;
    }

core._pageX,core._pageYに謎の値が入っていて、これが引かれていることで、よく分からない値が設定されているようだ。
だから、受け取る側でこの値を足して絶対位置に戻してから相対位置を計算しなおす。
ただし、core.scaleで割っているので、ここで切り捨てが発生している場合、完全に正しい値には戻せない。

具体的には次のコードのようにする。

		editScene.addEventListener('touchstart', function(e) {
			//マウスの位置を絶対位置に戻す
			var x = e.localX*core.scale + core._pageX,
			    y = e.localY*core.scale + core._pageY;
			
			//親要素の絶対位置を取得する
			var offsetX = 0, offsetY = 0;
			var element = e.target._element;
			while(element) {
				offsetX += element.offsetLeft;
				offsetY += element.offsetTop;
				element = element.offsetParent; //親要素のオフセットを足しこんでいけば、親要素の絶対位置が分かる
			}

			//マウスの絶対位置から親要素の絶対位置を引けば、マウスの相対位置が分かる
			x -= offsetX;
			y -= offsetY;

以上、x,yがマウスの相対位置である。


0

ゲーム基礎設定

アイデアノート的にゲームの基礎設定をメモっておきたいと思います。

最初、見た目もSimCityっぽくしたかったのですが、
enchant.jsで用意されている画像素材がアクションゲームとかRPG風のものしかなかったので、
ゲームの雰囲気はRPGの街を育てるゲームにしました。
ちなみに私は”元”ゲームプログラマーなので、プログラミングは得意ですが、絵を描くのが物凄く苦手です。
最初自分で簡単な絵を描いてお茶を濁そうと思ったのですが、それすらできませんでした。
enchant.jsのライブラリを見てると物凄く懐かしいドット絵ゲームのテクニックが満載で昔に帰ったような気分になりました。
と言っても、私がゲーム作ってた頃は、すでにポリゴンだったんですけど。

そんなことはさておき、そのドット絵と配役、機能、ゲームシステムを書いていきましょう。

town
町:SimCityにおける居住区です。
 町を建てるとそこに人が住み始めます。
 ただ、人々は住む場所だけがあっても生活できません。他に買い物などを行う城とお金を稼ぐためのダンジョンが必要です。
 町には住める人数に上限があります。

castle
城:SimCityにおける商業区です。
 町の住人が城へ買い物にやってきます。また学生が勉強するための学校も兼ねています。
 城と町は近く建てた方が良いです。
 遠いと買い物や学校へ通うのに時間がかかって食料の補給や学力の向上に支障をきたします。
 ただ町の住人は町から一番近い城を目指しますので、城へ住民が殺到し交通の便が悪くなっても、通うのに時間がかかってしまいます。
 城にも入れる人数の上限がありますが、町より大人数を収容できます。

dungeon
ダンジョン:SimCityにおける工業区です。
 ダンジョンは町の労働者がダンジョンのモンスターを倒してお金を稼ぐ場所です。
 ダンジョンは町や城からある程度離した方が良いでしょう。
 定期的にダンジョンからモンスターが出てきて、一番近い町や城を襲いに来ます。
 ただ移動速度が遅いので町・城とダンジョンを十分な距離を開ければ、襲われるまで時間稼ぎできます。
 労働者がモンスターを倒しに行くのですが、出勤時間と退勤時間が決まっています。
 労働者はモンスターよりも移動速度が速いです。
 しかし、町とダンジョンの移動距離があまりに遠くダンジョンに到達する前に退勤時間になってしまうとモンスターを倒さずに帰ってしまいます。
 ダンジョンはある程度モンスターが倒されると中級、上級とランクの高いモンスターを排出するようになります。
 モンスターのランクアップを合わせて、労働者のランクも上げる必要があります。

field
フィールド:町、城、ダンジョンを建てるための土地全般です。
道:町、城、ダンジョンの交通をつなげる。
 道につながっていないと住民はその場所までたどり着けません。

worker
労働者:SimCityと同じ労働者です。
 ダンジョンまで行ってモンスターを倒してお金を稼ぎます。
 最初は下級労働者ですが、お金と学力が貯まるごとに中級、高級と3段階のランクが上がっていきます。 
 労働者は出勤時間と退勤時間が決まっていて、出勤時間に町から出てダンジョンまで行って、退勤時間に町に帰ってきます。
 町に帰ってくると、買い物客が買って帰ってきた食糧を食べて体力を回復します。
 体力が回復していないと次の出勤ができません。

shopper
買い物客:SimCityと同じ労働者です。
 主に労働者のための食料を城まで買いに行きます。

student2student
学生:SimCityと同じ学生です。
 勉強するために城まで通います。
 学生が勉強すると学力が上がります。
 学力は労働者のランクアップに必要になります。

monster
モンスター:ダンジョンから定期的に出てきて町や城を襲おうとします。
 労働者より移動速度が遅いので、ダンジョンと町・城の間を十分な距離があれば、労働者が倒してくれるでしょう。

その他の要素
家族:必ず住人は労働者1人、買い物客1人、学生2人の構成で住んでいます。


0

SimCityもどきができるまで(enchant.jsを使おう)

chat.acを立ち上げたあとの
次なる野望はブラウザで気軽に遊べるSimCityもどきのゲームを開発しようと考えてます。

それで、開発環境を色々と調べてたら、
enchant.jsってのが良さそう。
enchant.js
http://enchantjs.com/ja/

これはHTML5 + JavaScriptを使ったゲーム開発用フレームワークとのこと。
9leapと言うゲーム投稿サイトには、
このフレームワークを使って1000本以上のミニゲームが作られているそうな。
そのミニゲームを見るとファミコンレベルのゲームは作れそうな感じ。
ファミコンレベルのゲームが作れるならシムシティぐらい作れるんじゃないか?

さらにenchant.js入門と言う分かりやすそうなチュートリアルがあったので、
私も試しに作ってみると簡単にゲームっぽいものができた。
これがそれ。
http://chat.ac/game/index.html

こうやってブラウザだけでゲームが動くのは他に変えがたい魅力だ。
しばらく、この環境で開発してみようと思う。


0