我在大学课程中使用Android Studio制作了一个经典乒乓球游戏的简单版本。目前,几乎所有东西都准备就绪,只是我为敌方挡板创建了一个无敌的AI。我使用默认的RectF
类创建了挡板和球,并根据球的当前位置调整我的AI挡板的位置(我减去/加上65,因为我的挡板长度是130像素,这使得挡板相对于球居中)。这实际上允许敌方挡板以无限速度移动,因为它与球的速度/位置匹配(球的速度随着每个新关卡增加)。以下是该方法的代码:
public void AI(Paddle paddle) { RectF paddleRect = paddle.getRect(); RectF ballRect = ball.getRect(); if (ballRect.left >= 65 && ballRect.right <= screenX - 65) { paddleRect.left = (ballRect.left - 65); paddleRect.right = (ballRect.right + 65); } if (ballRect.left < 65) { paddleRect.left = 0; paddleRect.right = 130; } if (ballRect.right > screenX - 65) { paddleRect.left = screenX - 130; paddleRect.right = screenX; }}
作为参考,以下是我Paddle
类的相关部分:
public Paddle(float screenX, float screenY, float xPos, float yPos, int defaultSpeed){ length = 130; height = 30; paddleSpeed = defaultSpeed; // 开始时挡板位于屏幕中央 x = (screenX / 2) - 65; xBound = screenX; // 创建矩形 rect = new RectF(x, yPos, x + length, yPos + height);}// 设置挡板的移动状态,如果它向左、向右移动或不动public void setMovementState(int state) { paddleMoving = state;}// 更新挡板的位置public void update(long fps){ if(x > 0 && paddleMoving == LEFT){ x = x - (paddleSpeed / fps); } if(x < (xBound - 130) && paddleMoving == RIGHT){ x = x + (paddleSpeed / fps); } rect.left = x; rect.right = x + length;}
上面的update(long fps)
方法中的fps
是从我的View
类中的run()
方法传递过来的:
public void run() { while (playing) { // 捕获当前时间(毫秒) startTime = System.currentTimeMillis(); // 更新并绘制帧 if (!paused) { onUpdate(); } draw(); // 计算此帧的fps thisTime = System.currentTimeMillis() - startTime; if (thisTime >= 1) { fps = 1000 / thisTime; } }}
我的挡板和球在View
类中的onUpdate()
方法中不断更新。
public void onUpdate() { // 更新对象的位置 paddle1.update(fps); ball.update(fps); AI(paddle2);}
我如何使用我为每个新挡板定义的挡板速度来限制我的AI挡板的速度?我已经尝试修改AI(Paddle paddle)
方法以包含+/- (paddleSpeed / fps)
,但似乎对挡板没有任何影响。也许我只是实现得不对,但任何帮助都将非常棒!
回答:
为了让AI以稳定的速度移动挡板,而不是直接跳到正确的位置,只需尝试使挡板的中间与球的中间对齐:
public void AI(Paddle paddle) { RectF paddleRect = paddle.getRect(); RectF ballRect = ball.getRect(); float ballCenter = (ballRect.left + ballRect.right) / 2; float paddleCenter = (paddleRect.left + paddleRect.right) / 2; if (ballCenter < paddleCenter) { setMovementState(LEFT); } else { setMovementState(RIGHT); }}
然后在onUpdate
中调用AI(paddle2)
之后,调用paddle2.update(fps)
。这样你就不会在绘图代码中重复自己。你会注意到,如果球的速度比挡板快很多,AI挡板可能不会表现得很完美。在这种情况下,你可以使用数学来预测球最终会到达哪里,并努力到达那里。