我已经在这方面工作了好几天而且一直无处可去。我们做了一个简单的模拟,有两种类型的生物:Fox和Tux。 Tux随机移动,我应该实现一种方法,以便Fox追逐最接近的Tux。我发布了生物类而不是Tux,因为他没有覆盖生物的move()方法。现在只有福克斯。
我对Fox的移动方法中的代码的推理:创建一个最接近的Tux的ArrayList(如果它们的距离小于10)。对列表进行排序,并将具有最小距离的Tux放入Creature对象中。获取该Creature对象角度并根据该角度移动Fox。到目前为止没有任何事福克斯只是全部走到房间的底部,朝南,永不动。
注意:使用的距离法是基于毕达哥拉斯。这个解决方案的代码很简单。要知道,例如,“this.distance(c)”返回这两个对象之间的距离。
Fox课程:
import env3d.EnvObject;
import java.util.ArrayList;
import java.util.Collections;
public class Fox extends Creature
{
private double rand = 0;
private double randangle = 0;
private int frame = 0;
private double angle = 0;
private ArrayList<Creature> neighbours;
public Fox(double x, double y, double z)
{
super(x, y, z);
// Must use the mutator as the fields have private access
// in the parent class
setTexture("models/fox/fox.png");
setModel("models/fox/fox.obj");
neighbours = new ArrayList<Creature>();
}
public void move(ArrayList<Creature> creatures, ArrayList<Creature> dead_creatures)
{
// Move the object based on it's closest neighbour
for (Creature c : creatures) {
// Creates a list of closest Tux
ArrayList<Creature> neighbours = new ArrayList<Creature>();
if (this.distance(c) < 4 && c instanceof Tux) {
neighbours.add(c);
}
// sorting algortihm
if (neighbours.size() > 0) {
Creature minc = neighbours.get(0);
for (int i = 1; i < neighbours.size(); i++) {
if (this.distance(neighbours.get(i)) < this.distance(minc) ) {
minc = neighbours.get(i);
}
// angle that Fox should go to catch Tux
angle = Math.toDegrees(Math.atan2(this.getZ()-minc.getZ(),this.getX()-minc.getX()))+90;
}
}
// Move Fox based on it's closest neighbour's angle
setX(getX()+(Math.sin(Math.toRadians(angle))));
setZ(getZ()+(Math.cos(Math.toRadians(angle))));
}
// Makes sure object stays in the dimensions of the room
if (getX() < getScale()) setX(getScale());
if (getX() > 50-getScale()) setX(50 - getScale());
if (getZ() < getScale()) setZ(getScale());
if (getZ() > 50-getScale()) setZ(50 - getScale());
// The move method now handles collision detection
for (Creature c : creatures) {
if (c.distance(this) < c.getScale()+this.getScale() && c instanceof Tux) {
dead_creatures.add(c);
}
}
}
}
Tux课程:
import env3d.EnvObject;
import java.util.ArrayList;
abstract public class Creature extends EnvObject
{
private double rand = 0;
private double randangle = 0;
private int frame = 0;
/**
* Constructor for objects of class Creature
*/
public Creature(double x, double y, double z)
{
setX(x);
setY(y);
setZ(z);
setScale(1);
}
protected void generateRand()
{
rand = Math.random();
}
protected void generateRandAngle()
{
randangle = Math.random()*120;
}
public void move(ArrayList<Creature> creatures, ArrayList<Creature> dead_creatures)
{
if (frame == 10) {
generateRand();
generateRandAngle();
if (rand < 0.5){
setRotateY(getRotateY()-randangle);
} else if (rand < 1) {
setRotateY(getRotateY()+randangle);
}
frame = 0;
}
setX(getX()+(Math.sin(Math.toRadians(getRotateY()))*0.2));
setZ(getZ()+(Math.cos(Math.toRadians(getRotateY()))*0.2));
if (getX() < getScale()) setX(getScale());
if (getX() > 50-getScale()) setX(50 - getScale());
if (getZ() < getScale()) setZ(getScale());
if (getZ() > 50-getScale()) setZ(50 - getScale());
// The move method now handles collision detection
if (this instanceof Fox) {
for (Creature c : creatures) {
if (c.distance(this) < c.getScale()+this.getScale() && c instanceof Tux) {
dead_creatures.add(c);
}
}
}
frame++;
}
}
游戏课程:
import env3d.Env;
import java.util.ArrayList;
import env3d.EnvApplet;
/**
* A predator and prey simulation. Fox is the predator and Tux is the prey.
*/
public class Game extends EnvApplet
{
private Env env;
private boolean finished;
private boolean move;
private ArrayList<Creature> creatures;
/**
* Constructor for the Game class. It sets up the foxes and tuxes.
*/
public Game()
{
// we use a separate ArrayList to keep track of each animal.
// our room is 50 x 50.
creatures = new ArrayList<Creature>();
for (int i = 0; i < 55; i++) {
if (i < 5) {
creatures.add(new Fox((int)(Math.random()*48)+1, 1, (int)(Math.random()*48)+1));
} else {
creatures.add(new Tux((int)(Math.random()*48)+1, 1, (int)(Math.random()*48)+1));
}
}
}
/**
* Play the game
*/
public void play()
{
finished = false;
// Create the new environment. Must be done in the same
// method as the game loop
env = new Env();
// Make the room 50 x 50.
env.setRoom(new Room());
// Add all the animals into to the environment for display
for (Creature c : creatures) {
env.addObject(c);
}
// Sets up the camera
env.setCameraXYZ(25, 50, 55);
env.setCameraPitch(-63);
// Turn off the default controls
env.setDefaultControl(false);
// A list to keep track of dead tuxes.
ArrayList<Creature> dead_creatures = new ArrayList<Creature>();
// The main game loop
while (!finished) {
if (env.getKey() == 1) {
finished = true;
}
// Move each fox and tux.
for (Creature c : creatures) {
c.move(creatures, dead_creatures);
}
// Clean up of the dead tuxes.
for (Creature c : dead_creatures) {
env.removeObject(c);
creatures.remove(c);
}
// we clear the ArrayList for the next loop. We could create a new one
// every loop but that would be very inefficient.
dead_creatures.clear();
// Update display
env.advanceOneFrame();
}
// Just a little clean up
env.exit();
}
/**
* Main method to launch the program.
*/
public static void main(String args[]) {
(new Game()).play();
}
}
答案 0 :(得分:1)
if (this.distance(c) < 4 && c instanceof Tux) {
neighbours.add(c);
}
结合
从你的介绍开始......首先,两者不一样。其次,出于调试目的,你为什么要关心距离?Tux(如果他们的距离小于10)
creatures.add(new Fox((int)(Math.random()*48)+1, 1, (int)(Math.random()*48)+1));
creatures.add(new Tux((int)(Math.random()*48)+1, 1, (int)(Math.random()*48)+1));
作为一般规则,我通常会在调试时尽量避免使用Math.random。任何狐狸都不会在距离任何狐狸4个单位的范围内产卵。这将导致它们遵循默认路径。
尝试手动将Fox和Tux彼此相邻放置 - 如果有效则算法很好。
即
creatures.add(new Fox(5, 1, 5);
creatures.add(new Tux(5, 1, 4);
另外,在
中添加断点if (neighbours.size() > 0) {
Creature minc = neighbours.get(0); // Breakpoint here
会告诉你它是否正在检测任何晚礼服。