gpt4 book ai didi

java - 游戏编程 - 让玩家保持在游戏场内并避开某些障碍

转载 作者:太空宇宙 更新时间:2023-11-04 09:58:34 25 4
gpt4 key购买 nike

我的类(class)正在学习 Java 子类化,并在下周扩展。我们的讲师给了我们一段游戏代码,其中人工智能四处移动并收集所谓的“苹果”。

A 是好苹果,而 B 是坏苹果。四处移动的1(当代码运行时)是我们的玩家。无论苹果B是否在其范围内,玩家都会自动向苹果A移动。它还往往会越界,从而导致程序停止。如果玩家没有出界,那么程序循环500次后就会停止。

我们的讲师要求我们更正此代码中的特定部分,以便

  1. 玩家 AI 永远不会出界,
  2. 玩家AI尽可能避开苹果B(除非它靠近边界,否则玩家别无选择,只能吃坏苹果)

我们唯一允许更正的地方标有※1(class MyPlayerAI extends PlayerAIBase)和※2(PlayerAIBase playerAI = new in main class)。我一直在尝试添加条件等等,但我似乎仍然无法获得预期的结果。

我知道这个问题可能是模糊且开放式的,但是有人可以帮助我知道我应该在这段代码中纠正什么吗?非常感谢任何帮助/指示。我并不是直接要求解决方案,但此时我只是非常迷失。

我还在我的 repl 的最后添加了一个链接来运行此代码。

import java.util.*;

class GameObject {
public double x;
public double y;
char mark = '*';

public GameObject(double x, double y, char mark) {
this.x = x;
this.y = y;
this.mark = mark;
}
}

class GoodApple extends GameObject {
public GoodApple(double x, double y) {
super(x, y, 'A');
}
public GoodApple(GoodApple other) {
super(other.x, other.y, other.mark);
}
}

class BadApple extends GameObject {
public BadApple(double x, double y) {
super(x, y, 'B');
}
public BadApple(BadApple other) {
super(other.x, other.y, other.mark);
}
}

class Player extends GameObject {
public double vx;
public double vy;

public Player(double x, double y, char mark) {
super(x, y, mark);
vx = 0.0;
vy = 0.0;
}
public Player(Player other) {
super(other.x, other.y, other.mark);
this.vx = other.vx;
this.vy = other.vy;
}
}

class Accel {
double ax;
double ay;
public Accel(double ax, double ay) {
this.ax = ax;
this.ay = ay;
}
}

class PlayerAIBase {
public Accel next(Player player, GoodApple goodApple, BadApple badApple, double stageSize) {
return new Accel(0.0, 0.0);
}
}

class PlayerAIDummyHead extends PlayerAIBase {
@Override
public Accel next(Player player, GoodApple goodApple, BadApple badApple, double stageSize) {
double dx = goodApple.x - player.x;
double dy = goodApple.y - player.y;
Accel a = new Accel(dx / 4, dy / 4);
return a;
}
}

class MyPlayerAI extends PlayerAIBase {
// ※1 recode class PlayerAIDummyHead so that player does not go out of bounds, and avoids apple B

// public Accel next(Player player, GoodApple goodApple, BadApple badApple, double stageSize) {

// }

}

class Main {
public static void main(String[] args) throws InterruptedException {
PlayerAIBase playerAI = new PlayerAIDummyHead(); // ※2 change this line to PlayerAIBase playerAI = new MyPlayerAI();

GameManager gm = new GameManager(playerAI);

gm.initializeStage();
while (gm.gameTick < 500) {
gm.printStage();
System.out.println("time: " + gm.gameTick + " score: " + gm.playerScore);
Thread.sleep(50);
gm.next();
if (gm.playerDropped) {
break; // while gm.gameTick
}
}
gm.printStage();
System.out.println("time: " + gm.gameTick + " score: " + gm.playerScore);
}
}

class GameManager {
static final double stageSize = 20.0;
static final double maxAccel = 1.0;
static final double maxVelocity = 2.5;

Random rand = new Random();

PlayerAIBase playerAI;
int playerScore;
int gameTick;
Player player;
boolean playerDropped;
GoodApple goodApple;
BadApple badApple;

public GameManager(PlayerAIBase playerAI) {
this.playerAI = playerAI;
}

public void initializeStage() {
playerScore = 0;
gameTick = 0;
double r = stageSize - 2.0 * 2;
player = new Player(rand.nextDouble() * r + 2.0, rand.nextDouble() * r + 2.0, '1');
goodApple = new GoodApple(rand.nextDouble() * r + 2.0, rand.nextDouble() * r + 2.0);
badApple = new BadApple(rand.nextDouble() * r + 2.0, rand.nextDouble() * r + 2.0);
}

public static double distance(GameObject obj, double px, double py) {
double dx = obj.x - px;
double dy = obj.y - py;
return Math.sqrt(dx * dx + dy * dy);
}

public static double distance(GameObject obj1, GameObject obj2) {
double dx = obj1.x - obj2.x;
double dy = obj1.y - obj2.y;
return Math.sqrt(dx * dx + dy * dy);
}

public void printStage() {
int stageDisplaySize = 20;
int stageDisplayMarginSize = 2;
GameObject[] objs = { player, badApple, goodApple };
for (int y = 0; y < stageDisplaySize + 2 * stageDisplayMarginSize; ++y) {
double py = (y - stageDisplayMarginSize) * stageSize / stageDisplaySize;
for (int x = 0; x < stageDisplaySize + 2 * stageDisplayMarginSize; ++x) {
double px = (x - stageDisplayMarginSize) * stageSize / stageDisplaySize;
boolean printed = false;
for (GameObject obj : objs) {
if (distance(obj, px, py) <= 1.0) {
System.out.print(obj.mark);
printed = true;
break; // for obj
}
}
if (! printed) {
if (0.0 <= py && py <= stageSize && 0.0 <= px && px <= stageSize) {
System.out.print('.');
}
else {
System.out.print(' ');
}
}
}
System.out.println();
}
}

public void next() {
++gameTick;

Accel playerAccel = playerAI.next(new Player(player), new GoodApple(goodApple), new BadApple(badApple), stageSize);
// if the absolute acceleration is more than maxAccel, recalculate to keep within bounds of maxAccel
double aSize = Math.sqrt(playerAccel.ax * playerAccel.ax + playerAccel.ay * playerAccel.ay);
if (aSize > maxAccel) {
playerAccel.ax = playerAccel.ax / aSize * maxAccel;
playerAccel.ay = playerAccel.ay / aSize * maxAccel;
}

player.vx += playerAccel.ax;
player.vy += playerAccel.ay;
// if absolute value of speed is more than maxVelocity, recalculate to keep within bounds of maxVelocity
double vSize = Math.sqrt(player.vx * player.vx + player.vy * player.vy);
if (vSize > maxVelocity) {
player.vx = player.vx / vSize * maxVelocity;
player.vy = player.vy / vSize * maxVelocity;
}

int timeResolution = 8;
for (int t = 0; t < timeResolution; ++t) {
player.x += player.vx / timeResolution;
player.y += player.vy / timeResolution;
if (player.x < 0.0 || player.x >= stageSize || player.y < 0.0 || player.y >= stageSize) {
playerDropped = true;
break; // for t
}

if (badApple != null && distance(player, badApple) < 2.0) {
playerScore -= 10;
badApple = null;
}

if (goodApple != null && distance(player, goodApple) < 2.0) {
playerScore += 1;
goodApple = null;
}
}

if (badApple == null) {
double r = stageSize - 2.0 * 2;
badApple = new BadApple(rand.nextDouble() * r + 2.0, rand.nextDouble() * r + 2.0);
}
if (goodApple == null) {
double r = stageSize - 2.0 * 2;
goodApple = new GoodApple(rand.nextDouble() * r + 2.0, rand.nextDouble() * r + 2.0);
}
}
}

Good Apple vs Bad Apple

最佳答案

您提供的代码编写得很好,因此请先仔细阅读并尝试了解每个类和方法的作用,即使您不了解它们是如何做的。

can someone please help me as to what I should correct in this code?

关于您应该更正哪些内容以及哪里的说明也很清楚:

  • ※1 是您需要实现新的玩家 AI 逻辑的地方,以使其符合您所获得的行为。
  • ※2 只是将旧的玩家 AI 逻辑实现类 PlayerAIDummyHead 替换为您在※1 中编写的新类 MyPlayerAI。它已在该行的评论中明确给出。

要解决※1,首先要了解当前的行为是什么。 PlayerAIDummyHead 使玩家加速一定的量和方向,这取决于玩家与 A 之间的当前距离。此计算是在循环中完成的,因此每次迭代时加速度都会根据先前加速度给出的结果而变化。

这种移动行为是有问题的,因为它没有考虑 B 的位置或舞台的大小,而这两者都是由计算方法给出的。在 MyPlayerAInext 方法中,尝试一点一点改进数学,以找到一条更理想的通向 A 的路径。这是您的主要任务:改进计算路线的数学方法。

Any help/pointers is extremely appreciated.

您可以尝试一些想法:

  • 让玩家直接前往A
  • 目标是到达 A 时速度为 0。这样可以避免您无法及时 parking 反转方向时冲出舞台。
  • 查看 B 是否位于该直接路由的路径中。如果是这样,请向侧面或对角线移动,直到它不在该路径中。
  • 操纵时避免出界。

I understand that the acceleration changes on every iteration but I can't really make out how it's used to calculate the next step the player is supposed to take.

加速度改变速度(speed):

player.vx += playerAccel.ax;
player.vy += playerAccel.ay;

然后通过执行速度改变位置

player.x += player.vx / timeResolution;
player.y += player.vy / timeResolution;

timeResolution 倍,因此基本上是 player.x +=player.vx(y 相同)。

所以加速度决定了速度如何变化,速度又决定了位置如何变化。如果你想到达一个点,只需向它加速一次(将在该方向上设置正速度),然后将加速度设置为0(将保持恒定速度),然后设置一次负加速度(将降低速度,可能为0)。如果你想更快地到达该点,请保持正加速度,这将使速度增长得更多,但请记住及时减速以降低这个大速度。

关于java - 游戏编程 - 让玩家保持在游戏场内并避开某些障碍,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53791175/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com