OSDN Git Service

初期インポート master
authoru6k.yu1 <u6k.yu1@gmail.com>
Sat, 30 Oct 2010 12:17:49 +0000 (21:17 +0900)
committeru6k.yu1 <u6k.yu1@gmail.com>
Sat, 30 Oct 2010 12:17:49 +0000 (21:17 +0900)
62 files changed:
state-engine/.classpath [new file with mode: 0644]
state-engine/.project [new file with mode: 0644]
state-engine/src/main/java/Main.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/animation/AbstractFpsListener.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/animation/AnimationListener.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/animation/AnimationWindow.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/animation/KeyInfo.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/animation/MouseInfo.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/animation/WaitListener.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/bar/BarCreateFadeoutState.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/bar/BarDrawState.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/bar/BarFadeoutDrawState.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/bar/BarFadeoutObject.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/bar/BarFadeoutTransition.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/bar/BarMoveState.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/bar/BarObject.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku1/EnemyBodyDrawState.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku1/EnemyBodyObject.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku1/EnemyBodyShotDanmakuState.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku1/EnemyBulletDisposedTransition.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku1/EnemyBulletDrawState.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku1/EnemyBulletMoveState.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku1/EnemyBulletObject.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku2/EnemyBodyDrawState.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku2/EnemyBodyObject.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku2/EnemyBodyShotDanmakuState.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku2/EnemyBulletDisposedTransition.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku2/EnemyBulletDrawState.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku2/EnemyBulletMoveState.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku2/EnemyBulletObject.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/moveChar1/PlayerDrawState.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/moveChar1/PlayerMoveState.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/moveChar1/PlayerObject.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/searcher1/BallDrawState.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/searcher1/BallMoveState.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/searcher1/BallObject.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/EnemyBulletDisposeTransition.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/EnemyBulletDrawState.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/EnemyBulletMoveState.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/EnemyBulletObject.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/EnemyDisposeTransition.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/EnemyDrawState.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/EnemyMoveState.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/EnemyObject.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/EnemyShotState.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/PlayerBulletAttackMessage.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/PlayerBulletDisposeTransition.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/PlayerBulletDrawState.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/PlayerBulletMoveState.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/PlayerBulletObject.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/PlayerDrawState.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/PlayerMoveState.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/PlayerObject.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/PlayerShotState.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/SceneObject.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/SceneState.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/state_engine/Message.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/state_engine/State.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/state_engine/StateContext.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/state_engine/StateEngine.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/state_engine/StateObject.java [new file with mode: 0644]
state-engine/src/main/java/jp/gr/java_conf/u6k/state_engine/Transition.java [new file with mode: 0644]

diff --git a/state-engine/.classpath b/state-engine/.classpath
new file mode 100644 (file)
index 0000000..1e6d54b
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+       <classpathentry kind="src" path="src/main/java"/>\r
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>\r
+       <classpathentry kind="output" path="bin"/>\r
+</classpath>\r
diff --git a/state-engine/.project b/state-engine/.project
new file mode 100644 (file)
index 0000000..1c2b45a
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>state-engine</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.jdt.core.javabuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.jdt.core.javanature</nature>\r
+       </natures>\r
+</projectDescription>\r
diff --git a/state-engine/src/main/java/Main.java b/state-engine/src/main/java/Main.java
new file mode 100644 (file)
index 0000000..d4bced9
--- /dev/null
@@ -0,0 +1,55 @@
+import jp.gr.java_conf.u6k.animation.AbstractFpsListener;\r
+import jp.gr.java_conf.u6k.animation.AnimationListener;\r
+import jp.gr.java_conf.u6k.animation.AnimationWindow;\r
+import jp.gr.java_conf.u6k.animation.WaitListener;\r
+import jp.gr.java_conf.u6k.sample.stg1.SceneObject;\r
+import jp.gr.java_conf.u6k.state_engine.StateEngine;\r
+\r
+// TODO オブジェクト間のメッセージ伝播。\r
+// TODO オブジェクト、状態、システム全体それぞれに値を持たせられるようにする。\r
+// TODO 状態コンテキストも継承実装にする。使用する型情報はどこで設定する?\r
+// TODO 状態遷移の外部情報化。\r
+// TODO 階層状態。\r
+// TODO 開始状態、終了状態、初期値の初期化方法、などなど、状態遷移マシンとしての設計をちゃんと考え直す必要がある。ALBPMはその辺、割と参考になる。\r
+// TODO State、StateObject、Transitionに遷移情報などを持たせてはならない。外部操作される可能性がある。\r
+// TODO オブジェクトのグループ化。\r
+// TODO もうちょっとスマートなオブジェクト管理。\r
+// TODO メモリの効率的な管理。\r
+// TODO エディタ。\r
+// TODO 全画面モード。\r
+// TODO 処理、描画の優先順位。\r
+// TODO リプレイ機能。ぶっちゃけ、入力のシミュレーション。\r
+// TODO 正確なシミュレーション。doubleは正確に再現できないんじゃ? 数値型を考える。\r
+// TODO フレームワーク・クラスのアクセス制御。\r
+\r
+public class Main {\r
+\r
+    public static void main(String[] args) throws Exception {\r
+        AnimationWindow w = new AnimationWindow(640, 480, "state-engine");\r
+        w.addAnimationListener(new AnimationListener() {\r
+\r
+            private StateEngine stateEngine;\r
+            {\r
+                this.stateEngine = new StateEngine(new SceneObject());\r
+            }\r
+\r
+            public void draw(AnimationWindow window) {\r
+                window.getCanvas().clearRect(0, 0, window.getWidth(), window.getHeight());\r
+\r
+                this.stateEngine.execute(window);\r
+            }\r
+\r
+        });\r
+        w.addAnimationListener(new WaitListener(60));\r
+        w.addAnimationListener(new AbstractFpsListener() {\r
+\r
+            @Override\r
+            public void elapsed(double fps) {\r
+                // System.out.println("fps: " + fps);\r
+            }\r
+\r
+        });\r
+        w.show();\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/animation/AbstractFpsListener.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/animation/AbstractFpsListener.java
new file mode 100644 (file)
index 0000000..1f5c6e4
--- /dev/null
@@ -0,0 +1,109 @@
+/*\r
+ * Copyright (C) 2007 u6k.yu1@gmail.com, All Rights Reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ *    1. Redistributions of source code must retain the above copyright\r
+ *       notice, this list of conditions and the following disclaimer.\r
+ *\r
+ *    2. Redistributions in binary form must reproduce the above copyright\r
+ *       notice, this list of conditions and the following disclaimer in the\r
+ *       documentation and/or other materials provided with the distribution.\r
+ *\r
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its\r
+ *       contributors may be used to endorse or promote products derived\r
+ *       from this software without prior written permission. For written\r
+ *       permission, please contact clarkware@clarkware.com.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\r
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL\r
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+package jp.gr.java_conf.u6k.animation;\r
+\r
+\r
+/**\r
+ * <p>\r
+ * FPSを測定するリスナーです。1秒ごとに{@link #elapsed(double)}メソッドが呼び出され、計測したFPSが渡されます。\r
+ * </p>\r
+ * \r
+ * @version $Id$\r
+ */\r
+public abstract class AbstractFpsListener implements AnimationListener {\r
+\r
+    /**\r
+     * <p>\r
+     * 1秒のナノ秒数。\r
+     * </p>\r
+     */\r
+    private static final double NANO_SECONDS = 1000000000;\r
+\r
+    /**\r
+     * <p>\r
+     * 基準時刻。この時刻と現在時刻の差を見て、1秒経過したかどうかを測定します。\r
+     * </p>\r
+     */\r
+    private long                time;\r
+\r
+    /**\r
+     * <p>\r
+     * 計測中の処理回数。\r
+     * </p>\r
+     */\r
+    private int                 count;\r
+\r
+    /**\r
+     * <p>\r
+     * 前回計測したFPS。\r
+     * </p>\r
+     */\r
+    private double              fps;\r
+\r
+    /**\r
+     * <p>\r
+     * 前回計測したFPSを返します。\r
+     * </p>\r
+     * \r
+     * @return 前回計測したFPS。\r
+     */\r
+    public final double getFps() {\r
+        return this.fps;\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    public final void draw(AnimationWindow window) {\r
+        this.count++;\r
+\r
+        double elapsedTime = (double) (System.nanoTime() - this.time) / AbstractFpsListener.NANO_SECONDS;\r
+        if (elapsedTime > 1) {\r
+            this.fps = (double) this.count / elapsedTime;\r
+            this.elapsed(this.fps);\r
+\r
+            this.time = System.nanoTime();\r
+            this.count = 0;\r
+        }\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * 1秒間が経過したときに呼び出され、計測したFPSが渡されます。\r
+     * </p>\r
+     * \r
+     * @param fps\r
+     *            計測したFPS。\r
+     */\r
+    public abstract void elapsed(double fps);\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/animation/AnimationListener.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/animation/AnimationListener.java
new file mode 100644 (file)
index 0000000..76e3f8e
--- /dev/null
@@ -0,0 +1,54 @@
+/*\r
+ * Copyright (C) 2007 u6k.yu1@gmail.com, All Rights Reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ *    1. Redistributions of source code must retain the above copyright\r
+ *       notice, this list of conditions and the following disclaimer.\r
+ *\r
+ *    2. Redistributions in binary form must reproduce the above copyright\r
+ *       notice, this list of conditions and the following disclaimer in the\r
+ *       documentation and/or other materials provided with the distribution.\r
+ *\r
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its\r
+ *       contributors may be used to endorse or promote products derived\r
+ *       from this software without prior written permission. For written\r
+ *       permission, please contact clarkware@clarkware.com.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\r
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL\r
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+package jp.gr.java_conf.u6k.animation;\r
+\r
+\r
+/**\r
+ * <p>\r
+ * {@link AnimationWindow}コンポーネントでアニメーション処理を行うためのリスナーを表します。\r
+ * </p>\r
+ * \r
+ * @version $Id$\r
+ */\r
+public interface AnimationListener {\r
+\r
+    /**\r
+     * <p>\r
+     * {@link AnimationWindow}コンポーネントにより、1FPSごとに呼び出されます。{@link AnimationWindow}コンポーネント・インスタンスが渡されるので、アニメーション処理を行います。\r
+     * </p>\r
+     * \r
+     * @param window\r
+     *            {@link AnimationWindow}コンポーネント・インスタンス。ウィンドウの情報を取得、設定することができます。\r
+     */\r
+    void draw(AnimationWindow window);\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/animation/AnimationWindow.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/animation/AnimationWindow.java
new file mode 100644 (file)
index 0000000..af9bee6
--- /dev/null
@@ -0,0 +1,404 @@
+/*\r
+ * Copyright (C) 2007 u6k.yu1@gmail.com, All Rights Reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ *    1. Redistributions of source code must retain the above copyright\r
+ *       notice, this list of conditions and the following disclaimer.\r
+ *\r
+ *    2. Redistributions in binary form must reproduce the above copyright\r
+ *       notice, this list of conditions and the following disclaimer in the\r
+ *       documentation and/or other materials provided with the distribution.\r
+ *\r
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its\r
+ *       contributors may be used to endorse or promote products derived\r
+ *       from this software without prior written permission. For written\r
+ *       permission, please contact clarkware@clarkware.com.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\r
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL\r
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+package jp.gr.java_conf.u6k.animation;\r
+\r
+import java.awt.Color;\r
+import java.awt.Graphics2D;\r
+import java.awt.event.KeyEvent;\r
+import java.awt.event.KeyListener;\r
+import java.awt.event.MouseEvent;\r
+import java.awt.event.MouseListener;\r
+import java.awt.event.MouseMotionListener;\r
+import java.awt.event.WindowEvent;\r
+import java.awt.event.WindowListener;\r
+import java.awt.image.BufferStrategy;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import javax.swing.JFrame;\r
+\r
+/**\r
+ * <p>\r
+ * アニメーションを行うウィンドウを表します。\r
+ * </p>\r
+ * \r
+ * @version $Id$\r
+ */\r
+public final class AnimationWindow {\r
+\r
+    /**\r
+     * <p>\r
+     * ウィンドウが閉じたかどうか。\r
+     * </p>\r
+     */\r
+    private boolean                 closed;\r
+\r
+    /**\r
+     * <p>\r
+     * ウィンドウの表示領域の横幅。\r
+     * </p>\r
+     */\r
+    private int                     width;\r
+\r
+    /**\r
+     * <p>\r
+     * ウィンドウの表示領域の縦幅。\r
+     * </p>\r
+     */\r
+    private int                     height;\r
+\r
+    /**\r
+     * <p>\r
+     * ウィンドウへの表示などの処理を行うリスナー。\r
+     * </p>\r
+     */\r
+    private List<AnimationListener> listeners = new ArrayList<AnimationListener>();\r
+\r
+    /**\r
+     * <p>\r
+     * ウィンドウ。\r
+     * </p>\r
+     */\r
+    private JFrame                  frame     = new JFrame();\r
+\r
+    /**\r
+     * <p>\r
+     * 描画用のキャンバス。\r
+     * </p>\r
+     */\r
+    private Graphics2D              g;\r
+\r
+    /**\r
+     * <p>\r
+     * マウス情報。\r
+     * </p>\r
+     */\r
+    private MouseInfo               mouseInfo = new MouseInfo();\r
+\r
+    /**\r
+     * <p>\r
+     * キーボード情報。\r
+     * </p>\r
+     */\r
+    private KeyInfo                 keyInfo   = new KeyInfo();\r
+\r
+    /**\r
+     * <p>\r
+     * ウィンドウを初期化します。\r
+     * </p>\r
+     * \r
+     * @param width\r
+     *            ウィンドウの表示領域の横幅。\r
+     * @param height\r
+     *            ウィンドウの表示領域の縦幅。\r
+     * @param title\r
+     *            ウィンドウのタイトル。\r
+     */\r
+    public AnimationWindow(int width, int height, String title) {\r
+        this.width = width;\r
+        this.height = height;\r
+\r
+        this.frame.setTitle(title);\r
+\r
+        this.setBackgroundColor(Color.BLACK);\r
+        this.setForegroundColor(Color.WHITE);\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * ウィンドウの横幅を返します。\r
+     * </p>\r
+     * \r
+     * @return ウィンドウの横幅。\r
+     */\r
+    public int getWidth() {\r
+        return this.width;\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * ウィンドウの縦幅を返します。\r
+     * </p>\r
+     * \r
+     * @return ウィンドウの縦幅。\r
+     */\r
+    public int getHeight() {\r
+        return this.height;\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * ウィンドウのタイトルを返します。\r
+     * </p>\r
+     * \r
+     * @return ウィンドウのタイトル。\r
+     */\r
+    public String getTitle() {\r
+        return this.frame.getTitle();\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * 背景色を返します。\r
+     * </p>\r
+     * \r
+     * @return 背景色。\r
+     */\r
+    public Color getBackgroundColor() {\r
+        return this.frame.getBackground();\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * 背景色を設定します。\r
+     * </p>\r
+     * \r
+     * @param backgroundColor\r
+     *            背景色。\r
+     */\r
+    public void setBackgroundColor(Color backgroundColor) {\r
+        this.frame.setBackground(backgroundColor);\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * 前景色を返します。\r
+     * </p>\r
+     * \r
+     * @return 前景色。\r
+     */\r
+    public Color getForegroundColor() {\r
+        return this.frame.getForeground();\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * 前景色を設定します。\r
+     * </p>\r
+     * \r
+     * @param foregroundColor\r
+     *            前景色。\r
+     */\r
+    public void setForegroundColor(Color foregroundColor) {\r
+        this.frame.setForeground(foregroundColor);\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * 描画用のキャンバスを返します。このメソッドは{@link AnimationListener}実装クラスにより呼び出されることを想定しています。\r
+     * </p>\r
+     * \r
+     * @return 描画用のキャンバス。\r
+     */\r
+    public Graphics2D getCanvas() {\r
+        return this.g;\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * マウス情報を返します。\r
+     * </p>\r
+     * \r
+     * @return マウス情報。\r
+     */\r
+    public MouseInfo getMouseInfo() {\r
+        return this.mouseInfo;\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * キーボード情報を返します。\r
+     * </p>\r
+     * \r
+     * @return キーボード情報。\r
+     */\r
+    public KeyInfo getKeyInfo() {\r
+        return this.keyInfo;\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * アニメーション・リスナーを追加します。\r
+     * </p>\r
+     * \r
+     * @param l\r
+     *            アニメーション・リスナー。\r
+     */\r
+    public void addAnimationListener(AnimationListener l) {\r
+        if (l != null) {\r
+            this.listeners.add(l);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * アニメーション・リスナーを削除します。\r
+     * </p>\r
+     * \r
+     * @param l\r
+     *            アニメーション・リスナー。\r
+     */\r
+    public void removeAnimationListener(AnimationListener l) {\r
+        this.listeners.remove(l);\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * ウィンドウを閉じます。\r
+     * </p>\r
+     */\r
+    public void close() {\r
+        this.closed = true;\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * ウィンドウを表示し、アニメーションを開始します。\r
+     * </p>\r
+     */\r
+    public void show() {\r
+        try {\r
+            this.frame.addMouseListener(new MouseListener() {\r
+\r
+                public void mouseClicked(MouseEvent e) {\r
+                }\r
+\r
+                public void mouseEntered(MouseEvent e) {\r
+                }\r
+\r
+                public void mouseExited(MouseEvent e) {\r
+                }\r
+\r
+                public void mousePressed(MouseEvent e) {\r
+                    if (e.getButton() == MouseEvent.BUTTON1) {\r
+                        AnimationWindow.this.mouseInfo.setLeftButton(true);\r
+                    } else if (e.getButton() == MouseEvent.BUTTON3) {\r
+                        AnimationWindow.this.mouseInfo.setRightButton(true);\r
+                    }\r
+                }\r
+\r
+                public void mouseReleased(MouseEvent e) {\r
+                    if (e.getButton() == MouseEvent.BUTTON1) {\r
+                        AnimationWindow.this.mouseInfo.setLeftButton(false);\r
+                    } else if (e.getButton() == MouseEvent.BUTTON3) {\r
+                        AnimationWindow.this.mouseInfo.setRightButton(false);\r
+                    }\r
+                }\r
+\r
+            });\r
+\r
+            this.frame.addKeyListener(new KeyListener() {\r
+\r
+                public void keyPressed(KeyEvent e) {\r
+                    AnimationWindow.this.keyInfo.setKey(e.getKeyCode(), true);\r
+                }\r
+\r
+                public void keyReleased(KeyEvent e) {\r
+                    AnimationWindow.this.keyInfo.setKey(e.getKeyCode(), false);\r
+                }\r
+\r
+                public void keyTyped(KeyEvent e) {\r
+                }\r
+\r
+            });\r
+\r
+            this.frame.addMouseMotionListener(new MouseMotionListener() {\r
+\r
+                public void mouseDragged(MouseEvent e) {\r
+                    AnimationWindow.this.mouseInfo.setX(e.getX() - AnimationWindow.this.frame.getInsets().left);\r
+                    AnimationWindow.this.mouseInfo.setY(e.getY() - AnimationWindow.this.frame.getInsets().top);\r
+                }\r
+\r
+                public void mouseMoved(MouseEvent e) {\r
+                    AnimationWindow.this.mouseInfo.setX(e.getX() - AnimationWindow.this.frame.getInsets().left);\r
+                    AnimationWindow.this.mouseInfo.setY(e.getY() - AnimationWindow.this.frame.getInsets().top);\r
+                }\r
+\r
+            });\r
+\r
+            this.frame.addWindowListener(new WindowListener() {\r
+\r
+                public void windowOpened(WindowEvent event) {\r
+                }\r
+\r
+                public void windowClosing(WindowEvent event) {\r
+                    AnimationWindow.this.closed = true;\r
+                }\r
+\r
+                public void windowClosed(WindowEvent event) {\r
+                }\r
+\r
+                public void windowIconified(WindowEvent event) {\r
+                }\r
+\r
+                public void windowDeiconified(WindowEvent event) {\r
+                }\r
+\r
+                public void windowActivated(WindowEvent event) {\r
+                }\r
+\r
+                public void windowDeactivated(WindowEvent event) {\r
+                }\r
+\r
+            });\r
+\r
+            this.frame.setVisible(true);\r
+\r
+            int l = this.frame.getInsets().left;\r
+            int t = this.frame.getInsets().top;\r
+            int r = this.frame.getInsets().right;\r
+            int b = this.frame.getInsets().bottom;\r
+\r
+            this.frame.setSize(l + r + this.width, t + b + this.height);\r
+            this.frame.setResizable(false);\r
+\r
+            this.frame.createBufferStrategy(2);\r
+            BufferStrategy bs = this.frame.getBufferStrategy();\r
+            while (!this.closed) {\r
+                this.g = (Graphics2D) bs.getDrawGraphics();\r
+                try {\r
+                    this.g.translate(l, t);\r
+                    this.g.setClip(0, 0, this.width, this.height);\r
+                    for (AnimationListener listener : this.listeners) {\r
+                        listener.draw(this);\r
+                    }\r
+                    bs.show();\r
+                } finally {\r
+                    this.g.dispose();\r
+                }\r
+            }\r
+        } finally {\r
+            this.frame.dispose();\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/animation/KeyInfo.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/animation/KeyInfo.java
new file mode 100644 (file)
index 0000000..8f67e9c
--- /dev/null
@@ -0,0 +1,22 @@
+\r
+package jp.gr.java_conf.u6k.animation;\r
+\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+public class KeyInfo {\r
+\r
+    private Map<Integer, Boolean> keyMap = new HashMap<Integer, Boolean>();\r
+\r
+    public boolean isKey(int keyCode) {\r
+        if (!this.keyMap.containsKey(keyCode)) {\r
+            return false;\r
+        }\r
+        return this.keyMap.get(keyCode);\r
+    }\r
+\r
+    public void setKey(int keyCode, boolean keyState) {\r
+        this.keyMap.put(keyCode, keyState);\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/animation/MouseInfo.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/animation/MouseInfo.java
new file mode 100644 (file)
index 0000000..1d27503
--- /dev/null
@@ -0,0 +1,46 @@
+\r
+package jp.gr.java_conf.u6k.animation;\r
+\r
+public class MouseInfo {\r
+\r
+    private int     x;\r
+\r
+    private int     y;\r
+\r
+    private boolean leftButton;\r
+\r
+    private boolean rightButton;\r
+\r
+    public int getX() {\r
+        return this.x;\r
+    }\r
+\r
+    public void setX(int x) {\r
+        this.x = x;\r
+    }\r
+\r
+    public int getY() {\r
+        return this.y;\r
+    }\r
+\r
+    public void setY(int y) {\r
+        this.y = y;\r
+    }\r
+\r
+    public boolean isLeftButton() {\r
+        return this.leftButton;\r
+    }\r
+\r
+    public void setLeftButton(boolean leftButton) {\r
+        this.leftButton = leftButton;\r
+    }\r
+\r
+    public boolean isRightButton() {\r
+        return this.rightButton;\r
+    }\r
+\r
+    public void setRightButton(boolean rightButton) {\r
+        this.rightButton = rightButton;\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/animation/WaitListener.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/animation/WaitListener.java
new file mode 100644 (file)
index 0000000..5ee371a
--- /dev/null
@@ -0,0 +1,87 @@
+/*\r
+ * Copyright (C) 2007 u6k.yu1@gmail.com, All Rights Reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ *    1. Redistributions of source code must retain the above copyright\r
+ *       notice, this list of conditions and the following disclaimer.\r
+ *\r
+ *    2. Redistributions in binary form must reproduce the above copyright\r
+ *       notice, this list of conditions and the following disclaimer in the\r
+ *       documentation and/or other materials provided with the distribution.\r
+ *\r
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its\r
+ *       contributors may be used to endorse or promote products derived\r
+ *       from this software without prior written permission. For written\r
+ *       permission, please contact clarkware@clarkware.com.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\r
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL\r
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+package jp.gr.java_conf.u6k.animation;\r
+\r
+\r
+/**\r
+ * <p>\r
+ * FPSを調整するリスナーです。\r
+ * </p>\r
+ * \r
+ * @version $Id$\r
+ */\r
+public final class WaitListener implements AnimationListener {\r
+\r
+    /**\r
+     * <p>\r
+     * 1秒のナノ秒数。\r
+     * </p>\r
+     */\r
+    private static final long NANO_SECONDS = 1000000000;\r
+\r
+    /**\r
+     * <p>\r
+     * 1FPSのミリ秒数。\r
+     * </p>\r
+     */\r
+    private long              waitTime;\r
+\r
+    /**\r
+     * <p>\r
+     * 次に処理を行う時刻(ミリ秒)。\r
+     * </p>\r
+     */\r
+    private long              nextTime;\r
+\r
+    /**\r
+     * <p>\r
+     * FPSを指定して、インスタンスを初期化します。\r
+     * </p>\r
+     * \r
+     * @param fps\r
+     *            FPS。\r
+     */\r
+    public WaitListener(int fps) {\r
+        this.waitTime = WaitListener.NANO_SECONDS / fps;\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    public void draw(AnimationWindow window) {\r
+        while (this.nextTime > System.nanoTime()) {\r
+            Thread.yield();\r
+        }\r
+        this.nextTime = System.nanoTime() + this.waitTime;\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/bar/BarCreateFadeoutState.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/bar/BarCreateFadeoutState.java
new file mode 100644 (file)
index 0000000..2ba6ee5
--- /dev/null
@@ -0,0 +1,32 @@
+\r
+package jp.gr.java_conf.u6k.sample.bar;\r
+\r
+import jp.gr.java_conf.u6k.state_engine.Message;\r
+import jp.gr.java_conf.u6k.state_engine.State;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+\r
+public class BarCreateFadeoutState extends State {\r
+\r
+    @Override\r
+    public void dispose(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void execute(StateContext ctx) {\r
+        BarObject obj = (BarObject) ctx.getTarget();\r
+\r
+        if (obj.getTime() % 10 == 0) {\r
+            BarFadeoutObject fadeout = new BarFadeoutObject(obj.getX(), obj.getY());\r
+            ctx.addStateObject(fadeout);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void receiveMessage(StateContext ctx, Message msg) {\r
+    }\r
+\r
+    @Override\r
+    public void initialize(StateContext ctx) {\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/bar/BarDrawState.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/bar/BarDrawState.java
new file mode 100644 (file)
index 0000000..0927d2d
--- /dev/null
@@ -0,0 +1,39 @@
+\r
+package jp.gr.java_conf.u6k.sample.bar;\r
+\r
+import java.awt.Graphics2D;\r
+\r
+import jp.gr.java_conf.u6k.animation.AnimationWindow;\r
+import jp.gr.java_conf.u6k.state_engine.Message;\r
+import jp.gr.java_conf.u6k.state_engine.State;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+\r
+public class BarDrawState extends State {\r
+\r
+    @Override\r
+    public void dispose(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void execute(StateContext ctx) {\r
+        // 取得\r
+        BarObject obj = (BarObject) ctx.getTarget();\r
+        AnimationWindow window = (AnimationWindow) ctx.getValueMap().get("window");\r
+        Graphics2D g = window.getCanvas();\r
+\r
+        double x = obj.getX();\r
+        double y = obj.getY();\r
+\r
+        // 描画\r
+        g.fillOval((int) x, (int) y, 20, 20);\r
+    }\r
+\r
+    @Override\r
+    public void receiveMessage(StateContext ctx, Message msg) {\r
+    }\r
+\r
+    @Override\r
+    public void initialize(StateContext ctx) {\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/bar/BarFadeoutDrawState.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/bar/BarFadeoutDrawState.java
new file mode 100644 (file)
index 0000000..734b394
--- /dev/null
@@ -0,0 +1,45 @@
+\r
+package jp.gr.java_conf.u6k.sample.bar;\r
+\r
+import java.awt.Color;\r
+import java.awt.Graphics2D;\r
+\r
+import jp.gr.java_conf.u6k.animation.AnimationWindow;\r
+import jp.gr.java_conf.u6k.state_engine.Message;\r
+import jp.gr.java_conf.u6k.state_engine.State;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+\r
+public class BarFadeoutDrawState extends State {\r
+\r
+    @Override\r
+    public void dispose(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void execute(StateContext ctx) {\r
+        // 取得\r
+        BarFadeoutObject obj = (BarFadeoutObject) ctx.getTarget();\r
+        AnimationWindow window = (AnimationWindow) ctx.getValueMap().get("window");\r
+        Graphics2D g = window.getCanvas();\r
+\r
+        double x = obj.getX();\r
+        double y = obj.getY();\r
+\r
+        // 計算、描画\r
+        int c = 255 - (int) (255d / 60 * obj.getTime());\r
+        Color color = new Color(c, c, c);\r
+\r
+        g.setColor(color);\r
+        g.fillOval((int) x, (int) y, 20, 20);\r
+        g.setColor(Color.BLACK);\r
+    }\r
+\r
+    @Override\r
+    public void receiveMessage(StateContext ctx, Message msg) {\r
+    }\r
+\r
+    @Override\r
+    public void initialize(StateContext ctx) {\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/bar/BarFadeoutObject.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/bar/BarFadeoutObject.java
new file mode 100644 (file)
index 0000000..681642c
--- /dev/null
@@ -0,0 +1,42 @@
+\r
+package jp.gr.java_conf.u6k.sample.bar;\r
+\r
+import jp.gr.java_conf.u6k.state_engine.StateObject;\r
+\r
+@SuppressWarnings("serial")\r
+public class BarFadeoutObject extends StateObject {\r
+\r
+    private double x;\r
+\r
+    private double y;\r
+\r
+    public BarFadeoutObject(double x, double y) {\r
+        BarFadeoutDrawState s = new BarFadeoutDrawState();\r
+\r
+        BarFadeoutTransition t = new BarFadeoutTransition();\r
+\r
+        s.getDestinationTransitionList().add(t);\r
+\r
+        this.getStateList().add(s);\r
+\r
+        this.x = x;\r
+        this.y = y;\r
+    }\r
+\r
+    public double getX() {\r
+        return this.x;\r
+    }\r
+\r
+    public void setX(double x) {\r
+        this.x = x;\r
+    }\r
+\r
+    public double getY() {\r
+        return this.y;\r
+    }\r
+\r
+    public void setY(double y) {\r
+        this.y = y;\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/bar/BarFadeoutTransition.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/bar/BarFadeoutTransition.java
new file mode 100644 (file)
index 0000000..ffc6a03
--- /dev/null
@@ -0,0 +1,15 @@
+\r
+package jp.gr.java_conf.u6k.sample.bar;\r
+\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+import jp.gr.java_conf.u6k.state_engine.StateObject;\r
+import jp.gr.java_conf.u6k.state_engine.Transition;\r
+\r
+public class BarFadeoutTransition extends Transition {\r
+\r
+    @Override\r
+    public boolean condition(StateObject obj, StateContext ctx) {\r
+        return obj.getTime() == 60;\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/bar/BarMoveState.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/bar/BarMoveState.java
new file mode 100644 (file)
index 0000000..0f9c0fd
--- /dev/null
@@ -0,0 +1,50 @@
+\r
+package jp.gr.java_conf.u6k.sample.bar;\r
+\r
+import jp.gr.java_conf.u6k.state_engine.Message;\r
+import jp.gr.java_conf.u6k.state_engine.State;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+\r
+public class BarMoveState extends State {\r
+\r
+    @Override\r
+    public void dispose(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void execute(StateContext ctx) {\r
+        // 取得\r
+        BarObject obj = (BarObject) ctx.getTarget();\r
+\r
+        double angle = obj.getAngle();\r
+        double speed = obj.getSpeed();\r
+        double centerX = obj.getCenterX();\r
+        double centerY = obj.getCenterY();\r
+        double x = obj.getX();\r
+        double y = obj.getY();\r
+        double length = obj.getLength();\r
+\r
+        // 計算\r
+        x = length * Math.cos(angle) + centerX;\r
+        y = length * Math.sin(angle) + centerY;\r
+\r
+        angle += speed;\r
+        if (angle > (2 * Math.PI)) {\r
+            angle -= 2 * Math.PI;\r
+        }\r
+\r
+        // 設定\r
+        obj.setX(x);\r
+        obj.setY(y);\r
+        obj.setAngle(angle);\r
+    }\r
+\r
+    @Override\r
+    public void receiveMessage(StateContext ctx, Message msg) {\r
+    }\r
+\r
+    @Override\r
+    public void initialize(StateContext ctx) {\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/bar/BarObject.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/bar/BarObject.java
new file mode 100644 (file)
index 0000000..6a9dbad
--- /dev/null
@@ -0,0 +1,90 @@
+\r
+package jp.gr.java_conf.u6k.sample.bar;\r
+\r
+import jp.gr.java_conf.u6k.state_engine.StateObject;\r
+\r
+@SuppressWarnings("serial")\r
+public class BarObject extends StateObject {\r
+\r
+    private double angle   = 0;\r
+\r
+    private double speed   = 0.01 * Math.PI;\r
+\r
+    private double centerX = 100;\r
+\r
+    private double centerY = 100;\r
+\r
+    private double x       = 0;\r
+\r
+    private double y       = 0;\r
+\r
+    private double length  = 100;\r
+\r
+    public BarObject() {\r
+        BarMoveState moveState = new BarMoveState();\r
+        this.getStateList().add(moveState);\r
+\r
+        BarDrawState drawState = new BarDrawState();\r
+        this.getStateList().add(drawState);\r
+\r
+        BarCreateFadeoutState createState = new BarCreateFadeoutState();\r
+        this.getStateList().add(createState);\r
+    }\r
+\r
+    public double getAngle() {\r
+        return this.angle;\r
+    }\r
+\r
+    public void setAngle(double angle) {\r
+        this.angle = angle;\r
+    }\r
+\r
+    public double getSpeed() {\r
+        return this.speed;\r
+    }\r
+\r
+    public void setSpeed(double speed) {\r
+        this.speed = speed;\r
+    }\r
+\r
+    public double getCenterX() {\r
+        return this.centerX;\r
+    }\r
+\r
+    public void setCenterX(double centerX) {\r
+        this.centerX = centerX;\r
+    }\r
+\r
+    public double getCenterY() {\r
+        return this.centerY;\r
+    }\r
+\r
+    public void setCenterY(double centerY) {\r
+        this.centerY = centerY;\r
+    }\r
+\r
+    public double getX() {\r
+        return this.x;\r
+    }\r
+\r
+    public void setX(double x) {\r
+        this.x = x;\r
+    }\r
+\r
+    public double getY() {\r
+        return this.y;\r
+    }\r
+\r
+    public void setY(double y) {\r
+        this.y = y;\r
+    }\r
+\r
+    public double getLength() {\r
+        return this.length;\r
+    }\r
+\r
+    public void setLength(double length) {\r
+        this.length = length;\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku1/EnemyBodyDrawState.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku1/EnemyBodyDrawState.java
new file mode 100644 (file)
index 0000000..aa02f46
--- /dev/null
@@ -0,0 +1,39 @@
+\r
+package jp.gr.java_conf.u6k.sample.danmaku1;\r
+\r
+import java.awt.Graphics2D;\r
+\r
+import jp.gr.java_conf.u6k.animation.AnimationWindow;\r
+import jp.gr.java_conf.u6k.state_engine.Message;\r
+import jp.gr.java_conf.u6k.state_engine.State;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+\r
+public class EnemyBodyDrawState extends State {\r
+\r
+    @Override\r
+    public void dispose(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void execute(StateContext ctx) {\r
+        // 取得\r
+        EnemyBodyObject obj = (EnemyBodyObject) ctx.getTarget();\r
+        AnimationWindow window = (AnimationWindow) ctx.getValueMap().get("window");\r
+        Graphics2D g = window.getCanvas();\r
+\r
+        double x = obj.getX();\r
+        double y = obj.getY();\r
+\r
+        // 描画\r
+        g.fillOval((int) x, (int) y, 20, 20);\r
+    }\r
+\r
+    @Override\r
+    public void receiveMessage(StateContext ctx, Message msg) {\r
+    }\r
+\r
+    @Override\r
+    public void initialize(StateContext ctx) {\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku1/EnemyBodyObject.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku1/EnemyBodyObject.java
new file mode 100644 (file)
index 0000000..d719fba
--- /dev/null
@@ -0,0 +1,40 @@
+\r
+package jp.gr.java_conf.u6k.sample.danmaku1;\r
+\r
+import jp.gr.java_conf.u6k.state_engine.StateObject;\r
+\r
+@SuppressWarnings("serial")\r
+public class EnemyBodyObject extends StateObject {\r
+\r
+    private double x;\r
+\r
+    private double y;\r
+\r
+    public EnemyBodyObject(double x, double y) {\r
+        EnemyBodyShotDanmakuState shotState = new EnemyBodyShotDanmakuState();\r
+        this.getStateList().add(shotState);\r
+\r
+        EnemyBodyDrawState drawState = new EnemyBodyDrawState();\r
+        this.getStateList().add(drawState);\r
+\r
+        this.x = x;\r
+        this.y = y;\r
+    }\r
+\r
+    public double getX() {\r
+        return this.x;\r
+    }\r
+\r
+    public void setX(double x) {\r
+        this.x = x;\r
+    }\r
+\r
+    public double getY() {\r
+        return this.y;\r
+    }\r
+\r
+    public void setY(double y) {\r
+        this.y = y;\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku1/EnemyBodyShotDanmakuState.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku1/EnemyBodyShotDanmakuState.java
new file mode 100644 (file)
index 0000000..7115c1f
--- /dev/null
@@ -0,0 +1,40 @@
+\r
+package jp.gr.java_conf.u6k.sample.danmaku1;\r
+\r
+import jp.gr.java_conf.u6k.state_engine.Message;\r
+import jp.gr.java_conf.u6k.state_engine.State;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+\r
+public class EnemyBodyShotDanmakuState extends State {\r
+\r
+    @Override\r
+    public void dispose(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void execute(StateContext ctx) {\r
+        // 取得\r
+        EnemyBodyObject obj = (EnemyBodyObject) ctx.getTarget();\r
+\r
+        double x = obj.getX();\r
+        double y = obj.getY();\r
+\r
+        // 弾幕発射\r
+        for (int i = 0; i < 1; i++) {\r
+            double speed = 5;\r
+            double angle = Math.random() * 2.0 * Math.PI / 20 - 2.0 * Math.PI / 40;\r
+\r
+            EnemyBulletObject bullet = new EnemyBulletObject(x, y, angle, speed);\r
+            ctx.addStateObject(bullet);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void receiveMessage(StateContext ctx, Message msg) {\r
+    }\r
+\r
+    @Override\r
+    public void initialize(StateContext ctx) {\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku1/EnemyBulletDisposedTransition.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku1/EnemyBulletDisposedTransition.java
new file mode 100644 (file)
index 0000000..fff6a35
--- /dev/null
@@ -0,0 +1,24 @@
+\r
+package jp.gr.java_conf.u6k.sample.danmaku1;\r
+\r
+import jp.gr.java_conf.u6k.animation.AnimationWindow;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+import jp.gr.java_conf.u6k.state_engine.StateObject;\r
+import jp.gr.java_conf.u6k.state_engine.Transition;\r
+\r
+public class EnemyBulletDisposedTransition extends Transition {\r
+\r
+    @Override\r
+    public boolean condition(StateObject obj, StateContext ctx) {\r
+        // 取得\r
+        EnemyBulletObject o = (EnemyBulletObject) obj;\r
+        AnimationWindow window = (AnimationWindow) ctx.getValueMap().get("window");\r
+\r
+        double x = o.getX();\r
+        double y = o.getY();\r
+\r
+        // 判断\r
+        return (x < 0) || (x > window.getWidth()) || (y < 0) || (y > window.getHeight());\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku1/EnemyBulletDrawState.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku1/EnemyBulletDrawState.java
new file mode 100644 (file)
index 0000000..42b8619
--- /dev/null
@@ -0,0 +1,39 @@
+\r
+package jp.gr.java_conf.u6k.sample.danmaku1;\r
+\r
+import java.awt.Graphics2D;\r
+\r
+import jp.gr.java_conf.u6k.animation.AnimationWindow;\r
+import jp.gr.java_conf.u6k.state_engine.Message;\r
+import jp.gr.java_conf.u6k.state_engine.State;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+\r
+public class EnemyBulletDrawState extends State {\r
+\r
+    @Override\r
+    public void dispose(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void execute(StateContext ctx) {\r
+        // 取得\r
+        EnemyBulletObject obj = (EnemyBulletObject) ctx.getTarget();\r
+        AnimationWindow window = (AnimationWindow) ctx.getValueMap().get("window");\r
+        Graphics2D g = window.getCanvas();\r
+\r
+        double x = obj.getX();\r
+        double y = obj.getY();\r
+\r
+        // 描画\r
+        g.fillOval((int) x, (int) y, 5, 5);\r
+    }\r
+\r
+    @Override\r
+    public void receiveMessage(StateContext ctx, Message msg) {\r
+    }\r
+\r
+    @Override\r
+    public void initialize(StateContext ctx) {\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku1/EnemyBulletMoveState.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku1/EnemyBulletMoveState.java
new file mode 100644 (file)
index 0000000..af74e26
--- /dev/null
@@ -0,0 +1,41 @@
+\r
+package jp.gr.java_conf.u6k.sample.danmaku1;\r
+\r
+import jp.gr.java_conf.u6k.state_engine.Message;\r
+import jp.gr.java_conf.u6k.state_engine.State;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+\r
+public class EnemyBulletMoveState extends State {\r
+\r
+    @Override\r
+    public void dispose(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void execute(StateContext ctx) {\r
+        // 取得\r
+        EnemyBulletObject obj = (EnemyBulletObject) ctx.getTarget();\r
+\r
+        double x = obj.getX();\r
+        double y = obj.getY();\r
+        double angle = obj.getAngle();\r
+        double speed = obj.getSpeed();\r
+\r
+        // 計算\r
+        x += speed * Math.cos(angle);\r
+        y += speed * Math.sin(angle);\r
+\r
+        // 設定\r
+        obj.setX(x);\r
+        obj.setY(y);\r
+    }\r
+\r
+    @Override\r
+    public void receiveMessage(StateContext ctx, Message msg) {\r
+    }\r
+\r
+    @Override\r
+    public void initialize(StateContext ctx) {\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku1/EnemyBulletObject.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku1/EnemyBulletObject.java
new file mode 100644 (file)
index 0000000..58f1f4c
--- /dev/null
@@ -0,0 +1,64 @@
+\r
+package jp.gr.java_conf.u6k.sample.danmaku1;\r
+\r
+import jp.gr.java_conf.u6k.state_engine.StateObject;\r
+\r
+@SuppressWarnings("serial")\r
+public class EnemyBulletObject extends StateObject {\r
+\r
+    private double x;\r
+\r
+    private double y;\r
+\r
+    private double angle;\r
+\r
+    private double speed;\r
+\r
+    public EnemyBulletObject(double x, double y, double angle, double speed) {\r
+        EnemyBulletMoveState moveState = new EnemyBulletMoveState();\r
+        moveState.getDestinationTransitionList().add(new EnemyBulletDisposedTransition());\r
+        this.getStateList().add(moveState);\r
+\r
+        EnemyBulletDrawState drawState = new EnemyBulletDrawState();\r
+        drawState.getDestinationTransitionList().add(new EnemyBulletDisposedTransition());\r
+        this.getStateList().add(drawState);\r
+\r
+        this.x = x;\r
+        this.y = y;\r
+        this.angle = angle;\r
+        this.speed = speed;\r
+    }\r
+\r
+    public double getX() {\r
+        return this.x;\r
+    }\r
+\r
+    public void setX(double x) {\r
+        this.x = x;\r
+    }\r
+\r
+    public double getY() {\r
+        return this.y;\r
+    }\r
+\r
+    public void setY(double y) {\r
+        this.y = y;\r
+    }\r
+\r
+    public double getAngle() {\r
+        return this.angle;\r
+    }\r
+\r
+    public void setAngle(double angle) {\r
+        this.angle = angle;\r
+    }\r
+\r
+    public double getSpeed() {\r
+        return this.speed;\r
+    }\r
+\r
+    public void setSpeed(double speed) {\r
+        this.speed = speed;\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku2/EnemyBodyDrawState.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku2/EnemyBodyDrawState.java
new file mode 100644 (file)
index 0000000..82626e0
--- /dev/null
@@ -0,0 +1,44 @@
+\r
+package jp.gr.java_conf.u6k.sample.danmaku2;\r
+\r
+import java.awt.Graphics2D;\r
+\r
+import jp.gr.java_conf.u6k.animation.AnimationWindow;\r
+import jp.gr.java_conf.u6k.state_engine.Message;\r
+import jp.gr.java_conf.u6k.state_engine.State;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+\r
+public class EnemyBodyDrawState extends State {\r
+\r
+    @Override\r
+    public void dispose(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void execute(StateContext ctx) {\r
+        // 取得\r
+        EnemyBodyObject obj = (EnemyBodyObject) ctx.getTarget();\r
+        AnimationWindow window = (AnimationWindow) ctx.getValueMap().get("window");\r
+        Graphics2D g = window.getCanvas();\r
+\r
+        double x = obj.getX();\r
+        double y = obj.getY();\r
+\r
+        // 描画\r
+        g.fillOval((int) x, (int) y, 20, 20);\r
+\r
+        g.drawString("mouse.x : " + window.getMouseInfo().getX(), 0, 30);\r
+        g.drawString("mouse.y : " + window.getMouseInfo().getY(), 0, 50);\r
+        g.drawString("mouse.left  : " + window.getMouseInfo().isLeftButton(), 0, 70);\r
+        g.drawString("mouse.right : " + window.getMouseInfo().isRightButton(), 0, 90);\r
+    }\r
+\r
+    @Override\r
+    public void receiveMessage(StateContext ctx, Message msg) {\r
+    }\r
+\r
+    @Override\r
+    public void initialize(StateContext ctx) {\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku2/EnemyBodyObject.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku2/EnemyBodyObject.java
new file mode 100644 (file)
index 0000000..e734bc1
--- /dev/null
@@ -0,0 +1,40 @@
+\r
+package jp.gr.java_conf.u6k.sample.danmaku2;\r
+\r
+import jp.gr.java_conf.u6k.state_engine.StateObject;\r
+\r
+@SuppressWarnings("serial")\r
+public class EnemyBodyObject extends StateObject {\r
+\r
+    private double x;\r
+\r
+    private double y;\r
+\r
+    public EnemyBodyObject(double x, double y) {\r
+        EnemyBodyShotDanmakuState shotState = new EnemyBodyShotDanmakuState();\r
+        this.getStateList().add(shotState);\r
+\r
+        EnemyBodyDrawState drawState = new EnemyBodyDrawState();\r
+        this.getStateList().add(drawState);\r
+\r
+        this.x = x;\r
+        this.y = y;\r
+    }\r
+\r
+    public double getX() {\r
+        return this.x;\r
+    }\r
+\r
+    public void setX(double x) {\r
+        this.x = x;\r
+    }\r
+\r
+    public double getY() {\r
+        return this.y;\r
+    }\r
+\r
+    public void setY(double y) {\r
+        this.y = y;\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku2/EnemyBodyShotDanmakuState.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku2/EnemyBodyShotDanmakuState.java
new file mode 100644 (file)
index 0000000..32fb981
--- /dev/null
@@ -0,0 +1,46 @@
+\r
+package jp.gr.java_conf.u6k.sample.danmaku2;\r
+\r
+import jp.gr.java_conf.u6k.animation.AnimationWindow;\r
+import jp.gr.java_conf.u6k.animation.MouseInfo;\r
+import jp.gr.java_conf.u6k.state_engine.Message;\r
+import jp.gr.java_conf.u6k.state_engine.State;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+\r
+public class EnemyBodyShotDanmakuState extends State {\r
+\r
+    @Override\r
+    public void dispose(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void execute(StateContext ctx) {\r
+        // 取得\r
+        EnemyBodyObject obj = (EnemyBodyObject) ctx.getTarget();\r
+        AnimationWindow window = (AnimationWindow) ctx.getValueMap().get("window");\r
+        MouseInfo mouseInfo = window.getMouseInfo();\r
+\r
+        double x = obj.getX();\r
+        double y = obj.getY();\r
+\r
+        // 弾幕発射\r
+        for (int i = 0; i < 1; i++) {\r
+            double speed = 5;\r
+            double angle;\r
+\r
+            angle = Math.atan2(mouseInfo.getY() - y, mouseInfo.getX() - x);\r
+\r
+            EnemyBulletObject bullet = new EnemyBulletObject(x, y, angle, speed);\r
+            ctx.addStateObject(bullet);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void receiveMessage(StateContext ctx, Message msg) {\r
+    }\r
+\r
+    @Override\r
+    public void initialize(StateContext ctx) {\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku2/EnemyBulletDisposedTransition.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku2/EnemyBulletDisposedTransition.java
new file mode 100644 (file)
index 0000000..30006f4
--- /dev/null
@@ -0,0 +1,22 @@
+\r
+package jp.gr.java_conf.u6k.sample.danmaku2;\r
+\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+import jp.gr.java_conf.u6k.state_engine.StateObject;\r
+import jp.gr.java_conf.u6k.state_engine.Transition;\r
+\r
+public class EnemyBulletDisposedTransition extends Transition {\r
+\r
+    @Override\r
+    public boolean condition(StateObject obj, StateContext ctx) {\r
+        // 取得\r
+        EnemyBulletObject o = (EnemyBulletObject) obj;\r
+\r
+        double x = o.getX();\r
+        double y = o.getY();\r
+\r
+        // 判断\r
+        return (x < 0) || (x > 640) || (y < 0) || (y > 480);\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku2/EnemyBulletDrawState.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku2/EnemyBulletDrawState.java
new file mode 100644 (file)
index 0000000..de9475b
--- /dev/null
@@ -0,0 +1,39 @@
+\r
+package jp.gr.java_conf.u6k.sample.danmaku2;\r
+\r
+import java.awt.Graphics2D;\r
+\r
+import jp.gr.java_conf.u6k.animation.AnimationWindow;\r
+import jp.gr.java_conf.u6k.state_engine.Message;\r
+import jp.gr.java_conf.u6k.state_engine.State;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+\r
+public class EnemyBulletDrawState extends State {\r
+\r
+    @Override\r
+    public void dispose(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void execute(StateContext ctx) {\r
+        // 取得\r
+        EnemyBulletObject obj = (EnemyBulletObject) ctx.getTarget();\r
+        AnimationWindow window = (AnimationWindow) ctx.getValueMap().get("window");\r
+        Graphics2D g = window.getCanvas();\r
+\r
+        double x = obj.getX();\r
+        double y = obj.getY();\r
+\r
+        // 描画\r
+        g.fillOval((int) x, (int) y, 5, 5);\r
+    }\r
+\r
+    @Override\r
+    public void receiveMessage(StateContext ctx, Message msg) {\r
+    }\r
+\r
+    @Override\r
+    public void initialize(StateContext ctx) {\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku2/EnemyBulletMoveState.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku2/EnemyBulletMoveState.java
new file mode 100644 (file)
index 0000000..2dcc3e1
--- /dev/null
@@ -0,0 +1,41 @@
+\r
+package jp.gr.java_conf.u6k.sample.danmaku2;\r
+\r
+import jp.gr.java_conf.u6k.state_engine.Message;\r
+import jp.gr.java_conf.u6k.state_engine.State;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+\r
+public class EnemyBulletMoveState extends State {\r
+\r
+    @Override\r
+    public void dispose(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void execute(StateContext ctx) {\r
+        // 取得\r
+        EnemyBulletObject obj = (EnemyBulletObject) ctx.getTarget();\r
+\r
+        double x = obj.getX();\r
+        double y = obj.getY();\r
+        double angle = obj.getAngle();\r
+        double speed = obj.getSpeed();\r
+\r
+        // 計算\r
+        x += speed * Math.cos(angle);\r
+        y += speed * Math.sin(angle);\r
+\r
+        // 設定\r
+        obj.setX(x);\r
+        obj.setY(y);\r
+    }\r
+\r
+    @Override\r
+    public void receiveMessage(StateContext ctx, Message msg) {\r
+    }\r
+\r
+    @Override\r
+    public void initialize(StateContext ctx) {\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku2/EnemyBulletObject.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/danmaku2/EnemyBulletObject.java
new file mode 100644 (file)
index 0000000..52e2540
--- /dev/null
@@ -0,0 +1,64 @@
+\r
+package jp.gr.java_conf.u6k.sample.danmaku2;\r
+\r
+import jp.gr.java_conf.u6k.state_engine.StateObject;\r
+\r
+@SuppressWarnings("serial")\r
+public class EnemyBulletObject extends StateObject {\r
+\r
+    private double x;\r
+\r
+    private double y;\r
+\r
+    private double angle;\r
+\r
+    private double speed;\r
+\r
+    public EnemyBulletObject(double x, double y, double angle, double speed) {\r
+        EnemyBulletMoveState moveState = new EnemyBulletMoveState();\r
+        moveState.getDestinationTransitionList().add(new EnemyBulletDisposedTransition());\r
+        this.getStateList().add(moveState);\r
+\r
+        EnemyBulletDrawState drawState = new EnemyBulletDrawState();\r
+        drawState.getDestinationTransitionList().add(new EnemyBulletDisposedTransition());\r
+        this.getStateList().add(drawState);\r
+\r
+        this.x = x;\r
+        this.y = y;\r
+        this.angle = angle;\r
+        this.speed = speed;\r
+    }\r
+\r
+    public double getX() {\r
+        return this.x;\r
+    }\r
+\r
+    public void setX(double x) {\r
+        this.x = x;\r
+    }\r
+\r
+    public double getY() {\r
+        return this.y;\r
+    }\r
+\r
+    public void setY(double y) {\r
+        this.y = y;\r
+    }\r
+\r
+    public double getAngle() {\r
+        return this.angle;\r
+    }\r
+\r
+    public void setAngle(double angle) {\r
+        this.angle = angle;\r
+    }\r
+\r
+    public double getSpeed() {\r
+        return this.speed;\r
+    }\r
+\r
+    public void setSpeed(double speed) {\r
+        this.speed = speed;\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/moveChar1/PlayerDrawState.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/moveChar1/PlayerDrawState.java
new file mode 100644 (file)
index 0000000..a41c64f
--- /dev/null
@@ -0,0 +1,39 @@
+\r
+package jp.gr.java_conf.u6k.sample.moveChar1;\r
+\r
+import java.awt.Graphics2D;\r
+\r
+import jp.gr.java_conf.u6k.animation.AnimationWindow;\r
+import jp.gr.java_conf.u6k.state_engine.Message;\r
+import jp.gr.java_conf.u6k.state_engine.State;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+\r
+public class PlayerDrawState extends State {\r
+\r
+    @Override\r
+    public void dispose(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void execute(StateContext ctx) {\r
+        // 取得\r
+        PlayerObject obj = (PlayerObject) ctx.getTarget();\r
+        AnimationWindow window = (AnimationWindow) ctx.getValueMap().get("window");\r
+        Graphics2D g = window.getCanvas();\r
+\r
+        double x = obj.getX();\r
+        double y = obj.getY();\r
+\r
+        // 描画\r
+        g.fillOval((int) x, (int) y, 20, 20);\r
+    }\r
+\r
+    @Override\r
+    public void receiveMessage(StateContext ctx, Message msg) {\r
+    }\r
+\r
+    @Override\r
+    public void initialize(StateContext ctx) {\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/moveChar1/PlayerMoveState.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/moveChar1/PlayerMoveState.java
new file mode 100644 (file)
index 0000000..d26f8b7
--- /dev/null
@@ -0,0 +1,55 @@
+\r
+package jp.gr.java_conf.u6k.sample.moveChar1;\r
+\r
+import java.awt.event.KeyEvent;\r
+\r
+import jp.gr.java_conf.u6k.animation.AnimationWindow;\r
+import jp.gr.java_conf.u6k.animation.KeyInfo;\r
+import jp.gr.java_conf.u6k.state_engine.Message;\r
+import jp.gr.java_conf.u6k.state_engine.State;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+\r
+public class PlayerMoveState extends State {\r
+\r
+    @Override\r
+    public void dispose(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void execute(StateContext ctx) {\r
+        // 取得\r
+        PlayerObject obj = (PlayerObject) ctx.getTarget();\r
+        AnimationWindow window = (AnimationWindow) ctx.getValueMap().get("window");\r
+        KeyInfo keyInfo = window.getKeyInfo();\r
+\r
+        double x = obj.getX();\r
+        double y = obj.getY();\r
+\r
+        // 計算\r
+        if (keyInfo.isKey(KeyEvent.VK_UP)) {\r
+            y -= 1;\r
+        }\r
+        if (keyInfo.isKey(KeyEvent.VK_DOWN)) {\r
+            y += 1;\r
+        }\r
+        if (keyInfo.isKey(KeyEvent.VK_LEFT)) {\r
+            x -= 1;\r
+        }\r
+        if (keyInfo.isKey(KeyEvent.VK_RIGHT)) {\r
+            x += 1;\r
+        }\r
+\r
+        // 設定\r
+        obj.setX(x);\r
+        obj.setY(y);\r
+    }\r
+\r
+    @Override\r
+    public void receiveMessage(StateContext ctx, Message msg) {\r
+    }\r
+\r
+    @Override\r
+    public void initialize(StateContext ctx) {\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/moveChar1/PlayerObject.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/moveChar1/PlayerObject.java
new file mode 100644 (file)
index 0000000..a22117b
--- /dev/null
@@ -0,0 +1,38 @@
+\r
+package jp.gr.java_conf.u6k.sample.moveChar1;\r
+\r
+import jp.gr.java_conf.u6k.state_engine.StateObject;\r
+\r
+@SuppressWarnings("serial")\r
+public class PlayerObject extends StateObject {\r
+\r
+    private double x = 0;\r
+\r
+    private double y = 0;\r
+\r
+    public PlayerObject() {\r
+        PlayerMoveState moveState = new PlayerMoveState();\r
+        this.getStateList().add(moveState);\r
+\r
+        PlayerDrawState drawState = new PlayerDrawState();\r
+        this.getStateList().add(drawState);\r
+\r
+    }\r
+\r
+    public double getX() {\r
+        return this.x;\r
+    }\r
+\r
+    public void setX(double x) {\r
+        this.x = x;\r
+    }\r
+\r
+    public double getY() {\r
+        return this.y;\r
+    }\r
+\r
+    public void setY(double y) {\r
+        this.y = y;\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/searcher1/BallDrawState.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/searcher1/BallDrawState.java
new file mode 100644 (file)
index 0000000..ce3d257
--- /dev/null
@@ -0,0 +1,39 @@
+\r
+package jp.gr.java_conf.u6k.sample.searcher1;\r
+\r
+import java.awt.Graphics2D;\r
+\r
+import jp.gr.java_conf.u6k.animation.AnimationWindow;\r
+import jp.gr.java_conf.u6k.state_engine.Message;\r
+import jp.gr.java_conf.u6k.state_engine.State;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+\r
+public class BallDrawState extends State {\r
+\r
+    @Override\r
+    public void dispose(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void execute(StateContext ctx) {\r
+        // 取得\r
+        BallObject obj = (BallObject) ctx.getTarget();\r
+        double x = obj.getX();\r
+        double y = obj.getY();\r
+\r
+        AnimationWindow window = (AnimationWindow) ctx.getValueMap().get("window");\r
+        Graphics2D g = window.getCanvas();\r
+\r
+        // 描画\r
+        g.fillOval((int) x, (int) y, 20, 20);\r
+    }\r
+\r
+    @Override\r
+    public void initialize(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void receiveMessage(StateContext ctx, Message msg) {\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/searcher1/BallMoveState.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/searcher1/BallMoveState.java
new file mode 100644 (file)
index 0000000..7d34d6e
--- /dev/null
@@ -0,0 +1,60 @@
+\r
+package jp.gr.java_conf.u6k.sample.searcher1;\r
+\r
+import jp.gr.java_conf.u6k.animation.AnimationWindow;\r
+import jp.gr.java_conf.u6k.animation.MouseInfo;\r
+import jp.gr.java_conf.u6k.state_engine.Message;\r
+import jp.gr.java_conf.u6k.state_engine.State;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+\r
+public class BallMoveState extends State {\r
+\r
+    private final static double a = 0.1;\r
+\r
+    @Override\r
+    public void dispose(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void execute(StateContext ctx) {\r
+        // 取得\r
+        BallObject obj = (BallObject) ctx.getTarget();\r
+        AnimationWindow window = (AnimationWindow) ctx.getValueMap().get("window");\r
+        MouseInfo mouseInfo = window.getMouseInfo();\r
+\r
+        double x = obj.getX();\r
+        double y = obj.getY();\r
+        double speedX = obj.getSpeedX();\r
+        double speedY = obj.getSpeedY();\r
+\r
+        // 計算\r
+        if (x > mouseInfo.getX()) {\r
+            speedX -= BallMoveState.a;\r
+        } else if (x < mouseInfo.getX()) {\r
+            speedX += BallMoveState.a;\r
+        }\r
+        if (y > mouseInfo.getY()) {\r
+            speedY -= BallMoveState.a;\r
+        } else if (y < mouseInfo.getY()) {\r
+            speedY += BallMoveState.a;\r
+        }\r
+\r
+        x += speedX;\r
+        y += speedY;\r
+\r
+        // 設定\r
+        obj.setX(x);\r
+        obj.setY(y);\r
+        obj.setSpeedX(speedX);\r
+        obj.setSpeedY(speedY);\r
+    }\r
+\r
+    @Override\r
+    public void initialize(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void receiveMessage(StateContext ctx, Message msg) {\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/searcher1/BallObject.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/searcher1/BallObject.java
new file mode 100644 (file)
index 0000000..f587cec
--- /dev/null
@@ -0,0 +1,56 @@
+\r
+package jp.gr.java_conf.u6k.sample.searcher1;\r
+\r
+import jp.gr.java_conf.u6k.state_engine.StateObject;\r
+\r
+public class BallObject extends StateObject {\r
+\r
+    private double x;\r
+\r
+    private double y;\r
+\r
+    private double speedX;\r
+\r
+    private double speedY;\r
+\r
+    public BallObject() {\r
+        BallMoveState moveState = new BallMoveState();\r
+        this.getStateList().add(moveState);\r
+\r
+        BallDrawState drawState = new BallDrawState();\r
+        this.getStateList().add(drawState);\r
+    }\r
+\r
+    public double getX() {\r
+        return this.x;\r
+    }\r
+\r
+    public void setX(double x) {\r
+        this.x = x;\r
+    }\r
+\r
+    public double getY() {\r
+        return this.y;\r
+    }\r
+\r
+    public void setY(double y) {\r
+        this.y = y;\r
+    }\r
+\r
+    public double getSpeedX() {\r
+        return this.speedX;\r
+    }\r
+\r
+    public void setSpeedX(double speedX) {\r
+        this.speedX = speedX;\r
+    }\r
+\r
+    public double getSpeedY() {\r
+        return this.speedY;\r
+    }\r
+\r
+    public void setSpeedY(double speedY) {\r
+        this.speedY = speedY;\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/EnemyBulletDisposeTransition.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/EnemyBulletDisposeTransition.java
new file mode 100644 (file)
index 0000000..6263dbb
--- /dev/null
@@ -0,0 +1,26 @@
+\r
+package jp.gr.java_conf.u6k.sample.stg1;\r
+\r
+import jp.gr.java_conf.u6k.animation.AnimationWindow;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+import jp.gr.java_conf.u6k.state_engine.StateObject;\r
+import jp.gr.java_conf.u6k.state_engine.Transition;\r
+\r
+public class EnemyBulletDisposeTransition extends Transition {\r
+\r
+    @Override\r
+    public boolean condition(StateObject obj, StateContext ctx) {\r
+        // 取得\r
+        EnemyBulletObject o = (EnemyBulletObject) obj;\r
+        double x = o.getX();\r
+        double y = o.getY();\r
+\r
+        AnimationWindow window = (AnimationWindow) ctx.getValueMap().get("window");\r
+        int w = window.getWidth();\r
+        int h = window.getHeight();\r
+\r
+        // 判断\r
+        return (x < 0) || (y < 0) || (x > w) || (y > h);\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/EnemyBulletDrawState.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/EnemyBulletDrawState.java
new file mode 100644 (file)
index 0000000..1443aba
--- /dev/null
@@ -0,0 +1,46 @@
+\r
+package jp.gr.java_conf.u6k.sample.stg1;\r
+\r
+import jp.gr.java_conf.u6k.animation.AnimationWindow;\r
+import jp.gr.java_conf.u6k.state_engine.Message;\r
+import jp.gr.java_conf.u6k.state_engine.State;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+\r
+public class EnemyBulletDrawState extends State {\r
+\r
+    @Override\r
+    public void dispose(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void execute(StateContext ctx) {\r
+        // 取得\r
+        EnemyBulletObject o = (EnemyBulletObject) ctx.getTarget();\r
+        double ox = o.getX();\r
+        double oy = o.getY();\r
+        long time = o.getTime();\r
+\r
+        AnimationWindow window = (AnimationWindow) ctx.getValueMap().get("window");\r
+\r
+        // 描画\r
+        int[] x = new int[4];\r
+        int[] y = new int[4];\r
+\r
+        for (int i = 0; i < 4; i++) {\r
+            double angle = 2 * Math.PI / 60 * (time % 60) + 2 * Math.PI / 4 * i;\r
+            x[i] = (int) (5 * Math.cos(angle) + ox);\r
+            y[i] = (int) (5 * Math.sin(angle) + oy);\r
+        }\r
+\r
+        window.getCanvas().drawPolygon(x, y, 4);\r
+    }\r
+\r
+    @Override\r
+    public void initialize(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void receiveMessage(StateContext ctx, Message msg) {\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/EnemyBulletMoveState.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/EnemyBulletMoveState.java
new file mode 100644 (file)
index 0000000..6f7c62c
--- /dev/null
@@ -0,0 +1,32 @@
+\r
+package jp.gr.java_conf.u6k.sample.stg1;\r
+\r
+import jp.gr.java_conf.u6k.state_engine.Message;\r
+import jp.gr.java_conf.u6k.state_engine.State;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+\r
+public class EnemyBulletMoveState extends State {\r
+\r
+    @Override\r
+    public void dispose(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void execute(StateContext ctx) {\r
+        // 取得\r
+        EnemyBulletObject o = (EnemyBulletObject) ctx.getTarget();\r
+\r
+        // 計算、設定\r
+        o.setX(o.getX() + o.getXSpeed());\r
+        o.setY(o.getY() + o.getYSpeed());\r
+    }\r
+\r
+    @Override\r
+    public void initialize(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void receiveMessage(StateContext ctx, Message msg) {\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/EnemyBulletObject.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/EnemyBulletObject.java
new file mode 100644 (file)
index 0000000..6e62d8f
--- /dev/null
@@ -0,0 +1,63 @@
+\r
+package jp.gr.java_conf.u6k.sample.stg1;\r
+\r
+import jp.gr.java_conf.u6k.state_engine.StateObject;\r
+\r
+public class EnemyBulletObject extends StateObject {\r
+\r
+    private double x;\r
+\r
+    private double y;\r
+\r
+    private double xSpeed;\r
+\r
+    private double ySpeed;\r
+\r
+    public EnemyBulletObject(double x, double y, double xSpeed, double ySpeed) {\r
+        this.x = x;\r
+        this.y = y;\r
+        this.xSpeed = xSpeed;\r
+        this.ySpeed = ySpeed;\r
+\r
+        EnemyBulletDrawState drawState = new EnemyBulletDrawState();\r
+        drawState.getDestinationTransitionList().add(new EnemyBulletDisposeTransition());\r
+        this.getStateList().add(drawState);\r
+\r
+        EnemyBulletMoveState moveState = new EnemyBulletMoveState();\r
+        moveState.getDestinationTransitionList().add(new EnemyBulletDisposeTransition());\r
+        this.getStateList().add(moveState);\r
+    }\r
+\r
+    public double getX() {\r
+        return this.x;\r
+    }\r
+\r
+    public void setX(double x) {\r
+        this.x = x;\r
+    }\r
+\r
+    public double getY() {\r
+        return this.y;\r
+    }\r
+\r
+    public void setY(double y) {\r
+        this.y = y;\r
+    }\r
+\r
+    public double getXSpeed() {\r
+        return this.xSpeed;\r
+    }\r
+\r
+    public void setXSpeed(double speed) {\r
+        xSpeed = speed;\r
+    }\r
+\r
+    public double getYSpeed() {\r
+        return this.ySpeed;\r
+    }\r
+\r
+    public void setYSpeed(double speed) {\r
+        ySpeed = speed;\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/EnemyDisposeTransition.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/EnemyDisposeTransition.java
new file mode 100644 (file)
index 0000000..7893442
--- /dev/null
@@ -0,0 +1,27 @@
+\r
+package jp.gr.java_conf.u6k.sample.stg1;\r
+\r
+import jp.gr.java_conf.u6k.animation.AnimationWindow;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+import jp.gr.java_conf.u6k.state_engine.StateObject;\r
+import jp.gr.java_conf.u6k.state_engine.Transition;\r
+\r
+public class EnemyDisposeTransition extends Transition {\r
+\r
+    @Override\r
+    public boolean condition(StateObject obj, StateContext ctx) {\r
+        // 取得\r
+        EnemyObject o = (EnemyObject) obj;\r
+        double x = o.getX();\r
+        double y = o.getY();\r
+        int hp = o.getHitPoint();\r
+\r
+        AnimationWindow window = (AnimationWindow) ctx.getValueMap().get("window");\r
+        int w = window.getWidth();\r
+        int h = window.getHeight();\r
+\r
+        // 判断\r
+        return (x < 0) || (y < 0) || (x > w) || (y > h) || (hp == 0);\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/EnemyDrawState.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/EnemyDrawState.java
new file mode 100644 (file)
index 0000000..bb0f28b
--- /dev/null
@@ -0,0 +1,49 @@
+\r
+package jp.gr.java_conf.u6k.sample.stg1;\r
+\r
+import java.awt.Graphics2D;\r
+\r
+import jp.gr.java_conf.u6k.animation.AnimationWindow;\r
+import jp.gr.java_conf.u6k.state_engine.Message;\r
+import jp.gr.java_conf.u6k.state_engine.State;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+\r
+public class EnemyDrawState extends State {\r
+\r
+    @Override\r
+    public void dispose(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void execute(StateContext ctx) {\r
+        // 取得\r
+        EnemyObject o = (EnemyObject) ctx.getTarget();\r
+        double x = o.getX();\r
+        double y = o.getY();\r
+        long time = o.getTime();\r
+\r
+        AnimationWindow window = (AnimationWindow) ctx.getValueMap().get("window");\r
+        Graphics2D g = window.getCanvas();\r
+\r
+        // 本体描画\r
+        g.drawRect((int) x - 15, (int) y - 15, 30, 30);\r
+\r
+        // オプション描画\r
+        for (int i = 0; i < 3; i++) {\r
+            double angle = 2 * Math.PI / 60 * (time % 60) + 2 * Math.PI / 3 * i;\r
+            int optX = (int) (15 * Math.cos(angle) + x);\r
+            int optY = (int) (15 * Math.sin(angle) + y);\r
+\r
+            g.drawRect(optX - 3, optY - 3, 6, 6);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void initialize(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void receiveMessage(StateContext ctx, Message msg) {\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/EnemyMoveState.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/EnemyMoveState.java
new file mode 100644 (file)
index 0000000..2be1c0d
--- /dev/null
@@ -0,0 +1,43 @@
+\r
+package jp.gr.java_conf.u6k.sample.stg1;\r
+\r
+import java.awt.Rectangle;\r
+\r
+import jp.gr.java_conf.u6k.state_engine.Message;\r
+import jp.gr.java_conf.u6k.state_engine.State;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+\r
+public class EnemyMoveState extends State {\r
+\r
+    @Override\r
+    public void dispose(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void execute(StateContext ctx) {\r
+        // 取得\r
+        EnemyObject o = (EnemyObject) ctx.getTarget();\r
+\r
+        // 計算、設定\r
+        o.setX(o.getX() + o.getXSpeed());\r
+    }\r
+\r
+    @Override\r
+    public void initialize(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void receiveMessage(StateContext ctx, Message msg) {\r
+        if (msg instanceof PlayerBulletAttackMessage) {\r
+            PlayerBulletAttackMessage m = (PlayerBulletAttackMessage) msg;\r
+            EnemyObject o = (EnemyObject) ctx.getTarget();\r
+            if (o.getHitPoint() > 0) {\r
+                Rectangle enemyHitRect = new Rectangle((int) o.getX() - 15, (int) o.getY() - 15, 30, 30);\r
+                if (m.getHitRect().contains(enemyHitRect)) {\r
+                    o.setHitPoint(o.getHitPoint() - 1);\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/EnemyObject.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/EnemyObject.java
new file mode 100644 (file)
index 0000000..e9b7bf4
--- /dev/null
@@ -0,0 +1,74 @@
+\r
+package jp.gr.java_conf.u6k.sample.stg1;\r
+\r
+import jp.gr.java_conf.u6k.state_engine.StateObject;\r
+\r
+public class EnemyObject extends StateObject {\r
+\r
+    private double x;\r
+\r
+    private double y;\r
+\r
+    private double xSpeed;\r
+\r
+    private int    hitPoint = 3;\r
+\r
+    public EnemyObject() {\r
+        // 属性\r
+        this.xSpeed = (Math.random() - 0.5) * 5;\r
+\r
+        if (this.xSpeed > 0) {\r
+            this.x = 0;\r
+        } else {\r
+            this.x = 640;\r
+        }\r
+\r
+        this.y = Math.random() * 90 + 10;\r
+\r
+        // 状態\r
+        EnemyDrawState drawState = new EnemyDrawState();\r
+        drawState.getDestinationTransitionList().add(new EnemyDisposeTransition());\r
+        this.getStateList().add(drawState);\r
+\r
+        EnemyMoveState moveState = new EnemyMoveState();\r
+        moveState.getDestinationTransitionList().add(new EnemyDisposeTransition());\r
+        this.getStateList().add(moveState);\r
+\r
+        EnemyShotState shotState = new EnemyShotState();\r
+        shotState.getDestinationTransitionList().add(new EnemyDisposeTransition());\r
+        this.getStateList().add(shotState);\r
+    }\r
+\r
+    public double getX() {\r
+        return this.x;\r
+    }\r
+\r
+    public void setX(double x) {\r
+        this.x = x;\r
+    }\r
+\r
+    public double getY() {\r
+        return this.y;\r
+    }\r
+\r
+    public void setY(double y) {\r
+        this.y = y;\r
+    }\r
+\r
+    public double getXSpeed() {\r
+        return this.xSpeed;\r
+    }\r
+\r
+    public void setXSpeed(double speed) {\r
+        xSpeed = speed;\r
+    }\r
+\r
+    public int getHitPoint() {\r
+        return this.hitPoint;\r
+    }\r
+\r
+    public void setHitPoint(int hitPoint) {\r
+        this.hitPoint = hitPoint;\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/EnemyShotState.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/EnemyShotState.java
new file mode 100644 (file)
index 0000000..7c93625
--- /dev/null
@@ -0,0 +1,36 @@
+\r
+package jp.gr.java_conf.u6k.sample.stg1;\r
+\r
+import jp.gr.java_conf.u6k.state_engine.Message;\r
+import jp.gr.java_conf.u6k.state_engine.State;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+\r
+public class EnemyShotState extends State {\r
+\r
+    @Override\r
+    public void dispose(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void execute(StateContext ctx) {\r
+        // 取得\r
+        EnemyObject o = (EnemyObject) ctx.getTarget();\r
+        double x = o.getX();\r
+        double y = o.getY();\r
+\r
+        // 敵弾生成\r
+        if (o.getTime() % 60 == 0) {\r
+            EnemyBulletObject bullet = new EnemyBulletObject(x, y, 0, 2);\r
+            ctx.addStateObject(bullet);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void initialize(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void receiveMessage(StateContext ctx, Message msg) {\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/PlayerBulletAttackMessage.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/PlayerBulletAttackMessage.java
new file mode 100644 (file)
index 0000000..c0a7f34
--- /dev/null
@@ -0,0 +1,23 @@
+\r
+package jp.gr.java_conf.u6k.sample.stg1;\r
+\r
+import java.awt.Rectangle;\r
+\r
+import jp.gr.java_conf.u6k.state_engine.Message;\r
+\r
+public class PlayerBulletAttackMessage implements Message {\r
+\r
+    private Rectangle hitRect;\r
+\r
+    public PlayerBulletAttackMessage(Rectangle hitRect) {\r
+        if (hitRect == null) {\r
+            throw new NullPointerException("hitRect == null");\r
+        }\r
+        this.hitRect = hitRect;\r
+    }\r
+\r
+    public Rectangle getHitRect() {\r
+        return this.hitRect;\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/PlayerBulletDisposeTransition.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/PlayerBulletDisposeTransition.java
new file mode 100644 (file)
index 0000000..84ce0dc
--- /dev/null
@@ -0,0 +1,26 @@
+\r
+package jp.gr.java_conf.u6k.sample.stg1;\r
+\r
+import jp.gr.java_conf.u6k.animation.AnimationWindow;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+import jp.gr.java_conf.u6k.state_engine.StateObject;\r
+import jp.gr.java_conf.u6k.state_engine.Transition;\r
+\r
+public class PlayerBulletDisposeTransition extends Transition {\r
+\r
+    @Override\r
+    public boolean condition(StateObject obj, StateContext ctx) {\r
+        // 取得\r
+        PlayerBulletObject o = (PlayerBulletObject) ctx.getTarget();\r
+        double x = o.getX();\r
+        double y = o.getY();\r
+\r
+        AnimationWindow window = (AnimationWindow) ctx.getValueMap().get("window");\r
+        int w = window.getWidth();\r
+        int h = window.getHeight();\r
+\r
+        // 判断\r
+        return (x < 0) || (y < 0) || (x > w) || (y > h);\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/PlayerBulletDrawState.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/PlayerBulletDrawState.java
new file mode 100644 (file)
index 0000000..94d6116
--- /dev/null
@@ -0,0 +1,36 @@
+\r
+package jp.gr.java_conf.u6k.sample.stg1;\r
+\r
+import jp.gr.java_conf.u6k.animation.AnimationWindow;\r
+import jp.gr.java_conf.u6k.state_engine.Message;\r
+import jp.gr.java_conf.u6k.state_engine.State;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+\r
+public class PlayerBulletDrawState extends State {\r
+\r
+    @Override\r
+    public void dispose(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void execute(StateContext ctx) {\r
+        // 取得\r
+        PlayerBulletObject o = (PlayerBulletObject) ctx.getTarget();\r
+        double x = o.getX();\r
+        double y = o.getY();\r
+\r
+        AnimationWindow window = (AnimationWindow) ctx.getValueMap().get("window");\r
+\r
+        // 描画\r
+        window.getCanvas().drawRect((int) x - 1, (int) y - 5, 3, 10);\r
+    }\r
+\r
+    @Override\r
+    public void initialize(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void receiveMessage(StateContext ctx, Message msg) {\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/PlayerBulletMoveState.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/PlayerBulletMoveState.java
new file mode 100644 (file)
index 0000000..a1fd843
--- /dev/null
@@ -0,0 +1,39 @@
+\r
+package jp.gr.java_conf.u6k.sample.stg1;\r
+\r
+import java.awt.Rectangle;\r
+\r
+import jp.gr.java_conf.u6k.state_engine.Message;\r
+import jp.gr.java_conf.u6k.state_engine.State;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+\r
+public class PlayerBulletMoveState extends State {\r
+\r
+    @Override\r
+    public void dispose(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void execute(StateContext ctx) {\r
+        // 取得\r
+        PlayerBulletObject o = (PlayerBulletObject) ctx.getTarget();\r
+\r
+        // 設定\r
+        o.setX(o.getX() + o.getXSpeed());\r
+        o.setY(o.getY() + o.getYSpeed());\r
+\r
+        // 攻撃\r
+        Rectangle hitRect = new Rectangle((int) o.getX() - 1, (int) o.getY() - 1, 3, 10);\r
+        PlayerBulletAttackMessage msg = new PlayerBulletAttackMessage(hitRect);\r
+        ctx.sendMessage(msg);\r
+    }\r
+\r
+    @Override\r
+    public void initialize(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void receiveMessage(StateContext ctx, Message msg) {\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/PlayerBulletObject.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/PlayerBulletObject.java
new file mode 100644 (file)
index 0000000..07bbb1e
--- /dev/null
@@ -0,0 +1,63 @@
+\r
+package jp.gr.java_conf.u6k.sample.stg1;\r
+\r
+import jp.gr.java_conf.u6k.state_engine.StateObject;\r
+\r
+public class PlayerBulletObject extends StateObject {\r
+\r
+    private double x;\r
+\r
+    private double y;\r
+\r
+    private double xSpeed;\r
+\r
+    private double ySpeed;\r
+\r
+    public PlayerBulletObject(double x, double y, double xSpeed, double ySpeed) {\r
+        this.x = x;\r
+        this.y = y;\r
+        this.xSpeed = xSpeed;\r
+        this.ySpeed = ySpeed;\r
+\r
+        PlayerBulletDrawState drawState = new PlayerBulletDrawState();\r
+        drawState.getDestinationTransitionList().add(new PlayerBulletDisposeTransition());\r
+        this.getStateList().add(drawState);\r
+\r
+        PlayerBulletMoveState moveState = new PlayerBulletMoveState();\r
+        moveState.getDestinationTransitionList().add(new PlayerBulletDisposeTransition());\r
+        this.getStateList().add(moveState);\r
+    }\r
+\r
+    public double getX() {\r
+        return this.x;\r
+    }\r
+\r
+    public void setX(double x) {\r
+        this.x = x;\r
+    }\r
+\r
+    public double getY() {\r
+        return this.y;\r
+    }\r
+\r
+    public void setY(double y) {\r
+        this.y = y;\r
+    }\r
+\r
+    public double getXSpeed() {\r
+        return this.xSpeed;\r
+    }\r
+\r
+    public void setXSpeed(double speed) {\r
+        xSpeed = speed;\r
+    }\r
+\r
+    public double getYSpeed() {\r
+        return this.ySpeed;\r
+    }\r
+\r
+    public void setYSpeed(double speed) {\r
+        ySpeed = speed;\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/PlayerDrawState.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/PlayerDrawState.java
new file mode 100644 (file)
index 0000000..ca52426
--- /dev/null
@@ -0,0 +1,39 @@
+\r
+package jp.gr.java_conf.u6k.sample.stg1;\r
+\r
+import java.awt.Graphics2D;\r
+\r
+import jp.gr.java_conf.u6k.animation.AnimationWindow;\r
+import jp.gr.java_conf.u6k.state_engine.Message;\r
+import jp.gr.java_conf.u6k.state_engine.State;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+\r
+public class PlayerDrawState extends State {\r
+\r
+    @Override\r
+    public void dispose(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void execute(StateContext ctx) {\r
+        // 取得\r
+        PlayerObject o = (PlayerObject) ctx.getTarget();\r
+        double x = o.getX();\r
+        double y = o.getY();\r
+\r
+        AnimationWindow window = (AnimationWindow) ctx.getValueMap().get("window");\r
+        Graphics2D g = window.getCanvas();\r
+\r
+        // 描画\r
+        g.drawRect((int) x - 10, (int) y - 10, 20, 20);\r
+    }\r
+\r
+    @Override\r
+    public void initialize(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void receiveMessage(StateContext ctx, Message msg) {\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/PlayerMoveState.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/PlayerMoveState.java
new file mode 100644 (file)
index 0000000..3811d89
--- /dev/null
@@ -0,0 +1,75 @@
+\r
+package jp.gr.java_conf.u6k.sample.stg1;\r
+\r
+import java.awt.event.KeyEvent;\r
+\r
+import jp.gr.java_conf.u6k.animation.AnimationWindow;\r
+import jp.gr.java_conf.u6k.animation.KeyInfo;\r
+import jp.gr.java_conf.u6k.state_engine.Message;\r
+import jp.gr.java_conf.u6k.state_engine.State;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+\r
+public class PlayerMoveState extends State {\r
+\r
+    @Override\r
+    public void dispose(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void execute(StateContext ctx) {\r
+        // 取得\r
+        PlayerObject o = (PlayerObject) ctx.getTarget();\r
+        double x = o.getX();\r
+        double y = o.getY();\r
+\r
+        AnimationWindow window = (AnimationWindow) ctx.getValueMap().get("window");\r
+        KeyInfo keyInfo = window.getKeyInfo();\r
+        int w = window.getWidth();\r
+        int h = window.getHeight();\r
+\r
+        // 計算\r
+        double speed;\r
+        if (keyInfo.isKey(KeyEvent.VK_SHIFT)) {\r
+            speed = 2;\r
+        } else {\r
+            speed = 4;\r
+        }\r
+\r
+        if (keyInfo.isKey(KeyEvent.VK_UP)) {\r
+            y -= speed;\r
+        }\r
+        if (keyInfo.isKey(KeyEvent.VK_DOWN)) {\r
+            y += speed;\r
+        }\r
+        if (keyInfo.isKey(KeyEvent.VK_LEFT)) {\r
+            x -= speed;\r
+        }\r
+        if (keyInfo.isKey(KeyEvent.VK_RIGHT)) {\r
+            x += speed;\r
+        }\r
+\r
+        if (x < 0) {\r
+            x = 0;\r
+        } else if (x > w) {\r
+            x = w;\r
+        }\r
+        if (y < 0) {\r
+            y = 0;\r
+        } else if (y > h) {\r
+            y = h;\r
+        }\r
+\r
+        // 設定\r
+        o.setX(x);\r
+        o.setY(y);\r
+    }\r
+\r
+    @Override\r
+    public void initialize(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void receiveMessage(StateContext ctx, Message msg) {\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/PlayerObject.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/PlayerObject.java
new file mode 100644 (file)
index 0000000..4e5ac37
--- /dev/null
@@ -0,0 +1,44 @@
+\r
+package jp.gr.java_conf.u6k.sample.stg1;\r
+\r
+import jp.gr.java_conf.u6k.state_engine.StateObject;\r
+\r
+public class PlayerObject extends StateObject {\r
+\r
+    private double x;\r
+\r
+    private double y;\r
+\r
+    public PlayerObject() {\r
+        // 属性\r
+        this.x = 320;\r
+        this.y = 400;\r
+\r
+        // 状態\r
+        PlayerDrawState drawState = new PlayerDrawState();\r
+        this.getStateList().add(drawState);\r
+\r
+        PlayerMoveState moveState = new PlayerMoveState();\r
+        this.getStateList().add(moveState);\r
+\r
+        PlayerShotState shotState = new PlayerShotState();\r
+        this.getStateList().add(shotState);\r
+    }\r
+\r
+    public double getX() {\r
+        return this.x;\r
+    }\r
+\r
+    public void setX(double x) {\r
+        this.x = x;\r
+    }\r
+\r
+    public double getY() {\r
+        return this.y;\r
+    }\r
+\r
+    public void setY(double y) {\r
+        this.y = y;\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/PlayerShotState.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/PlayerShotState.java
new file mode 100644 (file)
index 0000000..0794b42
--- /dev/null
@@ -0,0 +1,56 @@
+\r
+package jp.gr.java_conf.u6k.sample.stg1;\r
+\r
+import java.awt.event.KeyEvent;\r
+\r
+import jp.gr.java_conf.u6k.animation.AnimationWindow;\r
+import jp.gr.java_conf.u6k.animation.KeyInfo;\r
+import jp.gr.java_conf.u6k.state_engine.Message;\r
+import jp.gr.java_conf.u6k.state_engine.State;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+\r
+public class PlayerShotState extends State {\r
+\r
+    private int interval = 0;\r
+\r
+    @Override\r
+    public void dispose(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void execute(StateContext ctx) {\r
+        // 取得\r
+        PlayerObject o = (PlayerObject) ctx.getTarget();\r
+        double x = o.getX();\r
+        double y = o.getY();\r
+        long time = o.getTime();\r
+\r
+        AnimationWindow window = (AnimationWindow) ctx.getValueMap().get("window");\r
+        KeyInfo keyInfo = window.getKeyInfo();\r
+\r
+        // 自弾生成\r
+        if (keyInfo.isKey(KeyEvent.VK_Z) && this.interval == 0) {\r
+            for (int i = 0; i < 2; i++) {\r
+                double angle = 2 * Math.PI / 60 * (time % 60) + 2 * Math.PI / 2 * i;\r
+\r
+                PlayerBulletObject bullet = new PlayerBulletObject(10 * Math.sin(angle) + x, y, 0, -10);\r
+                ctx.addStateObject(bullet);\r
+            }\r
+\r
+            this.interval = 1;\r
+        } else {\r
+            if (this.interval > 0) {\r
+                this.interval--;\r
+            }\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void initialize(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void receiveMessage(StateContext ctx, Message msg) {\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/SceneObject.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/SceneObject.java
new file mode 100644 (file)
index 0000000..8e1176d
--- /dev/null
@@ -0,0 +1,12 @@
+\r
+package jp.gr.java_conf.u6k.sample.stg1;\r
+\r
+import jp.gr.java_conf.u6k.state_engine.StateObject;\r
+\r
+public class SceneObject extends StateObject {\r
+\r
+    public SceneObject() {\r
+        this.getStateList().add(new SceneState());\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/SceneState.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/sample/stg1/SceneState.java
new file mode 100644 (file)
index 0000000..d0ed44f
--- /dev/null
@@ -0,0 +1,40 @@
+\r
+package jp.gr.java_conf.u6k.sample.stg1;\r
+\r
+import jp.gr.java_conf.u6k.state_engine.Message;\r
+import jp.gr.java_conf.u6k.state_engine.State;\r
+import jp.gr.java_conf.u6k.state_engine.StateContext;\r
+\r
+public class SceneState extends State {\r
+\r
+    @Override\r
+    public void dispose(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void execute(StateContext ctx) {\r
+        // 取得\r
+        SceneObject o = (SceneObject) ctx.getTarget();\r
+\r
+        // 自機生成\r
+        if (o.getTime() == 0) {\r
+            PlayerObject player = new PlayerObject();\r
+            ctx.addStateObject(player);\r
+        }\r
+\r
+        // 敵機生成\r
+        if (o.getTime() % 60 == 0) {\r
+            EnemyObject enemy = new EnemyObject();\r
+            ctx.addStateObject(enemy);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void initialize(StateContext ctx) {\r
+    }\r
+\r
+    @Override\r
+    public void receiveMessage(StateContext ctx, Message msg) {\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/state_engine/Message.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/state_engine/Message.java
new file mode 100644 (file)
index 0000000..d55b9c9
--- /dev/null
@@ -0,0 +1,6 @@
+\r
+package jp.gr.java_conf.u6k.state_engine;\r
+\r
+public interface Message {\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/state_engine/State.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/state_engine/State.java
new file mode 100644 (file)
index 0000000..17a402d
--- /dev/null
@@ -0,0 +1,23 @@
+\r
+package jp.gr.java_conf.u6k.state_engine;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+public abstract class State {\r
+\r
+    private List<Transition> destTransList = new ArrayList<Transition>();\r
+\r
+    public abstract void initialize(StateContext ctx);\r
+\r
+    public abstract void execute(StateContext ctx);\r
+\r
+    public abstract void receiveMessage(StateContext ctx, Message msg);\r
+\r
+    public abstract void dispose(StateContext ctx);\r
+\r
+    public List<Transition> getDestinationTransitionList() {\r
+        return this.destTransList;\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/state_engine/StateContext.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/state_engine/StateContext.java
new file mode 100644 (file)
index 0000000..9ef0330
--- /dev/null
@@ -0,0 +1,56 @@
+\r
+package jp.gr.java_conf.u6k.state_engine;\r
+\r
+import java.util.HashMap;\r
+import java.util.LinkedList;\r
+import java.util.Map;\r
+import java.util.Queue;\r
+\r
+public class StateContext {\r
+\r
+    private Queue<StateObject>  addedStateObjectQueue = new LinkedList<StateObject>();\r
+\r
+    private Queue<Message>      sendedMessageQueue    = new LinkedList<Message>();\r
+\r
+    private StateObject         target;\r
+\r
+    private Map<String, Object> valueMap              = new HashMap<String, Object>();\r
+\r
+    public StateObject getTarget() {\r
+        return this.target;\r
+    }\r
+\r
+    final void setTarget(StateObject target) {\r
+        if (target == null) {\r
+            throw new NullPointerException("target == null");\r
+        }\r
+        this.target = target;\r
+    }\r
+\r
+    public void addStateObject(StateObject obj) {\r
+        if (obj == null) {\r
+            throw new NullPointerException("obj == null");\r
+        }\r
+        this.addedStateObjectQueue.offer(obj);\r
+    }\r
+\r
+    final Queue<StateObject> getAddedStateObjectQueue() {\r
+        return this.addedStateObjectQueue;\r
+    }\r
+\r
+    public Map<String, Object> getValueMap() {\r
+        return this.valueMap;\r
+    }\r
+\r
+    public void sendMessage(Message msg) {\r
+        if (msg == null) {\r
+            throw new NullPointerException("msg == null");\r
+        }\r
+        this.sendedMessageQueue.offer(msg);\r
+    }\r
+\r
+    final Queue<Message> getSendedMessageQueue() {\r
+        return this.sendedMessageQueue;\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/state_engine/StateEngine.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/state_engine/StateEngine.java
new file mode 100644 (file)
index 0000000..e2c5aba
--- /dev/null
@@ -0,0 +1,71 @@
+\r
+package jp.gr.java_conf.u6k.state_engine;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import jp.gr.java_conf.u6k.animation.AnimationWindow;\r
+\r
+public class StateEngine {\r
+\r
+    private List<StateObject> stateObjectList = new ArrayList<StateObject>();\r
+\r
+    private StateContext      ctx             = new StateContext();\r
+\r
+    public StateEngine(StateObject startupObject) {\r
+        if (startupObject == null) {\r
+            throw new NullPointerException("startupObject == null");\r
+        }\r
+        this.stateObjectList.add(startupObject);\r
+    }\r
+\r
+    public void execute(AnimationWindow window) {\r
+        StateObject obj;\r
+        Message msg;\r
+\r
+        // コンテキストを初期化\r
+        this.ctx.getValueMap().clear();\r
+        this.ctx.getValueMap().put("window", window);\r
+\r
+        // 元から存在するオブジェクトを処理\r
+        for (int i = 0; i < this.stateObjectList.size(); i++) {\r
+            obj = this.stateObjectList.get(i);\r
+\r
+            this.ctx.setTarget(obj);\r
+            obj.execute(this.ctx);\r
+            obj.incrementTime();\r
+        }\r
+\r
+        while (!this.ctx.getAddedStateObjectQueue().isEmpty() || !this.ctx.getSendedMessageQueue().isEmpty()) {\r
+            // 追加されたオブジェクトを処理&追加\r
+            while ((obj = this.ctx.getAddedStateObjectQueue().poll()) != null) {\r
+                this.stateObjectList.add(obj);\r
+\r
+                this.ctx.setTarget(obj);\r
+                obj.execute(this.ctx);\r
+                obj.incrementTime();\r
+            }\r
+\r
+            // メッセージを処理\r
+            while ((msg = this.ctx.getSendedMessageQueue().poll()) != null) {\r
+                for (int i = 0; i < this.stateObjectList.size(); i++) {\r
+                    obj = this.stateObjectList.get(i);\r
+\r
+                    this.ctx.setTarget(obj);\r
+                    obj.receiveMessage(ctx, msg);\r
+                }\r
+            }\r
+        }\r
+\r
+        // 状態遷移\r
+        for (int i = 0; i < this.stateObjectList.size(); i++) {\r
+            obj = this.stateObjectList.get(i);\r
+\r
+            ctx.setTarget(obj);\r
+            obj.stateTransition(ctx);\r
+            if (obj.isDisposed()) {\r
+                this.stateObjectList.remove(obj);\r
+            }\r
+        }\r
+    }\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/state_engine/StateObject.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/state_engine/StateObject.java
new file mode 100644 (file)
index 0000000..7cbfd83
--- /dev/null
@@ -0,0 +1,58 @@
+\r
+package jp.gr.java_conf.u6k.state_engine;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+public abstract class StateObject {\r
+\r
+    private List<State> stateList = new ArrayList<State>();\r
+\r
+    private long        time;\r
+\r
+    protected List<State> getStateList() {\r
+        return this.stateList;\r
+    }\r
+\r
+    final void execute(StateContext ctx) {\r
+        for (State s : this.stateList.toArray(new State[0])) {\r
+            s.execute(ctx);\r
+        }\r
+    }\r
+\r
+    final void receiveMessage(StateContext ctx, Message msg) {\r
+        for (State s : this.stateList.toArray(new State[0])) {\r
+            s.receiveMessage(ctx, msg);\r
+        }\r
+    }\r
+\r
+    final void stateTransition(StateContext ctx) {\r
+        for (State s : this.stateList.toArray(new State[0])) {\r
+            for (Transition t : s.getDestinationTransitionList()) {\r
+                if (t.condition(this, ctx)) {\r
+                    s.dispose(ctx);\r
+                    this.stateList.remove(s);\r
+\r
+                    State nextState = t.getDestinationState();\r
+                    if (nextState != null) {\r
+                        nextState.initialize(ctx);\r
+                        this.stateList.add(nextState);\r
+                    }\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    final boolean isDisposed() {\r
+        return this.stateList.size() == 0;\r
+    }\r
+\r
+    public long getTime() {\r
+        return this.time;\r
+    }\r
+\r
+    final void incrementTime() {\r
+        this.time++;\r
+    }\r
+\r
+}\r
diff --git a/state-engine/src/main/java/jp/gr/java_conf/u6k/state_engine/Transition.java b/state-engine/src/main/java/jp/gr/java_conf/u6k/state_engine/Transition.java
new file mode 100644 (file)
index 0000000..978135b
--- /dev/null
@@ -0,0 +1,18 @@
+\r
+package jp.gr.java_conf.u6k.state_engine;\r
+\r
+public abstract class Transition {\r
+\r
+    private State destinationState;\r
+\r
+    public abstract boolean condition(StateObject obj, StateContext ctx);\r
+\r
+    public void setDestinationState(State dest) {\r
+        this.destinationState = dest;\r
+    }\r
+\r
+    public State getDestinationState() {\r
+        return this.destinationState;\r
+    }\r
+\r
+}\r