最近、Slick を使用して Java ゲームをプログラミングする方法を学び始めました。私はいくつかのチュートリアル (YouTube の Bucky のもの) を見て、Slick のフォーラムでたくさん読んだことがあります。私は現在、完全に立ち往生する問題に苦しんでいます。ゲームループで 3 秒ごとに新しいオブジェクトを作成しようとしています。いくつかの人が Slick フォーラムで私を助けようとしましたが、まだうまくいきません。ここでもstackoverflowで質問しようと思いました...
ちょっとした背景: 古い DOS ゲームで空挺部隊が空から落下し、地上に到達すると大砲に向かって移動したことを覚えているかもしれません。10個入ると爆発。大砲の所有者として、あなたはすべての空挺部隊を地面の前で撃ちたいと思っています。だから、私はJavaでのみそれをやっています:)
Slick を使用したことがない人のために説明すると、初期化を行う init() 関数、すべてを画面にレンダリングする render() 関数、基本的にゲーム自体をループさせる update() 関数があります。すべての更新はそこで行われ、それに応じてレンダリング関数がレンダリングされます。
たとえば、空挺部隊をランダムな X から 3 秒ごとにドロップしようとしています。
queuedObjects を保持する ArrayList があります。更新のたびに、オブジェクトは、 update() 関数から派生したデルタに基づいて、展開するかどうかを判断する関数を使用します。そうである場合、そのオブジェクトは、render 関数で呼び出されている別の ArrayList に転送されます。そのため、オブジェクトが renderList に転送されるたびに、レンダリングされます。問題は、更新メソッドが非常に高速に実行されることです。したがって、最後に得られるのは、たとえば 3 秒ごとに一度に 1 つずつではなく、すべてのオブジェクトが瞬時に画面にレンダリングされることです。
Thread.sleep() テクニックを実装してみました。しかし、Slick ではうまく機能しませんでした。TimerTaks とスケジューラも試してみましたが、使い方がわかりませんでした...誰かが私を正しい方向に向けてもらえますか? ありがとうございました!!
空挺部隊オブジェクト:
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;
}
}