/*
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
*/
package SelectUnit.Hominini;
import CameraAndMouse.RayMap;
import FindPath.FindPath;
import FindPath.Tools;
import static SelectUnit.Hominini.T100.i;
import SelectUnit.UnitControl;
import SelectUnit.UnitGlobalData;
import com.dongbat.walkable.FloatArray;
import com.jme3.app.SimpleApplication;
import com.jme3.bullet.collision.ContactListener;
import com.jme3.bullet.collision.PhysicsCollisionEvent;
import com.jme3.bullet.collision.PhysicsCollisionListener;
import com.jme3.bullet.collision.PhysicsCollisionObject;
import com.jme3.bullet.collision.shapes.BoxCollisionShape;
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.bullet.control.GhostControl;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.AbstractControl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import mygame.Main;
import org.dyn4j.geometry.Vector2;
import physicsState.MinieBulletAppState;
import physicsState.dyn4j.BodyControl;
import scenario.scenarioState;
import static scenario.scenarioState.mapGrid3D;
/**
*
* @author icyboxs
*/
public class T100Control extends AbstractControl implements ContactListener, UnitControl,PhysicsCollisionListener {
//停止距离
private float STOPPING_DISTANCE = 2.5f;
public SimpleApplication simpleApp;
List<Vector3f> move = new ArrayList<Vector3f>();
int imove = 0;
private Vector3f moveTo = null;
private float moveSpeed = 0.5f; // 设置移动速度
Quaternion targetQua = new Quaternion();
private Vector3f previousGridPosition=new Vector3f();
private Vector3f spatialPreviousGridPosition = new Vector3f();
private float length;
private int Cellsize = (int) mapGrid3D.getCellsize();
private int CurrentState = 0;
private final int MoveState = 1;
private final int WaitState = 2;
private float AverageDistance=0;
/**
* @return the CurrentState
*/
public int getCurrentState() {
return CurrentState;
}
public T100Control(SimpleApplication app,Vector3f v3f,Spatial Role) {
this.simpleApp = app;
this.setSpatial(Role);
this.spatial.setLocalScale(3f, 3f, 3f);
this.spatial.setLocalTranslation(v3f);
this.spatial.setUserData("CombatantsUnitNode", i);
this.spatial.setUserData("Type", "CombatUnit");
this.spatial.setShadowMode(RenderQueue.ShadowMode.Cast);
this.spatial.setQueueBucket(RenderQueue.Bucket.Transparent);
Node GhostPhysicsNode = new Node();
GhostControl ghostControl = new GhostControl(new CapsuleCollisionShape(8f, 4f));
MinieBulletAppState.bulletAppState.getPhysicsSpace().add(ghostControl);
GhostPhysicsNode.addControl(ghostControl);
GhostPhysicsNode.move(0, 0.9f, 0);
((Node)this.spatial).attachChild(GhostPhysicsNode);
}
public void setPath(FloatArray floatArray) {
this.move.clear();
time = 0;
for (int i = 0; i < floatArray.size; i += 2) {
float x = (float) floatArray.get(i);
float y = 0.0f;
float z = (float) floatArray.get(i + 1);
Vector3f vector = new Vector3f(x, y, z);
this.move.add(vector);
}
}
public void setPath(FloatArray floatArray,float AverageDistance) {
this.AverageDistance=AverageDistance;
setPath(floatArray);
}
float FOWtime = 0;
@Override
protected void controlUpdate(float tpf) {
if (spatial != null) {
// if (imove < move.size() - 1) {
if (!move.isEmpty()) {
CurrentState = MoveState;
// var s=spatial.getUserData("CombatantsUnitNode");
// System.err.println(s);
// 获取当前空间位置
Vector3f currentWorldPosition = spatial.getLocalTranslation();
// 将世界位置转换为网格坐标
Vector3f currentGridPosition = new Vector3f((int) currentWorldPosition.x / Cellsize, 0, (int) currentWorldPosition.z / Cellsize);
// 判断位置是否改变
// this.FOWtime += tpf;
// if (this.FOWtime > 0.25) {
if (!currentGridPosition.equals(previousGridPosition)) {
// 位置已更改,执行相应的操作
// ...
simpleApp.enqueue(new Runnable() {
@Override
public void run() {
scenarioState.setFowImagAlpha( (int) previousGridPosition.x*Cellsize, (int) previousGridPosition.z*Cellsize, scenarioState.raster);
scenarioState.setFowImag((int) spatial.getLocalTranslation().x, (int) spatial.getLocalTranslation().z, scenarioState.raster);
}
});
System.out.println(spatial.getLocalTranslation().x+","+(int) spatial.getLocalTranslation().z+"----spatial");
System.out.println(previousGridPosition.x+","+previousGridPosition.z+"----previousGridPosition");
// 更新前一网格坐标
previousGridPosition = currentGridPosition;
}
// this.FOWtime = 0;
// }
MoveWork(this.spatial, tpf);
} else {
CurrentState = WaitState;
}
}
}
@Override
protected void controlRender(RenderManager rm, ViewPort vp) {
}
@Override
public void setSpatial(Spatial spatial) {
super.setSpatial(spatial);
MinieBulletAppState.bulletAppState.getPhysicsSpace().addContactListener(this);
MinieBulletAppState.bulletAppState.getPhysicsSpace().addCollisionListener(this);
}
/**
* 让物体按照寻路给出的坐标进行移动
*
* @param spatial
* @param tpf
*/
float time = 0;
private float interp = 0.0f;
protected void MoveWork(Spatial spatial, float tpf) {
Vector3f currentPoint = spatial.getLocalTranslation();
Vector3f nextPoint = this.move.get(0);
// 计算节点朝下一个点移动的步进
Vector3f step = nextPoint.subtract(currentPoint).normalizeLocal().multLocal(tpf).multLocal(50f);
//Vector3f step = currentPoint.interpolateLocal(nextPoint, 1.5f*tpf);
step.setY(0);//设置高度
//旋转
Quaternion rotation = spatial.getLocalRotation();
targetQua.lookAt(nextPoint.subtract(currentPoint).normalizeLocal(), new Vector3f(0, 1, 0));
rotation.nlerp(targetQua, 10f*tpf);
//移动
spatial.move(step);
// 检查是否已经到达下一个点getLocalTranslation
float distanceToNextPoint = spatial.getWorldTranslation().distance(nextPoint);
//System.err.println(distanceToNextPoint);
if (distanceToNextPoint < STOPPING_DISTANCE+(UnitGlobalData.getInstance().getGroup().size()*0.25f)) {
// 如果已经到达下一个点,更新当前路径索引
//imove++;
this.move.remove(0);
}
// this.time += tpf;
//
// if (this.time > 0.5) {
// System.err.println(this.spatial.getLocalTranslation()+"1秒内");
//
// float distance = this.spatial.getWorldTranslation().distance(this.spatialPreviousGridPosition);
// System.err.println(distance + ",distance123");
// if (distance<3f && getCurrentState()==1) {
//
// System.err.println("停止移动");
// this.move.clear();
// } else {
//
// }
//
// this.spatialPreviousGridPosition.set(this.spatial.getWorldTranslation()) ;
// System.err.println(this.spatialPreviousGridPosition);
// this.time = 0;
// }
}
public void collision(T100Control controlA, T100Control controlB, Spatial objectAParent, Spatial objectBParent, Vector3f worldTranslationA, Vector3f worldTranslationB){
if(controlB.getCurrentState() == 2 || controlA.getCurrentState() == 2){
if (controlB.getCurrentState() == 2 && controlB == this) {
Vector3f local = worldTranslationB.subtract(worldTranslationA).normalizeLocal();
try {
FloatArray path = FindPath.getInstance().PathFinding(worldTranslationB.x, worldTranslationB.z, worldTranslationB.add(local.mult(20f)).x, worldTranslationB.add(local.mult(20f)).z, 2);
controlB.setPath(path);
} catch (Exception e) {
}
if (UnitGlobalData.getInstance().getGroup().contains((Node) objectBParent) && UnitGlobalData.getInstance().getGroup().contains((Node) objectAParent)) {
if (UnitGlobalData.getInstance().getGroup().contains((Node) objectBParent) && UnitGlobalData.getInstance().getGroup().contains((Node) objectAParent)) {
controlA.move.clear();
}
}
} else if (controlA.getCurrentState() == 2 && controlA == this) {
Vector3f local = worldTranslationA.subtract(worldTranslationB).normalizeLocal();
//((Spatial) pcoA.getUserObject()).getParent().setLocalTranslation(this.spatial.getWorldTranslation().add(local.setY(0)));
try {
FloatArray path = FindPath.getInstance().PathFinding(worldTranslationA.x, worldTranslationA.z, worldTranslationA.add(local.mult(20f)).x, worldTranslationA.add(local.mult(20f)).z, 2);
controlA.setPath(path);
} catch (Exception e) {
}
if (UnitGlobalData.getInstance().getGroup().contains((Node) objectBParent) && UnitGlobalData.getInstance().getGroup().contains((Node) objectAParent)) {
if (UnitGlobalData.getInstance().getGroup().contains((Node) objectBParent) && UnitGlobalData.getInstance().getGroup().contains((Node) objectAParent)) {
controlB.move.clear();
}
}
}
}
// if (controlA.getCurrentState() == 2 && controlA == this) {
// Vector3f localB = worldTranslationA.subtract(worldTranslationB).normalizeLocal();
// simpleApp.enqueue(new Runnable() {
// @Override
// public void run() {
// System.out.println(localB+",localB");
// objectAParent.move(localB.setY(0));
// }
// });
// } else if (controlB.getCurrentState() == 2 && controlB == this) {
// Vector3f localA = worldTranslationB.subtract(worldTranslationA).normalizeLocal();
//
// simpleApp.enqueue(new Runnable() {
// @Override
// public void run() {
// System.out.println(localA+",localA");
// objectBParent.move(localA.setY(0));
// }
// });
// }
if (controlB.getCurrentState() == 1 && controlB == this) {
Vector3f localB = worldTranslationA.subtract(worldTranslationB).normalizeLocal();
simpleApp.enqueue(new Runnable() {
@Override
public void run() {
objectAParent.move(localB.setY(0));
}
});
} else if (controlA.getCurrentState() == 1 && controlA == this) {
Vector3f localA = worldTranslationB.subtract(worldTranslationA).normalizeLocal();
simpleApp.enqueue(new Runnable() {
@Override
public void run() {
objectBParent.move(localA.setY(0));
}
});
}
}
@Override
public void onContactEnded(long manifoldId) {
}
@Override
public void onContactProcessed(PhysicsCollisionObject pcoA, PhysicsCollisionObject pcoB, long manifoldPointId) {
T100Control controlA = ((Spatial) pcoA.getUserObject()).getParent().getControl(T100Control.class);
T100Control controlB = ((Spatial) pcoB.getUserObject()).getParent().getControl(T100Control.class);
Spatial objectAParent = ((Spatial) pcoA.getUserObject()).getParent();
Spatial objectBParent = ((Spatial) pcoB.getUserObject()).getParent();
Vector3f worldTranslationA = objectAParent.getWorldTranslation();
Vector3f worldTranslationB = objectBParent.getWorldTranslation();
int PhysicsSpace = MinieBulletAppState.bulletAppState.getPhysicsSpace().pairTest(pcoA, pcoB, new PhysicsCollisionListener() {
@Override
public void collision(PhysicsCollisionEvent event) {
}
});
if(PhysicsSpace>0){
collision(controlA,controlB,objectAParent,objectBParent,worldTranslationA,worldTranslationB);
}
}
@Override
public void onContactStarted(long manifoldId) {
}
public void path(float AverageDistance,Vector3f average,RayMap rayMap, Vector3f RightClickMapLocation) {
FloatArray path;
try {
UnitGlobalData.getInstance().addGroup(UnitGlobalData.getInstance().getSelectedUnit());
Vector3f Nodeoffset = this.spatial.getWorldTranslation().subtract(average);
float distance = average.distance(RightClickMapLocation);
System.err.println(distance + ",distance");
if (distance <= 30f) {
Nodeoffset.set(0, 0, 0);
}
if (average.distance(this.spatial.getWorldTranslation()) < AverageDistance * 1.8) {
path = FindPath.getInstance().PathFinding(this.spatial.getWorldTranslation().x, this.spatial.getWorldTranslation().z, RightClickMapLocation.add(Nodeoffset).x, RightClickMapLocation.add(Nodeoffset).z, 2);
this.setPath(path, AverageDistance);
} else {
path = FindPath.getInstance().PathFinding(this.spatial.getWorldTranslation().x, this.spatial.getWorldTranslation().z, RightClickMapLocation.x, RightClickMapLocation.z, 2);
this.setPath(path, AverageDistance);
}
if (path.size <= 0) {
FloatArray path1 = FindPath.getInstance().PathFinding(this.spatial.getWorldTranslation().x, this.spatial.getWorldTranslation().z, RightClickMapLocation.x, RightClickMapLocation.z, 2);
this.setPath(path1, AverageDistance);
if (path1.size <= 0) {
Vector3f vectors = this.spatial.getWorldTranslation().subtract(RightClickMapLocation).normalizeLocal();
//findPath(i,vectors,RightClickMapLocation);
FloatArray path2 = FindPath.getInstance().PathFinding(this.spatial.getWorldTranslation().x, this.spatial.getWorldTranslation().z, RightClickMapLocation.add(vectors).x, RightClickMapLocation.add(vectors).z, 2);
int p = 0;
while (true) {
p++;
System.err.println(p);
if (path2.size <= 0) {
vectors.addLocal(vectors);
path2 = FindPath.getInstance().PathFinding(this.spatial.getWorldTranslation().x, this.spatial.getWorldTranslation().z, RightClickMapLocation.add(vectors).x, RightClickMapLocation.add(vectors).z, 2);
if (p > 500) {
break; // 跳出循环
}
} else if (path2.size > 0) {
this.setPath(path2);
break; // 跳出循环
}
}
}
}
} catch (Exception e) {
System.err.println(e);
}
}
@Override
public void sendRightClickCommand(float AverageDistances,Vector3f average,RayMap rayMap, Vector3f RightClickMapLocation) {
path(AverageDistances,average,rayMap,RightClickMapLocation);
}
@Override
public void collision(PhysicsCollisionEvent event) {
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package scenario;
import CameraAndMouse.CamAndMouseCur;
import FindPath.FindPath;
import GUI.UI;
import physicsState.MinieBulletAppState;
import static physicsState.MinieBulletAppState.bulletAppState;
import com.jme3.app.Application;
import com.jme3.app.LostFocusBehavior;
import com.jme3.app.SimpleApplication;
import com.jme3.app.state.BaseAppState;
import com.jme3.asset.AssetManager;
import com.jme3.asset.TextureKey;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.shapes.Box2dShape;
import com.jme3.bullet.collision.shapes.BoxCollisionShape;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.collision.shapes.HeightfieldCollisionShape;
import com.jme3.bullet.collision.shapes.MeshCollisionShape;
import com.jme3.bullet.collision.shapes.PlaneCollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.light.DirectionalLight;
import com.jme3.material.MatParamOverride;
import com.jme3.material.Material;
import com.jme3.material.RenderState;
import com.jme3.material.RenderState.FaceCullMode;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.post.FilterPostProcessor;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.BatchNode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.Node;
import com.jme3.scene.debug.Grid;
import com.jme3.scene.instancing.InstancedNode;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Quad;
import com.jme3.shader.VarType;
import com.jme3.shadow.DirectionalLightShadowFilter;
import com.jme3.shadow.DirectionalLightShadowRenderer;
import com.jme3.shadow.EdgeFilteringMode;
import com.jme3.terrain.geomipmap.TerrainQuad;
import com.jme3.terrain.heightmap.HillHeightMap;
import com.jme3.texture.Image;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture2D;
import com.jme3.texture.image.ColorSpace;
import com.jme3.texture.image.ImageRaster;
import com.jme3.util.BufferUtils;
import com.jme3.util.TangentBinormalGenerator;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.nio.ByteBuffer;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;
import jme3utilities.minie.PhysicsDumper;
import mygame.Main;
import scenario.Grid.MapGrid3D;
import scenario.Grid.meshGrid;
/**
*
* @author Icyboxs
*/
public class scenarioState extends BaseAppState {
public static ImageRaster raster;
public String ShadersFow = "Shaders/Fow/FowLighting.j3md";
private AssetManager assetManager;
private SimpleApplication simpleApp;
private Node ScenarioRoot = new Node("ScenarioRoot");
// private Node MapNode = new Node("MapNode");
private Node batch = new BatchNode("MapNode");
private Material boxMaterial1;
private Material Material1;
public static MapGrid3D mapGrid3D = new MapGrid3D(2048, 2048, 8f);
private Node cliff = new Node("cliff");
meshGrid meshGrid = new meshGrid();
private boolean DisplayGrid = false;
public static HashMap<Vector2f, Integer> MapArrays = new HashMap<Vector2f, Integer>();
@Override
protected void initialize(Application app) {
simpleApp = (SimpleApplication) app;
assetManager = app.getAssetManager();
boxMaterial1 = new Material(assetManager, ShadersFow);
batch.setShadowMode(ShadowMode.Receive);
/* 产生阴影 */
// final int SHADOWMAP_SIZE=1024*2;
//
// DirectionalLightShadowFilter dlsf = new DirectionalLightShadowFilter(assetManager, SHADOWMAP_SIZE, 3);
// dlsf.setLight((DirectionalLight) simpleApp.getRootNode().getLocalLightList().get(1));
// dlsf.setEnabled(true);
// FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
// fpp.addFilter(dlsf);
// simpleApp.getViewPort().addProcessor(fpp);
//if(DisplayGrid){
// for(int i=0;i<mapGrid3D.getGridPositionDb().size();i++){
// quadBOX(mapGrid3D.getGridPositionDb().get(i));
// }
//}
quadBOX(new Vector3f(0,0,0));
Geometry gridGeometry = meshGrid.GameMap(mapGrid3D.getXLength(), 0, mapGrid3D.getZWidth(), mapGrid3D.getCellsize());
// Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
// material.setColor("Color", ColorRGBA.Red);
// material.getAdditionalRenderState().setWireframe(true);
// material.getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Off);
// 创建 Material
Material1 = new Material(assetManager, "Shaders/Fow/FowLighting.j3md");
Material1.setTexture("DiffuseMap", assetManager.loadTexture("Textures/map/dirt.png"));
// Material1.getAdditionalRenderState().setWireframe(true);
Material1.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off);
// 加载纹理
// Texture texture = assetManager.loadTexture(new TextureKey("Textures/map/vehicule01_apresUVW.png", true));
// material.setTexture("ColorMap",texture);
gridGeometry.setMaterial(Material1);
batch.attachChild(gridGeometry);
simpleApp.getRootNode().attachChild(batch);
FindPath.getInstance().setPathHelper(mapGrid3D.getXLength(), mapGrid3D.getZWidth());
initializeFowImag((int) mapGrid3D.getXLength(), (int) mapGrid3D.getZWidth());
}
@Override
protected void cleanup(Application aplctn) {
}
@Override
protected void onEnable() {
//simpleApp.setPauseOnLostFocus(false);
simpleApp.setLostFocusBehavior(LostFocusBehavior.ThrottleOnLostFocus);
// CollisionShape sceneShape = CollisionShapeFactory.createMeshShape(batch);
// RigidBodyControl landscape = new RigidBodyControl(sceneShape, 0);
// batch.addControl(landscape);
// MinieBulletAppState.bulletAppState.getPhysicsSpace().add(landscape);
// MinieBulletAppState.bulletAppState.startPhysics();
}
@Override
protected void onDisable() {
ScenarioRoot.removeFromParent();
}
float FOWtime = 0;
@Override
public void update(float tpf) {
// FOWtime += tpf;
// if (FOWtime > 0.5) {
//
// for (int i = 0; i < (int) mapGrid3D.getXLength(); i++) {
// for (int j = 0; j < (int) mapGrid3D.getZWidth(); j++) {
// ColorRGBA color = new ColorRGBA(0.2f, 0.2f, 0.2f, 1.0f);
// raster.setPixel(j, i, color);
//
// }
// }
//
// FOWtime = 0;
// }
}
public void quadBOX(Vector3f loc) {
Quad quad;
// 创建一个蓝色四边形
if (DisplayGrid) {
quad = new Quad(mapGrid3D.getCellsize()*2, mapGrid3D.getCellsize()*2);
} else {
quad = new Quad(mapGrid3D.getXLength()*2, mapGrid3D.getZWidth()*2);
}
//System.err.println(mapGrid3D.getXLength()+","+mapGrid3D.getZWidth());
Geometry quadBoxGeometry = new Geometry("quadBox", quad);
// 创建一个蓝色材质
Material boxMaterial1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
boxMaterial1.setColor("Color", ColorRGBA.Blue);
// boxMaterial1.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
// boxMaterial1.getAdditionalRenderState().setWireframe(true);
boxMaterial1.getAdditionalRenderState().setFaceCullMode(FaceCullMode.FrontAndBack);
quadBoxGeometry.setMaterial(boxMaterial1);
quadBoxGeometry.setLocalTranslation(loc);
Quaternion y = new Quaternion().fromAngleAxis(90 * FastMath.DEG_TO_RAD, Vector3f.UNIT_X);
quadBoxGeometry.setLocalRotation(y);
quadBoxGeometry.move(-1024, 0, -1024);
// 将盒子添加到场景中
// instancedNode.onTransformChange(quadBoxGeometry);
Main.MapUIBox.attachChild(quadBoxGeometry);
// MapNode.attachChild(quadBoxGeometry);
}
public void BOX(Vector3f loc) {
// 创建一个蓝色盒子
Box box = new Box(1, 1, 1);
Geometry boxGeometry = new Geometry("Box", box);
// 创建一个蓝色材质
Material boxMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
boxMaterial.setColor("Color", ColorRGBA.White);
boxGeometry.setMaterial(boxMaterial);
boxGeometry.setLocalTranslation(loc);
// 将盒子添加到场景中
simpleApp.getRootNode().attachChild(boxGeometry);
}
/**
* @return the DisplayGrid
*/
public boolean getDisplayGrid() {
return DisplayGrid;
}
/**
* @param DisplayGrid the DisplayGrid to set
*/
public void setDisplayGrid(boolean DisplayGrid) {
this.DisplayGrid = DisplayGrid;
}
/**
* 初始化战争迷雾
*
* @param imageSizeW
* @param imageSizeH
*/
public void initializeFowImag(int imageSizeW, int imageSizeH) {
// Create the raw FOW overlay image
ByteBuffer data = BufferUtils.createByteBuffer(imageSizeW * imageSizeH * 4); // square image, four bytes per color
Image image = new Image(Image.Format.ABGR8, imageSizeW, imageSizeH, data, ColorSpace.Linear);
// Create a raster that we can draw to
raster = ImageRaster.create(image);
// Create the texture to set to the FowMap on materials
Texture2D fowMap = new Texture2D(image);
// Set the texture for any material that will take it.
// This is a JME trick that keeps us from having to remember to set it
// on every material.
simpleApp.getRootNode().addMatParamOverride(new MatParamOverride(VarType.Texture2D, "FowMap", fowMap));
// Put some test data into the fog of war texture
for( int i = 0; i < imageSizeW; i++ ) {
for( int j = 0; j < imageSizeH; j++ ) {
MapArrays.put(new Vector2f(j,i), 0);
}
}
}
public static void setFowImag(int givenX, int givenY, ImageRaster raster) {
// long s = Instant.now().toEpochMilli();
int radius = 40;
// 计算给定点所在的格子cellsize
int gridX = (int) (givenX / mapGrid3D.getCellsize());
int gridY = (int) (givenY / mapGrid3D.getCellsize());
// 遍历半径范围内的格子
for (int x = Math.max(0, gridX - radius); x <= Math.min(mapGrid3D.getXLength() - 1, gridX + radius); x++) {
for (int y = Math.max(0, gridY - radius); y <= Math.min(mapGrid3D.getZWidth() - 1, gridY + radius); y++) {
// 计算格子的实际坐标
int currentGridX = (int) (x * mapGrid3D.getCellsize());
int currentGridY = (int) (y * mapGrid3D.getCellsize());
// 计算给定点到当前格子的距离
double distanceToGivenPoint = Math.sqrt(
Math.pow(givenX - currentGridX, 2) + Math.pow(givenY - currentGridY, 2)
);
// 如果距离小于或等于半径,输出坐标
if (distanceToGivenPoint <= radius) {
for (int i = 0; i <= (int) mapGrid3D.getCellsize(); i++) {
for (int j = 0; j <= (int) mapGrid3D.getCellsize(); j++) {
if (currentGridX + j >= 0 && currentGridX + j < raster.getWidth() && currentGridY + i >= 0 && currentGridY + i < raster.getHeight()) {
ColorRGBA color = new ColorRGBA(1, 1, 1, 0.5f);
raster.setPixel(currentGridX + j, currentGridY + i, color);
// MapArrays.put(new Vector2f(j,i), 1);
}
}
}
}
}
}
// System.err.println(" 耗时"+(Instant.now().toEpochMilli()-s)/1000D+"秒");
}
public static void setFowImagAlpha(int givenX, int givenY, ImageRaster raster) {
// long s = Instant.now().toEpochMilli();
int radius = 55;
// 计算给定点所在的格子cellsize
int gridX = (int) (givenX / mapGrid3D.getCellsize());
int gridY = (int) (givenY / mapGrid3D.getCellsize());
// 遍历半径范围内的格子
for (int x = Math.max(0, gridX - radius); x <= Math.min(mapGrid3D.getXLength() - 1, gridX + radius); x++) {
for (int y = Math.max(0, gridY - radius); y <= Math.min(mapGrid3D.getZWidth() - 1, gridY + radius); y++) {
// 计算格子的实际坐标
int currentGridX = (int) (x * mapGrid3D.getCellsize());
int currentGridY = (int) (y * mapGrid3D.getCellsize());
// 计算给定点到当前格子的距离
double distanceToGivenPoint = Math.sqrt(
Math.pow(givenX - currentGridX, 2) + Math.pow(givenY - currentGridY, 2)
);
// 如果距离小于或等于半径,输出坐标
if (distanceToGivenPoint <= radius) {
for (int i = 0; i <= (int) mapGrid3D.getCellsize(); i++) {
for (int j = 0; j <= (int) mapGrid3D.getCellsize(); j++) {
if (currentGridX + j >= 0 && currentGridX + j < raster.getWidth() && currentGridY + i >= 0 && currentGridY + i < raster.getHeight()) {
ColorRGBA color = new ColorRGBA(0.2f, 0.2f, 0.2f, 1.0f);
raster.setPixel(currentGridX + j, currentGridY + i, color);
}
}
}
}
}
}
// System.err.println(" 耗时"+(Instant.now().toEpochMilli()-s)/1000D+"秒");
}
}
I used this code to populate the previous position of the unit
scenarioState.setFowImagAlpha( (int) previousGridPosition.x*Cellsize, (int) previousGridPosition.z*Cellsize, scenarioState.raster);
Use this code to populate the current unit’s position
scenarioState.setFowImag((int) spatial.getLocalTranslation().x, (int) spatial.getLocalTranslation().z, scenarioState.raster);
That way you can refill the areas you’ve travelled。
And of course that’s when the problem arises。
Looks good when there is one unit, but not so good when there are multiple units (shown in the video)。
I did another idea of trying everyupdate(tpf) on the map in general
Sorting the map but processing the whole map at the same time doesn’t seem to be a good decision it makes the screen laggy and jerky
How should I fill the fog of war when multiple units are moving at the same time?