1

我最近开始学习如何使用 Slick 编写 Java 游戏。我看过一些教程(来自 Youtube 的 Bucky 的)并在 Slick 的论坛上阅读了很多内容。我目前正在努力解决一个让我完全陷入困境的问题。我试图每 3 秒左右在游戏循环中创建一个新对象。一些人试图在 Slick 论坛上帮助我,但我仍然无法让它工作。我也想过在stackoverflow上问...

一点背景知识:也许你还记得那个古老的 DOS 游戏,你让伞兵从天上掉下来,当他们到达地面时,他们会朝着一门大炮移动。当10进入它时,它会爆炸。作为佳能拥有者,您想在地面前射击所有伞兵。所以,我只在java中这样做:)

对于那些从未使用过 Slick 的人来说,有一个 init() 函数来初始化东西,一个 render() 函数负责将所有内容渲染到屏幕上,一个 update() 函数基本上就是游戏循环本身。所有更新都在那里发生,然后渲染函数相应地渲染。

例如,我正试图每 3 秒从随机 X 中放下伞兵。

有一个包含 queuedObjects 的 ArrayList。每次更新,对象使用一个函数来决定是否部署它的时间,基于从 update() 函数派生的增量。如果是,则该对象将被传输到另一个在渲染函数中调用的 ArrayList。因此,每次将对象传输到 renderList 时,它都会被渲染。问题是,更新方法运行得非常快。所以我最终得到的是所有对象都立即渲染到屏幕上,而不是例如每 3 秒一次 1 个。

我尝试实现 Thread.sleep() 技术。但它不适用于 Slick。我也尝试过使用 TimerTaks 和 schedualer,但我不知道如何使用它......有人可以指点我正确的方向吗?谢谢你!!

伞兵对象:

package elements;

import java.awt.Rectangle;
import java.util.Random;

import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;

public class Paratrooper1 {

//private int strength = 100;
private float yd;
private float x;
private float y;
private int width;
private int height;
private boolean visible;
private Image paratrooperImage;

private int time;

private Random random;

public Paratrooper1() throws SlickException {
    random = new Random();
    paratrooperImage = new Image("/res/paratrooper1.png");
    width = paratrooperImage.getWidth();
    height = paratrooperImage.getHeight();
    this.x = generateX();
    this.y = 0;
    visible = true;
    time = 0;
}

public Image getParaImage(){
    return paratrooperImage.getScaledCopy(0.2f);
}

public void Move(int delta){
    yd += 0.1f * delta;
    if(this.y+yd > 500){
        this.x = generateX();
        this.y = 0;
    }else{
        this.y += yd;
        yd = 0;
    }
}

public int getX(){
    return (int) x;
}

public int getY(){
    return (int) y;
}

public boolean isVisisble(){
    return visible;
}

public void setVisible(boolean tof){
    visible = tof;
}

public Rectangle getBound(){
    return new Rectangle((int)x,(int)y,width,height);
}

private int generateX(){
    return random.nextInt(940)+30;
}

public boolean isReadyToDeploy(int delta) {
    float pastTime = 0;
    pastTime += delta;

    long test = System.currentTimeMillis();
    if(test >= (pastTime + 3 * 1000)) { //multiply by 1000 to get milliseconds
      return true;
    }else{
        return false;
    }
}

}

和游戏代码:

package javagame;

import java.util.ArrayList;

import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;

import elements.Paratrooper1;

public class Play extends BasicGameState{

Paratrooper1 para1;

private Image cursor;
private int mousePosX = 0;
private int mousePosY = 0;
private String mouseLocationString = "";
private int score;
private ArrayList<Paratrooper1> renderParatroopers;
private ArrayList<Paratrooper1> queuedParatroopers;

private int time;


public Play(int state){
}

public void init(GameContainer gc, StateBasedGame sbg) throws SlickException{
    score = 0;
    time = 0;

    renderParatroopers = new ArrayList<Paratrooper1>();

    //populate arraylist with paratroopers
    queuedParatroopers = new ArrayList<Paratrooper1>();
    for (int i=0; i<5; i++){
        queuedParatroopers.add(new Paratrooper1());
    }

    cursor = new Image("res/cursor.png");
    cursor.setCenterOfRotation(cursor.getWidth()/2, cursor.getHeight()/2);
    gc.setMouseCursor(cursor.getScaledCopy(0.1f), 0, 0);

    para1 = new Paratrooper1();
}

public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException{
    g.drawString(mouseLocationString, 50, 30);
    g.drawString("Paratrooper location: X:" +para1.getY()+ " Y:" +para1.getY(), 50, 45);
    g.drawString("Current score: " +score, 800, 30);

    //go through arraylist and render each paratrooper object to screen
    if (renderParatroopers != null){
        for (int i = 0; i < renderParatroopers.size(); i++) {
            Paratrooper1 para1 = (Paratrooper1)renderParatroopers.get(i);
            if(para1.isVisisble()){
                g.drawImage(para1.getParaImage(),para1.getX(),para1.getY());
            }
        }       
    }
}

public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException{
    Input input = gc.getInput();
    mousePosX = input.getMouseX();
    mousePosY = input.getMouseY();
    mouseLocationString = "Pointer location --- X:" +mousePosX+ " Y:" +mousePosY;


    for (int i=0; i<queuedParatroopers.size(); i++){
        if (queuedParatroopers.get(i).isReadyToDeploy(delta)){
            renderParatroopers.add(queuedParatroopers.get(i));
        }
    }

    //update the x and y of each paratrooper object.
    //Move() method accepts the delta and is calculated in to 
    //create a new x and y. Render method will update accordingly.
    if(renderParatroopers != null){
        for (Paratrooper1 para : renderParatroopers){
            para.Move(delta);
        }
    }
}   

/*private boolean isItTimeToDeploy(int deltaVar) {
    float pastTime = 0;
    pastTime += deltaVar;

    long test = System.currentTimeMillis();
    if(test >= (pastTime + 3*1000)) { //multiply by 1000 to get milliseconds
      return true;
    }else{
        return false;
    }
}*/


public int getID(){
    return 1;
}

}

4

1 回答 1

1

pastTime是一个局部变量,它应该是一个实例变量。试试这个版本:

long pastTime = 0;
public boolean isReadyToDeploy(long delta) {
    if(pastTime < 3 * 1000) { //multiply by 1000 to get milliseconds
        pastTime += delta;
        return false;
    }else{
        pastTime = 0;
        return true;
    }
}

long previousTime = 0;

public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException{
    long tmp = System.currentTimeMillis();
    long customDelta = tmp - previousTime;
    previousTime = tmp;

    Input input = gc.getInput();
    mousePosX = input.getMouseX();
    mousePosY = input.getMouseY();
    mouseLocationString = "Pointer location --- X:" +mousePosX+ " Y:" +mousePosY;

    for (int i=0; i<queuedParatroopers.size(); i++){
        if (queuedParatroopers.get(i).isReadyToDeploy(customDelta)){
            renderParatroopers.add(queuedParatroopers.get(i));
        }
    }

    //update the x and y of each paratrooper object.
    //Move() method accepts the delta and is calculated in to 
    //create a new x and y. Render method will update accordingly.
    if(renderParatroopers != null){
        for (Paratrooper1 para : renderParatroopers){
            para.Move(delta);
        }
    }
}   
于 2012-10-21T14:04:09.450 回答