"ゲーム制作ログ"

Unity製LCD風レトロゲーム制作の進捗

このエントリーをはてなブックマークに追加
2014/10/02 12:16 am
Blog Category / ゲーム制作ログ
Tags /
 

 

lcd1

だいぶできてきた
LCD風ゲームをUnityで作りたい。と書いていたが、早速実際に制作にとりかかった。先生はWEB上の解説。なけなしの思考力を振り絞り、トライ・アンド・エラーを繰り返してもがいた結果、レトロLCDゲームっぽい雰囲気を作り出す事ができてきた。とっかかりとしてAdobe Aiでイラストを描き、妄想と願望だけが先行していたが、勢いだけでUnityに手をつけても何とかなるもんだな。
実装した要素
■ベルトコンベア上の缶の動き
■プレイヤーキャラの動き
■ベルトコンベアパーツの取得・移動
■効果音
■缶の落下処理
■スコア表示の実装
後はハイスコア表示、ミス数の表示、ゲームオーバー処理等を実装すれば動作部分は完成する。左上のインジェークターから缶が落下してくるのだが、ここでのオブジェクト生成タイミングとベルトコンベアスピードの様々なパターンを作ればゲームとして成り立つ。完成度は5割といったところ。
非効率なオブジェクト移動の実装
lcd2
プレイヤーの移動、缶、パーツの移動処理実装は、オブジェクトの座標を変更すればよいのだろうが、そうではない非効率な方法で実装した。実機LCDゲームにおいてセグメントが点灯するイメージで、上記スクリーンショットのように表示箇所それぞれにスプライトを配置。スプライトオブジェクトの表示・非表示で移動を表現した。スキルの低さ故の方法だが、こういったプログラムはアホなりに努力すればそれに応えるように動いてくれるのが楽しい。
public GameObject player1 = GameObject.Find(player1);
メンバ変数でゲームオブジェクトを定義
player1.SetActive(true);
SetActiveで表示・非表示をコントロール
スコア表示
スコアの表示には当初LCD風フリーフォントを使ってみたが、数字が切り替わるたびに表示位置が微妙にずれて雰囲気が台無しになった。対策としてスコアの変数を桁ごとに分解し、スプライト画像に置き換えるという実装方法を選択した。今思えば等幅フォントを使えば一発解決だったな。。しかし、この方法を用いればスコアの表示だけでなく、今後様々な応用がききそうなので無駄ではなかったと信じたい。
int[] score_table = new int[5];
int score_calc;
score_calc = main_script.score;
score_table[0] = (score_calc % 10); score_calc /= 10;
score_table[1] = (score_calc % 10); score_calc /= 10
score_table[2] = (score_calc % 10); score_calc /= 10;  
score_table[3] = (score_calc % 10); score_calc /= 10;  
score_table[4] = (score_calc % 10); score_calc /= 10;  
配列を定義して、スコアを代入・計算すれば桁ごとの数値を取得できる。これで5桁分取得し、スプライトに変換。
効果音の実装
LCDゲームなので、効果音はBEEP音じゃないと雰囲気が出ない。試しに缶の落下時にファミコン風の効果音を入れてみると、一気に時代が進化した感が出て雰囲気ぶち壊しだった。BEEP音はLogic9のソフトシンセで作成。
そのほか
背景は当時のLCDゲームでよく見られた擬似カラーを意識して、液晶の上に重ねられたフィルムシートから落ちる微妙な影を再現した。ここまでくると、ゲーム筐体やボタンなどもデザインしてよりレトロな雰囲気を強めたくなる。
で、目標としてあと1週間程で完成させたい。
無理かもしれないけど。

Unityで昔風のLCDゲームを作りたい

このエントリーをはてなブックマークに追加
2014/09/29 9:39 pm
Blog Category / ゲーム制作ログ
Tags /
 

lcd1
とりあえず1本仕上げたい
環境をUnityに移行しピンボールゲームの制作を再開したが、まだまだ完成までには時間が掛かる見込み。多分、真面目にやったとしても仕上がりは来年になるんじゃないだろうか。僕はロードバイクに乗るので忙しいんだ。と言い訳ばかりで何一つゲームが仕上がらないというのも情けないので、ここは1つ、簡単なゲームを短期間で仕上げようかと思う。
題材はゲーム&ウォッチ風に
単純なゲームと言えば、ファミコン発売以前に一大ブームを起こしたゲーム&ウォッチ等のLCDゲームを思い出す。当時は幼稚園児だったと思うが、旅行先の東京で祖母に買ってもらったLCDゲーム「トンデケパーマン」の存在が僕の中では大きい。パーマンバッジ型のステキな本体、手に汗握るゲーム性。かつて熱中した思い出のゲームを再現したい。しかし、そのままキャラを使う事はできないので、根源的なゲーム性を参考するにとどめ、キャラやデザインはオリジナルな素材を用いる。そもそも30年以上前の実機の記憶は当然の事ながら薄らいでおり、おぼろげに何となくで作るしかない。
lcd1
オリジナルキャラ
ゲームに用いるキャラは僕のオリジナルである会社の犬「社畜犬」だ。
LCDゲーム風のデザインを意識してキャラを描いてゆく。
ゲームのルール
トンデケパーマンは遊園地内の線路を走る列車(ブービーが乗ってる)を脱線しないようにパーマンが活躍するゲームだった。線路は4箇所が分断されており、内3箇所には線路オブジェクトが配置されているが、残り1箇所は途切れたまま。3つの線路オブジェクトのうちの1つを持ち、列車の位置に応じて線路を移動させて脱線を防ぐ。というルールだった筈。
lcd2
たしかこんなん
今になって調べてみると、このトンデケパーマンのゲームデザインはゲーム&ウォッチのマンホールをパクった多少アレンジしたデザインなのかもしれない。今回はオリジナルの「社畜犬」がメインキャラなので、遊園地と列車といった要素を用いるにはテーマが違いすぎる。社畜犬はあくまで会社の犬なんだ。虐げられ、それでも我慢し、歯車という部品と人間(犬)との間で、己の存在意義に葛藤する日々を送る存在やないと駄目なんやで。あくまでも社畜(自分)視点でデザインしてみる。
社畜なりの解釈
lcd3
社畜が考えたらこうなった
ベルトコンベア上を流れる缶詰を落とさないように、契約社員である社畜犬がワンオペで作業するゲーム。コスト節減の為、ベルトコンベアは1箇所が寸断されており、他3つある部品を移動させながら、ラインの流れを妨げないように孤独にオペレートするんだ。失敗したら、本社社員に怒られてクビになる。元ネタをリスペクトしつつ、著作権に配慮した結果こうなった。
上記の絵はまだ実際にUnityに落としこんでいない素材データ。絵だけなら誰でも描けるが、これからLCDゲーム風に動かさなければならない。ベルトコンベア上の缶詰の動きに苦慮する予感がする。

enchant.jsからUnityへ鞍替えした

このエントリーをはてなブックマークに追加
2014/09/29 9:39 pm
Blog Category / ゲーム制作ログ
Tags /
 

unity1
統合開発環境であるUnity。マルチプラットフォームに対応し、簡単にゲームが作れてしまうと評判高いが、何となく敷居の高さを感じて今まで手を出せずにいた。そこでenchant.js+box2Dでこつこつとピンボールゲームを作っていたが、制作しているうちに色々と不便な点が見えてきて、制作へのモチベーションが保てなくなっていた。
ここがあかんのや
限りなく低いスキルしか持ちあわせていない癖に何を宣っているのだと自分ながらに思うが、enchant.jsはどうしようもない問題があるんだ。それは自分にとって2点ほど存在する。
■スプライト画像が自動的にスムージングされてしまう。
例えば32×32ピクセル程度の低解像でシャープなスプライトを使いたくても、少しでも拡大しようものなら強制的にスムージングがかかり、ドット絵のエッジがぼやけてしまう。これはenchant.jsの仕様上どうしようも無いらしく、対策するには元のドット絵画像を実際の描画解像度に合わせて用意するしか無い。
■動作が遅い
enchant.jsと物理演算を組み合わせて制作するとHTML5+Javascriptの限界なのだろうか、途端に実行速度が遅くなる。ピンボールゲームは根源となる動作を作り終えていたが、その頃になると自宅のiMacではテストプレイの際に著しくフレームレートが低下していた。プログラムの組み方にもよるのかもしれないが、ここから更に数々の要素を加えていくと、動作速度の面で行き詰まるのは目に見えていた。これじゃスマートフォン上での動作は絶対に無理だ。
これじゃやる気出ねえや。
Unity2Dを試してみる
仕事の繁忙期を終え多少なり時間が取れるようになってきたので、重い腰を上げてUnityをインストール。まずは公式のチュートリアルをかじり、Unityの触りを学んだ後でenchant.jsで作っていたようなピンボールゲームの動作を検証してみた。
unity2
何やこの呆気なさは。。
enchant.jsでは矩形の物理演算オブジェクト座標を手入力で打ち込みしていたが、Unityの場合、透過pngのスプライトに当たり判定用のコンポーネントを適用してやるだけで画像のエッジを検出し、自動で当たり判定が設定されてしまった。何だろうこの呆気なさは…唖然とする。物理演算のパラメーターはGUI上で簡単に設定でき、動作速度も比べるまでもなく高速。これなら作りこんでも大丈夫かなぁと再びやる気を湧き起こさせてくれた。
Unityにおける決まり事や、僕にとってはちんぷんかんなC#でのコーディングなど苦戦する事も多いが、現在はWEB上の情報に助けられながら、以前制作途中の素材を流用し、移植作業をコツコツと進めている。

素人がenchant.js + box2Dで作るピンボールゲーム

このエントリーをはてなブックマークに追加
2014/04/29 9:42 pm
Blog Category / ゲーム制作ログ
 

pinball
社畜犬はワイのオリジナルキャラやで
Z,C:フリッパー / カーソル↓で玉を弾く / ←↑→で玉を強制移動
※現在スマホのタッチ操作には非対応 / Chrome推奨
少し前からJavascriptゲームフレームワーク「enchant.js」でピンボールゲームを作っている。テーマは会社の犬、「社畜犬」を用いた社畜による社畜の為のピンボール、ボロアパートから出勤し、ブラック企業内で弾かれながら何とか生き延びるんだ。今年に入ってからJavascriptとenchant.jsを学びながら少しづつ形にしてきたが、最近は3Dプリンタにうつつを抜かしている為制作が停滞している。そろそろ再開させたい。
■enchant.js : http://enchantjs.com/ja/
■PhySprite.enchant.js : かっしぃのメモ帳
ピンボールの挙動には物理エンジン「box2D」をenchant.js向けにラップしたプラグインを用いた。簡単なコードで複雑な動きと当たり判定を再現でき、正にピンボールにうってつけのプラグインと言えるが、その動作には癖も多く、数々のバグや設定に悩まされる事に。そもそも僕のプログラミング言語スキルはゼロに等しく、N88-BASICやActionScriptを少しかじったくらいのもの。なんとなく概念は理解できるが、実践方法が分からん。したがって、数々の要素は学習と平行しながら実装するという状態、その進行スピードは牛歩並みなんだ。
ステージデータは物理オブジェクトである矩形を組み合わせた。多角形も作ることができるが、その場合当たり判定がおかしな事になってしまう為、矩形を組み合わせる方法しか思い浮かばなかった。エディタが無いので、配置座標は全て手入力。非常に効率が悪い。
function stage_data(){
wall = []; // 配列定義// 壁0 右端
wall[0] = new PhyBoxSprite(16, 448, STATIC_SPRITE, 1.0, 0, 0.0, false);
wall[0].position = { x: 320 – 8,y: 448 / 2};// 壁1 左端
wall[1] = new PhyBoxSprite(16, 480, STATIC_SPRITE, 1.0, friction, 0.0, false);
wall[1].position = {x: 8,y: 220};// 壁2
wall[2] = new PhyBoxSprite(16, 100, STATIC_SPRITE, 1.0, 0, 0.0, false);
wall[2].angle = -20; wall[2].position = {x: 320 – 8,y: 60 };// 壁3
wall[3] = new PhyBoxSprite(16, 100, STATIC_SPRITE, 1.0, 0, 0.0, false);
wall[3].angle = -40; wall[3].position = {x: 320 – 30,y: 20};
手動で確認しながら延々と配置していく苦行
当たり判定用の矩形はaddChildしなければ判定を保ったまま表示されないので、透過PNGで意匠を与えた。表示の優先順位はGroupで実装。古いバージョンのenchant.jsでは裏技的にCSSのz-Indexで表示順序をコントロールできたようだが、現在のバージョンでは通用しなくなっている。
var layer_main = new Group();
var layer_stage = new Group();
var layer_stage_top = new Group();
var layer_stage_top_middle = new Group();
var layer_stage_top_high = new Group();
var layer_stage_shadow = new Group();
var layer_stage_background = new Group();
コードの冒頭でグループを宣言。暫定的に7レイヤー分。
var stage_top = new Sprite(320,448);
stage_top.image = game.assets[‘stage_top.png’];
layer_stage_top.addChild(stage_top);
//stage_top.opacity = 0.3;
var stage_shadow = new Sprite(320,448);
stage_shadow.image = game.assets[‘stage_shadow.png’];
layer_stage_shadow.addChild(stage_shadow);
var stage_background = new Sprite(320,448);
stage_background.image = game.assets[‘stage_background.png’];
layer_stage_background.addChild(stage_background);//テンプレートイメージ(デバッグ用)
var temp = new Sprite(320,448);
temp.image = game.assets[‘temp.jpg’];
temp.opacity = 0.3;
//layer_stage_top.addChild(temp);layer_stage_top.addChild(db1); // デバッグ用変数表示配置
先程宣言したグループに画像をaddChild。背景やら影やらデバッグ用やら
//グループ配置
scene_main.addChild(layer_stage_background);
scene_main.addChild(layer_main);
scene_main.addChild(layer_stage);
scene_main.addChild(layer_stage_shadow);
scene_main.addChild(layer_stage_top);
scene_main.addChild(layer_stage_top_middle);
scene_main.addChild(layer_stage_top_high);
で、グループ自体をシーンにaddChild。記述の順に従って表示される。画面の上部のループレーンに進入した際は、ボールの配置Groupを入れ替えている
根源となる動作はほぼ完成したとはいえ、各種ギミック、アニメーション、スコア表示など、課題は山積みでまだまだ理解していない事が多いが、あまり頭の出来がよろしくない僕がWEBの情報を頼りに動かせるまで来れたので、他の方だともっと上手くできるんじゃないかと思われる。
最後に汚いソースコードを晒しとくよ。

  • 最近の投稿
  • 最近の特集
  • 人気の記事
  • アーカイブ
  • カテゴリー
  • タグクラウド