如果我的代码有点原始,我很抱歉,我还是编程的新手。
我目前正在开发小型Java游戏,我需要让对象从右边缘向左滚动。
然后左边的玩家需要抓住物体,用鼠标或键盘上下滚动。
我遇到了让对象同时移动的问题,我可以让玩家在没有对象滚动时完美移动。但是当对象开始移动时,我有问题在哪里为玩家实现move()函数,以便它随着输入不断移动,而不依赖于向左滚动的对象。
目前我正试图在三个地方更新玩家的动作,如果没有相对于scollers移动玩家,则无法正常工作。 在游戏循环中:
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函数中后,随着滚动对象的增加,程序变慢,滚动的对象越多,滚动的速度就越慢。我该如何防止这种情况?
答案 0 :(得分:1)
查看here了解更多/更不完整的示例。
说明:
首先,使用OOP和继承,比如,您的所有可处理实体必须具有(并继承)某些void process()
方法和可渲染 - 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
库。