「JavaScriptでインベーダー・ゲームを書いて」
単一のHTMLページが生成されます。最後に以下のようにメッセージが返されています。
このコードをローカルに保存し、ブラウザで開くとシンプルなインベーダー・ゲームが動作します。
※このサンプルは基本的な実装例ですので、衝突判定の精度向上やエフェクトの追加など、さらなる拡張が可能です。
最初にこの生成されたコードをAPEXに組み込んでみます。場合によってReactのコードが生成されることがあります。Oracle APEXにReactを組み込むのはほぼできないので、その場合はプロンプトにVanilla JavaScriptと明示すると、フレームワークを使わないコードが生成されます。
空のAPEXアプリケーションを作成します。名前はRetro Gameとします。
デフォルトで作成されるホーム・ページに組み込みます。
ページ・デザイナでホーム・ページを開きます。
生成されたコードのstyleタグからbodyの指定を除いた記述を、ページ・プロパティのCSSのインラインに転記します。
scriptタグに記述されたJavaScriptのコードをコピーします。
静的コンテンツのリージョンを作成し、生成されたコードに含まれているキャンバス要素をソースのHTMLコードとして記述します。
<canvas id="gameCanvas" width="800" height="600"></canvas>
以上で組み込みは完了です。ページを実行して遊びます。
ゲームに一時停止と再開のボタンを追加します。
「一時停止と再開のボタンを追加してください。」
一時停止と再開のボタンが追加されたコードが生成されました。
APEXアプリケーションに空白ページを作成し、先ほどと同じ手順でstyleタグとscriptタグの記述をページに転記します。
静的コンテンツのリージョンに、ボタンが追加された以下のHTMLソースを記述します。
<div id="controls">
<button id="pauseButton">一時停止</button>
<button id="resumeButton">再開</button>
</div>
<canvas id="gameCanvas" width="800" height="600"></canvas>
ボタンのクリック時に後続の処理をキャンセルするように指示します。
preventDefault()を呼び出すコードが生成されました。
ページを実行して遊んでみます。今度は一時停止と再開が効きます。
データベースとレトロ・ゲームを連携するために、一時停止したときの状態をJSONドキュメントとして出力するファンクションと、そのJSONドキュメントを受け取ってゲームを再開するファンクションを作成してもらいます。
「一時停止したときの状態をJSONドキュメントとして出力するファンクションと、そのJSONドキュメントを受け取ってゲームを再開するファンクションを作成してください。」
ファンクションexportGameState()とimportGameState(jsonDocument)のふたつのファンクションが生成され、状態出力と状態読込というボタンが追加されたコードが生成されました。生成されたコードはこちらです。
APEXアプリケーションに空白ページを作成し、先ほどと同じ手順でstyleタグとscriptタグの記述をページに転記します。
静的コンテンツのリージョンには、ボタンとテキスト領域が追加された以下のHTMLソースを記述します。
<div id="controls">
<button id="pauseButton">一時停止</button>
<button id="resumeButton">再開</button>
<button id="exportButton">状態出力</button>
<button id="importButton">状態読込</button>
</div>
<textarea id="stateOutput" placeholder="ここにJSON状態を貼り付けて読込"></textarea>
<canvas id="gameCanvas" width="800" height="600"></canvas>
最後にデータベースと連携させます。
クイックSQLの以下のモデルより、ゲームの状態を保存する表EBAJ_RETRO_GAME_STATEを作成します。
# prefix: ebaj
retro_game_state
state_name vc80 /nn /unique
state json
レビューおよび実行をクリックした後は、実行や即時実行のボタンをクリックして表を作成するところまで進みます。
表EBAJ_RETRO_GAME_STATEが作成されます。
これからは、通常のAPEXのアプケーション作成作業を行います。
ページ4をコピーしてページ5を作成し、データベースへの連携を追加します。
ページ4からページ5を作成します。
新規ナビゲーション・メニュー・エントリの作成を選択します。
ページのコピーを実行します。
ページのコピーが作成されました。
APEXのアプリケーションらしくするため、および、ボタンの動作をAPEXアクションとして定義するために、Gameのリージョンに作成されているボタンやテキスト領域に代えて、APEXのボタンなどを作成します。
ボタンなどを配置するリージョンを静的コンテンツとして作成します。APEXアクションのコンテキストを作成するため、静的IDとしてCONTROLSを設定します。
ボタンPAUSE(一時停止)、RESUME(再開)、EXPORT(状態出力)、IMPORT(状態読込)を作成します。これらの動作のアクションに動的アクションで定義を選択し、詳細のカスタム属性としてdata-action="<ボタン名>"を設定します。
ボタンRESETは表EBAJ_RETRO_GAME_STATEの内容を全削除して、初期状態に戻すために使用します。このボタンだけは動作のアクションはページの送信です。
JSONドキュメントとして出力した状態はデータベースに保存します。データベースへの状態の保存および取り出しを実行するにあたって、状態名の指定および選択にコンボボックスを使うことにします。
先にコンボボックスの手動入力アイテムを作成します。識別の名前はP5_STATE_NAME_NEW、タイプは非表示です。コンボボックスの手動入力アイテムなので、設定の保護された値はオフにします。
セッション・ステートのデータ型はVARCHAR2、ストレージはリクエストごと(メモリーのみ)とします。
コンボボックスの名前はP5_STATE_NAMEとします。手動入力アイテムとして作成済みのP5_STATE_NAME_NEWを指定します。
LOVのタイプにSQL問合せを選択し、SQL問合せとして以下を記述します。
select state_name d from ebaj_retro_game_state order by id asc
セッション・ステートのデータ型はVARCHAR2、ストレージはリクエストごと(メモリーのみ)です。
リージョンGameのソースのHTMLコードより、ボタンやテキスト領域の要素を除きます。
<canvas id="gameCanvas" width="800" height="600"></canvas>
ブラウザのJavaScriptから呼び出す、データベースにゲームの状態を保存するプロセスをAjaxコールバックとして作成します。名前はEXPORT、ソースのPL/SQLコードとして以下を記述します。
データベースからゲームの状態を取り出すプロセスをAjaxコールバックとして作成します。名前はIMPORT、ソースのPL/SQLコードとして以下を記述します。
ボタンRESETを押したときに呼び出されるプロセスとしてRESETを作成します。
ソースのPL/SQLコードに以下を記述します。
delete from ebaj_retro_game_state;
サーバー側の条件のボタン押下時にRESETを指定します。
ボタンなどのコンポーネントをAPEX由来のものに置き換えたので、ページ・プロパティのJavaScriptのページ・ロード時に実行をこちらのコードに置き換えます。
とりあえず一通りは完成しました。ページを実行して遊んでみます。
ボタン状態出力および状態入力でデータベースへの保存と取り出しはできていることは確認できました。しかし、キャンバス要素外でのキーボード・イベントでミサイルとかが発射されたりします。また逆にボタンにフォーカスが当たっていると、キャンバス上でのキーボード入力に反応します。
以下のプロンプトを与えて、問題点を修正します。
また、mouseenterの際にcanvasにフォーカスをセットしてください。」
不具合を修正したコードに置き換えます。
リージョンGameのHTMLコードに含まれるキャンバス要素にフォーカスを当てるため、tabindex="0"が追加されています。
<canvas id="gameCanvas" width="800" height="600" tabindex="0"></canvas>
不具合を修正したJavaScriptコードに含まれるボタンの処理をする部分を、再度APEXと連携するコードに置き換えます。置き換えたコードで、ページ・プロパティのJavaScriptのページ・ロード時に実行を置き換えます。
ページを実行し遊んでみます。先ほどの不具合は修正されているようです。
以上でAPEXアプリケーションは完成です。
今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/retro-game.zip
Oracle APEXのアプリケーション作成の参考になれば幸いです。
完