自機の左右移動 - Javaでシューティングゲームを作ろう
目次
- Javaでシューティングゲームを作ろう
- 自機の左右移動
- 弾発射・はみ出しチェック
- 敵登場・仮想画面
- 当たり判定(敵と弾)・スコア
- 当たり判定(自機と敵)・シーン切り替え
- クラス化
- 継承・Vectorによるキャラ管理・サウンド
- パワーアップ・複数種類の敵
- ペンギンシューティング
今回の題材
-自機の左右移動プレイしてみる
一式ダウンロード
ソースの解説
import宣言
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
ここの部分は今はそれほど重要でないので分からなくても構いません。講座が進むにつれて自然に分かってきます。import文はパッケージをインポートする命令です。Shooting1クラス
クラス宣言の部分です。
public class Shooting1 extends Applet implements Runnable, KeyListener {
いきなり訳の分からない単語が沢山並んでいますが、この部分もゲームを作る上で本質的ではないので今の段階では分からなくても構いません。とりあえず単語をひとつずつ説明します。publicはこのクラスをどこからでもアクセスできるようにするというアクセス修飾子です。
class Shooting1はShooting1というクラス名のクラスを定義しています。中括弧の中身({…})にクラス内容を記述します。
extends AppletはAppletクラスをスーパークラスとし、それを継承してShooting1クラスを作っています。
implements Runnable, KeyListenerは、Runnable, KeyListenerインターフェースをこのクラスで実装する、という意味です。
Shooting1クラス フィールド
- jiki : 自機の画像が入ったImageオブジェクト。
- jx, jy : 自機の(x,y)座標。
- keyLeft : 左キーの状態(false:押されていない true:押されている)を保持する変数。
- keyRight : 右キーの状態を保持する変数。
- gameThread : ゲームスレッド。
Shooting1クラス initメソッド
initメソッドはアプレットがブラウザに読み込まれたときに呼ばれるAppletクラスのメソッドです。Shooting1クラスはAppletクラスのinitメソッドをオーバーライドして独自の処理を実装しています。
jx = 134; jy = 352;
自機が最初に表示される座標をフィールド変数に代入しています。こういった最初に一度だけ行うべき処理はinitメソッドに書いておきます。
keyLeft = keyRight = false;
キーフラグをクリアしています。キーフラグは、そのキーが押されたときにtrueになる変数です。Javaではbooleanの初期値はfalseなので本来は初期化する必要はありませんが、書いた方が自分的に分かりやすいので記述しています。
setBackground(Color.black);
setForeground(Color.white);
シューティングゲームの宇宙空間ぽくするために、前景色(文字の色)を白、背景色を黒にしています。上記ふたつのメソッドはAppletクラスのメソッドです。Color.black, Color.whiteはColorクラスのクラス変数で、それぞれ黒と白を表します。
jiki = getImage(getDocumentBase(), "jiki.gif");
自機画像をImageクラスのオブジェクトjikiにセットします。getDocumentBaseメソッドはアプレットがあるURLを返します。
addKeyListener(this);
キーリスナーを設定します。キーリスナーというのは、キー入力があったときに「キー入力があったよ」と知らされるオブジェクトのことです。ここではthisを設定していますがこれは自分自身、つまりShooting1オブジェクトのことです。キーリスナーになったクラスは以下の3つのメソッドを実装しなければなりません。
-keyPressed … キーが押されたときに発生するメソッド
-keyReleased … キーが離されたときに発生するメソッド
-keyTyped … キーがタイプされたときに発生するメソッド
「タイプ」というのはキーを押して離すことです。
requestFocus();
ブラウザに対してフォーカスを要求します。アプレットにフォーカスを当てることによって初めてキー入力ができるようになります。フォーカスという概念について少し補足します。例えばテキスト入力ボックスが沢山あったときに、現在どのテキストボックスが書ける状態なのか?というのを表すのがフォーカスです。あるテキストボックスを書ける状態にすることを「フォーカスを当てる」と言います。requestFocusメソッドはブラウザに対して「フォーカスくださいよ」とお願いするだけなので、実際にフォーカスが貰えるかどうかはブラウザの挙動によって変わります。
Shooting1クラス startメソッド
startメソッドはアプレットが表示されたときに呼ばれるAppletクラスのメソッドです。まずブラウザにアプレットが読み込まれたときにinitメソッドが呼ばれ、アプレットが表示されるときにstartメソッドが呼ばれます。initメソッドは一度しか呼ばれませんが、startメソッドはブラウザを他のページに切り替えて戻ったときなど、何度も呼ばれる可能性があります。
startメソッドでは、ゲームの処理用のスレッドを作成して開始しています。Javaでは何もしなければアプレット用のメインスレッドひとつしか作られません。もしメインスレッドで全ての処理を行うとなると、ゲームの処理をしている間アプレットがやらなければならない処理が止まってしまいます。そこでゲームの処理だけを行うスレッドを専用で作ってやれば、メインスレッドが止まることもありません。
gameThread = new Thread(this);
この行でゲームスレッドオブジェクトを作成しています。
gameThread.start();
この行でゲームスレッドを開始しています。Shooting1クラス stopメソッド
stopメソッドはアプレットが停止したときに呼ばれるAppletクラスのメソッドです。ブラウザを他のページに切り替えたときなどに呼ばれます。
gameThread = null;
ゲームスレッドを停止するために、スレッド変数にnullを代入しています。Shooting1クラス runメソッド
runメソッドはスレッドのメイン処理部分です。runメソッドが終了した時点でスレッドは終了します。ここでゲーム処理部分を全て行います。
while (gameThread == Thread.currentThread()) {
Thread.currentThreadメソッドは現在のスレッドを返すメソッドです。ゲーム用のスレッドが動いている限りそれが現在のスレッドのはずなのでwhile文の条件は真になります。上記のstopメソッドが呼ばれたときにゲーム用スレッド変数にnullが代入され、whileループを抜けrunメソッドを終了します。
Thread.sleep(20);
20ミリ秒なにもせずに待ちます。自機を移動するだけだと速過ぎるのでここで待ち処理を行っています。
if (keyLeft) jx -= 8;
左キーが押されていたらX座標を-8しています。
if (keyRight) jx += 8;
右キーが押されていたらX座標を+8しています。
repaint();
画面の再描画を行います。ただ座標が動いただけでは画面に反映されません。このメソッドを呼ぶとアプレットに対して再描画をするように伝えることができます。Shooting1クラス keyPressedメソッド
キーボードのキーが押されたときの処理を行います。左キーが押されたときはkeyLeft、右キーが押されたときはkeyRight変数にtrueを代入しています。
switch (e.getKeyCode()) {
はKeyEventオブジェクトで、押されたキーの各種情報を持ちます。getKeyCodeメソッドによって押されたキーのキーコードを取得できます。Shooting1クラス keyReleasedメソッド
キーボードのキーが離されたときの処理を行います。左キーが押されたときはkeyLeft、右キーが押されたときはkeyRight変数にfalseを代入しています。
Shooting1クラス keyTypedメソッド
キーボードのキーがタイプされたときの処理を行います。中身はありませんが、これを実装しないとエラーがでるのでダミーで実装しています。
Shooting1クラス paintメソッド
アプレットが描画されるときに呼ばれるメソッドです。最初に表示されたとき・画面を最小化して戻したとき・他のウインドウに隠れていたのが表示されたとき・repaintメソッドを実行したとき、などに呼ばれます。
g.drawImage(jiki, jx, jy, this);
gはアプレットのGraphicsクラスのオブジェクトです。画面描画するときに便利なメソッドを沢山持っています。ここでは、drawImageメソッドによって自機画像を座標(jx, jy)に描画しています。