I recently started learning how to program java games using Slick. I've seen some tutorials (Bucky's from Youtube) and read A LOT on Slick's forum. I currently am struggling with an issue that got me totally stuck. I'm trying to create a new object in the game loop every 3 seconds or so. A few have tried to help me on the Slick forum but I still can't get it to work. I thought of asking here on stackoverflow as well...
A bit of background: Maybe you remember that old DOS game where you got paratroopers dropping from the sky and when they reach the ground, they move towards a cannon. When 10 enter it, it explodes. As the canon owner, you want to shoot all paratroopers before the ground. So, I'm doing that only in java :)
For those of you who never used Slick, there's an init() function to initialize stuff, a render() function that is in charge of rendering everything to screen and an update() function that is basically the game loops itself. All updates take place there and then render function renders accordingly.
I'm trying to drop the paratroopers from a random X every 3 seconds for instance.
There's an ArrayList that holds queuedObjects. Each update, the object uses a function that decided weather its time to deploy or not based on the delta derived from the update() function. If it is, that object gets transfered to another ArrayList that is being called in render function. So each time an object gets transferred to the renderList, it gets rendered. Problem is, the update method runs extremly fast. So what I get at teh end, is all objects rendered to screen instantaneously, instead of 1 at a time every 3 seconds for instance.
I tried implementing Thread.sleep() techniques. But it didnt work well with Slick. I also tried working witha TimerTaks and schedualer but I couldnt figure out how to use it... Could someone please point me in the right direction? THANK YOU!!
Paratrooper object:
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;
}
}
}
AND THE GAME CODE:
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;
}
}
pastTime is a local variable it should be an instance variable. Try this version instead:
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);
}
}
}