package template.shooting; import java.awt.Color; import java.awt.Font; import java.awt.Frame; import java.awt.GraphicsConfiguration; import java.util.ArrayList; import javax.media.j3d.AmbientLight; import javax.media.j3d.BoundingSphere; import javax.media.j3d.DirectionalLight; import javax.media.j3d.Geometry; import javax.media.j3d.Texture; import javax.vecmath.Color3f; import javax.vecmath.Point3d; import javax.vecmath.Vector3d; import javax.vecmath.Vector3f; import com.sun.j3d.utils.image.TextureLoader; import framework.AI.GeometryGraph; import framework.AI.IState; import framework.AI.Location; import framework.RWT.RWTBoard; import framework.RWT.RWTCanvas3D; import framework.RWT.RWTContainer; import framework.RWT.RWTFrame3D; import framework.RWT.RWTLabel; import framework.RWT.RWTVirtualController; import framework.RWT.RWTVirtualKey; import framework.animation.Animation3D; import framework.animation.AnimationFactory; import framework.gameMain.SimpleGame; import framework.model3D.BackgroundBox; import framework.model3D.CollisionResult; import framework.model3D.GeometryCollector; import framework.model3D.ModelFactory; import framework.model3D.Object3D; import framework.model3D.Position3D; import framework.model3D.Universe; import framework.physics.Ground; import framework.physics.PhysicsUtility; import framework.physics.Velocity3D; import framework.view3D.Camera3D; /** * シューティングゲームのためのテンプレート * @author 新田直也 * */ public class TemplateShooting extends SimpleBattleGame { private boolean bShot = false; private RWTContainer container; // プレイ画面のコンテナ private RWTLabel gameOver = null; // ゲームオーバー表示用 private RWTLabel scoreDisplay = null; // スコア表示用 private int score = 0; // スコア @Override public void init(BattleField field, Camera3D camera) { // 環境光 AmbientLight amblight = new AmbientLight(new Color3f(0.3f, 0.3f, 0.3f)); amblight.setInfluencingBounds(new BoundingSphere(new Point3d(), 10000.0)); field.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)); field.placeLight(dirlight); // キャラクターの3Dデータを読み込み配置する Object3D pochaBody = ModelFactory.loadModel("data\\pocha\\pocha.wrl").createObject(); Animation3D pochaAnimation = AnimationFactory.loadAnimation("data\\pocha\\walk.wrl"); Player player = new Player(pochaBody, pochaAnimation); player.setPosition(new Position3D(-5.0, 0.0, 0.0)); player.setDirection(new Vector3d(0.0, 0.0, 1.0)); field.place(player); // ステージの3Dデータを読み込み配置する Object3D stageObj = ModelFactory.loadModel("data\\konan\\konan3.wrl", false, true).createObject(); Stage stage = new Stage(stageObj, "jimen1"); field.place(stage); // 背景を作成する buildSkyBox(field); // カメラの設定(一人称視点にする) camera.setViewPoint(player.getPosition().add(0.0, 1.5, 0.0)); camera.setViewLine(player.getDirection()); camera.setFieldOfView(1.5); } @Override public RWTFrame3D createFrame3D() { RWTFrame3D f = new RWTFrame3D(); f.setSize(800, 600); f.setTitle("Template for Shooting Games"); f.setMouseCapture(true); return f; } protected RWTContainer createRWTContainer() { container = new RWTContainer() { @Override public void build(GraphicsConfiguration gc) { RWTCanvas3D canvas; if (gc != null) { canvas = new RWTCanvas3D(gc, true); } else { canvas = new RWTCanvas3D(true); } canvas.setRelativePosition(0.0f, 0.0f); canvas.setRelativeSize(1.0f, 1.0f); gameOver = new RWTLabel(0.25f, 0.5f, "Game Over!!", Color.RED, new Font("", Font.ITALIC, 36)); gameOver.setVisible(false); canvas.addWidget(gameOver); RWTBoard scoreBoard = new RWTBoard(0.72f, 0.035f, 0.27f, 0.08f, new Color(1.0f, 1.0f, 1.0f, 0.3f)); scoreBoard.setVisible(true); canvas.addWidget(scoreBoard); scoreDisplay = new RWTLabel(0.75f, 0.1f, "Score: " + score, Color.WHITE, new Font("", Font.PLAIN, 20)); scoreDisplay.setVisible(true); canvas.addWidget(scoreDisplay); addCanvas(canvas); repaint(); } // RWT側ではイベント処理をしない @Override public void keyPressed(RWTVirtualKey key) {} @Override public void keyReleased(RWTVirtualKey key) {} @Override public void keyTyped(RWTVirtualKey key) {} }; return container; } @Override public void progress(RWTVirtualController virtualController, long interval) { // マウス操作の処理 double yaw = (virtualController.getMouseX() - .5) * Math.PI * 2.0; double pitch = (virtualController.getMouseY() - .5) * Math.PI; Vector3d direction = new Vector3d(Math.sin(yaw) * Math.cos(pitch), -Math.sin(pitch), -Math.cos(yaw) * Math.cos(pitch)); battleField.setPlayerDirection(direction); // キー操作の処理 Velocity3D curV = battleField.getPlayerVelocity(); if (virtualController.isKeyDown(0, RWTVirtualController.LEFT)) { curV.setX(battleField.getPlayerDirection().getZ() * 5.0); curV.setZ(battleField.getPlayerDirection().getX() * -5.0); battleField.setPlayerVelocity(curV); } else if (virtualController.isKeyDown(0, RWTVirtualController.RIGHT)) { curV.setX(battleField.getPlayerDirection().getZ() * -5.0); curV.setZ(battleField.getPlayerDirection().getX() * 5.0); battleField.setPlayerVelocity(curV); } else if (virtualController.isKeyDown(0, RWTVirtualController.UP)) { curV.setX(battleField.getPlayerDirection().getX() * 5.0); curV.setZ(battleField.getPlayerDirection().getZ() * 5.0); battleField.setPlayerVelocity(curV); } else if (virtualController.isKeyDown(0, RWTVirtualController.DOWN)) { curV.setX(battleField.getPlayerDirection().getX() * -5.0); curV.setZ(battleField.getPlayerDirection().getZ() * -5.0); battleField.setPlayerVelocity(curV); } else { curV.setX(0.0); curV.setZ(0.0); battleField.setPlayerVelocity(curV); } if (virtualController.isKeyDown(0, RWTVirtualController.BUTTON_A)) { // ジャンプ if (battleField.isPlayerOnGround()) { curV.setY(10.0); battleField.setPlayerVelocity(curV); } } if (virtualController.isMouseButtonDown(0)) { // 弾の発射 if (!bShot) { battleField.playerShoots(); } bShot = true; } else { bShot = false; } // 一定の確率で敵を発生 if (Math.random() < 0.01) { battleField.createEnemy(); } // 一定の確率で敵の弾を発射 if (Math.random() < 0.005) { battleField.enemyShoots(); } // 戦場のすべての登場物(プレイヤーや敵など)を一斉に動かす battleField.motion(interval); // ゲームオーバーか否かを判定する if (battleField.isPlayerHit()) { // プレイヤーに当たった gameOver.setVisible(true); } // 点数計算 int hits = battleField.getHitEnemyCount(); if (hits > 0) { score += hits * 100; scoreDisplay.setString("Score: " + score); } // カメラの移動、回転 camera.setViewPoint(battleField.getPlayerPosition().add(0.0, 1.5, 0.0)); camera.setViewLine(direction); } /** * ゲームのメイン * @param args */ public static void main(String[] args) { TemplateShooting game = new TemplateShooting(); game.setFramePolicy(5, 33, false); game.start(); } /** * 背景を作成する * @param field */ private void buildSkyBox(BattleField field) { TextureLoader loaderTop = new TextureLoader("data\\konan\\sky.jpg", TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, null); Texture textureTop = loaderTop.getTexture(); TextureLoader loaderBottom = new TextureLoader("data\\konan\\sky.jpg", TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, null); Texture textureBottom = loaderBottom.getTexture(); TextureLoader loaderNorth = new TextureLoader("data\\konan\\sky.jpg", TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, null); Texture textureNorth = loaderNorth.getTexture(); TextureLoader loaderSouth = new TextureLoader("data\\konan\\sky.jpg", TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, null); Texture textureSouth = loaderSouth.getTexture(); TextureLoader loaderWest = new TextureLoader("data\\konan\\sky.jpg", TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, null); Texture textureWest = loaderWest.getTexture(); TextureLoader loaderEast = new TextureLoader("data\\konan\\sky.jpg", TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, null); Texture textureEast = loaderEast.getTexture(); BackgroundBox background = new BackgroundBox(textureNorth, textureWest, textureSouth, textureEast, textureTop, textureBottom); BoundingSphere bs = new BoundingSphere(); bs.setRadius(1000); background.setApplicationBounds(bs); field.place(background); } }