- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我无法成功地让敌人从一个节点移动到另一个节点。
我设法设置了整个寻路,我得到了玩家的完整路径和下一个节点的位置,一直到最后。
如何将 box2d 主体从一个节点移动到另一个节点?
或者更简单 - 如何将 box2d 主体移动到某个位置?
我尝试施加冲动,力量无法做到。
这是我的简化代码。 Monster 和 Player 类都扩展了 Sprite:
public class B2dSteeringEntity implements Steerable<Vector2>, Updateable {
public static final String TAG = B2dSteeringEntity.class.getName();
Body body;
boolean tagged;
float maxLinearSpeed, maxLinearAcceleration;
float maxAngularSpeed, maxAngularAcceleration;
float boundingRadius;
SteeringBehavior<Vector2> behavior;
SteeringAcceleration<Vector2> steeringOutput;
public B2dSteeringEntity(Body body, float boundingRadius) {
this.body = body;
this.boundingRadius = boundingRadius;
this.maxLinearSpeed = 250;
this.maxLinearAcceleration = 200;
this.maxAngularSpeed = 0;
this.maxAngularAcceleration = 0;
this.tagged = false;
this.steeringOutput = new SteeringAcceleration<Vector2>(new Vector2());
}
@Override
public Vector2 getLinearVelocity() {
return body.getLinearVelocity();
}
@Override
public float getAngularVelocity() {
return body.getAngularVelocity();
}
@Override
public float getBoundingRadius() {
return 0;
}
@Override
public boolean isTagged() {
return tagged;
}
@Override
public void setTagged(boolean tagged) {
this.tagged = tagged;
}
@Override
public float getZeroLinearSpeedThreshold() {
return 0;
}
@Override
public void setZeroLinearSpeedThreshold(float value) {
}
@Override
public float getMaxLinearSpeed() {
return maxLinearSpeed;
}
@Override
public void setMaxLinearSpeed(float maxLinearSpeed) {
this.maxLinearSpeed = maxLinearSpeed;
}
@Override
public float getMaxLinearAcceleration() {
return maxLinearAcceleration;
}
@Override
public void setMaxLinearAcceleration(float maxLinearAcceleration) {
this.maxLinearAcceleration = maxLinearAcceleration;
}
@Override
public float getMaxAngularSpeed() {
return maxAngularSpeed;
}
@Override
public void setMaxAngularSpeed(float maxAngularSpeed) {
this.maxAngularSpeed = maxAngularSpeed;
}
@Override
public float getMaxAngularAcceleration() {
return maxAngularAcceleration;
}
@Override
public void setMaxAngularAcceleration(float maxAngularAcceleration) {
this.maxAngularAcceleration = maxAngularAcceleration;
}
@Override
public Vector2 getPosition() {
return body.getPosition();
}
@Override
public float getOrientation() {
return body.getAngle();
}
@Override
public void setOrientation(float orientation) {
}
@Override
public float vectorToAngle(Vector2 vector) {
return SteeringUtils.vectorToAngle(vector);
}
@Override
public Vector2 angleToVector(Vector2 outVector, float angle) {
return SteeringUtils.angleToVector(outVector, angle);
}
@Override
public Location<Vector2> newLocation() {
return null;
}
public Body getBody() {
return body;
}
public void setBehavior(SteeringBehavior<Vector2> behavior) {
this.behavior = behavior;
}
public SteeringBehavior<Vector2> getBehavior() {
return behavior;
}
private void applySteering(float deltaTime) {
boolean anyAccelerations = false;
if(!steeringOutput.linear.isZero()) {
Vector2 force = steeringOutput.linear.scl(deltaTime);
body.applyForceToCenter(force, true);
anyAccelerations = true;
}
if(anyAccelerations) {
Vector2 velocity = body.getLinearVelocity();
float currentSpeedSquare = velocity.len2();
if(currentSpeedSquare > maxLinearSpeed * maxLinearSpeed) {
body.setLinearVelocity(velocity.scl(maxLinearSpeed / (float) Math.sqrt(currentSpeedSquare)));
}
if (body.getAngularVelocity() > maxAngularSpeed) {
body.setAngularVelocity(maxAngularSpeed);
}
}
}
@Override
public void update(float deltaTime) {
if (behavior != null) {
behavior.calculateSteering(steeringOutput);
applySteering(deltaTime);
}
}
}
public Skeleton(B2WorldCreator creator, GameScreen screen, float x, float y, State state, HeroKnight player) {
super(creator, screen, x, y, state, player);
controller = screen.getController();
setBounds(x, y, 150 / Constants.PPM, 150 / Constants.PPM);
enemyAgentComponent = new EnemyAgentComponent(b2body, b2dSteeringEntity, controller, player);
}
这是 EnemyAgentComponent 类:
public class EnemyAgentComponent implements Component, Telegraph, Updateable, Pather<Node> {
public static final String TAG = EnemyAgentComponent.class.getName();
public StateMachine<EnemyAgentComponent, EnemyState> stateMachine;
public boolean isInProximity() {
return inProximity;
}
public boolean inProximity = false;
public boolean lowHP = false;
public boolean isShot = false;
private boolean isRequested = false;
private boolean requestingMovement;
private Steering wayPoint;
private Body body;
private Controller controller;
private HeroKnight player;
private Node startNode, endNode, previousStartNode, previousEndNode;
private Vector2 goal;
private PathfindingTarget newGoal;
private float impulseMag;
private boolean nodeReached;
private boolean pathGenerated;
private Arrive<Vector2> arriveSB;
private Steering waypoint;
private B2dSteeringEntity steering;
private IndexedAStarPathFinder<Node> pathFinder;
private GraphPathImp resultPath = new GraphPathImp();
private float pathfindingTimer;
private boolean firstPathGenerated;
public boolean isTouchingPlayer() {
return touchingPlayer;
}
public void setTouchingPlayer(boolean touchingPlayer) {
this.touchingPlayer = touchingPlayer;
}
private boolean touchingPlayer;
public EnemyAgentComponent(Body body, B2dSteeringEntity steering, Controller controller, HeroKnight player) {
construct(body, steering, controller, player);
}
public void construct(Body body, B2dSteeringEntity steering, Controller controller, HeroKnight player) {
this.steering = steering;
this.controller = controller;
this.body = body;
this.player = player;
stateMachine = new DefaultStateMachine<>(this, EnemyState.SEEKING);
MessageManager.getInstance().addListener(this, Messages.PLAYER_IN_SIGHT);
MessageManager.getInstance().addListener(this, Messages.PLAYER_ATTACKED_ENEMY);
MessageManager.getInstance().addListener(this, Messages.LOW_HP);
MessageManager.getInstance().addListener(this, Messages.PLAYER_OUT_OF_SIGHT);
MessageManager.getInstance().addListener(this, Messages.TOUCHING_PLAYER);
pathFinder = new IndexedAStarPathFinder<Node>(LevelManager.groundGraph, false);
requestingMovement = false;
goal = null;
nodeReached = false;
pathGenerated = false;
firstPathGenerated = false;
pathfindingTimer = 0;
touchingPlayer = false;
}
public Vector2 getGoal() {
return goal;
}
public boolean isRequestingMovement() {
return requestingMovement;
}
public void setRequestingMovement(boolean requestingMovement) {
this.requestingMovement = requestingMovement;
}
public boolean isPathGenerated() {
return pathGenerated;
}
public GraphPathImp getResultPath() {
return resultPath;
}
public void generatePath() {
previousEndNode = endNode;
previousStartNode = startNode;
resultPath.clear();
pathFinder.searchNodePath(startNode, endNode, new HeuristicImp(), resultPath);
newGoal = new PathfindingTarget(resultPath.get(0).getNodePosition());
pathGenerated = true;
}
public void update(float deltaTime) {
startNode = LevelManager.groundGraph.getNodeByXY(body.getPosition().x, body.getPosition().y);
endNode = LevelManager.groundGraph.getNodeByXY(player.b2body.getPosition().x, player.b2body.getPosition().y);
//If player gets in certain range of the enemy and is not touching the enemy, enemy's path is being generated
if (inProximity) {
if (!firstPathGenerated && !touchingPlayer)
if ((pathfindingTimer == 0)) {
generatePath();
previousStartNode = startNode;
previousEndNode = endNode;
firstPathGenerated = true;
}
//If a path was already created, a new path is being requested only if player's position changes
if (firstPathGenerated && (previousEndNode != endNode) && pathfindingTimer == 0 && !touchingPlayer) {
generatePath();
}
if (firstPathGenerated)
pathfindingTimer += deltaTime;
//Paths are generated every 2 seconds
if (pathfindingTimer >= 2) {
pathfindingTimer = 0;
}
//If enemy touches the player pathfinding ends
if (touchingPlayer) {
pathfindingTimer = 0;
pathGenerated = false;
resultPath.clear();
body.setLinearVelocity(0, 0);
}
}
//The arrive behaviour is set, newGoal being the position of next node
if (steering.getLinearVelocity().x == 0 && steering.getLinearVelocity().y == 0 && newGoal != null) {
steering.setBehavior(new Arrive<Vector2>(steering, newGoal));
}
steering.update(deltaTime);
//Updating the next node position based on the enemy reaching a node
if (pathGenerated)
if (Math.abs(body.getPosition().x - newGoal.getPosition().x) <= 0.1f && Math.abs(body.getPosition().y - newGoal.getPosition().y) <= 51 / 2f / Constants.PPM)
{
updatePath();
}
}
public void updatePath() {
//Setting the next target position
if (resultPath.getCount() > 0) {
resultPath.removeIndex(0);
if (!touchingPlayer && resultPath.getCount() > 0) {
newGoal.setPosition(resultPath.get(0).getNodePosition());
requestingMovement = true;
nodeReached = false;
}
}
}
@Override
public boolean handleMessage(Telegram telegram) {
if (telegram.message == Messages.PLAYER_IN_SIGHT) {
inProximity = true;
return true;
}
if (telegram.message == Messages.PLAYER_OUT_OF_SIGHT) {
inProximity = false;
firstPathGenerated = false;
pathGenerated = false;
pathfindingTimer = 0;
resultPath.clear();
}
if (telegram.message == Messages.LOW_HP) {
lowHP = true;
return true;
}
if (telegram.message == Messages.PLAYER_ATTACKED_ENEMY) {
isShot = true;
return true;
}
if (telegram.message == Messages.TOUCHING_PLAYER) {
touchingPlayer = true;
return true;
}
return false;
}
@Override
public void acceptPath(PathFinderRequest<Node> request) {
if (request.pathFound) {
resultPath = (GraphPathImp) request.resultPath;
}
}
}
if (newGoal != null) {
Vector2 direction = new Vector2(newGoal.getPosition().x - body.getPosition().x, newGoal.getPosition().y - body.getPosition().y).nor();
float speed = Constants.SKELETON_SPEED;
Vector2 velocity = new Vector2(speed * direction.x, speed * direction.y);
body.applyLinearImpulse(velocity.x * body.getMass(), velocity.y * body.getMass(), body.getWorldCenter().x, body.getWorldCenter().y, true);
}
if (pathGenerated)
if (Math.abs(body.getPosition().x - newGoal.getPosition().x) <= 0.1f && Math.abs(body.getPosition().y - newGoal.getPosition().y) <= 51 / 2f / Constants.PPM)
{
Gdx.app.debug(TAG, "Node reached!");
updatePath();
}
最佳答案
移动实体与 AI 没有直接关系。 AI 只是找到了一条路,实体跟随它。
使用 box2d,你必须向正确的方向施加力或脉冲,确保你的 box2d 世界的 step() 方法被调用并更新你的实体渲染坐标(例如 Sprite )以匹配 box2d 的 body 坐标。然后在下一个循环中再次从新坐标调用您的 AI,确定您现在必须向哪个方向移动并再次施加您的力。
所以循环看起来像
关于java - 如何将对象从节点移动到节点? Libgdx Box2d A*寻路,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62696067/
我正在编写一个具有以下签名的 Java 方法。 void Logger(Method method, Object[] args); 如果一个方法(例如 ABC() )调用此方法 Logger,它应该
我是 Java 新手。 我的问题是我的 Java 程序找不到我试图用作的图像文件一个 JButton。 (目前这段代码什么也没做,因为我只是得到了想要的外观第一的)。这是我的主课 代码: packag
好的,今天我在接受采访,我已经编写 Java 代码多年了。采访中说“Java 垃圾收集是一个棘手的问题,我有几个 friend 一直在努力弄清楚。你在这方面做得怎么样?”。她是想骗我吗?还是我的一生都
我的 friend 给了我一个谜语让我解开。它是这样的: There are 100 people. Each one of them, in his turn, does the following
如果我将使用 Java 5 代码的应用程序编译成字节码,生成的 .class 文件是否能够在 Java 1.4 下运行? 如果后者可以工作并且我正在尝试在我的 Java 1.4 应用程序中使用 Jav
有关于why Java doesn't support unsigned types的问题以及一些关于处理无符号类型的问题。我做了一些搜索,似乎 Scala 也不支持无符号数据类型。限制是Java和S
我只是想知道在一个 java 版本中生成的字节码是否可以在其他 java 版本上运行 最佳答案 通常,字节码无需修改即可在 较新 版本的 Java 上运行。它不会在旧版本上运行,除非您使用特殊参数 (
我有一个关于在命令提示符下执行 java 程序的基本问题。 在某些机器上我们需要指定 -cp 。 (类路径)同时执行java程序 (test为java文件名与.class文件存在于同一目录下) jav
我已经阅读 StackOverflow 有一段时间了,现在我才鼓起勇气提出问题。我今年 20 岁,目前在我的家乡(罗马尼亚克卢日-纳波卡)就读 IT 大学。足以介绍:D。 基本上,我有一家提供簿记应用
我有 public JSONObject parseXML(String xml) { JSONObject jsonObject = XML.toJSONObject(xml); r
我已经在 Java 中实现了带有动态类型的简单解释语言。不幸的是我遇到了以下问题。测试时如下代码: def main() { def ks = Map[[1, 2]].keySet()
一直提示输入 1 到 10 的数字 - 结果应将 st、rd、th 和 nd 添加到数字中。编写一个程序,提示用户输入 1 到 10 之间的任意整数,然后以序数形式显示该整数并附加后缀。 public
我有这个 DownloadFile.java 并按预期下载该文件: import java.io.*; import java.net.URL; public class DownloadFile {
我想在 GUI 上添加延迟。我放置了 2 个 for 循环,然后重新绘制了一个标签,但这 2 个 for 循环一个接一个地执行,并且标签被重新绘制到最后一个。 我能做什么? for(int i=0;
我正在对对象 Student 的列表项进行一些测试,但是我更喜欢在 java 类对象中创建硬编码列表,然后从那里提取数据,而不是连接到数据库并在结果集中选择记录。然而,自从我这样做以来已经很长时间了,
我知道对象创建分为三个部分: 声明 实例化 初始化 classA{} classB extends classA{} classA obj = new classB(1,1); 实例化 它必须使用
我有兴趣使用 GPRS 构建车辆跟踪系统。但是,我有一些问题要问以前做过此操作的人: GPRS 是最好的技术吗?人们意识到任何问题吗? 我计划使用 Java/Java EE - 有更好的技术吗? 如果
我可以通过递归方法反转数组,例如:数组={1,2,3,4,5} 数组结果={5,4,3,2,1}但我的结果是相同的数组,我不知道为什么,请帮助我。 public class Recursion { p
有这样的标准方式吗? 包括 Java源代码-测试代码- Ant 或 Maven联合单元持续集成(可能是巡航控制)ClearCase 版本控制工具部署到应用服务器 最后我希望有一个自动构建和集成环境。
我什至不知道这是否可能,我非常怀疑它是否可能,但如果可以,您能告诉我怎么做吗?我只是想知道如何从打印机打印一些文本。 有什么想法吗? 最佳答案 这里有更简单的事情。 import javax.swin
我是一名优秀的程序员,十分优秀!