所以,我正在从RealTutsGML学习Java教程,而我正处于第7集的最后一部分。我有一个问题 - 敌人AI不能正常工作 - 它不会一直跟随玩家,当它发生时,它是紧张的,只在短距离内。敌人也只向右下方移动。
以下是我的所有代码:(所需部分)
package com.project.main;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.util.Random;
public class Game extends Canvas implements Runnable{
private static final long serialVersionUID = -2379768900378456337L;
public static final int WIDTH = 640, HEIGHT = WIDTH / 12 * 9;
private Thread thread;
private boolean running = false;
private Random r;
private Handler handler;
private HUD hud;
private Spawn spawner;
public Game(){
handler = new Handler();
this.addKeyListener(new KeyInput(handler));
new Window(WIDTH, HEIGHT, "Dodge BETA", this);
hud = new HUD();
spawner = new Spawn(handler, hud);
r = new Random();
handler.addObject(new Player(WIDTH/2-32, HEIGHT/2-32, ID.Player, handler));
handler.addObject(new BasicEnemy(r.nextInt(WIDTH - 32), r.nextInt(HEIGHT - 32), ID.BasicEnemy, handler));
}
public synchronized void start(){
thread = new Thread(this);
thread.start();
running = true;
}
public synchronized void stop(){
try{
thread.join();
running = false;
}catch(Exception e){
e.printStackTrace();
}
}
public void run(){
this.requestFocus();
long lastTime = System.nanoTime();
double amountOfTicks = 60.0;
double ns = 1000000000 / amountOfTicks;
double delta = 0;
long timer = System.currentTimeMillis();
int frames = 0;
while(running){
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while(delta >= 1){
tick();
delta--;
}
if(running)
render();
frames++;
if(System.currentTimeMillis() - timer > 1000){
timer += 1000;
System.out.println("FPS: " + frames);
}
}
stop();
}
private void tick(){
handler.tick();
hud.tick();
spawner.tick();
}
private void render(){
BufferStrategy bs = this.getBufferStrategy();
if(bs == null){
this.createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.setColor(Color.black);
g.fillRect(0, 0, WIDTH, HEIGHT);
handler.render(g);
hud.render(g);
g.dispose();
bs.show();
}
public static float clamp(float var, float min, float max){
if(var >= max)
return var = max;
else if(var <= min)
return var = min;
else
return var;
}
public static void main(String args[]){
new Game();
}
}
GameObject是敌人和玩家的主类。它有助于使用许多预制方法使东西更容易和更清洁。
package com.project.main;
import java.awt.Graphics;
import java.awt.Rectangle;
public abstract class GameObject {
protected float x, y;
protected ID id;
protected float velX, velY;
public GameObject(float x, float y, ID id){
this.x = x;
this.y = y;
this.id = id;
}
public abstract void tick();
public abstract void render(Graphics g);
public abstract Rectangle getBounds();
public void setX(int x){
this.x = x;
}
public void setY(int y){
this.y = y;
}
public float getX(){
return x;
}
public float getY(){
return y;
}
public void setId(ID id){
this.id = id;
}
public ID getId(){
return id;
}
public void setVelX(int velX){
this.velX = velX;
}
public void setVelY(int velY){
this.velY = velY;
}
public float getVelX(){
return velX;
}
public float getVelY(){
return velY;
}
}
处理程序类 该类有助于将对象添加到游戏中并将其删除,以及更新它们并渲染对象。
package com.project.main;
import java.awt.Graphics;
import java.util.LinkedList;
public class Handler {
LinkedList<GameObject> object = new LinkedList<GameObject>();
public void tick(){
for(int i = 0; i < object.size(); i++){
GameObject tempObject = object.get(i);
tempObject.tick();
}
}
public void render(Graphics g){
for(int i = 0; i < object.size(); i++){
GameObject tempObject = object.get(i);
tempObject.render(g);
}
}
public void addObject(GameObject object){
this.object.add(object);
}
public void removeObject(GameObject object){
this.object.remove(object);
}
}
SMARTENEMY AI CLASS应该创造出跟随玩家的聪明敌人 - 但正如我之前所解释的那样,它真的是错误的。
package com.project.main;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
public class SmartEnemy extends GameObject{
private Handler handler;
private GameObject player;
public SmartEnemy(int x, int y, ID id, Handler handler) {
super(x, y, id);
this.handler = handler;
for(int i = 0; i < handler.object.size(); i++){
if(handler.object.get(i).getId() == ID.Player) player = handler.object.get(i);
}
}
public Rectangle getBounds(){
return new Rectangle((int)x, (int)y, 16, 16);
}
public void tick() {
x += velX;
y += velY;
float diffX = x - player.getX() - 8;
float diffY = y - player.getY() - 8;
float distance = (float) Math.sqrt((x - player.getX())*(x - player.getX()) + (y-player.getY())*(y-player.getY()));
velX = (int) ((-1.0/distance) * diffX);
velY = (int) ((-1.0/distance) * diffY);
if(y <= 0 || y >= Game.HEIGHT - 50) velY *= -1;
if(x <= 0 || x >= Game.WIDTH - 20) velX *= -1;
handler.addObject(new Trail(x, y, ID.Trail, Color.green, 16, 16, 0.03f, handler));
}
public void render(Graphics g) {
g.setColor(Color.green);
g.fillRect((int)x, (int)y, 16, 16);
}
}
答案 0 :(得分:0)
有几件事情浮现在脑海中: 如果它只是向右和向下移动,则表示你的增量总是正的(velX,velY)。从代码i SMARTENEMY开始,为什么会发生这种情况并不明显。
其次,随着distance
的增长,速度会下降。这可能就是为什么它只适用于短距离。
第三,如果你翻转你的差异计算的参数(player.x - x),你可以在速度计算上放下-1f。 我不明白为什么速度应该取决于距离。