次の状況を想像してください
3つの画面があります。
- スプラッシュスクリーン(最初に表示されます);
- メニュー画面;
- ゲーム画面。
たとえば、気を散らすだけなので、宇宙戦のアニメーションを含む3Dゲームやメニューは作成しません。 各画面は次のアクションを実行します。
- 「スプラッシュ」画面-「スプラッシュ」というテキストを10秒間表示します。
- メニュー画面-「MENU」というテキストを10秒間表示します。
- 「ゲーム」画面-「ゲーム」というテキストが表示されます。
したがって、すでにこの情報を持っているので、画面には共通の抽象クラスを選択できます。その名前は「Screen」です。
すべての画面の共通点は何ですか?
- 各画面には独自の最大サイズがあります。
- 各画面には、描画用の独自のオブジェクトがあります。
- ディスプレイにインストールした後のみ画面に描画するため、一般的なイベントを特定できます。
- start-画面をDisplayに設定した後に呼び出されます。
すべての画面の抽象クラス。
public abstract class Screen extends GameCanvas { protected final int screenWidth; // protected final int screenHeight; // protected final Graphics graphics; // public Screen() { super(false); setFullScreenMode(true); screenWidth = getWidth(); screenHeight = getHeight(); graphics = getGraphics(); } //, , public abstract void start(); }
GameCanvasから共通のインターフェイスを継承し、それにいくつかの変更を加えました。
protected修飾子を使用して独自のフィールドを追加し、共通イベントを定義しました。
保護フィールドは子クラスのみを見ることができます。
メソッド定義の抽象は、メソッドが抽象であることを意味します。 つまり、メソッドの本体は記述しませんが、子孫がそれを実装していることは確かです(抽象的でない限り)。 メソッドに少なくとも1つの抽象メソッドが含まれる場合、クラスに抽象マークを付ける必要があります。そうでない場合、コンパイラーはエラーをスローします。
さらに、画面を作成すると、GameCanvasではなくScreenから継承します。 次の階層が得られます。
Object -> GameCanvas -> Screen -> MyScreen
Javaでは、すべてのクラスは暗黙的にObjectから継承されます。 画面は、クリックを描画および処理するための「キャンバス」のままにするために、GameCanvasから継承されます(ただし、すべてではありません)。 すべての画面は、共通のインターフェースを定義するためにScreenから継承します。 各クラスに同じことを書くことは完全に正しいとは限りません。別の構成のために共通のインターフェイスが必要になるためです。これについては後で学びます。
メインクラス
public class MIDletStructure extends MIDlet { public static MIDletStructure midlet; // private final Display display; public MIDletStructure() { midlet = this; display = Display.getDisplay(this); } // public void setCanvas(Screen canvas) { display.setCurrent(canvas); canvas.start(); } public void startApp() {} public void pauseApp() {} public void destroyApp(boolean unconditional) {} }
メインクラスでは、フィールドmidletとdisplayを定義します。 1つ目はそれ自体を指し、2つ目はディスプレイへのリンクです。 メインクラスと通信するには、ミッドレットリンクが必要です。 たとえば、アプリケーションをオフにするか、別の画面を設定します。これは後で行います。
setCanvasメソッドをより詳細に検討してください:setCanvasメソッドは、Screenから継承されたクラスへのリンクをパラメーターで受け入れます。ScreenはGameCanvasから継承されるため(これはDisplayableから継承されます)、ディスプレイに設定し、startメソッドを使用して開始します。 Screenの全体的なキャッチ-Screenから継承されたクラスのインスタンスを、それがメニュー画面であろうとゲームであろうとメソッドに渡すことができます。また、すべてのインスタンスにstartメソッドが実装されていることがわかっている共通インターフェースのおかげです。 これはすべてJavaのレイトバインディングのおかげで行われますが、そうでない場合はScreenの子孫クラスごとに個別のメソッドを記述する必要があります。
最初の画面
public class Splash extends Screen { //, , public void start() { graphics.setColor(0xFFFFFF); graphics.fillRect(0, 0, screenWidth, screenHeight); graphics.setColor(0x000000); graphics.drawString("SPLASH", 0, 0, 0); flushGraphics(); try { Thread.sleep(10000); } catch (InterruptedException interruptedException) { System.out.println(interruptedException.getMessage()); MIDletStructure.midlet.notifyDestroyed(); } } }
startメソッドでは、先祖クラスで初期化されたクラスを既に使用していることが簡単にわかります。
次に、ゲーム画面用の同様のクラスを作成します。
public class Game extends Screen { //, , public void start() { graphics.setColor(0xFFFFFF); graphics.fillRect(0, 0, screenWidth, screenHeight); graphics.setColor(0x000000); graphics.drawString("GAME", 0, 0, 0); flushGraphics(); while (true) { try { Thread.sleep(20); } catch (InterruptedException interruptedException) { System.out.println(interruptedException.getMessage()); MIDletStructure.midlet.notifyDestroyed(); } } } }
メインクラスの画面へのリンクを追加します。
public class MIDletStructure extends MIDlet { public static MIDletStructure midlet; // private final Display display; public final Screen splash; // “” public final Screen menu; // public final Screen game; // public MIDletStructure() { midlet = this; display = Display.getDisplay(this); splash = new Splash(); menu = new Menu(); game = new Game(); } // public void setCanvas(Screen canvas) { display.setCurrent(canvas); canvas.start(); } public void startApp() { // setCanvas(splash); } public void pauseApp() {} public void destroyApp(boolean unconditional) {} }
ミッドレットリンクに注目しましょう。リンクは統計的であり、パブリックであり、それが配置されているクラスのインスタンスを指します。 なぜこれが必要なのですか? publicは、プログラムのどこからでもリンクにアクセスできることを意味し、staticは、クラス(Main.midlet)を介してリンクにアクセスできることを意味します。また、すべての画面フィールドとsetCanvasメソッドもパブリックであるため、画面はどこでも置換できますプログラム:
Main.midlet.setCanvas(Main.midlet.game);
おわりに
最初の読み物の後、初心者はおそらく一語を理解できませんが、より思慮深い読み方をすれば、OOPテクノロジーを使用したアルゴリズムとその論理ソリューションのすべての単純さに気付くことができます。 この記事では、必要なすべてを詳しく説明しようとしましたが、まだ質問や不正確な点がある場合は、以下の完全なソースを見ることができます。
完全なソース