2013年07月07日

久しぶりにプログラミング、タイルマップに対応

この前まで敵キャラの画像を作ってばかりいたので随分久しぶりにプログラミングをしたのような気がします。

今週はTiledというフリーソフトを使って作成したタイルマップから敵とか障害物の位置を読み取ってステージ上に配置する処理を作成しました。

スクリーンショット 2013-07-07 18.10.06.png

Tiledを使えば1枚の画像を細かいタイルに分割して配置したタイルマップを作成することができます。

※参考サイト:Cocos2D 2.Xでタイルベースゲームの作成チュートリアル

タイルマップをcocos2dで読み込むと1個のノードとして扱われるので、そのまま1枚の画像として表示することもできます。が、敵キャラなんかをそのまま画像として表示してもしょうがないのでマップ上の敵キャラ画像は非表示にしておいて代わりに敵キャラクラスを作っていおいてタイルの位置にそのインスタンスを作成することになります。

障害物に関しては敵キャラと違って動くわけではないので1枚画像として表示していればいいのですが、当たり判定の処理とかを敵キャラの場合と同じにしたかったので、敵キャラと同じように障害物クラスを作成しました。なんとなく、これは普通のやり方と違うような気もしています。

障害物をキャラクターとして扱えば当たり判定自体は一本化できるので楽ができるのですが、一個だけ問題点として地面のタイルの切れ目に隙間がちらつくというバグが発生してしまいました。

原因は簡単に言うとfloatの演算誤差によって隣のタイルと1ドットずれて隙間ができることがあるというものでした。

例えば32x32ドットのサイズの地面のタイルを幅384ドットの画面に敷き詰める場合、まず初期表示として(0,0),(32,0),(64,0),...,(384,0)の位置にタイルを配置します。その後、マップがスクロールして32ドット左に動いた時に新しい新しい地面を再び(384,0)の位置に配置することになります。

ただ、実際には毎秒60フレームで各処理を更新しているので、丁度32.0ドット移動した時というわけではなく、32.00123ドットみたいな数値のときに次のタイルを配置することになってりします。この場合、次のタイルの位置は(384.00123,0)になるのですが、このときに誤差が発生するということがありました。

座標の計算にはfloatを使用しています。実際には2進数で管理しているのですが、とりあえず説明を簡単にするために扱える有効桁数を10進で7桁とします。そうすると、32.00123は7桁なのでOKなのですが、384.00123は8桁なので下1桁が落とされて384.0012と0.00003の誤差が発生してしまいます。

通常この程度の誤差は無視できるし、実際0.00003ドットの位置に表示なんてできることはなく、四捨五入で切り捨てられるものです。ところが、タイルの座標が丁度四捨五入の境目付近に来た時に問題が発生します。例えば、あるタイルが(10.49998,0)の位置にあり、その隣のタイルが(42.50001,0)の位置にある場合、四捨五入の結果、それぞれ(10,0),(43,0)の位置に配置されることになり、タイル間の距離が33ドットになって隙間ができることになります。

しょうがないので、障害物はそれぞれ独立したキャラクターになっているはいるのですが、画像を表示する位置は自分が持っている座標の位置ではなく、タイルマップ全体の位置からの相対距離で決めるようにしました。こうすることで四捨五入で切り捨てか切り上げかの判定に使う変数を共通化できるのでズレを防ぐことができます。


なんか無駄に文章が長くなった上にわかりづらいですが今週はこんな感じでした。来週は敵キャラの動きの部分を実装していくつもりです。
ラベル:とりとま
posted by かねだ at 21:54| Comment(0) | 開発記録 | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

×

この広告は180日以上新しい記事の投稿がないブログに表示されております。