mirror of
https://github.com/Dejvino/roadtrip
synced 2024-12-22 11:48:49 +00:00
Map: refactoring of map generation. Added RoadTrip Planner app.
This commit is contained in:
parent
f75fdecf07
commit
cbf342cb97
@ -26,6 +26,12 @@ public abstract class GameApplication extends NotSoSimpleApplication
|
|||||||
stateManager.attach(bulletAppState);
|
stateManager.attach(bulletAppState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update() {
|
||||||
|
super.update();
|
||||||
|
updateListenerPosition();
|
||||||
|
}
|
||||||
|
|
||||||
protected PhysicsSpace getPhysicsSpace(){
|
protected PhysicsSpace getPhysicsSpace(){
|
||||||
return bulletAppState.getPhysicsSpace();
|
return bulletAppState.getPhysicsSpace();
|
||||||
}
|
}
|
||||||
@ -43,4 +49,10 @@ public abstract class GameApplication extends NotSoSimpleApplication
|
|||||||
{
|
{
|
||||||
bulletAppState.setEnabled(!paused);
|
bulletAppState.setEnabled(!paused);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void updateListenerPosition()
|
||||||
|
{
|
||||||
|
listener.setLocation(cam.getLocation());
|
||||||
|
listener.setRotation(cam.getRotation());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -153,6 +153,8 @@ public class RoadTrip extends GameApplication implements ActionListener {
|
|||||||
VehicleNode vehicle = new VehicleNode("Car " + vehicleInstance.toString(), vehicleInstance);
|
VehicleNode vehicle = new VehicleNode("Car " + vehicleInstance.toString(), vehicleInstance);
|
||||||
vehicle.initialize(assetManager);
|
vehicle.initialize(assetManager);
|
||||||
|
|
||||||
|
vehicle.vehicleControl.setPhysicsLocation(new Vector3f(10f + (float)Math.random() * 40f, 228f, 12f + (float)Math.random() * 40f));
|
||||||
|
|
||||||
gameWorldState.vehicles.add(vehicle);
|
gameWorldState.vehicles.add(vehicle);
|
||||||
getPhysicsSpace().addAll(vehicle);
|
getPhysicsSpace().addAll(vehicle);
|
||||||
rootNode.attachChild(vehicle);
|
rootNode.attachChild(vehicle);
|
||||||
@ -169,7 +171,7 @@ public class RoadTrip extends GameApplication implements ActionListener {
|
|||||||
person.addControl(personControl);
|
person.addControl(personControl);
|
||||||
/**/personControl.setJumpForce(new Vector3f(0,5f,0));
|
/**/personControl.setJumpForce(new Vector3f(0,5f,0));
|
||||||
personControl.setGravity(new Vector3f(0,1f,0));
|
personControl.setGravity(new Vector3f(0,1f,0));
|
||||||
personControl.warp(new Vector3f(10f + (float)Math.random() * 20f, 30f, 12f + (float)Math.random() * 20f));/**/
|
personControl.warp(new Vector3f(10f + (float)Math.random() * 20f, 230f, 12f + (float)Math.random() * 20f));/**/
|
||||||
//personControl.setPhysicsLocation(new Vector3f(10f, 30f, 12f));
|
//personControl.setPhysicsLocation(new Vector3f(10f, 30f, 12f));
|
||||||
getPhysicsSpace().add(personControl);
|
getPhysicsSpace().add(personControl);
|
||||||
//getPhysicsSpace().addAll(person);
|
//getPhysicsSpace().addAll(person);
|
||||||
|
77
src/roadtrip/RoadTripPlanner.java
Normal file
77
src/roadtrip/RoadTripPlanner.java
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
package roadtrip;
|
||||||
|
|
||||||
|
import com.jme3.app.SimpleApplication;
|
||||||
|
import com.jme3.audio.AudioNode;
|
||||||
|
import com.jme3.audio.AudioSource.Status;
|
||||||
|
import com.jme3.bullet.BulletAppState;
|
||||||
|
import com.jme3.bullet.PhysicsSpace;
|
||||||
|
import com.jme3.bullet.collision.shapes.*;
|
||||||
|
import com.jme3.bullet.control.BetterCharacterControl;
|
||||||
|
import com.jme3.bullet.control.RigidBodyControl;
|
||||||
|
import com.jme3.bullet.control.VehicleControl;
|
||||||
|
import com.jme3.font.BitmapFont;
|
||||||
|
import com.jme3.font.BitmapText;
|
||||||
|
import com.jme3.font.Rectangle;
|
||||||
|
import com.jme3.input.ChaseCamera;
|
||||||
|
import com.jme3.input.KeyInput;
|
||||||
|
import com.jme3.input.controls.ActionListener;
|
||||||
|
import com.jme3.input.controls.KeyTrigger;
|
||||||
|
import com.jme3.light.AmbientLight;
|
||||||
|
import com.jme3.light.DirectionalLight;
|
||||||
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.math.*;
|
||||||
|
import com.jme3.renderer.queue.RenderQueue;
|
||||||
|
import com.jme3.scene.Geometry;
|
||||||
|
import com.jme3.scene.Node;
|
||||||
|
import com.jme3.scene.Spatial;
|
||||||
|
import com.jme3.scene.debug.Arrow;
|
||||||
|
import com.jme3.scene.shape.Box;
|
||||||
|
import com.jme3.scene.shape.Cylinder;
|
||||||
|
import com.jme3.terrain.geomipmap.TerrainGrid;
|
||||||
|
import com.jme3.terrain.geomipmap.TerrainGridListener;
|
||||||
|
import com.jme3.terrain.geomipmap.TerrainQuad;
|
||||||
|
import java.util.Random;
|
||||||
|
import roadtrip.model.VehicleInstance;
|
||||||
|
import roadtrip.view.CompassNode;
|
||||||
|
import roadtrip.view.GameMenuNode;
|
||||||
|
import roadtrip.view.GameWorldView;
|
||||||
|
import roadtrip.view.VehicleNode;
|
||||||
|
import roadtrip.view.model.GameWorldState;
|
||||||
|
import roadtrip.view.model.Player;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author dejvino
|
||||||
|
*/
|
||||||
|
public class RoadTripPlanner extends SimpleApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
RoadTripPlanner app = new RoadTripPlanner();
|
||||||
|
app.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean DEBUG = /*false;/*/true;/**/
|
||||||
|
|
||||||
|
protected BulletAppState bulletAppState;
|
||||||
|
private GameWorldState gameWorldState;
|
||||||
|
private GameWorldView gameWorldView;
|
||||||
|
|
||||||
|
protected PhysicsSpace getPhysicsSpace(){
|
||||||
|
return bulletAppState.getPhysicsSpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void simpleInitApp()
|
||||||
|
{
|
||||||
|
bulletAppState = new BulletAppState();
|
||||||
|
stateManager.attach(bulletAppState);
|
||||||
|
|
||||||
|
bulletAppState.setDebugEnabled(DEBUG);
|
||||||
|
|
||||||
|
gameWorldState = new GameWorldState(1L);
|
||||||
|
gameWorldView = GameWorldView.create(gameWorldState, assetManager, cam, rootNode, getPhysicsSpace());
|
||||||
|
|
||||||
|
flyCam.setMoveSpeed(300f);
|
||||||
|
cam.setLocation(new Vector3f(0, 200f, 0));
|
||||||
|
}
|
||||||
|
}
|
26
src/roadtrip/model/MapObjectInstance.java
Normal file
26
src/roadtrip/model/MapObjectInstance.java
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package roadtrip.model;
|
||||||
|
|
||||||
|
import com.jme3.math.Vector3f;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by dejvino on 21.01.2017.
|
||||||
|
*/
|
||||||
|
public class MapObjectInstance
|
||||||
|
{
|
||||||
|
private Vector3f position;
|
||||||
|
|
||||||
|
public MapObjectInstance(Vector3f position)
|
||||||
|
{
|
||||||
|
this.position = new Vector3f(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3f getPosition()
|
||||||
|
{
|
||||||
|
return new Vector3f(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPosition(Vector3f position)
|
||||||
|
{
|
||||||
|
this.position = new Vector3f(position);
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package roadtrip.model;
|
package roadtrip.model;
|
||||||
|
|
||||||
|
import com.jme3.terrain.geomipmap.TerrainQuad;
|
||||||
import roadtrip.model.AbstractProceduralBlock;
|
import roadtrip.model.AbstractProceduralBlock;
|
||||||
import roadtrip.model.ProceduralMapQuadBlock;
|
import roadtrip.model.ProceduralMapQuadBlock;
|
||||||
|
|
||||||
@ -13,8 +14,10 @@ public class ProceduralMapBlock extends AbstractProceduralBlock
|
|||||||
super(seed);
|
super(seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProceduralMapQuadBlock getMapQuadBlock(String quadName)
|
public ProceduralMapQuadBlock getMapQuadBlock(TerrainQuad terrainQuad)
|
||||||
{
|
{
|
||||||
return getSubBlock(quadName, ProceduralMapQuadBlock.class);
|
ProceduralMapQuadBlock quadBlock = getSubBlock(terrainQuad.getName(), ProceduralMapQuadBlock.class);
|
||||||
|
quadBlock.initialize(terrainQuad);
|
||||||
|
return quadBlock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,56 @@
|
|||||||
package roadtrip.model;
|
package roadtrip.model;
|
||||||
|
|
||||||
|
import com.jme3.bullet.collision.shapes.ConeCollisionShape;
|
||||||
|
import com.jme3.bullet.control.RigidBodyControl;
|
||||||
|
import com.jme3.math.Vector2f;
|
||||||
|
import com.jme3.math.Vector3f;
|
||||||
|
import com.jme3.scene.Spatial;
|
||||||
|
import com.jme3.terrain.geomipmap.TerrainQuad;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by dejvino on 21.01.2017.
|
* Created by dejvino on 21.01.2017.
|
||||||
*/
|
*/
|
||||||
public class ProceduralMapQuadBlock extends AbstractProceduralBlock
|
public class ProceduralMapQuadBlock extends AbstractProceduralBlock
|
||||||
{
|
{
|
||||||
|
protected float cellSize = 64 * 2f * 2f; /* terrainGrid.getPatchSize() * terrainGrid.getLocalScale().x * 2f */
|
||||||
|
|
||||||
|
private List<MapObjectInstance> mapObjects;
|
||||||
|
|
||||||
public ProceduralMapQuadBlock(long seed)
|
public ProceduralMapQuadBlock(long seed)
|
||||||
{
|
{
|
||||||
super(seed);
|
super(seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void initialize(TerrainQuad terrainQuad)
|
||||||
|
{
|
||||||
|
mapObjects = new LinkedList<>();
|
||||||
|
Random quadRand = getBlockRandom();
|
||||||
|
Vector2f prevPos = null;
|
||||||
|
Vector2f quadPos = new Vector2f(terrainQuad.getLocalTranslation().x, terrainQuad.getLocalTranslation().z);
|
||||||
|
for (int i = 0; i < quadRand.nextInt(10000); i++) {
|
||||||
|
Vector2f pos;
|
||||||
|
if (prevPos == null || quadRand.nextFloat() < 0.2f) {
|
||||||
|
pos = new Vector2f((quadRand.nextFloat() - 0.5f) * cellSize, (quadRand.nextFloat() - 0.5f) * cellSize)
|
||||||
|
.addLocal(quadPos);
|
||||||
|
} else {
|
||||||
|
pos = new Vector2f((quadRand.nextFloat() - 0.5f) * 20f, (quadRand.nextFloat() - 0.5f) * 20f)
|
||||||
|
.addLocal(prevPos);
|
||||||
|
}
|
||||||
|
prevPos = pos;
|
||||||
|
float height = terrainQuad.getHeight(pos);
|
||||||
|
Vector3f location = new Vector3f(pos.x, height, pos.y);
|
||||||
|
mapObjects.add(new MapObjectInstance(location));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterable<? extends MapObjectInstance> getMapObjects()
|
||||||
|
{
|
||||||
|
if (mapObjects == null) throw new RuntimeException("Call to getMapObjects on an uninitialized block.");
|
||||||
|
return mapObjects;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,10 @@ import com.jme3.bullet.PhysicsSpace;
|
|||||||
import com.jme3.bullet.collision.shapes.ConeCollisionShape;
|
import com.jme3.bullet.collision.shapes.ConeCollisionShape;
|
||||||
import com.jme3.bullet.collision.shapes.HeightfieldCollisionShape;
|
import com.jme3.bullet.collision.shapes.HeightfieldCollisionShape;
|
||||||
import com.jme3.bullet.control.RigidBodyControl;
|
import com.jme3.bullet.control.RigidBodyControl;
|
||||||
|
import com.jme3.light.AmbientLight;
|
||||||
|
import com.jme3.light.DirectionalLight;
|
||||||
import com.jme3.material.Material;
|
import com.jme3.material.Material;
|
||||||
import com.jme3.math.Vector2f;
|
import com.jme3.math.ColorRGBA;
|
||||||
import com.jme3.math.Vector3f;
|
import com.jme3.math.Vector3f;
|
||||||
import com.jme3.renderer.Camera;
|
import com.jme3.renderer.Camera;
|
||||||
import com.jme3.scene.Node;
|
import com.jme3.scene.Node;
|
||||||
@ -23,12 +25,11 @@ import com.jme3.terrain.noise.filter.SmoothFilter;
|
|||||||
import com.jme3.terrain.noise.fractal.FractalSum;
|
import com.jme3.terrain.noise.fractal.FractalSum;
|
||||||
import com.jme3.terrain.noise.modulator.NoiseModulator;
|
import com.jme3.terrain.noise.modulator.NoiseModulator;
|
||||||
import com.jme3.texture.Texture;
|
import com.jme3.texture.Texture;
|
||||||
|
import roadtrip.model.MapObjectInstance;
|
||||||
import roadtrip.model.ProceduralMapQuadBlock;
|
import roadtrip.model.ProceduralMapQuadBlock;
|
||||||
import roadtrip.model.TerrainDataProvider;
|
import roadtrip.model.TerrainDataProvider;
|
||||||
import roadtrip.view.model.GameWorldState;
|
import roadtrip.view.model.GameWorldState;
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by dejvino on 14.01.2017.
|
* Created by dejvino on 14.01.2017.
|
||||||
*/
|
*/
|
||||||
@ -59,6 +60,15 @@ public class GameWorldView {
|
|||||||
|
|
||||||
private void initialize()
|
private void initialize()
|
||||||
{
|
{
|
||||||
|
// Environment
|
||||||
|
DirectionalLight dl = new DirectionalLight();
|
||||||
|
dl.setColor(ColorRGBA.LightGray);
|
||||||
|
dl.setDirection(new Vector3f(1, -1, 1));
|
||||||
|
rootNode.addLight(dl);
|
||||||
|
AmbientLight al = new AmbientLight();
|
||||||
|
al.setColor(new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f));
|
||||||
|
rootNode.addLight(al);
|
||||||
|
|
||||||
// TERRAIN TEXTURE material
|
// TERRAIN TEXTURE material
|
||||||
terrain.mat_terrain = new Material(assetManager, "Common/MatDefs/Terrain/HeightBasedTerrain.j3md");
|
terrain.mat_terrain = new Material(assetManager, "Common/MatDefs/Terrain/HeightBasedTerrain.j3md");
|
||||||
|
|
||||||
@ -133,15 +143,15 @@ public class GameWorldView {
|
|||||||
|
|
||||||
ground.addPreFilter(terrain.terrainDataProvider.iterate);
|
ground.addPreFilter(terrain.terrainDataProvider.iterate);
|
||||||
|
|
||||||
terrain.terrainGrid = new TerrainGrid("terrain", 64 + 1, 256 + 1, new FractalTileLoader(ground, 300f));
|
terrain.terrainGrid = new TerrainGrid("terrain", 16 + 1, 512 + 1, new FractalTileLoader(ground, 300f));
|
||||||
|
|
||||||
terrain.terrainGrid.setMaterial(terrain.mat_terrain);
|
terrain.terrainGrid.setMaterial(terrain.mat_terrain);
|
||||||
terrain.terrainGrid.setLocalTranslation(0, -200, 0);
|
//terrain.terrainGrid.setLocalTranslation(0, -200, 0);
|
||||||
terrain.terrainGrid.setLocalScale(2f, 1f, 2f);
|
//terrain.terrainGrid.setLocalScale(2f, 1f, 2f);
|
||||||
this.rootNode.attachChild(terrain.terrainGrid);
|
this.rootNode.attachChild(terrain.terrainGrid);
|
||||||
|
|
||||||
TerrainLodControl control = new TerrainGridLodControl(terrain.terrainGrid, camera);
|
TerrainLodControl control = new TerrainGridLodControl(terrain.terrainGrid, camera);
|
||||||
control.setLodCalculator(new DistanceLodCalculator(64 + 1, 2.7f)); // patch size, and a multiplier
|
control.setLodCalculator(new DistanceLodCalculator(32 + 1, 2.7f)); // patch size, and a multiplier
|
||||||
terrain.terrainGrid.addControl(control);
|
terrain.terrainGrid.addControl(control);
|
||||||
|
|
||||||
final TerrainGrid terrainGrid = terrain.terrainGrid;
|
final TerrainGrid terrainGrid = terrain.terrainGrid;
|
||||||
@ -163,48 +173,33 @@ public class GameWorldView {
|
|||||||
|
|
||||||
String quadObjectsNodeKey = getQuadObjectsNodeKey(quad);
|
String quadObjectsNodeKey = getQuadObjectsNodeKey(quad);
|
||||||
Node objects = new Node(quadObjectsNodeKey);
|
Node objects = new Node(quadObjectsNodeKey);
|
||||||
populateQuadObjectsNode(quad, quadObjectsNodeKey, objects);
|
populateQuadObjectsNode(quad, objects);
|
||||||
rootNode.attachChild(objects);
|
rootNode.attachChild(objects);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void populateQuadObjectsNode(TerrainQuad quad, String quadObjectsNodeKey, Node objects)
|
protected void populateQuadObjectsNode(TerrainQuad quad, Node objects)
|
||||||
{
|
{
|
||||||
ProceduralMapQuadBlock mapQuadBlock = state.proceduralMap.getMapQuadBlock(quad.getName());
|
ProceduralMapQuadBlock mapQuadBlock = state.proceduralMap.getMapQuadBlock(quad);
|
||||||
|
|
||||||
// TODO: move any access to the Random into the ProceduralMapQuadBlock
|
// Add map objects (for now - trees)
|
||||||
Random quadRand = mapQuadBlock.getBlockRandom();
|
|
||||||
|
|
||||||
// Generate trees
|
|
||||||
Spatial treeModel = assetManager.loadModel("Models/tree.j3o");
|
Spatial treeModel = assetManager.loadModel("Models/tree.j3o");
|
||||||
//System.out.println("Grid @ " + terrainGrid.getLocalTranslation() + " s " + terrainGrid.getLocalScale());
|
//System.out.println("Grid @ " + terrainGrid.getLocalTranslation() + " s " + terrainGrid.getLocalScale());
|
||||||
//System.out.println("Quad " + quad.getName() + " @ " + quad.getLocalTranslation());
|
//System.out.println("Quad " + quad.getName() + " @ " + quad.getLocalTranslation());
|
||||||
float cellSize = terrainGrid.getPatchSize() * terrainGrid.getLocalScale().x * 2f;
|
for (MapObjectInstance mapObject : mapQuadBlock.getMapObjects()) {
|
||||||
Vector2f prevPos = null;
|
Vector3f pos = mapObject.getPosition();
|
||||||
for (int i = 0; i < quadRand.nextInt(10000); i++) {
|
Spatial modelInstance = treeModel.clone();
|
||||||
Vector2f pos;
|
modelInstance.setLocalTranslation(pos);
|
||||||
if (prevPos == null || quadRand.nextFloat() < 0.2f) {
|
|
||||||
pos = new Vector2f((quadRand.nextFloat() - 0.5f) * cellSize, (quadRand.nextFloat() - 0.5f) * cellSize)
|
|
||||||
.addLocal(quad.getWorldTranslation().x, quad.getWorldTranslation().z);
|
|
||||||
} else {
|
|
||||||
pos = new Vector2f((quadRand.nextFloat() - 0.5f) * 20f, (quadRand.nextFloat() - 0.5f) * 20f).addLocal(prevPos);
|
|
||||||
}
|
|
||||||
prevPos = pos;
|
|
||||||
float height = quad.getHeight(pos);
|
|
||||||
Vector3f location = new Vector3f(pos.x, height, pos.y)
|
|
||||||
.addLocal(terrainGrid.getWorldTranslation());
|
|
||||||
System.out.println("Tree " + i + ": " + location);
|
|
||||||
Spatial treeInstance = treeModel.clone();
|
|
||||||
treeInstance.setLocalTranslation(location);
|
|
||||||
// TODO: physics from the model and not hard-coded
|
// TODO: physics from the model and not hard-coded
|
||||||
//RigidBodyControl control = treeInstance.getControl(RigidBodyControl.class);
|
//RigidBodyControl control = treeInstance.getControl(RigidBodyControl.class);
|
||||||
RigidBodyControl control = new RigidBodyControl(new ConeCollisionShape(1f, 5f), 0f);
|
RigidBodyControl control = new RigidBodyControl(new ConeCollisionShape(1f, 5f), 0f);
|
||||||
if (control != null) {
|
if (control != null) {
|
||||||
treeInstance.addControl(control);
|
modelInstance.addControl(control);
|
||||||
control.setPhysicsLocation(location);
|
control.setPhysicsLocation(pos);
|
||||||
physicsSpace.add(control);
|
physicsSpace.add(control);
|
||||||
}
|
}
|
||||||
objects.attachChild(treeInstance);
|
objects.attachChild(modelInstance);
|
||||||
}
|
}
|
||||||
|
//objects.setLocalTranslation(terrainGrid.getWorldTranslation());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -213,7 +213,6 @@ public class VehicleNode extends Node
|
|||||||
vehicle.attachChild(vehicle.wheelSlipAudio);
|
vehicle.attachChild(vehicle.wheelSlipAudio);
|
||||||
|
|
||||||
vehicle.addControl(vehicleControl);
|
vehicle.addControl(vehicleControl);
|
||||||
vehicleControl.setPhysicsLocation(new Vector3f(10f + (float)Math.random() * 40f, 28f, 12f + (float)Math.random() * 40f));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(float tpf)
|
public void update(float tpf)
|
||||||
|
Loading…
Reference in New Issue
Block a user