Javaでクラスの考え方について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
海Sea
記事: 102
登録日時: 9年前
住所: 大阪
連絡を取る:

Javaでクラスの考え方について

#1

投稿記事 by 海Sea » 7年前

いつもありがとうございます。
現在Java用ビデオゲームライブラリを使用して
シューティングゲームを構築しようとしています。

言語と環境は
Java:SE7u21 eclipse4.2

ライブラリ:JavaSE向けビデオゲームライブラリ
ISLeのビデオゲーム工房(カテゴリ:JavaSE)
► スポイラーを表示
ゲーム用コードは現在この部分だけなのですが、
例えばショットクラスや自機クラスにわける場合
掲載したコード内の描画部分との関連付けを
どうすべきか、イメージがよくわかりません。

たとえば、

コード:

public class jiki
{
     public jiki()
    {
        jiki_x = 320;//初期値X
        jiki_y = 400;//初期表示Y
    } 
}
というものがあって、
そのクラスをインスタンス化した際に
描画するタイミングでjiki.jiki_xなどを代入する分け方で良いでしょうか。
ゲームプログラミングで描画と値をわけるという考え方で言うと
こういうことだと思うのですが。
アドバイス等ありましたら、よろしくお願いします。
最後に編集したユーザー 海Sea on 2013年5月05日(日) 02:35 [ 編集 1 回目 ]

ISLe
記事: 2645
登録日時: 9年前
連絡を取る:

Re: Javaでクラスの考え方について

#2

投稿記事 by ISLe » 7年前

このサイトのAndroidの館のイライラ棒アプリの作成講座が参考になると思います。
VGCanvasはイライラ棒アプリのGameMgrに相当します。

更新と描画のメソッドを持ったインターフェースを継承して、ゲームオブジェクト(タスク)のクラスを作ります。
構築したタスクをリストに登録しておいて、VGCanvas#frameUpdateで各タスクの更新メソッドを呼び出し、VGCanvas#frameRenderで各タスクの描画メソッドを呼び出します。


あと、わたしが言うのもなんですけど、回答者が検証できるように、使用しているライブラリの所在を書いておくと良いと思います。

アバター
海Sea
記事: 102
登録日時: 9年前
住所: 大阪
連絡を取る:

Re: Javaでクラスの考え方について

#3

投稿記事 by 海Sea » 7年前

ISLe さんが書きました:このサイトのAndroidの館のイライラ棒アプリの作成講座が参考になると思います。
VGCanvasはイライラ棒アプリのGameMgrに相当します。

更新と描画のメソッドを持ったインターフェースを継承して、ゲームオブジェクト(タスク)のクラスを作ります。
構築したタスクをリストに登録しておいて、VGCanvas#frameUpdateで各タスクの更新メソッドを呼び出し、VGCanvas#frameRenderで各タスクの描画メソッドを呼び出します。


あと、わたしが言うのもなんですけど、回答者が検証できるように、使用しているライブラリの所在を書いておくと良いと思います。
構築の仕方は、そちらを参考に手をつけて見ます。
何気に時間がかかりそうですが・・・

あと、ご指摘のとおり、トピックを修正して、
ライブラリの所在を明記しておきました!

アバター
海Sea
記事: 102
登録日時: 9年前
住所: 大阪
連絡を取る:

Re: Javaでクラスの考え方について

#4

投稿記事 by 海Sea » 7年前

Androidの館を参考に組んで見ました。
ISLeさんのアドバイスではupdate()メソッドなどをもったインターフェースを継承するとあったのですが、
自分でわかりやすいよう、Androidの館同様にタスククラスは抽象クラスとして継承しています。

しかし、自機は初期位置で描画されるのですが、
キーを押しても全く自機が動かず困っています。

コード量が多いかもしれませんが、指摘等ありましたらよろしくお願いします。
環境などはトピックの一つめに記載してあります。

タスククラス
► スポイラーを表示
ゲームのPadクラス(キーの押下を担うクラス・ライブラリからの流用)
► スポイラーを表示
プレイヤー(自機)クラス
► スポイラーを表示
実際のゲーム画面を出すクラス
► スポイラーを表示

ISLe
記事: 2645
登録日時: 9年前
連絡を取る:

Re: Javaでクラスの考え方について

#5

投稿記事 by ISLe » 7年前

interfaceを使うとabstract(のタイプ量)を省略できますけど。
実装を含まないときはclassよりinterfaceをお勧めします。
classとinterfaceでは継承の仕方が違ってきますし。

キーを押しても反応しないのは、リスナーを定義して構築してますけど、登録していないからです。
定義したキーイベントのコールバックメソッドが呼ばれないのでとうぜん動きません。

リスナーはアクティブなコンポーネント(この場合はVGCanvas)に登録する必要があります。
キーボードにアクセスする機能を自機に持たせるとコンポーネントに依存することになるのでキー入力は独立させることをお勧めします。
いわゆるMVCアーキテクチャで言われるコントローラを分離するという考え方です。

自機モジュールがキー入力を見て移動を決めるのではなく、コントローラーの指示で自機が動くように実装します。
そうすることで、自機モジュールはそのままにリプレイなどキー入力以外の指示で自機を動かすことも可能になります。

自機の移動も変数ごとのゲッタ/セッタではなく、移動メソッドのような機能として意味のある振る舞いを持たせてX,Y座標をまとめて処理すべきです。

アバター
海Sea
記事: 102
登録日時: 9年前
住所: 大阪
連絡を取る:

Re: Javaでクラスの考え方について

#6

投稿記事 by 海Sea » 7年前

ISLe さんが書きました:interfaceを使うとabstract(のタイプ量)を省略できますけど。
実装を含まないときはclassよりinterfaceをお勧めします。
classとinterfaceでは継承の仕方が違ってきますし。

キーを押しても反応しないのは、リスナーを定義して構築してますけど、登録していないからです。
定義したキーイベントのコールバックメソッドが呼ばれないのでとうぜん動きません。
これはよくわかりました。ありがとうございます!
ISLe さんが書きました: リスナーはアクティブなコンポーネント(この場合はVGCanvas)に登録する必要があります。
キーボードにアクセスする機能を自機に持たせるとコンポーネントに依存することになるのでキー入力は独立させることをお勧めします。
いわゆるMVCアーキテクチャで言われるコントローラを分離するという考え方です。

自機モジュールがキー入力を見て移動を決めるのではなく、コントローラーの指示で自機が動くように実装します。
そうすることで、自機モジュールはそのままにリプレイなどキー入力以外の指示で自機を動かすことも可能になります。

自機の移動も変数ごとのゲッタ/セッタではなく、移動メソッドのような機能として意味のある振る舞いを持たせてX,Y座標をまとめて処理すべきです。
VGCanvasにリスナー登録とあるので、とりあえず先のPadクラスはやめてライブラリのまま使うことにしました。

そして、質問なのですが、
『自機モジュールがキー入力を見て移動を決めるのではなく、コントローラーの指示で自機が動くように実装します。』
ここがいまいちよくわかりません。
キー入力受付用のクラスを作ってそのクラスから自機クラスの座標移動を呼び出してみたのですが
そういうことでしょうか?

キー入力用クラス

コード:

package testgame;

import videogame.VGCanvas;

public class KeyTriger
{
	int pad_states;
	int pad_states_old;
	int pad_trigger;

	public void Key()
	{
		if((pad_states & (1<<VGCanvas.PAD_LEFT))!=0)//左ボタンが押されたら
		{
			Player.playercontrollerx();//自機移動用メソッド
		}
	}
}

MVCアーキテクチャはまだちゃんとやったことがないので、
これを機会に学習しようと思います。

ISLe
記事: 2645
登録日時: 9年前
連絡を取る:

Re: Javaでクラスの考え方について

#7

投稿記事 by ISLe » 7年前

例えばゲーム画面を90度回転するモードがあったら、左ボタンが押されたらX座標を更新するとは限りません。

コントローラーは、キーボード入力と自機のあいだに入ります。

まず設計として、コントローラーから入力される方向を定義します。
入力方向は4方向、8方向、アナログなど入力タイプに合わせて抽象化します。

キーボード入力モジュールから入力情報を得て移動方向に変換します。
自機モジュールに移動方向を指示します。
ここまでがコントローラーの仕事です。

そして自機は指示された移動方向から座標を更新します。

こうすることによって画面の座標系とゲーム座標系を分離でき、また、オブジェクト自身が移動量を決められます。

アバター
海Sea
記事: 102
登録日時: 9年前
住所: 大阪
連絡を取る:

Re: Javaでクラスの考え方について

#8

投稿記事 by 海Sea » 7年前

ISLe さんが書きました:例えばゲーム画面を90度回転するモードがあったら、左ボタンが押されたらX座標を更新するとは限りません。

コントローラーは、キーボード入力と自機のあいだに入ります。

まず設計として、コントローラーから入力される方向を定義します。
入力方向は4方向、8方向、アナログなど入力タイプに合わせて抽象化します。

キーボード入力モジュールから入力情報を得て移動方向に変換します。
自機モジュールに移動方向を指示します。
ここまでがコントローラーの仕事です。

そして自機は指示された移動方向から座標を更新します。

こうすることによって画面の座標系とゲーム座標系を分離でき、また、オブジェクト自身が移動量を決められます。
ひとまず、形にしてみました。
抽象化等足りない部分はありますが、おそらくコントロールが間に来るというのは
こういうことかな?と思ったのですが・・・

・キー入力クラス
► スポイラーを表示
・コントローラークラス
► スポイラーを表示
・プレイヤークラス
► スポイラーを表示
・ゲーム画面のクラス
► スポイラーを表示

ISLe
記事: 2645
登録日時: 9年前
連絡を取る:

Re: Javaでクラスの考え方について

#9

投稿記事 by ISLe » 7年前

キー入力やコントローラーは機能として独立していなければいけません。

キー入力クラスはコントローラークラスが必要とするキーの押下状態を返す機能を持つだけで良いです。

コントローラークラスの仕事は、入力によって発生するイベントを作ることです。
方向以外にも、決定、キャンセル、自機ショット、自機ボム、などもコントローラーが生成します。
例え自機ショットと決定が同じキーだったとしてもイベントとしては別になります。

イベントの発生によって指示を飛ばす方法はいくつかあります。

1.コントローラーの参照を持って、必要なときにコントローラーのメソッドを呼び出して発生しているイベントを見る方法。
2.リスナーのように、コントローラーに登録してコールバックを使う方法。

メニューの実装などで2.は便利ですが、1.に2.を後付けすることもできるので、とりあえず1.でやるというのでもかまわないと思います。

アバター
海Sea
記事: 102
登録日時: 9年前
住所: 大阪
連絡を取る:

Re: Javaでクラスの考え方について

#10

投稿記事 by 海Sea » 7年前

ISLe さんが書きました:キー入力やコントローラーは機能として独立していなければいけません。

キー入力クラスはコントローラークラスが必要とするキーの押下状態を返す機能を持つだけで良いです。

コントローラークラスの仕事は、入力によって発生するイベントを作ることです。
方向以外にも、決定、キャンセル、自機ショット、自機ボム、などもコントローラーが生成します。
例え自機ショットと決定が同じキーだったとしてもイベントとしては別になります。

イベントの発生によって指示を飛ばす方法はいくつかあります。

1.コントローラーの参照を持って、必要なときにコントローラーのメソッドを呼び出して発生しているイベントを見る方法。
2.リスナーのように、コントローラーに登録してコールバックを使う方法。

メニューの実装などで2.は便利ですが、1.に2.を後付けすることもできるので、とりあえず1.でやるというのでもかまわないと思います。
何度もありがとうございます。
キーの入力とイベントの状態によって振る舞いが変わるということはわかるのですが、
設計や実装になると、難しいですね。もっとプログラミング力をつけないと駄目なことがよくわかります。

キー入力、コントローラーは独立した状態にできたと思うのですが、どうでしょうか・・・
イベントもアドバイスの1を目指してみました。

・キー入力クラス
► スポイラーを表示
・コントローラークラス
► スポイラーを表示
・イベントクラス(自機の移動メソッドの呼び出しなど)
► スポイラーを表示
・ゲーム画面クラス(コントローラークラスはここでインスタンス化している)
► スポイラーを表示

ISLe
記事: 2645
登録日時: 9年前
連絡を取る:

Re: Javaでクラスの考え方について

#11

投稿記事 by ISLe » 7年前

うーん、どんどん違う方向に進んでいる気がします。

キー入力クラスもコントローラークラスもゲーム本体とは切り離す必要があります。
要するにゲーム要素を一切含んではいけません。

簡単なサンプルを用意しますのでしばしお待ちください。

ISLe
記事: 2645
登録日時: 9年前
連絡を取る:

Re: Javaでクラスの考え方について

#12

投稿記事 by ISLe » 7年前

キー入力クラスとコントローラークラスの役割分担に重点を置いてサンプルコードを書いてみました。
とりあえずシンプルに、コントローラーのメソッドと定義を使って情報を読み取る形にしました。
► スポイラーを表示
キー入力クラス(KeyInput)は、仮想キーコードの配列を与え、各キーの押下状態をビットに反映したint値を取得します。
サンプルではキー入力クラスのインスタンスを2つ作り、カーソルキー以外にAWSDキーでも操作できるようにしています。
仮想キーコードの配列を書き換えたり配列ごと差し替えることでキーコンフィグを実装できます。

コントローラークラス(Controller)は、キー入力クラスから取得した情報をゲーム本体で使う情報に変換します。
サンプルではコントローラーの定義とキー配置が合致するのでそのまま論理和を取って使っています。
サンプルには含めませんでしたが、反対方向同時押しを消去するなど情報の正規化をここで行います。
Zキーを押すと、モニタを左に回転した場合の操作体系に変わります。
コントローラー内部で完結しているのでゲーム本体のプログラムには影響を与えません。
もう一度Zキーを押すと元に戻ります。

アバター
海Sea
記事: 102
登録日時: 9年前
住所: 大阪
連絡を取る:

Re: Javaでクラスの考え方について

#13

投稿記事 by 海Sea » 7年前

わざわざサンプルを書いて頂いてありがとうございます。
これをもとに実装を施してみます!
キー入力クラスやコントロールクラスにも
Taskインターフェースを実装する考えに至りませんでした。
どちらかというと前のPadクラスのようにわけるほうが
ISLeさんのサンプルにまだ近いですね(^^;

ある程度構築のイメージができましたので、
長々と続いてしまいましたが
ひとまず解決ということにさせて頂きます。
本当にありがとうございます。

閉鎖

“C言語何でも質問掲示板” へ戻る