1
0
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:
Dejvino 2017-01-22 18:28:05 +01:00
parent f75fdecf07
commit cbf342cb97
8 changed files with 196 additions and 38 deletions

View File

@ -26,6 +26,12 @@ public abstract class GameApplication extends NotSoSimpleApplication
stateManager.attach(bulletAppState);
}
@Override
public void update() {
super.update();
updateListenerPosition();
}
protected PhysicsSpace getPhysicsSpace(){
return bulletAppState.getPhysicsSpace();
}
@ -43,4 +49,10 @@ public abstract class GameApplication extends NotSoSimpleApplication
{
bulletAppState.setEnabled(!paused);
}
protected void updateListenerPosition()
{
listener.setLocation(cam.getLocation());
listener.setRotation(cam.getRotation());
}
}

View File

@ -153,6 +153,8 @@ public class RoadTrip extends GameApplication implements ActionListener {
VehicleNode vehicle = new VehicleNode("Car " + vehicleInstance.toString(), vehicleInstance);
vehicle.initialize(assetManager);
vehicle.vehicleControl.setPhysicsLocation(new Vector3f(10f + (float)Math.random() * 40f, 228f, 12f + (float)Math.random() * 40f));
gameWorldState.vehicles.add(vehicle);
getPhysicsSpace().addAll(vehicle);
rootNode.attachChild(vehicle);
@ -169,7 +171,7 @@ public class RoadTrip extends GameApplication implements ActionListener {
person.addControl(personControl);
/**/personControl.setJumpForce(new Vector3f(0,5f,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));
getPhysicsSpace().add(personControl);
//getPhysicsSpace().addAll(person);

View 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));
}
}

View 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);
}
}

View File

@ -1,5 +1,6 @@
package roadtrip.model;
import com.jme3.terrain.geomipmap.TerrainQuad;
import roadtrip.model.AbstractProceduralBlock;
import roadtrip.model.ProceduralMapQuadBlock;
@ -13,8 +14,10 @@ public class ProceduralMapBlock extends AbstractProceduralBlock
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;
}
}

View File

@ -1,12 +1,56 @@
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.
*/
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)
{
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;
}
}

View File

@ -5,8 +5,10 @@ import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.shapes.ConeCollisionShape;
import com.jme3.bullet.collision.shapes.HeightfieldCollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.Vector2f;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
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.modulator.NoiseModulator;
import com.jme3.texture.Texture;
import roadtrip.model.MapObjectInstance;
import roadtrip.model.ProceduralMapQuadBlock;
import roadtrip.model.TerrainDataProvider;
import roadtrip.view.model.GameWorldState;
import java.util.Random;
/**
* Created by dejvino on 14.01.2017.
*/
@ -59,6 +60,15 @@ public class GameWorldView {
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.mat_terrain = new Material(assetManager, "Common/MatDefs/Terrain/HeightBasedTerrain.j3md");
@ -133,15 +143,15 @@ public class GameWorldView {
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.setLocalTranslation(0, -200, 0);
terrain.terrainGrid.setLocalScale(2f, 1f, 2f);
//terrain.terrainGrid.setLocalTranslation(0, -200, 0);
//terrain.terrainGrid.setLocalScale(2f, 1f, 2f);
this.rootNode.attachChild(terrain.terrainGrid);
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);
final TerrainGrid terrainGrid = terrain.terrainGrid;
@ -163,48 +173,33 @@ public class GameWorldView {
String quadObjectsNodeKey = getQuadObjectsNodeKey(quad);
Node objects = new Node(quadObjectsNodeKey);
populateQuadObjectsNode(quad, quadObjectsNodeKey, objects);
populateQuadObjectsNode(quad, 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
Random quadRand = mapQuadBlock.getBlockRandom();
// Generate trees
// Add map objects (for now - trees)
Spatial treeModel = assetManager.loadModel("Models/tree.j3o");
//System.out.println("Grid @ " + terrainGrid.getLocalTranslation() + " s " + terrainGrid.getLocalScale());
//System.out.println("Quad " + quad.getName() + " @ " + quad.getLocalTranslation());
float cellSize = terrainGrid.getPatchSize() * terrainGrid.getLocalScale().x * 2f;
Vector2f prevPos = null;
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(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);
for (MapObjectInstance mapObject : mapQuadBlock.getMapObjects()) {
Vector3f pos = mapObject.getPosition();
Spatial modelInstance = treeModel.clone();
modelInstance.setLocalTranslation(pos);
// TODO: physics from the model and not hard-coded
//RigidBodyControl control = treeInstance.getControl(RigidBodyControl.class);
RigidBodyControl control = new RigidBodyControl(new ConeCollisionShape(1f, 5f), 0f);
if (control != null) {
treeInstance.addControl(control);
control.setPhysicsLocation(location);
modelInstance.addControl(control);
control.setPhysicsLocation(pos);
physicsSpace.add(control);
}
objects.attachChild(treeInstance);
objects.attachChild(modelInstance);
}
//objects.setLocalTranslation(terrainGrid.getWorldTranslation());
}
@Override

View File

@ -213,7 +213,6 @@ public class VehicleNode extends Node
vehicle.attachChild(vehicle.wheelSlipAudio);
vehicle.addControl(vehicleControl);
vehicleControl.setPhysicsLocation(new Vector3f(10f + (float)Math.random() * 40f, 28f, 12f + (float)Math.random() * 40f));
}
public void update(float tpf)