シンタックスハイライト

JavaFXでRPGを作る(1)―タイトル画面

--はじめに--
Moddingで次にやることも見つからなかったので、とりあえずエディタオフ会に向けてJavaFX力を高めよう!ということでJavaFXでRPGを作ってみようかと思います。
私は初心者なので、チュートリアルというより日記としてみてくださると嬉しいです。
タイトルは仮に「Legend of Yith」としておきましょう。
さすがに最初からキャラクタを動かしたりは出来ないのでまず形から、タイトル画面から作っていきます。

JavaFXの雛形はIDEAに任せて、まずはstartメソッドにコードを書いていきます。

KeyEventで呼ばれるメソッドを作る

キーボードからの入力で様々なことを行っていきたいので打鍵時に呼ばれるイベントを作ります。
イベントが呼ばれるときに呼ばれるメソッドをMainクラスに書いていくのはあまり好きではないので、Interfaceのメソッドを呼ぶ形にします。
IKeyListener.java



package core.toImpl;

import javafx.scene.input.KeyEvent;

public interface IKeyListener{
    public void onKeyPressed(KeyEvent event);
    public void onKeyReleased(KeyEvent event);
    public void onKeyTyped(KeyEvent event);
}
そしてこれらのメソッドを呼ぶためにstartにコードを書いていきます。
LOYCore.java

package core;

import core.toImpl.IKeyListener;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.util.ArrayList;


public class LOYCore extends Application {
    public static ArrayList keyListeners=new ArrayList<>();
    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("fxml/title.fxml"));
        primaryStage.setTitle("Legend of Yith");
        Scene rScene=new Scene(root, 640, 480);
        rScene.setOnKeyPressed(event -> {for(IKeyListener listener:keyListeners) listener.onKeyPressed(event);});
        rScene.setOnKeyReleased(event -> {for(IKeyListener listener : keyListeners) listener.onKeyReleased(event);});
        rScene.setOnKeyTyped(event ->{for(IKeyListener listener:keyListeners) listener.onKeyTyped(event);});
        primaryStage.setScene(rScene);
        primaryStage.show();
    }


    public static void main(String[] args) {
        launch(args);
    }
}
JavaFXには
  • onKeyPressed:キーが押されている間呼ばれる。
  • onKeyReleased:キーが放された際に呼ばれる。
  • onKeyTyped:文字を打った際に呼ばれる。
の三種類のKeyEventがあります。
Java8にはラムダ式があるので、それを利用してささっとメソッドを呼べるようにしておきます。

IKeyListenerを実装する

今回はControllerに実装していきます。
TitleController.java

package core.controller;

import core.LOYCore;
import core.toImpl.IKeyListener;
import core.util.FontHelper;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.GridPane;

public class TitleController implements IKeyListener{
    public boolean keyPressing=false;

    public TitleController(){
        LOYCore.keyListeners.add(this);
    }

    public void onKeyPressed(KeyEvent event){
        if(!keyPressing){
            keyPressing=true;
        }
    }

    public void onKeyReleased(KeyEvent event){
        keyPressing=false;
    }

    public void onKeyTyped(KeyEvent event){

    }
}
こうすることによってキーをおした時のみ反応するということが出来ます。

GUIを設計する

JavaFXはGUIを設計するためのソフト(ScineBuilder)があるのでそれを利用します。
そして出来たのがこちら
title.fxml


<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.paint.*?>
<?import javafx.scene.shape.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>

<AnchorPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="core.controller.TitleController">
   <children>
      <ImageView fitHeight="480.0" fitWidth="640.0" pickOnBounds="true" preserveRatio="true">
         <image>
            <Image url="@../title.jpg" />
         </image></ImageView>
      <VBox prefHeight="480.0" prefWidth="640.0">
         <children>
            <Label alignment="CENTER" contentDisplay="TEXT_ONLY" prefHeight="130.0" prefWidth="641.0" text="Legend of Yith">
               <font>
                  <Font name="MoolBoran" size="96.0" />
               </font>
            </Label>
            <BorderPane prefHeight="352.0" prefWidth="640.0">
               <top>
                  <Pane prefHeight="26.0" prefWidth="640.0" BorderPane.alignment="CENTER" />
               </top>
               <left>
                  <Pane prefHeight="153.0" prefWidth="131.0" BorderPane.alignment="CENTER" />
               </left>
               <right>
                  <Pane prefHeight="197.0" prefWidth="129.0" BorderPane.alignment="CENTER" />
               </right>
               <bottom>
                  <Pane prefHeight="84.0" prefWidth="640.0" BorderPane.alignment="CENTER" />
               </bottom>
               <center>
                  <Pane prefHeight="147.0" prefWidth="389.0">
                     <children>
                        <Rectangle arcHeight="5.0" arcWidth="5.0" fill="#ffffff80" height="197.0" stroke="#ffffff00" strokeType="INSIDE" width="380.0" />
                        <GridPane fx:id="gridPane" prefHeight="195.0" prefWidth="379.0" BorderPane.alignment="CENTER">
                          <columnConstraints>
                            <ColumnConstraints hgrow="SOMETIMES" maxWidth="162.0" minWidth="10.0" prefWidth="46.0" />
                            <ColumnConstraints hgrow="SOMETIMES" maxWidth="333.0" minWidth="10.0" prefWidth="333.0" />
                          </columnConstraints>
                          <rowConstraints>
                            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                          </rowConstraints>
                           <children>
                              <Label prefHeight="42.0" prefWidth="141.0" text="はじめから" GridPane.columnIndex="1">
                                 <font>
                                    <Font size="36.0" />
                                 </font>
                              </Label>
                              <Label text="つづきから" GridPane.columnIndex="1" GridPane.rowIndex="1">
                                 <font>
                                    <Font size="36.0" />
                                 </font>
                              </Label>
                              <Label text="げーむをやめる" GridPane.columnIndex="1" GridPane.rowIndex="2">
                                 <font>
                                    <Font size="36.0" />
                                 </font>
                              </Label>
                              <Label fx:id="top" alignment="CENTER_RIGHT" prefHeight="42.0" prefWidth="38.0" text="▶">
                                 <font>
                                    <Font size="36.0" />
                                 </font>
                              </Label>
                              <Label fx:id="middle" alignment="CENTER_RIGHT" prefHeight="42.0" prefWidth="39.0" GridPane.rowIndex="1">
                                 <font>
                                    <Font size="36.0" />
                                 </font>
                              </Label>
                              <Label fx:id="bottom" alignment="CENTER_RIGHT" prefHeight="42.0" prefWidth="42.0" GridPane.rowIndex="2">
                                 <font>
                                    <Font size="36.0" />
                                 </font>
                              </Label>
                           </children>
                        </GridPane>
                     </children>
                  </Pane>
               </center>
            </BorderPane>
         </children>
      </VBox>
   </children>
</AnchorPane>
またそれに合わせてTitleControllerも書き換えます。
TitleController.java

package core.controller;

import core.LOYCore;
import core.toImpl.IKeyListener;
import core.util.FontHelper;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.GridPane;

public class TitleController implements IKeyListener{
    @FXML
    public GridPane gridPane;
    @FXML
    public Label top,middle,bottom;

    public boolean keyPressing=false;

    public TitleController(){
        LOYCore.keyListeners.add(this);
    }
    public void onKeyPressed(KeyEvent event){
        try{
            if(!keyPressing){
                switch(event.getCode()){
                    case UP:
                        moveLabel(-1);
                        break;
                    case DOWN:
                        moveLabel(1);
                        break;
                    case SPACE:
                        top.setFont(new FontHelper().createFont("src/core/misaki_gothic.ttf"));
                        break;
                }
                keyPressing = true;
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    public void moveLabel(int y){
        if(!top.getText().isEmpty()){
            top.setText("");
            if(y==-1)bottom.setText("▶");
            else if(y==1)middle.setText("▶");
        }else if(!middle.getText().isEmpty()){
            middle.setText("");
            if(y==-1)top.setText("▶");
            else if(y==1)bottom.setText("▶");
        }else if(!bottom.getText().isEmpty()){
            bottom.setText("");
            if(y==-1)middle.setText("▶");
            else if(y==1)top.setText("▶");
        }
    }

    public void onKeyReleased(KeyEvent event){
        keyPressing=false;
    }

    public void onKeyTyped(KeyEvent event){

    }
}
これで終わりです。
お疲れ様でした。
タイトルの背景画像としてhttp://guttari8.sakura.ne.jp/index.shtmlを利用しました。

0 件のコメント:

コメントを投稿