[英]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.