You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

525 regels
21 KiB

  1. package roadtrip;
  2. import com.jme3.bullet.control.BetterCharacterControl;
  3. import com.jme3.bullet.control.VehicleControl;
  4. import com.jme3.input.ChaseCamera;
  5. import com.jme3.input.KeyInput;
  6. import com.jme3.input.MouseInput;
  7. import com.jme3.input.controls.ActionListener;
  8. import com.jme3.input.controls.AnalogListener;
  9. import com.jme3.input.controls.KeyTrigger;
  10. import com.jme3.input.controls.MouseAxisTrigger;
  11. import com.jme3.light.AmbientLight;
  12. import com.jme3.light.DirectionalLight;
  13. import com.jme3.material.Material;
  14. import com.jme3.math.*;
  15. import com.jme3.post.FilterPostProcessor;
  16. import com.jme3.post.filters.DepthOfFieldFilter;
  17. import com.jme3.post.filters.FogFilter;
  18. import com.jme3.scene.Geometry;
  19. import com.jme3.scene.Node;
  20. import com.jme3.scene.Spatial;
  21. import com.jme3.scene.shape.Box;
  22. import roadtrip.model.VehicleInstance;
  23. import roadtrip.view.CompassNode;
  24. import roadtrip.view.GameMenuNode;
  25. import roadtrip.view.GameWorldView;
  26. import roadtrip.view.HideControl;
  27. import roadtrip.view.VehicleNode;
  28. import roadtrip.view.model.CameraType;
  29. import roadtrip.view.model.GameWorldState;
  30. import roadtrip.view.model.Player;
  31. /**
  32. *
  33. * @author dejvino
  34. */
  35. public class RoadTrip extends GameApplication implements ActionListener, AnalogListener {
  36. public static void main(String[] args) {
  37. RoadTrip app = new RoadTrip();
  38. app.start();
  39. }
  40. public static boolean DEBUG = !true;
  41. private GameWorldState gameWorldState;
  42. private GameWorldView gameWorldView;
  43. private GameMenuNode gameMenuNode;
  44. private CameraType cameraType = CameraType.FIRST_PERSON;
  45. private ChaseCamera chaseCam;
  46. private float camFov = 85;
  47. private Player player = new Player();
  48. private Vector3f journeyTarget = new Vector3f(50, 0f, 50f);
  49. private Node targetNode;
  50. private CompassNode compassNode;
  51. float inputTurning;
  52. float inputAccel;
  53. float lookX, lookY;
  54. int score = 0;
  55. private FilterPostProcessor fpp;
  56. DepthOfFieldFilter dofFilter;
  57. @Override
  58. public void initializeGame() {
  59. super.initializeGame();
  60. bulletAppState.setDebugEnabled(DEBUG);
  61. if (DEBUG) {
  62. attachDebugStates();
  63. }
  64. inputManager.setCursorVisible(false);
  65. setupKeys();
  66. //audioRenderer.setEnvironment(Environment.Dungeon);
  67. //AL10.alDistanceModel(AL11.AL_EXPONENT_DISTANCE);
  68. // Environment
  69. DirectionalLight dl = new DirectionalLight();
  70. dl.setColor(ColorRGBA.LightGray);
  71. dl.setDirection(new Vector3f(1, -1, 1));
  72. rootNode.addLight(dl);
  73. AmbientLight al = new AmbientLight();
  74. al.setColor(new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f));
  75. rootNode.addLight(al);
  76. gameWorldState = new GameWorldState(1L);
  77. gameWorldView = GameWorldView.create(gameWorldState, assetManager, cam, rootNode, getPhysicsSpace(), new HideControl.TargetProvider() {
  78. @Override
  79. public Vector3f getTarget() {
  80. return player.node.getWorldTranslation();
  81. }
  82. });
  83. addCar();
  84. addCar();
  85. addCar();
  86. addCar();
  87. addCar();
  88. addPerson();
  89. addPerson();
  90. addPerson();
  91. addPerson();
  92. addPerson();
  93. addPerson();
  94. addPerson();
  95. addPlayer();
  96. addTarget();
  97. addCompass();
  98. addGameMenu();
  99. cam.setFrustumPerspective(camFov, settings.getWidth() / ((float)settings.getHeight()), 0.5f, 150f);
  100. chaseCam = new ChaseCamera(cam, player.node, inputManager);
  101. chaseCam.setDefaultDistance(60f);
  102. chaseCam.setSmoothMotion(true);
  103. fpp = new FilterPostProcessor(assetManager);
  104. //fpp.setNumSamples(4);
  105. FogFilter fog=new FogFilter();
  106. fog.setFogColor(new ColorRGBA(0.02f, 0.02f, 0.05f, 1.0f));
  107. fog.setFogDistance(1000);
  108. fog.setFogDensity(3.0f);
  109. fpp.addFilter(fog);
  110. dofFilter = new DepthOfFieldFilter();
  111. dofFilter.setFocusRange(5f);
  112. dofFilter.setFocusDistance(6f);
  113. dofFilter.setBlurScale(0.6f);
  114. fpp.addFilter(dofFilter);
  115. viewPort.addProcessor(fpp);
  116. viewPort.addProcessor(fpp);
  117. }
  118. protected void addGameMenu()
  119. {
  120. gameMenuNode = new GameMenuNode();
  121. gameMenuNode.initialize(getAssetManager());
  122. }
  123. private void setupKeys() {
  124. inputManager.clearMappings();
  125. inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_A));
  126. inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_D));
  127. inputManager.addMapping("Ups", new KeyTrigger(KeyInput.KEY_W));
  128. inputManager.addMapping("Downs", new KeyTrigger(KeyInput.KEY_S));
  129. inputManager.addMapping("Revs", new KeyTrigger(KeyInput.KEY_X));
  130. inputManager.addMapping("Space", new KeyTrigger(KeyInput.KEY_SPACE));
  131. inputManager.addMapping("Reset", new KeyTrigger(KeyInput.KEY_RETURN));
  132. inputManager.addMapping("Esc", new KeyTrigger(KeyInput.KEY_ESCAPE));
  133. inputManager.addMapping("Pause", new KeyTrigger(KeyInput.KEY_P));
  134. inputManager.addMapping("View", new KeyTrigger(KeyInput.KEY_V));
  135. inputManager.addMapping("LookX-", new MouseAxisTrigger(MouseInput.AXIS_X, true));
  136. inputManager.addMapping("LookX+", new MouseAxisTrigger(MouseInput.AXIS_X, false));
  137. inputManager.addMapping("LookY-", new MouseAxisTrigger(MouseInput.AXIS_Y, true));
  138. inputManager.addMapping("LookY+", new MouseAxisTrigger(MouseInput.AXIS_Y, false));
  139. inputManager.addListener(this, new String[] {
  140. "Lefts", "Rights", "Ups", "Downs", "Revs", "Space", "Reset", "Esc", "Pause", "View",
  141. "LookX-", "LookX+", "LookY-", "LookY+"
  142. });
  143. }
  144. private void addCar()
  145. {
  146. VehicleInstance vehicleInstance = VehicleInstance.createVehicle(gameWorldState.vehicles.size() % VehicleInstance.getVehicleTypesCount());
  147. vehicleInstance.brakeForce = vehicleInstance.accelerationForce;
  148. VehicleNode vehicle = new VehicleNode("Car " + vehicleInstance.toString(), vehicleInstance);
  149. vehicle.initialize(assetManager);
  150. vehicle.vehicleControl.setPhysicsLocation(new Vector3f(10f + (float)Math.random() * 40f, 228f, 12f + (float)Math.random() * 40f));
  151. gameWorldState.vehicles.add(vehicle);
  152. getPhysicsSpace().addAll(vehicle);
  153. rootNode.attachChild(vehicle);
  154. }
  155. private Node addPerson() {
  156. Spatial personModel = assetManager.loadModel("Models/person.j3o");
  157. Node person = new Node("person");
  158. person.attachChild(personModel);
  159. BetterCharacterControl personControl = new BetterCharacterControl(1f, 4f, 10f);
  160. /*personModel.setLocalTranslation(0f, -1f, 0f);
  161. BoxCollisionShape personShape = new BoxCollisionShape(new Vector3f(0.5f, 2f, 0.5f));
  162. RigidBodyControl personControl = new RigidBodyControl(personShape, 80f);/**/
  163. person.addControl(personControl);
  164. /**/personControl.setJumpForce(new Vector3f(0,5f,0));
  165. personControl.setGravity(new Vector3f(0,1f,0));
  166. personControl.warp(new Vector3f(10f + (float)Math.random() * 20f, 230f, 12f + (float)Math.random() * 20f));/**/
  167. //personControl.setPhysicsLocation(new Vector3f(10f, 30f, 12f));
  168. getPhysicsSpace().add(personControl);
  169. //getPhysicsSpace().addAll(person);
  170. rootNode.attachChild(person);
  171. Vector3f dir = new Vector3f((float)Math.random() * 2f - 1f, 0f, (float)Math.random() * 2f - 1f);
  172. personControl.setViewDirection(dir);
  173. personControl.setWalkDirection(dir);
  174. return person;
  175. }
  176. private void addPlayer()
  177. {
  178. player.node = addPerson();
  179. player.characterControl = player.node.getControl(BetterCharacterControl.class);
  180. player.headNode = new Node("head");
  181. player.headNode.setLocalTranslation(0f, 2.5f, 0f);
  182. player.node.attachChild(player.headNode);
  183. }
  184. private void addTarget()
  185. {
  186. Material matTarget = new Material(getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
  187. matTarget.setColor("Color", ColorRGBA.Red);
  188. Geometry targetGeom = new Geometry("target", new Box(new Vector3f(0.0f, 0f, 0.0f), 1.0f, 1000.0f, 1.0f));
  189. targetGeom.setMaterial(matTarget);
  190. targetNode = new Node("target");
  191. targetNode.attachChild(targetGeom);
  192. rootNode.attachChild(targetNode);
  193. targetNode.setLocalTranslation(journeyTarget);
  194. }
  195. private void addCompass()
  196. {
  197. compassNode = new CompassNode();
  198. compassNode.initialize(getAssetManager());
  199. rootNode.attachChild(compassNode);
  200. }
  201. @Override
  202. public void updateGame(float tpf) {
  203. float focusDist = 20f;
  204. chaseCam.setEnabled(cameraType == CameraType.CHASE);
  205. if (cameraType == CameraType.CHASE) {
  206. focusDist = cam.getLocation().distance(player.node.getWorldTranslation()) / 10f;
  207. }
  208. dofFilter.setFocusDistance(focusDist * 1.1f);
  209. dofFilter.setFocusRange(focusDist * 0.9f);
  210. for (VehicleNode vehicle : gameWorldState.vehicles) {
  211. vehicle.update(tpf);
  212. }
  213. listener.setLocation(cam.getLocation());
  214. listener.setRotation(cam.getRotation());
  215. gameMenuNode.moveToCamera(cam, player.node);
  216. if (player.vehicleNode == null) {
  217. player.characterControl.setViewDirection(new Quaternion().fromAngleAxis(inputTurning * tpf, Vector3f.UNIT_Y).mult(player.characterControl.getViewDirection()));
  218. player.characterControl.setWalkDirection(new Vector3f(player.characterControl.getViewDirection()).mult(inputAccel * tpf * 1000f).multLocal(1f, 0f, 1f));
  219. }
  220. Vector3f playerPos2d = new Vector3f(player.node.getWorldTranslation());
  221. playerPos2d.y = 0;
  222. Vector3f targetPos2d = new Vector3f(targetNode.getWorldTranslation());
  223. targetPos2d.y = 0;
  224. Vector3f targetDir = targetPos2d.subtract(playerPos2d);
  225. float targetDistance = targetDir.length();
  226. if (targetDistance < 5f) {
  227. onReachedTarget();
  228. }
  229. compassNode.setTargetText(((int)targetDistance) + " m");
  230. compassNode.setLocalTranslation(new Vector3f(player.node.getWorldTranslation()).addLocal(0f, 5f, 0f));
  231. compassNode.setLocalRotation(new Quaternion().fromAngles(0f, (float)Math.atan2(targetDir.x, targetDir.z)/*targetDir.angleBetween(Vector3f.UNIT_Z)*/, 0f));
  232. }
  233. @Override
  234. protected void updatePreRender(float tpf) {
  235. super.updatePreRender(tpf);
  236. Vector3f playerLocation = player.headNode.getWorldTranslation();
  237. Vector3f newLocation = new Vector3f(playerLocation).add(new Vector3f(-1f, 1.5f, 2.4f).mult(20f));
  238. if (cameraType == CameraType.FIRST_PERSON) {
  239. cam.setLocation(new Vector3f().addLocal(playerLocation));
  240. Vector3f lookAtDir = new Vector3f((float)Math.cos(lookX), (float)Math.tan(lookY - 1f), (float)Math.sin(lookX)).normalizeLocal();
  241. Quaternion camRot = new Quaternion();
  242. camRot.lookAt(lookAtDir, Vector3f.UNIT_Y);
  243. cam.setRotation(camRot);
  244. player.characterControl.setViewDirection(lookAtDir);
  245. }
  246. }
  247. protected void onReachedTarget()
  248. {
  249. score++;
  250. gameMenuNode.setMenuEntriesPrefix("SCORE: " + score + "\n\n");
  251. double angle = Math.random() * 2d - 1d;
  252. journeyTarget = journeyTarget.add(new Quaternion().fromAngleAxis((float) angle, Vector3f.UNIT_Y).mult(Vector3f.UNIT_Z).mult(100f));
  253. targetNode.setLocalTranslation(journeyTarget);
  254. }
  255. @Override
  256. public void onAction(String binding, boolean value, float tpf) {
  257. if (binding.equals("View")) {
  258. if (value) {
  259. cameraType = cameraType == CameraType.CHASE ? CameraType.FIRST_PERSON : CameraType.CHASE;
  260. }
  261. }
  262. if (gamePaused) {
  263. if (binding.equals("Lefts")) {
  264. // meh
  265. } else if (binding.equals("Rights")) {
  266. // meh
  267. } else if (binding.equals("Ups")) {
  268. if (value) {
  269. gameMenuNode.nextMenuEntry();
  270. }
  271. } else if (binding.equals("Downs")) {
  272. if (value) {
  273. gameMenuNode.prevMenuEntry();
  274. }
  275. } else if (binding.equals("Reset")) {
  276. if (value) {
  277. switch (gameMenuNode.getMenuEntryIndex()) {
  278. case 0: // New
  279. break;
  280. case 1: // Load
  281. break;
  282. case 2: // Settings
  283. break;
  284. case 3: // Credits
  285. break;
  286. case 4: // Exit
  287. stop();
  288. break;
  289. default:
  290. throw new RuntimeException("Unrecognized menu entry: " + gameMenuNode.getMenuEntryIndex());
  291. }
  292. }
  293. } else if (binding.equals("Esc")) {
  294. // TODO: hide menu
  295. if (value) {
  296. setGamePaused(false);
  297. }
  298. }
  299. } else {
  300. if (player.vehicleNode == null) {
  301. float walkSpeed = 1f;
  302. float turnSpeed = 1f;
  303. if (binding.equals("Lefts")) {
  304. if (value) {
  305. inputTurning += turnSpeed;
  306. } else {
  307. inputTurning -= turnSpeed;
  308. }
  309. } else if (binding.equals("Rights")) {
  310. if (value) {
  311. inputTurning -= turnSpeed;
  312. } else {
  313. inputTurning += turnSpeed;
  314. }
  315. } else if (binding.equals("Ups")) {
  316. if (value) {
  317. inputAccel += walkSpeed;
  318. } else {
  319. inputAccel -= walkSpeed;
  320. }
  321. } else if (binding.equals("Downs")) {
  322. if (value) {
  323. inputAccel -= walkSpeed;
  324. } else {
  325. inputAccel += walkSpeed;
  326. }
  327. } else if (binding.equals("Reset")) {
  328. if (value) {
  329. System.out.println("Reset - to car");
  330. Vector3f playerPos = player.node.getWorldTranslation();
  331. for (VehicleNode vehicle : gameWorldState.vehicles) {
  332. Vector3f vehiclePos = vehicle.getWorldTranslation();
  333. float dist = playerPos.distance(vehiclePos);
  334. System.out.println(" .. dist: " + dist);
  335. if (dist < 5f) {
  336. player.vehicleNode = vehicle;
  337. player.node.removeFromParent();
  338. player.node.setLocalTranslation(0f, 0f, -1f);
  339. player.node.setLocalRotation(Quaternion.DIRECTION_Z);
  340. player.node.removeControl(player.characterControl);
  341. player.vehicleNode.attachChild(player.node);
  342. VehicleInstance playerVehicle = player.vehicleNode.vehicleInstance;
  343. playerVehicle.accelerationValue = 0;
  344. playerVehicle.steeringValue = 0;
  345. player.walkDir = new Vector3f();
  346. break;
  347. }
  348. }
  349. }
  350. }
  351. } else {
  352. VehicleInstance playerVehicle = player.vehicleNode.vehicleInstance;
  353. VehicleControl playerVehicleControl = player.vehicleNode.vehicleControl;
  354. int playerCarType = playerVehicle.carType;
  355. float steerMax = 0.5f;
  356. if (playerCarType == VehicleInstance.TRUCK) {
  357. steerMax = 0.7f;
  358. }
  359. if (binding.equals("Lefts")) {
  360. if (value) {
  361. playerVehicle.steeringValue += steerMax;
  362. } else {
  363. playerVehicle.steeringValue += -steerMax;
  364. }
  365. playerVehicleControl.steer(playerVehicle.steeringValue);
  366. } else if (binding.equals("Rights")) {
  367. if (value) {
  368. playerVehicle.steeringValue += -steerMax;
  369. } else {
  370. playerVehicle.steeringValue += steerMax;
  371. }
  372. playerVehicleControl.steer(playerVehicle.steeringValue);
  373. } else if (binding.equals("Ups")) {
  374. if (value) {
  375. playerVehicle.accelerationValue += playerVehicle.accelerationForce;
  376. } else {
  377. playerVehicle.accelerationValue -= playerVehicle.accelerationForce;
  378. }
  379. playerVehicleControl.accelerate(2, playerVehicle.accelerationValue);
  380. playerVehicleControl.accelerate(3, playerVehicle.accelerationValue);
  381. if (playerCarType == VehicleInstance.TRUCK) {
  382. playerVehicleControl.accelerate(4, playerVehicle.accelerationValue);
  383. playerVehicleControl.accelerate(5, playerVehicle.accelerationValue);
  384. }
  385. } else if (binding.equals("Downs")) {
  386. float b;
  387. if (value) {
  388. playerVehicle.brakeForce = playerVehicle.accelerationForce;
  389. } else {
  390. playerVehicle.brakeForce = 0f;
  391. }
  392. playerVehicleControl.brake(0, playerVehicle.brakeForce);
  393. playerVehicleControl.brake(1, playerVehicle.brakeForce);
  394. } else if (binding.equals("Revs")) {
  395. if (value) {
  396. playerVehicle.accelerationValue += playerVehicle.accelerationForce;
  397. } else {
  398. playerVehicle.accelerationValue -= playerVehicle.accelerationForce;
  399. }
  400. playerVehicleControl.accelerate(2, -playerVehicle.accelerationValue);
  401. playerVehicleControl.accelerate(3, -playerVehicle.accelerationValue);
  402. if (playerCarType == VehicleInstance.TRUCK) {
  403. playerVehicleControl.accelerate(4, -playerVehicle.accelerationValue);
  404. playerVehicleControl.accelerate(5, -playerVehicle.accelerationValue);
  405. }
  406. } else if (binding.equals("Space")) {
  407. if (value) {
  408. playerVehicleControl.applyImpulse(player.jumpForce, Vector3f.ZERO);
  409. }
  410. } else if (binding.equals("Reset")) {
  411. if (value) {
  412. System.out.println("Reset - from car");
  413. player.node.removeFromParent();
  414. player.node.addControl(player.characterControl);
  415. player.characterControl.warp(player.vehicleNode.getLocalTranslation());
  416. rootNode.attachChild(player.node);
  417. player.vehicleNode = null;
  418. player.walkDir = new Vector3f();
  419. } else {
  420. }
  421. }
  422. }
  423. if (binding.equals("Esc")) {
  424. // TODO: open menu
  425. if (value) {
  426. setGamePaused(true);
  427. }
  428. } else if (binding.equals("Pause")) {
  429. if (value) {
  430. setGamePaused(!gamePaused);
  431. }
  432. }
  433. }
  434. }
  435. @Override
  436. public void onAnalog(String name, float value, float tpf) {
  437. if (gamePaused) { return; }
  438. float speedX = 100f;
  439. float speedY = 100f;
  440. if ("LookX-".equals(name)) {
  441. lookX += -value * tpf * speedX;
  442. }
  443. if ("LookX+".equals(name)) {
  444. lookX += value * tpf * speedX;
  445. }
  446. if ("LookY-".equals(name)) {
  447. lookY += -value * tpf * speedY;
  448. }
  449. if ("LookY+".equals(name)) {
  450. lookY += value * tpf * speedY;
  451. }
  452. lookY = (float)Math.max(0, Math.min(lookY, 2f));
  453. }
  454. @Override
  455. protected void onGamePause(boolean paused) {
  456. super.onGamePause(paused);
  457. if (paused) {
  458. rootNode.attachChild(gameMenuNode);
  459. } else {
  460. gameMenuNode.removeFromParent();
  461. }
  462. }
  463. }