Java中的流畅运动

时间:2011-02-07 00:02:04

标签: java simulation

我正在3D环境中进行模拟。到目前为止,我有所有生物的动作,但它不是“平滑的”。我尝试了很多东西但是非常错误。现在我只是不知道该怎么做。我正在考虑实现一个向量(不是向量类),但实际上并不知道如何。

import env3d.EnvObject;
import java.util.ArrayList;

abstract public class Creature extends EnvObject
{

/**
 * Constructor for objects of class Creature
 */
public Creature(double x, double y, double z)
{
    setX(x);
    setY(y);
    setZ(z);
    setScale(1);
}

public void move(ArrayList<Creature> creatures, ArrayList<Creature> dead_creatures)
{                
    double rand = Math.random();
    if (rand < 0.25) {
        setX(getX()+getScale());
        setRotateY(90);
    } else if (rand < 0.5) {
        setX(getX()-getScale());
        setRotateY(270);
    } else if (rand < 0.75) {
        setZ(getZ()+getScale());
        setRotateY(0);
    } else if (rand < 1) {
        setZ(getZ()-getScale());
        setRotateY(180);
    }                

    if (getX() < getScale()) setX(getScale());
    if (getX() > 50-getScale()) setX(50 - getScale());
    if (getZ() < getScale()) setZ(getScale());
    if (getZ() > 50-getScale()) setZ(50 - getScale());

    // 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);
            }
        }
    }
}        

}

import env3d.Env;
import java.util.ArrayList;

/**
 * A predator and prey simulation.  Fox is the predator and Tux is the prey.
 */
public class Game
{
private Env env;    
private boolean finished;

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();
}

}

2 个答案:

答案 0 :(得分:0)

您没有展示足够的程序。基本上,如果你想让动画流畅,并且你想自己做(而不是使用JavaFX或其他东西),那么你需要做很多帧间。因此,不是推进整个计时器滴答,而是提前计时器滴答的十分之一,将屏幕上的所有内容移动一点,然后再次前进。您应该每10秒钟进行一次背景重绘,以获得流畅的动画效果。

答案 1 :(得分:0)

正如vy32所述,我们需要查看更多代码。但看起来你错过了时间码。

您可能想要做的是检查游戏循环的每次迭代的时间,然后睡眠一段时间以达到一些所需的帧速率。否则你的游戏循环将每秒运行数十万次。

或者,你应该将你的生物推进一个距离,该距离与自上一帧以来经过的时间量成正比。

这是一个非常简单的调节回路的例子(“fps”是所需的帧速率):

private long frameLength = 1000000000 / fps;

public void run() {
    long ns = System.nanoTime();
    while (!finished) {

        //Do one frame of work
        step();

        //Wait until the time for this frame has elapsed
        try {
            ns += frameLength;
            Thread.sleep(Math.max(0, (ns - System.nanoTime())/10000000));
        } catch (InterruptedException e) {
            break;
        }
    }
}

将它改装成游戏循环应该很容易。