【JavaFX】自機をキー操作で動かせるようにする

2018年3月14日

本稿ではJavaFXでゲーム制作するにおいて、自機を操作できるようにしてみましょう。

サンプルは2Dシューティングを想定していますが、アクションだろうとRPGだろうと同じやり方で問題ありません。

今回使用するサンプル画像はこれ。なんか城みたいになってますが、許してください。

キー操作で自機を上下左右に動かす

まずは、キー操作で自機を移動できる処理を実装してみましょう。

キーイベントの実装方法はこちらの記事でも紹介しています。

keyPressedイベントを処理し、上下左右キ―を押下したときにそれぞれ、x座標、y座標の値を変更するだけで移動できます。

右に移動させたい場合はx座標を加算。
左に移動させたい場合はx座標を減算。
上に移動させたい場合はy座標を減算。
下に移動させたい場合はy座標を加算。

横移動させる場合はNodeオブジェクトのsetXメソッドかsetTranslateXメソッド利用します。
縦移動させる場合はNodeオブジェクトのsetYメソッドかsetTranslateYメソッド利用します。

それでは自機を移動させるサンプルをご覧ください。

import java.io.File;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;

public class Test extends Application{

	//自機
	ImageView img = new ImageView(new File("sample3.png").toURI().toString());

	@Override
	public void start(Stage primaryStage) throws Exception {
		Pane p = new Pane();
		Scene scene = new Scene(p, 400, 300);
		primaryStage.setScene(scene);
		primaryStage.show();

		//表示
		p.getChildren().add(img);

		//キーイベントの登録
		scene.setOnKeyPressed(e -> keyPressed(e));
	}

	private void keyPressed(KeyEvent e) {
		//上下左右キーを押した時imgの座標を移動させる。
		switch(e.getCode()) {
		case LEFT:
			//左キーを押したらxを減算させ、画像を左に移動させる
			img.setX(img.getX()-3);
			break;
		case RIGHT:
			//右キーを押したらxを加算させ、画像を右に移動させる
			img.setX(img.getX()+3);
			break;
		case UP:
			//上キーを押したらyを減算させ、画像を上に移動させる
			img.setY(img.getY()-3);
			break;
		case DOWN:
			//下キーを押したらyを加算させ、画像を下に移動させる
			img.setY(img.getY()+3);
			break;
		default:
			break;
		}
	}
}
実行結果

より滑らかに移動させ、斜め移動にも対応する方法

先ほど紹介した方法だとどうしてもカクカク移動となってしまう上に斜め移動もできません。これを回避し、滑らかなアニメーションにするためには、キーが押された時の押されたフラグをONにしておき、離されたらOFFにするという処理を実行するのが良いです。

ただフラグを保持するだけでは動かないので、こちらの記事でも紹介したAnimationTimerを使用し、ゲームループ上で移動処理を実装します。

それではサンプルをご覧ください。


import java.io.File;

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;

public class Test extends Application{

	//自機
	ImageView img = new ImageView(new File("sample3.png").toURI().toString());

	//キーフラグ
	boolean isLeft;
	boolean isRight;
	boolean isUp;
	boolean isDown;

	@Override
	public void start(Stage primaryStage) throws Exception {
		Pane p = new Pane();
		Scene scene = new Scene(p, 400, 300);
		primaryStage.setScene(scene);
		primaryStage.show();

		//表示
		p.getChildren().add(img);

		//キーイベントの登録
		scene.setOnKeyPressed(e -> keyPressed(e));
		scene.setOnKeyReleased(e -> keyReleased(e));

		//ゲームループの起動
		new AnimationTimer() {

			@Override
			public void handle(long arg0) {
				gameLoop();
			}
		}.start();
	}

	//ゲームループ(通常60fpsで呼び出される)
	public void gameLoop() {
		if ( isLeft ) {
			//左キーを押し下げ状態ならxを減算させ、画像を左に移動させる
			img.setX(img.getX()-3);
		}
		if ( isRight ) {
			//右キーを押し下げ状態ならxを加算させ、画像を右に移動させる
			img.setX(img.getX()+3);
		}
		if ( isUp ) {
			//上キーを押し下げ状態ならyを減算させ、画像を上に移動させる
			img.setY(img.getY()-3);
		}
		if ( isDown ) {
			//下キーを押し下げ状態ならyを加算させ、画像を下に移動させる
			img.setY(img.getY()+3);
		}
	}

	//キーを押した時のイベント
	private void keyPressed(KeyEvent e) {
		//上下左右キーを押した時フラグをONにする。
		switch(e.getCode()) {
		case LEFT:
			isLeft = true;
			break;
		case RIGHT:
			isRight = true;
			break;
		case UP:
			isUp = true;
			break;
		case DOWN:
			isDown = true;
			break;
		default:
			break;
		}
	}

	//キーを離した時のイベント
	private void keyReleased(KeyEvent e) {
		//上下左右キーを離した時フラグをOFFにする。
		switch(e.getCode()) {
		case LEFT:
			isLeft = false;
			break;
		case RIGHT:
			isRight = false;
			break;
		case UP:
			isUp = false;
			break;
		case DOWN:
			isDown = false;
			break;
		default:
			break;
		}
	}
}
実行結果

これでより滑らかなアニメーションとなり、斜め移動にも対応できました。

JavaJavaFX

Posted by nompor