繁体   English   中英

Java:同时移动对象

[英]Java: Moving objects at the same time

我很抱歉,如果我的代码有点原始,我还是编程新手。

我目前正在开发小型Java游戏,需要让对象从右边缘向左滚动。

然后,对象需要由左侧的播放器捕获,并使用鼠标或键盘上下滚动。

我在使对象同时移动时遇到问题,当没有对象在滚动时,我可以使播放器完美移动。 但是当对象开始移动时,我就遇到了在哪里为播放器实现move()函数的问题,以便它随输入而不断移动,而不依赖于向左滚动的对象。

目前,我正在尝试在三个位置更新播放器的移动,如果不相对于同伴移动播放器,这三个位置将无法正常工作。 在游戏循环中:

public void play()
{
    while (!isGameOver())
    { 
        StdDraw.clear(StdDraw.BLACK);   
        grid.moveAll();
        grid.draw(0, 10);
        StdDraw.setPenColor(StdDraw.WHITE);
        StdDraw.text(100, 5, "Score: " + game.getScore());
        //Grid.U.move(Grid.playerR, Grid.playerC);
        StdDraw.show(20);
        //Grid.U.move(Grid.playerR, Grid.playerC);
        if (msElapsed % 300 == 0)
        {
            grid.populateRightEdge();
        }
        msElapsed += 20;
    }
}

在网格文件中,当告知要绘制对象G(滚动条之一)时:

public void draw(int atX, int atY) {

    for (int r = 0; r < num_Cols; r++) {
        for (int c = 0; c < num_Rows; c++) {
            //System.out.println("test1");
            if (grid[r][c] == U) {
                U.draw(c, r, grid_CellSize);
            }    if (grid[r][c] == A) {
                A.draw(c, r, grid_CellSize);;
            } if (grid[r][c] == G) {
                //Grid.U.move(Grid.playerR, Grid.playerC);
                G.draw(c, r, grid_CellSize);
            }
        }
    }

在对象G移动的类中:

  public Location move(int r, int c) {
 //Grid.U.move(Grid.playerR, Grid.playerC);
 Grid.grid[r-1][c] = Grid.grid[r][c];
 Grid.grid[r][c] = null;
//Grid.U.move(Grid.playerR, Grid.playerC);
 try {
    TimeUnit.MILLISECONDS.sleep(300);
} catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
return null;

}}

带注释的文本显示了读取播放器运动的命令。 我需要一种不依赖于滚动条的方式来执行此操作,我还可以在代码中实现哪些其他方法来执行此操作?

编辑:将代码移至thread.sleep函数后,遇到滚动对象增加时程序变慢的情况,滚动的对象越多,滚动速度就越慢。 我该如何预防?

在这里查看更多/更少的完整示例。


说明:

首先,利用OOP和继承,例如,您所有可处理的实体都必须具有(并继承)一些void process()方法和renderable- void render()方法。 像网格:

class Grid {

  int w;
  int h;

  public Entity[][] cells;

  public Grid(int w, int h) {
    this.w = w;
    this.h = h;
    cells = new Entity[h][w];
  }

  public void process(long timemillis) {
    // here you can process grid

    // like, change some tiles, progress animations, etc
  }

  public void render(long timemillis) {
    // here you can draw grid
  }

}

此外,玩家和G实体遵循相同的规则:

class Entity {

  public void process(long timemillis) {

  }

  public void render(long timemillis) {

  }

}

从而:

class G extends Entity {

  // override parent process() method
  @Override
  public void process(long timemillis) {
    moveLeft(speed); // we should move left by amount, specified by "speed" 
  }

  @Override
  public void render(long timemillis) {
    // here goes rendering code for G entities
  }
}

class Enemy extends Entity {

  @Override
  public void render(long timemillis) {
    // here goes rendering code for Enemy entities
  }
}

class Bonus extends Entity {

  @Override
  public void render(long timemillis) {
    // here goes rendering code for Bonus entities
  }
}

class Player extends G {

  // override processing method if needed...
  @Override
  public void process(long timemillis) {
  }

  @Override
  public void render(long timemillis) {
    // here goes rendering code for player
  }
}

为什么这样? 因为现在您可以这样做:

class Game {

  Grid grid;
  ArrayList<Entity> entities;
  long lastProcess;

  public Game() {
    grid = new Grid(30, 20);
  }

  public void newGame() {
    lastProcess = 0;
    entities = new ArrayList<>();
  }

  public void render(long timemillis) {
    grid.render(timemillis);

    for (Entity entity : entities)
      entity.render(timemillis);
  }

  public void process(long timemillis) {
    grid.process(timemillis); // process grid (like, some animation)

    for (Entity entity : entities) // process entities
      entity.process(timemillis);

    if (timemillis - lastProcess > 300) { // each 300 msec ()
      lastProcess = timemillis;

      Entity spawn;

      // choose and spawn some random object
      switch (((int)(Math.random() * 10)) % 4) {
      case 0: // spawn G
        spawn = new G(this); break;
      case 1: // spawn Enemy
        spawn = new Enemy(this); break;
      case 2: // spawn Bonus
        spawn = new Bonus(this); break;
      case 3: // spawn Secret
        spawn = new Secret(this); break;
      }

      // spawn it at right grid edge (grid.w - 1) at random y position
      spawn.moveTo(grid.w - 1, (int)(Math.random() * 9999) % grid.h);
      entities.add(spawn);
    }
  }

}

为了使处理/渲染异步,请使用线程(Thread类):

public class Launcher extends Application {

  Thread gameThread;

  int renderFPS = 30; // 

  int processPPS = 10;
  // five processings per second (around 1000 / 10 = 100 msec between each)

  boolean running;

  Game game;

  public static void main(String[] args) {
    // here goes the initialization
    Launcher launcher = new Launcher();
    launcher.launch();
  }

  public void launch() {
    running = false;

    // instantiating game object
    game = new Game();

    // creating thread
    gameThread = new Thread(new Runnable() {

      @Override
      public void run() {
        // this code will be executed in thread

        running = true;
        // here goes the rendering/processing "meat";
        long lastIteration = System.currentTimeMillis();
        long lastRender = lastIteration;
        long lastProcess = lastIteration;

        long msecPerRender = 1000 / renderFPS;
        long msecPerProcess = 1000 / processPPS;

        // main game loop
        while (running) {
          long now = System.currentTimeMillis();

          // should we draw next frame?
          long delta = now - lastRender;
          if (delta >= msecPerRender) {
            lastRender = now - (delta - msecPerRender);
            game.render(lastRender);
          }

          // is it time for processing next game iteration?
          delta = now - lastProcess;
          if (delta >= msecPerProcess) {
            lastProcess = now - (delta - msecPerProcess);
            game.process(lastProcess);
          }
        }
      }
    });

    // start the thread
    gameThread.start();

    // in order to keep app running, we should wait for thread execution finished
    try {
      gameThread.join();
    } catch (InterruptedException ex) {
    }
  }

  // to stop the application execution
  public void stop() {
    running = false;
  }

  // here you can move yours player
  public void movePlayer() {
    boolean moveUp = true; // calc direction
    if (moveUp)
      game.player.moveVertically(1);
    else
      game.player.moveVertically(-1);
  }

}

注意:pastebin上的代码为简单起见使用了swing库。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM