LibGDX / Java奇怪的行为

时间:2016-02-21 14:14:43

标签: java libgdx

这是在LibGDX中制作的游戏。用户可以产生绵羊,然后应该随意游荡。有两个问题。

  1. 羊并不总是改变他们的“正确”变量。
  2. 他们似乎总是以同样的方式行动,这不应该发生。
  3. 这是MainClass和Entity类的代码。其他不应该是这个错误的原因。

    主:

    package com.god.game;
    
    import com.badlogic.gdx.*;
    import com.badlogic.gdx.Input;
    import com.badlogic.gdx.graphics.GL20;
    import com.badlogic.gdx.graphics.OrthographicCamera;
    import com.badlogic.gdx.graphics.g2d.SpriteBatch;
    import com.badlogic.gdx.graphics.g2d.TextureAtlas;
    import com.badlogic.gdx.input.GestureDetector;
    import com.badlogic.gdx.math.Vector2;
    import com.badlogic.gdx.math.Vector3;
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    
    public class MainClass extends ApplicationAdapter {
        public static final int width = 1600;
        public static final int height = 1000;
        public static final String title = "God Game";
    
        public static EntityType[] entityTypes;
        public static float rand, cameraSpeed;
        public static Comparator<Entity> layerComp;
        public static int selectedId;
        public static String aiStr;
        public static InputMultiplexer input;
    
        SpriteBatch batch;
    
        public static ArrayList<Entity> entities;
        public static OrthographicCamera camera;
        public static Vector3 mousePos;
    
        @Override
        public void create () {
            input = new InputMultiplexer();
            input.addProcessor(new com.god.game.Input());
            input.addProcessor(new GestureDetector(new Gestures()));
            Gdx.input.setInputProcessor(input);
    
            entityTypes = new EntityType[]{new EntityType("Sheep", new Vector2(55, 38), new TextureAtlas(Gdx.files.internal("Textures/sheep.atlas")), 20, new AI(new String[]{"Wander"}))};
            entities = new ArrayList<Entity>();
    
            layerComp = new Comparator<Entity>() {
                @Override
                public int compare(Entity e1, Entity e2) {
                    if (e1.getPosition().y > e2.getPosition().y)
                        return -1;
                    if (e1.getPosition().y < e2.getPosition().y)
                        return 1;
                    return 0;
                }
            };
    
            camera = new OrthographicCamera(width, height);
            cameraSpeed = 500;
            selectedId = 0;
    
            batch = new SpriteBatch();
        }
    
        public void update(float deltaTime){
    
            handleInput(deltaTime);
    
            for(Entity e : entities){
                e.update(deltaTime);
            }
    
            Collections.sort(entities, layerComp);
    
            camera.update();
        }
    
        @Override
        public void render () {
    
            update(Gdx.graphics.getDeltaTime());
    
            Gdx.gl.glClearColor(0, 0.8f, 0, 1);
            Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    
            batch.setProjectionMatrix(camera.combined);
            batch.begin();
            for(Entity e : entities){
                if(!e.isRight())
                    entityTypes[e.getId()].getAtlas().findRegion(e.getFrame()).flip(true, false);
                batch.draw(entityTypes[e.getId()].getAtlas().findRegion(e.getFrame()), e.getPosition().x, e.getPosition().y);
                if(!e.isRight())
                    entityTypes[e.getId()].getAtlas().findRegion(e.getFrame()).flip(true, false);
            }
            batch.end();
        }
    
        @Override
        public void dispose(){
            batch.dispose();
            for(EntityType e : entityTypes)
                e.dispose();
        }
    
        public void handleInput(float deltaTime){
    
            mousePos = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);
            camera.unproject(mousePos);
    
            if(Gdx.input.isKeyPressed(Input.Keys.W))
                camera.translate(0, cameraSpeed*deltaTime);
            if(Gdx.input.isKeyPressed(Input.Keys.A))
                camera.translate(-cameraSpeed*deltaTime, 0);
            if(Gdx.input.isKeyPressed(Input.Keys.S))
                camera.translate(0, -cameraSpeed*deltaTime);
            if(Gdx.input.isKeyPressed(Input.Keys.D))
                camera.translate(cameraSpeed*deltaTime, 0);
        }
    }
    

    实体:

    package com.god.game;
    
    import com.badlogic.gdx.math.MathUtils;
    import com.badlogic.gdx.math.Vector2;
    
    public class Entity {
        private int id;
        private Vector2 position, goalPos;
        private boolean right;
        private String frame;
        private float animationTimer;
    
        public Entity(int id, Vector2 position) {
            this.id = id;
            this.position = position;
            this.right = true;
            this.frame = "stand";
            this.animationTimer = 0;
            this.goalPos = Vector2.Zero;
        }
    
        public void update(float deltaTime){
            MainClass.aiStr = MainClass.entityTypes[id].getAi().getBrainList()[0];
            if(MainClass.aiStr == "Wander"){
                MainClass.rand = MathUtils.random(1000);
    
                if(MainClass.rand == 1){
                    goalPos.x = -1;
                    right = false;
                }
                else if(MainClass.rand == 2)
                    goalPos.x = 0;
                else if(MainClass.rand == 3){
                    goalPos.x = 1;
                    right = true;
                }
    
                MainClass.rand = MathUtils.random(1000);
    
                if(MainClass.rand == 1)
                    goalPos.y = -1;
                else if(MainClass.rand == 2)
                    goalPos.y = 0;
                else if(MainClass.rand == 3)
                    goalPos.y = 1;
    
                moveForward(deltaTime);
            }
            else{
                frame = "stand";
                animationTimer = 0;
            }
            animationTimer += deltaTime;
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public Vector2 getPosition() {
            return position;
        }
    
        public void setPosition(Vector2 position) {
            this.position = position;
        }
    
        public boolean isRight() {
            return right;
        }
    
        public void setRight(boolean right) {
            this.right = right;
        }
    
        public String getFrame() {
            return frame;
        }
    
        public void setFrame(String frame) {
            this.frame = frame;
        }
    
        public float getAnimationTimer() {
            return animationTimer;
        }
    
        public void setAnimationTimer(float animationTimer) {
            this.animationTimer = animationTimer;
        }
    
        public Vector2 getGoalPos() {
            return goalPos;
        }
    
        public void setGoalPos(Vector2 goalPos) {
            this.goalPos = goalPos;
        }
    
        public void moveForward(float deltaTime){
            position.x += MainClass.entityTypes[id].getMoveSpeed() * deltaTime * goalPos.x;
            position.y += MainClass.entityTypes[id].getMoveSpeed() * deltaTime * goalPos.y;
            if(goalPos.x == 0 && goalPos.y == 0){
                frame = "stand";
                animationTimer = 0;
            }
            else if(animationTimer >= 0.2f){
                if(frame.equals("stand"))
                    frame = "move";
                else
                    frame = "stand";
                animationTimer = 0;
            }
        }
    }
    
    每当他们将goalPos.x改为-1或1时,绵羊应该都将他们的正确变量设置为true / false,但他们似乎并没有这样做。它们似乎也没有独立移动,相反它们就像一个阵型,每次都朝着同一个方向移动。他们独立地将他们的正确变量设置为真/假,但它与他们的运动不匹配。例如:一只羊向右移动,然后在向右移动时随机向左转,等等。

    非常感谢任何帮助,谢谢!

3 个答案:

答案 0 :(得分:2)

首先,你永远不应该说Java表现得很奇怪,而是你的代码表现不像预期的那样。如果你为你的错误责备一些内部java功能,你就不会发现它们。现在让我们来看看如果你的ai设置为wander会发生什么。

if(MainClass.aiStr == "Wander"){
        MainClass.rand = MathUtils.random(1000);
//Random number in the range of 0 to 1000.

        if(MainClass.rand == 1){ //happens .1% of the time
            goalPos.x = -1;
            right = false;
        }
        else if(MainClass.rand == 2) //happens .1% of the time
            goalPos.x = 0;
        else if(MainClass.rand == 3){ //happens .1% of the time
            goalPos.x = 1;
            right = true;
        }
 //since there is no else nothing happens 99.7% of the time.
    }

我的猜测是你的代码表现得像你期望的那样,你的计算机里面没有黑色伏都教。因此,将来责备自己并检查您的代码,它实际上没有那么多代码,只有您发布的内容的一小部分负责指导您的实体。

现在您可能想要的是这样的MathUtils.random(1, 4),因为最大值是独占的。或MathUtils.random(1, 5)如果您希望25%的时间没有发生任何事情。

一种更具可扩展性的方式,我总是喜欢这样的东西:

int randomNumber = MathUtils.random(1, 101);
if (randomNumber <= 33)
{
  //do something 33% of the time
}
else if (randomNumber <= 66)
{
  //do something 33% of the time
}
else
{
  //do something 34% of the time
}

现在这更容易改变,因为你需要做的就是改变百分比,你可以轻松添加另一个案例。

if (randomNumber <= 20)
{
  //do something 20% of the time
}
else if (randomNumber <= 60)
{
  //do something 40% of the time
}
else if (randomNumber <= 58)
{
  //do something 18% of the time
}
else
{
  //do something 22% of the time
}

答案 1 :(得分:1)

首先,你是在静态方式上访问变量,比如

         [...]
    MainClass.aiStr = MainClass.entityTypes[id].getAi().getBrainList()[0];
         [...]
    MainClass.rand = MathUtils.random(1000);
         [...]

所以所有的羊都会使用相同的值并像这样移动,只需在同一个实例上进行调用。

如果你是数学兰特1000并且比较值是否为1,每帧的概率为0.1%,如果你的游戏被锁定在30fps,它触发的可能性非常非常低。

你在渲染方法上检查了两次 if(!e.isRight()),所以它会翻转两次。

 for(Entity e : entities){
            if(!e.isRight())
                entityTypes[e.getId()].getAtlas().findRegion(e.getFrame()).flip(true, false);
            batch.draw(entityTypes[e.getId()].getAtlas().findRegion(e.getFrame()), e.getPosition().x, e.getPosition().y);
            if(!e.isRight())
                entityTypes[e.getId()].getAtlas().findRegion(e.getFrame()).flip(true, false);
        }

您能否提供有关EntityType类的更多信息?因此,当您在实体上设置移动速度时,我们可以找出您在做什么。

[编辑]如mbrlabs所述,总是使用.equals来比较字符串,因为即使它们看起来相同,它们实际上是包含相同文本的内存上的2个不同对象,因此使用==将永远不会为真。

答案 2 :(得分:0)

在您的实体班中,将此if(MainClass.aiStr == "Wander")更改为MainClass.aiStr.equals("Wander")

比较字符串时,应始终这样做。通过使用==您正在比较引用,但您想要比较字符串的实际内容。 if语句之间的代码很可能永远不会执行,因为您正在比较引用。