package template.RPG; import java.awt.Color; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import javax.media.j3d.AmbientLight; import javax.media.j3d.BoundingSphere; import javax.media.j3d.DirectionalLight; import javax.media.j3d.GraphicsConfigTemplate3D; import javax.vecmath.Color3f; import javax.vecmath.Point3d; import javax.vecmath.Vector3d; import javax.vecmath.Vector3f; import framework.RWT.RWTContainer; import framework.RWT.RWTFrame3D; import framework.RWT.RWTVirtualController; import framework.animation.Animation3D; import framework.animation.AnimationFactory; import framework.gameMain.BaseScenarioGameContainer; import framework.gameMain.SimpleScenarioGame; import framework.model3D.ModelFactory; import framework.model3D.Object3D; import framework.model3D.Position3D; import framework.model3D.Quaternion3D; import framework.model3D.Universe; import framework.physics.Ground; import framework.physics.PhysicsUtility; import framework.physics.Velocity3D; import framework.scenario.Event; import framework.scenario.IWorld; import framework.scenario.ScenarioManager; import framework.scenario.ScenarioState; import framework.view3D.Camera3D; /** * シナリオ駆動型ゲームのためのテンプレート * @author 新田直也 * */ public class TemplateScenarioGame extends SimpleScenarioGame implements IWorld { private Player player; // プレイヤー private Player king; // 王様 private Ground stage; // ステージ private RWTFrame3D frame; // サブ画面用 private Universe subUniverse; private Camera3D subCamera; private BaseScenarioGameContainer subContainer = null; @Override public void init(Universe universe, Camera3D camera) { // 環境光 AmbientLight amblight = new AmbientLight(new Color3f(0.3f, 0.3f, 0.3f)); amblight.setInfluencingBounds(new BoundingSphere(new Point3d(), 10000.0)); universe.placeLight(amblight); // 平行光源 DirectionalLight dirlight = new DirectionalLight(true, // 光のON/OFF new Color3f(1.0f, 1.0f, 1.0f), // 光の色 new Vector3f(0.0f, -1.0f, -0.5f) // 光の方向ベクトル ); dirlight.setInfluencingBounds(new BoundingSphere(new Point3d(), 10000.0)); universe.placeLight(dirlight); // キャラクターの3Dデータを読み込み配置する Object3D pochaBody = ModelFactory.loadModel("data\\pocha\\pocha.wrl").createObject(); Animation3D pochaAnimation = AnimationFactory.loadAnimation("data\\pocha\\walk.wrl"); player = new Player(pochaBody, pochaAnimation); player.setPosition(new Position3D(-77.68, 0.0, -1.9)); universe.place(player); // 王様を配置(キャラクターは流用) king = new Player(pochaBody, pochaAnimation); king.setPosition(new Position3D(3.87, -11.92, 21.39)); universe.place(king); // ステージの3Dデータを読み込み配置する Object3D stageObj = ModelFactory.loadModel("data\\konan\\konan3.wrl").createObject(); stage = new Ground(stageObj); universe.place(stage); // カメラの設定(俯瞰視点にする) camera.addTarget(player); camera.setViewLine(new Vector3d(0.0, -10.0, -10.0)); camera.setFieldOfView(1.5); } /** * 戦闘画面の初期化 * @param universe * @param camera */ private void subInit(Universe universe, Camera3D camera) { // 環境光 AmbientLight amblight = new AmbientLight(new Color3f(0.3f, 0.3f, 0.3f)); amblight.setInfluencingBounds(new BoundingSphere(new Point3d(), 10000.0)); universe.placeLight(amblight); // 平行光源 DirectionalLight dirlight = new DirectionalLight(true, // 光のON/OFF new Color3f(1.0f, 1.0f, 1.0f), // 光の色 new Vector3f(0.0f, -1.0f, -0.5f) // 光の方向ベクトル ); dirlight.setInfluencingBounds(new BoundingSphere(new Point3d(), 10000.0)); universe.placeLight(dirlight); // 敵キャラクターの3Dデータを読み込み配置する Object3D enemy = ModelFactory.loadModel("data\\pocha\\pocha.wrl").createObject(); enemy.apply(new Position3D(0.0, 0.0, 0.0), false); enemy.apply(new Quaternion3D(0.0, 1.0, 0.0, Math.PI / 2.0), false); universe.place(enemy); // カメラの設定(横視点にする) camera.addTarget(enemy.getPosition3D().add(0.0, 1.0, 0.0)); camera.setViewLine(new Vector3d(0.0, -2.0, 10.0)); camera.setCameraBack(new Vector3d(0.0, 0.0, 2.0)); camera.setFieldOfView(1.5); } @Override public RWTFrame3D createFrame3D() { frame = new RWTFrame3D(); frame.setSize(800, 600); frame.setTitle("Template for Role Playing Games"); frame.setBackground(Color.BLACK); return frame; } @Override protected RWTContainer createRWTContainer() { scenario = new ScenarioManager("data\\sampleScenario\\scenario2.xml", this); // シナリオファイルの読み込み container = new ScenarioGameContainer(scenario); return container; } // 戦闘用画面の作成 protected RWTContainer createSubRWTContainer() { subContainer = new FightContainer(scenario); return subContainer; } // 戦闘用画面への切り替え protected void changeToSubContainer() { if (subContainer == null) { subContainer = (BaseScenarioGameContainer)createSubRWTContainer(); frame.setContentPane(subContainer); GraphicsConfiguration gc = null; if (frame.isShadowCasting()) { // 影を付ける場合 // ステンシルバッファを使用する GraphicsConfiguration の生成 GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice gd = ge.getDefaultScreenDevice(); GraphicsConfigTemplate3D gct3D = new GraphicsConfigTemplate3D(); gct3D.setStencilSize(8); gc = gd.getBestConfiguration(gct3D); } subContainer.build(gc); subUniverse = new Universe(); subCamera = new Camera3D(subUniverse); subInit(subUniverse, subCamera); subCamera.adjust(0L); subContainer.getPrimaryRWTCanvas3D().attachCamera(subCamera); subUniverse.compile(); } else { frame.setContentPane(subContainer); subContainer.repaint(); } } // 戦闘用画面からメイン画面への切り替え protected void changeToMainContainer() { frame.setContentPane(container); container.repaint(); } @Override public void progress(RWTVirtualController virtualController, long interval) { // 以下にキー操作のプログラムを書く Velocity3D curV = player.getVelocity(); if (virtualController.isKeyDown(0, RWTVirtualController.LEFT)) { player.setDirection(new Vector3d(-1.0, 0.0, 0.0)); curV.setX(-10.0); curV.setZ(0.0); } else if (virtualController.isKeyDown(0, RWTVirtualController.RIGHT)) { player.setDirection(new Vector3d(1.0, 0.0, 0.0)); curV.setX(10.0); curV.setZ(0.0); } else if (virtualController.isKeyDown(0, RWTVirtualController.UP)) { player.setDirection(new Vector3d(0.0, 0.0, -1.0)); curV.setZ(-10.0); curV.setX(0.0); } else if (virtualController.isKeyDown(0, RWTVirtualController.DOWN)) { player.setDirection(new Vector3d(0.0, 0.0, 1.0)); curV.setZ(10.0); curV.setX(0.0); } else { curV.setX(0.0); curV.setZ(0.0); } player.setVelocity(curV); // プレイヤーを動かす player.motion(interval, stage); // 衝突判定 if (PhysicsUtility.checkCollision(player.body, null, king.body, null) != null) { // プレイヤーと王様がぶつかった場合 scenario.fire("王様とぶつかる"); // 「王様とぶつかる」というイベントを発生する(シナリオが進む) } } @Override public void action(String action, Event event, ScenarioState nextState) { // シナリオ進行による世界への作用をここに書く if (action.equals("startFight")) { changeToSubContainer(); } else if (action.equals("endFight")) { changeToMainContainer(); } } /** * ゲームのメイン * @param args */ public static void main(String[] args) { TemplateScenarioGame game = new TemplateScenarioGame(); game.start(); } }