所以我的AI乒乓球拍有问题。现在,人工智能非常简单和愚蠢。它所做的就是以连续的速度上下移动。我不想完善这个项目,因为它只是向我介绍LWJGL,所以我永远不会为这个系统创建一个直观的AI。但是,我对桨的AI有问题。当比赛开始时,球拍从中间开始并直线上升,直至击中天花板。它撞到天花板然后停下来而不是下降直到它可以重复运动。我想知道为什么桨只是停止而不是继续并且跟着它意味着要划桨。
Startup Class :(此类用于启动显示和渲染,包括paddle。)
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;
}
}
}
我的问题很简单,桨只拒绝切换方向,而是粘在显示屏的顶部。为什么会发生这种情况,我该怎么做才能解决这个问题?如果您有任何其他问题或需要任何其他具体细节,请不要犹豫,让我知道。
答案 0 :(得分:3)
问题在于当它到达顶部时,你只是告诉它向下移动一次。在那之后,它仍然试图向上移动而不是向下移动一次。要解决这个问题,你需要有一个'direction'变量来告诉它是应该向上还是向下移动,并在达到顶部/底部时更改变量。
例如:
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
}
}
}
答案 1 :(得分:2)
您总是减去moveSpeed
,然后重新添加movepeed以切换方向。这导致净变化为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语句。
答案 2 :(得分:1)
您的移动方法首先从startY中扣除,然后检查是否应该进一步添加或减少。在它应该添加到startY的情况下,该值只是在移动调用之前返回到原始值。所以startY一旦低于-10就永远不会改变。
我认为你的方法存在缺陷。您无法准确地确定球拍的哪个方向仅从其当前位置开始。而是使用像“isMovingUp”这样的布尔值,并基于此推断/添加到startY。在满足边界条件时更改布尔值。
答案 3 :(得分: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 ;
}
因此,将moveSpeed
添加到startY
会产生-moveSpeed + moveSpeed = 0
。
要修复,请添加两倍moveSpeed
:
if (startY <= -10) {
startY += 2 * moveSpeed; // switch directions
} else if (startY >= 338) {
startY -= 2 * moveSpeed ;
}