我的僵尸找不到自己。

3

听起来非常哲学,不是吗?

无论如何,我有一个相当复杂的问题。

我的main_activity类像这样收集所有的僵尸:

//Testing Runnable (used to compare the first zombie with the player)
private Runnable updateLocations = new Runnable(){
    @Override
    public void run(){
        try {
            while(true) {
                image_player.getLocationInWindow(pLoc);
                Zombie zoms = zombieCollection.next();
                if(!zoms.equals(null)){
                    zoms.getZombieImage().getLocationInWindow(zLoc);
                }
                System.out.println("Zombie: x = " + zLoc[0] + "; y = " + zLoc[1]);
                System.out.println("Player: x = " + pLoc[0] + "; y = " + pLoc[1]);
                Thread.sleep(500);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
};

我的僵尸类通过以下方式收集信息:

public class Zombie{

float X, Y;
int Width, Height;
Direction fdirc;
ImageView zImage;
Player player;

boolean dead;
int[] zLoc;


public Zombie(ImageView zImage, Player player){
    zLoc = new int[2];
    zImage.getLocationOnScreen(zLoc);

    this.zImage = zImage;
    this.X = zLoc[0];
    this.Y = zLoc[1];
    this.Width = zImage.getWidth();
    this.Height = zImage.getHeight();
    this.fdirc = Direction.EAST;
    this.player = player;
    this.dead = false;

    Thread thread = new Thread(this.startZombieChase);
    thread.start();
}

public ImageView getZombieImage(){
    return zImage;
}
private Runnable startZombieChase = new Runnable() {
    @Override
    public void run() {
        try {
            while(!dead) {
                moveTowardsPlayer();

                Thread.sleep(10);
                updateZombie.sendEmptyMessage(0);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
};
private Handler updateZombie = new Handler(Looper.getMainLooper()) {
    public void handleMessage(android.os.Message msg) {

        /** Because the zombie should always be on top! **/
        zImage.getLocationOnScreen(zLoc);
        zImage.bringToFront();
        zImage.setX(X);
        zImage.setY(Y);

    }
};

private void moveTowardsPlayer(){
    int player_x = player.getPosition()[0];
    int player_y = player.getPosition()[1];

    l("Where is it in zombie class : player - " + player_x + " " + player_y + "zombie  - " + X + " " + Y);

    float compareX = player_x - (int)X;
    float compareY = player_y - (int)Y;



    // Y is closer, so we're moving horizontally.
    if(Math.abs(compareX) < Math.abs(compareY)){
        //Moving North
        if(player_y > Y){
            Y+=1;
        }
        //Moving South
        else if(player_y < Y){
            Y-=1;
        }
    }
    // X is closer, so we're moving vertically.
    else{
        //Moving East
        if(player_x > X){
            X+=1;
        }
        //Moving West
        else if(player_x < X){
            X-=1;
        }

    }
}
public void l(Object string){
    System.out.println("Log - " + string);
}
}

我遇到的问题是,它会相对于某个数字移动(所以它确实会移动),但不是正确的东西。 logcat告诉我:
- 它在僵尸类中的位置:玩家 - 750 451 僵尸 - 750 451 - 它在main_activity中的位置:玩家 - 750 451 僵尸 - 792 619
有人能帮我理解我做错了什么吗?
整个项目位于这里.

7
首先,!zoms.equals(null) 将始终返回 true 或由于 NPE 失败。 - Tunaki
4
好的,我会尽力进行翻译。以下是需要翻译的内容:Yes.... it will...是的……它会(指一个对象和null进行比较)…… - Tunaki
2
也许,但是 zoms.equals(null) 要么会抛出异常,要么返回 false。因此 !zoms.equals(null) 要么会抛出异常,要么返回 true。这不是与 null 进行比较的方式,您可以参考上面的链接。 - Tunaki
1
添加悬赏会导致更多的踩,顺便说一句,你没有理解编程逻辑,并且对SO社区成员很无礼。 - Maveňツ
2
我理解你的想法,但是对我来说,downvotes只是没有任何意义的像素。我明白我可能处理得不当,我很抱歉。人们试图“优化我的代码”。这很好,但它并没有回答我的问题,而这正是我需要的。我需要知道为什么有两个不同的引用,而没有人帮助我回答这个问题。 - sheepiiHD
显示剩余6条评论
2个回答

4

远离Brainz的僵尸必定是生病的僵尸。我们不能容忍这种情况,不是吗?

如果想要让僵尸向非僵尸移动,可以使用一个函数,但该函数使用了非参数变量,因此很难找出它们来自哪里。我建议使用以下代码:(这有点冗长,但清楚地显示了正在发生的事情)

/*
 * Function to update the position of the Zombie, aka walk to the Player.
 * @player_pos       - Where's the Brainz at?
 * @zombie_pos       - Where am I?
 * Might want to build it overloaded with an option for the speed.
 *
 * @return           - We return the new Zombie pos.
 */
private double [] moveTowardsPlayer(double [] player_pos, double [] zombie_pos) {
    // To make sure we don't override the old position, we copy values. (Java stuff)
    double [] player_pos_old = player_pos.clone();
    double [] zombie_pos_old = zombie_pos.clone();

    // Let's get the new X pos for the Zombie
    double left_or_right = player_pos_old[0] - zombie_pos_old[0]; // pos number is right, neg is left
    double zombie_pos_new_x;
    if (left_or_right > 0) { // Right
        zombie_pos_new_x = player_pos_old[0] + zombie_speed;
    } else { // Left - this way we make sure we are always getting nearer to the Brainz.
        zombie_pos_new_x = player_pos_old[0] - zombie_speed;
    }

     // TODO: do the same for the Y pos.

    // Bring it together
    double [] zombie_pos_new = {zombie_pos_new_x, zombie_pos_new_y};

    // One step closer to the Brainz!
    return zombie_pos_new;
}

并像这样使用:

double [] zombie_pos = moveTowardsPlayer([2, 2], [5, 4]);
this.X = zombie_pos[0]; // I'd advice to keep these together as one var.
this.Y = zombie_pos[1]; // But it's your game.

然后确定僵尸何时获取Brainz(或子弹)。


3

这里不正确:

if(!zoms.equals(null)){

如果您想检查zoms是否指向空引用,请执行以下操作:

if(zoms != null ){

我已经更改了这个,但它并没有解决问题。我也不知道它怎么可能解决问题。我正在检查该位置的引用,问题不在于检查它是否为空。我没有收到NPEs。 - sheepiiHD
4
即使它不能解决你的问题,但是如果有错误的话,就按照ΦXocę 웃 Пepeúpa ツ的建议去做。 - Opiatefuchs
我不是让你批评我的编程。我是在寻求解决我的问题的帮助。这个方法并没有解决我的问题。如果它不能解决我的问题,那它为什么会是一个答案呢?它不是我问题的答案,因此对我来说毫无意义。 - sheepiiHD
3
也许你可以欣赏一下人们无偿地试图帮助你的事实? :) - denvercoder9
我理解你的想法,但你也需要理解我的想法。这个回答并没有解决我的问题,只是批评。它不是一个解决方案,对我没有帮助,即使我已经实施了这个方案,我仍然会回到原点,面临同样的问题。我不是要求别人修改我的代码。我已经意识到这部分是错误的,但是:这并没有对我有所帮助。那么,如果他们根本没有帮助我,他们怎么能免费帮助我呢? - sheepiiHD
为什么这被标记为非常低质量???我就是不明白。 - Nissa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接