【JavaFX:横スクロールアクションゲーム】ステージの表示を実装

2018年8月22日

ブロックなどを表示して、ステージを作成してみます。

前の記事 横スクロールアクションゲームTop 次の記事

ステージは50×50のマップチップを敷き詰めた形で作成します。50×50にした理由は単純に計算しやすいからです。

ここでフィールドを構成するクラスをもう一度おさらいです。

Fieldクラス

このクラスはゲームフィールド上に配置される50×50のブロック、または装飾を表します。

ブロックには当たり判定がありますが、装飾には当たり判定がなく、ただの飾りという扱いです。

これら二つをまとめてFieldクラスとします。Fieldクラスには当たり判定がないので、キャラを押し戻すメソッド、sinkingReviseは空のままです。

Blockクラス

このクラスはゲームフィールド上に配置される50×50のブロックを表します。

Fieldクラスを継承し、50×50のRectangleオブジェクトを当たり判定Nodeとします。

このオブジェクトはGameManagerクラスで各種キャラクターオブジェクトと当たり判定を行い、当たっていた場合は、適切に押し戻し処理を実行するようにします。

GameFieldクラス

このクラスでは50×50のFieldオブジェクトの集合体を2次元配列で保持するクラスです。

1ステージに対して全Fieldオブジェクトを作成しておき、キャラと各種ブロックとの当たり判定を行います。

当たり判定は全ブロックではなく、キャラクターの隣接したFieldオブジェクトと行います。

隣接オブジェクトの配列インデックスを特定する計算はキャラとステージの判定処理で行います。

ステージ表示サンプル

ステージはブロックの集合を描画して表示します。表示リストへの追加はFieldObjectManagerで行っていますが、ここではわかりやすいように、3つのクラスとサンプルクラスを新たに作成して表示してみます。実際にゲームで表示している方法もここのサンプルと同じです。(実際はクラスが入り乱れてキモくなってしまっていますが・・・)

表示はGameFieldの二次元配列から取得できるFieldオブジェクトから、ViewNodeを取得し、JavaFXの表示用オブジェクトに追加するだけです。

Test1.java
import java.io.File;

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class Sample1 extends Application{

	public static void main(String[] args) {
		launch(args);
	}

	@Override
	public void start(Stage primaryStage) throws Exception {
		//ウィンドウ表示領域800*600に合わせて二次元配列構築
		final int WIDTH = 800, HEIGHT = 600;
		final int ROW=HEIGHT/50,COL=WIDTH/50;
		Field[][] field = new Field[ROW][COL];

		//画面一番下に地面ブロック配置
		final int UNDER_INDEX = (ROW-1);
		for ( int i = 0;i < COL;i++ ) {
			Rectangle rect = new Rectangle(i * 50,UNDER_INDEX*50,50,50);//当たり判定Node
			ImageView imgView = new ImageView(new File("img/jimen.png").toURI().toString());//表示Node
			imgView.setTranslateX(rect.getX());
			imgView.setTranslateY(rect.getY());
			field[UNDER_INDEX][i] = new Block(imgView, rect);
		}

		//画面一番下から二つ上にいくつかブロック配置
		final int BLOCK_INDEX = (ROW-3);
		for ( int i = 5;i < 11;i++ ) {
			Rectangle rect = new Rectangle(i * 50,BLOCK_INDEX*50,50,50);//当たり判定Node
			ImageView imgView = new ImageView(new File("img/block.png").toURI().toString());//表示Node
			imgView.setTranslateX(rect.getX());
			imgView.setTranslateY(rect.getY());
			field[BLOCK_INDEX][i] = new Block(imgView, rect);
		}

		//装飾を追加
		ImageView imgView = new ImageView(new File("img/kusa.png").toURI().toString());//表示Node
		final int idxRow = UNDER_INDEX-1,idxCol = 3;
		imgView.setTranslateX(idxCol*50);
		imgView.setTranslateY(idxRow*50);
		field[UNDER_INDEX-1][3] = new Field(imgView);

		//GameFieldオブジェクトの構築
		GameField fields = new GameField(field);
		Field[][] fieldList = fields.getFieldList();
		Group jxGrp = new Group();
		for ( int i = 0;i < fieldList.length;i++ ) {
			for ( int j = 0;j < fieldList[i].length;j++ ) {
				Field fld = fieldList[i][j];
				if ( fld != null ) {
					jxGrp.getChildren().add(fld.getViewNode());
				}
			}
		}

		Scene scene = new Scene(jxGrp, WIDTH, HEIGHT);
		primaryStage.setScene(scene);
		primaryStage.show();

		//キャラクターとの判定
		//CharaObject ch = ...;
		//fields.fieldCheck(ch);
	}
}
実行結果

公開ソースであるObstacleAvoid1.00のソースの中にもTest1は含めておきます。これらのプログラムと一緒に配置すれば実行できるはずです。

JavaJavaFX

Posted by nompor