1

所以我的 AI 乒乓球拍有问题。现在,人工智能非常简单和愚蠢。它所做的只是以连续的速度上下移动。我并不想完善这个项目,因为它真的只是为了向我介绍 LWJGL,所以我永远不会为这个系统创建一个直观的 AI。但是,我遇到了桨的 AI 问题。比赛开始时,桨从中间开始,一直向上,直到碰到天花板。它撞到天花板然后停止而不是下降,直到它可以重复运动。我想知道为什么桨只是停止而不是继续并跟随它的意思是桨。

启动类:(此类用于启动显示和渲染,包括桨。)

import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;

import com.evanklein.pong.entitity.CPUPlayer;
import com.evanklein.pong.entitity.Player;
import com.evanklein.pong.entitity.Ball;

public class Startup {

    // set up display
    public void start() {
        try {
            Display.setDisplayMode(new DisplayMode(600, 400));
            Display.setTitle("Pong");
            Display.create();
        } catch (LWJGLException e) {
            e.printStackTrace();
            System.exit(0);
        }

        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();
        GL11.glOrtho(0, 600, 400, 0, 1, -1);

        while (!Display.isCloseRequested()) {
            // render OpenGL here
            GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);

            // render player
            GL11.glBegin(GL11.GL_QUADS);
            GL11.glVertex2d(player.startX, player.startY);
            GL11.glVertex2d(player.startX + 20, player.startY);
            GL11.glVertex2d(player.startX + 20, player.startY + 70);
            GL11.glVertex2d(player.startX, player.startY + 70);
            GL11.glEnd();

            // player controls
            if (Keyboard.isKeyDown(Keyboard.KEY_UP)) {
                player.moveUp();
            }
            if (Keyboard.isKeyDown(Keyboard.KEY_DOWN)) {
                player.moveDown();
            }

            // render AI
            GL11.glBegin(GL11.GL_QUADS);
            GL11.glVertex2d(ai.startX, ai.startY);
            GL11.glVertex2d(ai.startX + 20, ai.startY);
            GL11.glVertex2d(ai.startX + 20, ai.startY + 70);
            GL11.glVertex2d(ai.startX, ai.startY + 70);
            GL11.glEnd();

            // set ai
            ai.move();

            // render Ball
            GL11.glBegin(GL11.GL_LINE_LOOP);

            GL11.glEnd();

            Display.update();
            Display.sync(60);

        }

        Display.destroy();
    }

    // Let's start this beyotch up!
    Player player = new Player();
    CPUPlayer ai = new CPUPlayer();
    Ball ball = new Ball();

    public static void main(String[] args) {
        new Startup().start();
    }
}

CPUPlayer 类:

public class CPUPlayer {

    public int startX = 550; // starting positions (x, y), always locked
    public int startY = 150;

    private int moveSpeed = 2;
    public int score = 0; // init

    public void move() {
        startY -= moveSpeed;
        if (startY <= -10) {
            startY += moveSpeed; // switch directions
        } else if (startY >= 338) {
            startY -= moveSpeed;
        }
    }

}

我的问题只是桨拒绝切换方向,而是粘在显示屏的顶部。为什么会发生这种情况,我能做些什么来解决它?如果您有任何其他问题或需要任何其他具体细节,请随时告诉我。

4

4 回答 4

3

问题在于,当它到达顶部时,您只是告诉它向下移动一次。在那之后,它仍然尝试向上移动而不是向下移动一次。要解决此问题,您需要有一个“方向”变量来告诉它应该向上还是向下移动,并在达到顶部/底部时更改变量。

例如:

public class CPUPlayer {

    public int startX = 550;    // starting positions (x, y), always locked
    public int startY = 150;

    private int moveSpeed = 2;
    private boolean movingUp = true;
    public int score = 0;    // init

    public void move() {
        if(movingUp) {
            startY -= moveSpeed;
            if (startY <= -10)
                movingUp = false;    // switch directions
        } else {                     // Should be moving down
            startY += moveSpeed;
            if (startY >= 338)
                movingUp = true;    // switch directions
        }
    }

}
于 2013-07-16T02:09:30.560 回答
2

你总是减去moveSpeed,然后你又添加 movespeed 来切换方向。这导致净变化为 0。

您需要添加moveSpeed*2何时startY <= -10才能更改方向。您的代码将像这样工作:

public void move() {
    startY -= moveSpeed;
    if (startY <= -10) {
        startY += (moveSpeed*2); // switch directions
    } else if (startY >= 338) {
        startY -= moveSpeed;
    }
}

中提琴!固定的!但是,我可以建议一种更复杂的方法。让桨在不同的模式下运行,如下所示:

boolean movingDown = false;
public void move() {
    int moveDir = movingDown?-moveSpeed:moveSpeed;
    startY += moveSpeed;
    if (startY <= -10 || startY>=338){
        movingDown = !movingDown;
    }
}

当桨移动得太低或太高时,这将切换对桨位置应用正增量还是负增量。

编辑:我的代码和 Sharks 代码基本上做同样的事情。我的使用 turnery 运算符,他使用 if/else 语句。

于 2013-07-16T02:09:39.340 回答
1

您的 move 方法首先从 startY 中扣除,然后检查是否应该进一步添加或扣除。在它应该添加到 startY 的情况下,该值只是简单地返回到移动调用之前的原始值。所以 startY 一旦低于 -10 就永远不会改变。

我认为你的方法有缺陷。您无法准确地确定桨仅从其当前位置朝哪个方向前进。而是使用像“isMovingUp”这样的布尔值并基于此扣除/添加到 startY。满足边界条件时更改布尔值。

于 2013-07-16T02:15:16.493 回答
0

这是你的问题:

startY -= moveSpeed; // here, startY is -moveSpeed;


if (startY <= -10) {
        startY += moveSpeed; // switch directions (here, startY is 0) because
                             // -moveSpeed + moveSpeed = 0
} else if (startY >= 338) {
        startY -= moveSpeed ;
}

所以添加moveSpeedstartY-moveSpeed + moveSpeed = 0.

要修复,请添加两倍的量moveSpeed

if (startY <= -10) {
        startY += 2 * moveSpeed; // switch directions                                  
} else if (startY >= 338) {
        startY -= 2 * moveSpeed ;
}
于 2013-07-16T02:10:11.720 回答