/*
* 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 com.dongbat.walkable.FloatArray;
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.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.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.AbstractControl;
import java.util.ArrayList;
import java.util.List;
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 PhysicsCollisionListener, ContactListener {
List<Vector3f> move = new ArrayList<Vector3f>();
int groupSize = 2;
Vector3f group = new Vector3f(0, 0, 0);
int i = 0;
private Vector3f moveTo = null;
private float moveSpeed = 5.0f; // 设置移动速度
Quaternion targetQua = new Quaternion();
private Vector3f previousGridPosition;
private int Cellsize = (int) mapGrid3D.getCellsize();
public ArrayList<Vector3f> Avoid;
private int CurrentState = 0;
private int MoveState = 1;
private int WaitState = 2;
public void addAvoid(Vector3f v3f) {
this.Avoid.add(v3f);
}
/**
* @return the CurrentState
*/
public int getCurrentState() {
return CurrentState;
}
public T100Control() {
this.Avoid = new ArrayList<>();
}
public void setPath(FloatArray floatArray, Vector3f RightClickMapLocation) {
move.clear();
i = 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);
move.add(vector);
}
}
float FOWtime = 0;
@Override
protected void controlUpdate(float tpf) {
if (spatial != null) {
if (i < move.size() - 1) {
CurrentState = MoveState;
// var s=spatial.getUserData("CombatantsUnitNode");
// System.err.println(s);
// 获取当前空间位置
Vector3f currentWorldPosition = spatial.getWorldTranslation();
// 将世界位置转换为网格坐标
Vector3f currentGridPosition = new Vector3f((int) currentWorldPosition.x / Cellsize, 0, (int) currentWorldPosition.z / Cellsize);
// 判断位置是否改变
FOWtime += tpf;
if (FOWtime > 0.25) {
if (!currentGridPosition.equals(previousGridPosition)) {
// 位置已更改,执行相应的操作
// ...
scenarioState.setFowImag((int) spatial.getLocalTranslation().x, (int) spatial.getLocalTranslation().z, scenarioState.raster);
// 更新前一网格坐标
previousGridPosition = currentGridPosition;
}
FOWtime = 0;
}
MoveWork(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().addCollisionListener(this);
MinieBulletAppState.bulletAppState.getPhysicsSpace().addContactListener(this);
}
/**
* 让物体按照寻路给出的坐标进行移动
*
* @param spatial
*/
protected void MoveWork(Spatial spatial, float tpf) {
Vector3f currentPoint = spatial.getLocalTranslation();
Vector3f nextPoint = move.get(i + 1);
// 计算节点朝下一个点移动的步进
Vector3f step = nextPoint.subtract(currentPoint).normalizeLocal().multLocal(tpf).multLocal(50f);
//旋转
Quaternion rotation = spatial.getLocalRotation();
targetQua.lookAt(step, new Vector3f(0, 1, 0));
rotation.nlerp(targetQua, 0.05f);
//移动
spatial.setLocalTranslation(currentPoint.add(step));
// 检查是否已经到达下一个点getLocalTranslation
float distanceToNextPoint = spatial.getLocalTranslation().distance(nextPoint);
//System.err.println(distanceToNextPoint);
if (distanceToNextPoint < 2.5f) {
// 如果已经到达下一个点,更新当前路径索引
i++;
}
}
@Override
public void collision(PhysicsCollisionEvent event) {
//if(event.getNodeB().getParent().getControl(T100Control.class).getCurrentState()==2){
// Vector3f local = event.getNodeB().getParent().getLocalTranslation().subtract(spatial.getLocalTranslation()).normalize();
// event.getNodeB().getParent().getControl(T100Control.class).addAvoid(local);
//
//}else if(event.getNodeA().getParent().getControl(T100Control.class).getCurrentState()==2){
// Vector3f local = event.getNodeA().getParent().getLocalTranslation().subtract(spatial.getLocalTranslation()).normalize();
// event.getNodeA().getParent().getControl(T100Control.class).addAvoid(local);
//
//
//}
}
@Override
public void onContactEnded(long manifoldId) {
}
@Override
public void onContactProcessed(PhysicsCollisionObject pcoA, PhysicsCollisionObject pcoB, long manifoldPointId) {
if (((Spatial) pcoB.getUserObject()).getParent().getControl(T100Control.class).getCurrentState() == 2) {
System.err.println(((Spatial) pcoB.getUserObject()).getParent().getUserData("CombatantsUnitNode").toString());
Vector3f local = ((Spatial) pcoB.getUserObject()).getParent().getWorldTranslation().subtract(((Spatial) pcoA.getUserObject()).getWorldTranslation()).normalizeLocal();
System.err.println(local);
((Spatial) pcoB.getUserObject()).getParent().move(local.setY(0));
} else if (((Spatial) pcoA.getUserObject()).getParent().getControl(T100Control.class).getCurrentState() == 2) {
System.err.println(((Spatial) pcoA.getUserObject()).getParent().getUserData("CombatantsUnitNode").toString());
Vector3f local = ((Spatial) pcoA.getUserObject()).getParent().getWorldTranslation().subtract(((Spatial) pcoB.getUserObject()).getWorldTranslation()).normalizeLocal();
System.err.println(local);
((Spatial) pcoA.getUserObject()).getParent().move(local.setY(0));
}
}
@Override
public void onContactStarted(long manifoldId) {
}
}
This code implements exactly how to make the collided target extrude to another location.
@Override
public void onContactProcessed(PhysicsCollisionObject pcoA, PhysicsCollisionObject pcoB, long manifoldPointId) {
if (((Spatial) pcoB.getUserObject()).getParent().getControl(T100Control.class).getCurrentState() == 2) {
System.err.println(((Spatial) pcoB.getUserObject()).getParent().getUserData("CombatantsUnitNode").toString());
Vector3f local = ((Spatial) pcoB.getUserObject()).getParent().getWorldTranslation().subtract(((Spatial) pcoA.getUserObject()).getWorldTranslation()).normalizeLocal();
System.err.println(local);
((Spatial) pcoB.getUserObject()).getParent().move(local.setY(0));
} else if (((Spatial) pcoA.getUserObject()).getParent().getControl(T100Control.class).getCurrentState() == 2) {
System.err.println(((Spatial) pcoA.getUserObject()).getParent().getUserData("CombatantsUnitNode").toString());
Vector3f local = ((Spatial) pcoA.getUserObject()).getParent().getWorldTranslation().subtract(((Spatial) pcoB.getUserObject()).getWorldTranslation()).normalizeLocal();
System.err.println(local);
((Spatial) pcoA.getUserObject()).getParent().move(local.setY(0));
}
}
That’s what I thought at first,
Unit A on the move collides with unit B on standby, calculates the vector of unit A based on the collision information and uses MOVE to move unit B. Theoretically this should work (and it does in practice but there are some problems).
This is me placing the T100Control on 2 Nodes (tanks) and as you can see from the video everything is fine and within normal expectations.
https://youtu.be/f1H7PybxR34
This is me putting the T100Control into multiple Nodes (tanks), from the video you can see that the tanks are “squeezed” very far away? I don’t understand what’s going on, there’s no particular change in the value of local, but after the actual Move() operation the tanks are “squeezed” very far away.
https://youtu.be/ZvHUtnD1rys
If anyone knows what happened, please help me.