gpt4 book ai didi

java游戏如何构造定时效果/定距效果?

转载 作者:塔克拉玛干 更新时间:2023-11-01 23:02:40 26 4
gpt4 key购买 nike

我正在用 javafx 编写一个 java 游戏,但我认为这个问题的解决方案并不是 javafx 独有的......

我有一个实体类和一堆它的子类,如导弹、激光等。 但是,当导弹和激光是由游戏中的角色创建时,它们总是会一直运行,直到它们碰到 Canvas 的矩形边界或当它们击中一个角色并消失。

但是,我预计导弹/激光还有许多其他行为:

  • 导弹可以继续飞行,直到 4 秒后消失
  • 导弹飞行600像素后可以继续飞行直到消失(这个和上一个类似)
  • 激光可以存在于矩形区域中或与角色一起移动,直到它在 4 秒后消失。

  • 问题是,我们如何才能达到这种定时效果? (也许是 propertyChangeListener?)或者我应该向实体本身添加内容,还是应该考虑更改我的 Controller 类?
    这是我拥有的代码:
    public abstract class Entity implements Collidable{

    private double x;
    private double y;
    private int z;
    private double velocityX;
    private double velocityY;
    private Image img;
    private boolean ally;
    protected double width;
    protected double height;

    public Entity(int x,int y,int z,boolean b,Image hihi)
    {
    setX(x);
    setY(y);
    setZ(z);
    ally=b;
    setVelocityX(0);
    setVelocityY(0);
    img= hihi;
    }
    public void move()
    {
    x+=getVelocityX();
    y+=getVelocityY();
    }

    ...
    ...
    }

    public class Controller {

    private List<BattleShip> bs;
    private List<Missile> m;
    private Rectangle2D rect;


    public Controller()
    {
    bs= new ArrayList<BattleShip>();
    m= new ArrayList<Missile>();
    rect= new Rectangle2D(-300, -300, 1300, 1050);
    }
    public void update()
    {

    for(int i = bs.size() - 1; i >= 0; i --) {
    bs.get(i).move();
    if (!rect.contains(bs.get(i).getRect())) {
    bs.remove(i);
    }
    }
    for(int i = m.size() - 1; i >= 0; i --) {
    m.get(i).move();
    if (!rect.contains(m.get(i).getRect())) {
    m.remove(i);
    }
    }
    collide();
    }

    更新[看起来不错:)]:

    enter image description here

    最佳答案

    好吧,我不是游戏行业的专家,但这是我的建议:

  • 有一个变量( boolean 值)显示对象的状态。
  • private volatile boolean isDestroyed = false ;

  • 注意 : volatile 是必要的!
  • 如果游戏对象有时间限制(自毁),那么在它的构造函数(或通常在它的类中)创建时,启动一个在你想要的持续时间内 hibernate 的任务,并在任务结束时将 isDestroyed 变量更新为 true。

  • 注意 :您还可以在 Task 中放置销毁游戏对象的动画。
  • 在执行所有渲染操作的主要 update() 中,您可以忽略渲染游戏对象或将其从列表中删除(小心避免 ConcurrentModificationException )

  • 编辑 :
    所以让我们尝试一个例子..下面的代码不是绘制/移动形状的最佳方式,它只是为了展示我的解决方案。

    主类
    import java.util.ArrayList;
    import java.util.Random;
    import javafx.animation.AnimationTimer;
    import javafx.application.Application;
    import javafx.scene.Group;
    import javafx.scene.Scene;
    import javafx.scene.canvas.Canvas;
    import javafx.scene.canvas.GraphicsContext;
    import javafx.stage.Stage;

    public class TestApp extends Application {

    public static void main(String[] args) {
    launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {

    Group root = new Group();
    Scene theScene = new Scene(root);
    stage.setScene(theScene);

    Canvas canvas = new Canvas(512, 820);
    root.getChildren().add(canvas);

    GraphicsContext gc = canvas.getGraphicsContext2D();

    ArrayList<Lasser> allLassers = new ArrayList<>();

    Random randGen = new Random();

    for (int i = 0; i < 10; i++) {
    // create 10 lessers with different self-destruction time
    // on random places
    allLassers.add(new Lasser(randGen.nextInt(500) + 10, 800, i * 1000));
    }

    new AnimationTimer() {
    public void handle(long currentNanoTime) {
    // Clear the canvas
    gc.clearRect(0, 0, 512, 820);

    for (Lasser l : allLassers) {
    // if the current object is still ok
    if (!l.isDestroyed()) {
    // draw it
    gc.fillRect(l.getxPos(), l.getyPos(), l.getWidth(), l.getHeight());
    }
    }

    // remove all destroyed object
    for (int i = allLassers.size() - 1; i >= 0; i--) {
    if (allLassers.get(i).isDestroyed()) {
    allLassers.remove(i);
    }
    }
    }
    }.start();

    stage.show();
    }
    }

    小类
    import javafx.concurrent.Task;
    import javafx.scene.shape.Rectangle;

    public class Lasser extends Rectangle {

    private volatile boolean isDestroyed = false;

    private double xPos;
    private double yPos;

    public Lasser(double x, double y, long time) {
    super(x, y, 5, 20);
    this.xPos = x;
    this.yPos = y;
    startSelfDestruct(time);
    }

    private void startSelfDestruct(long time) {

    Task<Void> task = new Task<Void>() {
    @Override
    protected Void call() {
    try {
    Thread.sleep(time);
    } catch (InterruptedException e) {
    }
    return null;
    }
    };

    task.setOnSucceeded(e -> {
    isDestroyed = true;
    });

    new Thread(task).start();
    }

    public void move(double x, double y) {
    this.xPos = x;
    this.yPos = y;
    }

    public boolean isDestroyed() {
    return isDestroyed;
    }

    public double getxPos() {
    return xPos;
    }

    public double getyPos() {
    this.yPos -= 1;
    return yPos;
    }

    }

    关于java游戏如何构造定时效果/定距效果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46760004/

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