gpt4 book ai didi

java - Jmonkey 碰撞检测

转载 作者:行者123 更新时间:2023-12-04 05:26:51 28 4
gpt4 key购买 nike

我是 Jmonkey 编程的新手,我想问一个关于碰撞交互的问题,因为我的代码似乎从地形中找到了可能的碰撞,我不知道如何解决这个问题。我的目标是玩家作为第一个被检测到的人,如果他与敌人的幽灵控制相撞以显示一条消息作为输出。我的代码显示持续碰撞,然后崩溃...

package test;

//imports...

public class test extends SimpleApplication
implements ActionListener,PhysicsTickListener{
private MotionPath path;
private MotionPath path2;
private MotionTrack motionTrack;
private MotionTrack motionTrack2;
private AnimChannel channel2;
private AnimControl control2;
private AnimControl control3;
private AnimChannel channel3;
private BulletAppState bulletAppState;
private RigidBodyControl landscape;
private CharacterControl player;
private Vector3f walkDirection = new Vector3f();
private boolean left = false, right = false, up = false, down = false;
private TerrainQuad terrain;
private Material mat_terrain;
private GhostControl ghost;
static test app;
Material matMarker;
public static void main(String[] args) {
app = new test();
app.start();

}
float displacement=60;
int score = 0;
int robotHealth=0;
Geometry mark;
Node shootables;
Node pickUpObject1;
BitmapText hudText;
@Override
public void simpleInitApp() {

createScene();
enemies();
pickUptype1();
initCrossHairs(); // a "+" in the middle of the screen to help aiming
initKeys(); // load custom key mappings
initMark(); // a red sphere to mark the hit



hudText = new BitmapText(guiFont, false);
hudText.setSize(guiFont.getCharSet().getRenderedSize()); // font size
hudText.setColor(ColorRGBA.Red); // font color

hudText.setLocalTranslation(600, 700, 0); // position
guiNode.attachChild(hudText);


DirectionalLight sun2 = new DirectionalLight();
sun2.setDirection(new Vector3f(-0.1f, -0.7f, -1.0f));
int width = settings.getWidth(); //width is the width of the gui
int height = settings.getHeight(); //height is the height of the gui
}


protected Geometry makeCube(String name, float x, float y, float z) {
Box box = new Box(new Vector3f(x, y, z), 3f, 3f, 3f);
Geometry cube = new Geometry(name, box);

Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
Texture tex_ml = assetManager.loadTexture("Interface/Logo/Monkey.jpg");
mat1.setTexture("ColorMap", tex_ml);
cube.setMaterial(mat1);

return cube;
}

private PhysicsSpace getPhysicsSpace() {
return bulletAppState.getPhysicsSpace();
}

/**
* This is the main event loop--walking happens here.
* We check in which direction the player is walking by interpreting
* the camera direction forward (camDir) and to the side (camLeft).
* The setWalkDirection() command is what lets a physics-controlled player walk.
* We also make sure here that the camera moves with player.
*/
@Override
public void simpleUpdate(float tpf) {
hudText.setText("SCORE \n" + " " + score);// the text
Vector3f camDir = cam.getDirection().clone().multLocal(0.6f);
Vector3f camLeft = cam.getLeft().clone().multLocal(0.4f);
walkDirection.set(0, 0, 0);
if (left) { walkDirection.addLocal(camLeft); }
if (right) { walkDirection.addLocal(camLeft.negate()); }
if (up) { walkDirection.addLocal(camDir); }
if (down) { walkDirection.addLocal(camDir.negate()); }


player.setWalkDirection(walkDirection);
cam.setLocation(player.getPhysicsLocation());
path.setCycle(true); // Make path a complete circuit
path2.setCycle(true);
motionTrack.setLoopMode(LoopMode.Loop);
motionTrack2.setLoopMode(LoopMode.Loop);

}

public Node robot(){

Node monster = (Node) assetManager.loadModel("Models/Oto/Oto.mesh.xml");
monster.scale(1.5f, 1.5f, 1.5f);
monster.rotate(0.0f, -3.0f, 0.0f);
// Create a appropriate physical shape for it

return monster;
}


public void createScene(){

/** Set up Physics */
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
//bulletAppState.getPhysicsSpace().enableDebug(assetManager);

flyCam.setMoveSpeed(100);
setUpKeys();


terrain = new TerrainQuad("my terrain", 65, 513, heightmap.getHeightMap());


/** 6. Add physics: */
// We set up collision detection for the scene by creating a
// compound collision shape and a static RigidBodyControl with mass zero.*/
CollisionShape terrainShape =
CollisionShapeFactory.createMeshShape((Node) terrain);
landscape = new RigidBodyControl(terrainShape, 0);
terrain.addControl(landscape);


CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1.5f, 6f, 1);
player = new CharacterControl(capsuleShape, 0.05f);
player.setJumpSpeed(20);
player.setFallSpeed(30);
player.setGravity(30);
player.setPhysicsLocation(new Vector3f(145f, -28f, 10f));
player.setCollisionGroup(PhysicsCollisionObject.COLLISION_GROUP_01);
player.addCollideWithGroup(PhysicsCollisionObject.COLLISION_GROUP_01);


setUpLight();
rootNode.attachChild(SkyFactory.createSky( assetManager,
"Textures/Sky/Bright/BrightSky.dds", false));
}


public void enemies(){

shootables = new Node("Shootables");
rootNode.attachChild(shootables);


Node Robot1 = robot();
Node Robot2 = robot();


CapsuleCollisionShape capsule = new CapsuleCollisionShape(4f, 10f);
RigidBodyControl robot1Cap = new RigidBodyControl(capsule, 0.01f);

Robot1.addControl(robot1Cap);


getPhysicsSpace().add(robot1Cap);

bulletAppState.getPhysicsSpace().add(robot1Cap);
bulletAppState.getPhysicsSpace().enableDebug(assetManager);

robot1Cap.setMass(100f);
robot1Cap.setKinematic(true);

CapsuleCollisionShape capsule2 = new CapsuleCollisionShape(4f, 10f);
RigidBodyControl robot2Cap = new RigidBodyControl(capsule, 0.01f);

Robot2.addControl(robot2Cap);

getPhysicsSpace().add(robot2Cap);

bulletAppState.getPhysicsSpace().add(robot2Cap);
bulletAppState.getPhysicsSpace().enableDebug(assetManager);

robot2Cap.setMass(100f);
robot2Cap.setKinematic(true);

ghost = new GhostControl(
new BoxCollisionShape(new Vector3f(8f,8f,8f))); // a box-shaped ghost
Robot1.addControl(ghost);

ghost.setCollisionGroup(PhysicsCollisionObject.COLLISION_GROUP_01);
ghost.setCollideWithGroups(PhysicsCollisionObject.COLLISION_GROUP_01);


getPhysicsSpace().add(ghost);

getPhysicsSpace().addTickListener(this);

control2 = Robot1.getControl(AnimControl.class);
channel2 = control2.createChannel();
channel2.setAnim("Walk");

control3 = Robot2.getControl(AnimControl.class);
channel3 = control3.createChannel();
channel3.setAnim("Walk");
path = new MotionPath();

path.addWayPoint(new Vector3f(500f,-83f,3f));
path.addWayPoint(new Vector3f(350f,-79f, 3f));
path.enableDebugShape(assetManager,rootNode);

// Initialize our motionTrack object
motionTrack = new MotionTrack(Robot1, path);

motionTrack.setDirectionType(MotionTrack.Direction.Path);
// Enable the motionTrack
motionTrack.setEnabled(true);


path2 = new MotionPath();



path2.addWayPoint(new Vector3f(180f,-50f,-100f));
path2.addWayPoint(new Vector3f(200f, -55f, -30f));
path2.enableDebugShape(assetManager,rootNode);

// Initialize our motionTrack object
motionTrack2 = new MotionTrack(Robot2, path2);
motionTrack2.setDirectionType(MotionTrack.Direction.Path);
// Enable the motionTrack
motionTrack2.setEnabled(true);

shootables.attachChild(Robot1);
shootables.attachChild(Robot2);


}

public void physicsTick(PhysicsSpace space, float f) {
if (ghost.getOverlappingObjects().size() > 0) {
final Vector3f bPoint = ghost.getPhysicsLocation();
try {
app.enqueue(new Callable<Boolean>() {
public Boolean call() throws Exception {
app.addMarker(bPoint);
return true;
}
});
} catch (Exception ex) {
}
}
}


public void pickUptype1(){
pickUpObject1 = new Node("pickUpObject1");
rootNode.attachChild(pickUpObject1);


Node cube1 = new Node();
cube1.attachChild(makeCube("the Deputy", 220f, -63f, -150f));
Node cube2 = new Node();
cube2.attachChild(makeCube("the Deputy2", 410f, -89f, -270f));


RigidBodyControl floor_phy = new RigidBodyControl(0.0f);
cube1.addControl(floor_phy);

RigidBodyControl floor_phy2 = new RigidBodyControl(0.0f);
cube2.addControl(floor_phy2);
bulletAppState.getPhysicsSpace().add(floor_phy);
bulletAppState.getPhysicsSpace().add(floor_phy2);
pickUpObject1.attachChild(cube1);
pickUpObject1.attachChild(cube2);
}


}

最佳答案

您包含了许多不必要的代码,并且从您总体上不熟悉编程的风格来看,我编辑了您的问题以使其具有可读性,以便人们可以尝试并提供帮助(虽然没有修复缩进,但这会花费太多的耐心. 代码应该被剥离,只包括物理代码、成员变量和上下文设置。如果你的幽灵控件没有放在地面上,它会掉下来离开你的机器人,所以它会不断地与你的机器人发生碰撞地面或在最初穿过地面后穿过虚空坠落。

您应该使用 getOverlappingObjects() 来获取它与之碰撞的对象列表,然后检查该列表以获取物理空间中的字符表示。

这下面也是不好的形式。如果你的方法要抛出一个异常,你应该知道它可以抛出什么,抛出那些确切的异常并处理每个异常。否则,你基本上是穿上防弹衣,闭着眼睛跑来跑去,因为相信你不会受伤。

public Boolean call() throws Exception

你的敌人功能也设计得很差。函数最好是小的,并且绝对应该只实现一个目的,而您的函数创建一个带有可射击的节点,创建两个敌人并设置控件。

创建节点并将其附加到根节点应该在构造函数或在开始附近调用的初始化函数中。然后你应该有一个叫做 addEnemy 的函数,它可以添加一个敌人。例如:
/*
* adds an enemy and returns a reference to that enemy
*/
Spatial addEnemy()
{
//Characters are spatials typically in JMonkey
Spatial enemy=new Spatial();
CapsuleCollisionShape collisionShape=new CapsuleCollisionShape(4.0f, 10.0f);
CharacterControl characterControl = new CharacterControl(collisionShape, stepHeight);

enemy.addControl(characterControl);
getPhysicsSpaceState(characterControl);
shootables.attachChild(enemy);
}

现在你注意到这真的很不一样了吧?

在 JMonkey 中,角色使用空间(从节点派生的类),而且他们不使用刚体物理,诸如地形之类的东西太颠簸,而是使用角色控制,使它们保持直立,因此它们不会倾倒并允许您可以设置步行方向和查看方向。角色控件还可以访问碰撞形状,当角色控件彼此发生碰撞时,您可以在其上运行碰撞。

为了控制您的空间,您需要继承 AbstractControl,使用它您可以访问其他控件并经常更新您的空间。在我的游戏中,所有角色都是具有不同皮肤设置的空间,不同之处在于控件。

玩家拥有:
CharacterControl
//to send keyboard input to the character controller to move it
KeyboardControl
GunControl

而人工智能有
CharacterControl
//does path planning to get a route and steers character control along it
RouteController
GunControl
//AI to determine where/if I want to walk, what to shoot at, where to aim
BehaviourControl

您应该将许多此功能拆分为一条路径以使其更易于维护,通过查看示例进一步了解 JMonkey API 的工作原理,并了解面向对象设计的工作原理以及如何构建事物以便于阅读并且易于维护。如果您对 Robert C Martin 所著的《clean code》一书感兴趣,它是有关干净可维护编码风格的绝佳指南:)

有任何问题请随时提出

关于java - Jmonkey 碰撞检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13103753/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com