Why can't I multiply an object? - java

I'm working with Android (Java), and what I want is to take a class, and make 3 instances out of it, but with some variables set to random.
public class MainActivity extends Activity{
Player ourView;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ourView = new Player(this);
setContentView(ourView);
}
protected void onPause() {
super.onPause();
ourView.pause();
}
protected void onResume() {
super.onResume();
ourView.resume();
}
}
The other class...
public class Player extends SurfaceView implements Runnable {
Canvas canvas = new Canvas();
SurfaceHolder ourHolder;
Thread ourThread = null;
boolean isRunning = true;
public Player(Context context) {
super(context);
ourHolder = getHolder();
ourThread = new Thread(this);
ourThread.start();
}
public void pause() {
isRunning = false;
while(true){
try{
ourThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
}
ourThread = null;
}
public void resume() {
isRunning = true;
}
public void run() {
while(isRunning) {
if(!ourHolder.getSurface().isValid())
continue;
canvas = ourHolder.lockCanvas();
canvas.drawRGB(30, 30, 200);
Enemy[] enemy = new Enemy[3];
for(int i = 0; i<enemy.length; i++){
enemy[i] = new Enemy();
enemy[i].draw();
}
ourHolder.unlockCanvasAndPost(canvas);
}
}
}
And the "Enemy" class:
public class Enemy{
Canvas canvas = new Canvas();
float x = (float) (Math.random()*200);
float y = (float) (Math.random()*200);
public void draw(){
Bitmap bitmap = (Bitmap) BitmapFactory.decodeResource(getContext(), R.drawable.ic_launcher);
canvas.drawBitmap(bitmap, x, y, null);
}
}
I can see that there are 3 bitmaps created, which is cool. But they don't stay still, it's like if the for loop never stops even though the condition is no longer satisfied.
I've asked the question before but I couldn't find any answer. Hope you can help me, thanks.

You are creating a new array of 3 enemies every cycle of the while loop, once the while loop completes execution, the enemy array will leave the scope and be destroyed and a new array will be created. If you want to keep these enemies you will need to store them outside of the scope of the loop.
** EDIT ** - Try this
public class Player extends SurfaceView implements Runnable {
Canvas canvas = new Canvas();
SurfaceHolder ourHolder;
Thread ourThread = null;
boolean isRunning = true;
Enemy[] enemy;
public Player(Context context) {
super(context);
ourHolder = getHolder();
ourThread = new Thread(this);
ourThread.start();
enemy = new Enemy[3];
for(int i = 0; i<enemy.length; i++){
enemy[i] = new Enemy();
}
}
public void pause() {
isRunning = false;
while(true){
try{
ourThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
}
ourThread = null;
}
public void resume() {
isRunning = true;
}
public void run() {
while(isRunning) {
if(!ourHolder.getSurface().isValid())
continue;
canvas = ourHolder.lockCanvas();
canvas.drawRGB(30, 30, 200);
for(int i = 0; i<enemy.length; i++){
enemy[i].draw();
}
ourHolder.unlockCanvasAndPost(canvas);
}
}
}

exactly as you said, it is like if the for loop never stops.
because that for loop is in while(isrunning) loop that never stops and triggers your for loop over and over.
you need to reorganize your code.

Related

Programmatically move ImageView(s) from top to bottom in a loop, starting and ending outside of screen

I'm making a small Android game in which I need two ImageViews (obstacles) to move, at the same time, from the top of the screen to the bottom of the screen; starting and ending OUTSIDE of the screen. Doing this would be a start.
I've got a timer, and each time the timer ends, it runs again and I would also want two other ImageViews (same as two previous ones) to move in the same way described above.
In other words:
Some random event triggers a timer
Timer hits threshold -> timer resets and two ImageViews start their way down
What I've got kind of works, but with Bitmaps and Y incrementation. The problem is, because the phone increments as fast as it can, the game can get laggy and the speed of the two images going down won't be the same on two different phones.
I know I've got to use Animations, but I can't get what I want each time I try something with them. They usually don't start where I want them to be and weird stuff happens.
Here are some links I already visited:
Start simple Animation top to bottom from a specific position
Move an ImageView to different position in Animated way in Android
move imageView from outside screen
Android continuous moving animation
How to slide an ImageView from left to right smoothly in Android?
Here's some code to show you what I've got:
GAMEVIEW
public class GameView extends SurfaceView implements SurfaceHolder.Callback {
// [...]
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
// [...]
this.obstacles = new ArrayList <> ();
this.handleObstacleTimer = null;
this.runnableObstacleTimer = null;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
// [...]
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
this.startObstacleTimer();
GameLogic.gameState = GameState.RUNNING;
// [...]
}
return result;
}
#Override
public void draw (Canvas canvas) {
super.draw(canvas);
if (canvas != null) {
this.background.draw(canvas);
if (! this.obstacles.isEmpty()) {
for (Obstacle obstacle : this.obstacles) {
obstacle.draw(canvas);
}
}
// [...]
}
}
public void createObstacle () {
Bitmap imageObstacle = BitmapFactory.decodeResource(this.getResources(), R.drawable.obstacle);
this.obstacles.add(new Obstacle(imageObstacle, this, this.displayMetrics.widthPixels, this.displayMetrics.heightPixels));
}
public void removeObstacle (Obstacle obstacle) {
this.obstacles.remove(obstacle);
}
private void stopObstacleTimer () {
if (this.handleObstacleTimer != null && this.runnableObstacleTimer != null) {
this.handleObstacleTimer.removeCallbacks(this.runnableObstacleTimer);
this.handleObstacleTimer = null;
}
}
private void startObstacleTimer () {
if (this.handleObstacleTimer == null) {
final Handler handler = new Handler();
this.runnableObstacleTimer = new Runnable() {
#Override
public void run() {
if (GameLogic.gameState == GameState.RUNNING) {
createObstacle();
handler.postDelayed(this, 2700);
}
}
};
handler.postDelayed(this.runnableObstacleTimer, 2700);
this.handleObstacleTimer = handler;
}
}
// [...]
// Called by a custom Thread class
public void update () {
if (! this.obstacles.isEmpty()) {
for (Obstacle obstacle : this.obstacles) {
obstacle.update();
}
}
// [...]
}
}
MAINTHREAD (custom Thread class)
public class MainThread extends Thread {
private SurfaceHolder surfaceHolder;
private GameView gameView;
private GameLogic gameLogic;
private boolean running;
public static Canvas canvas;
public MainThread (SurfaceHolder surfaceHolder, GameView gameView, GameLogic gameLogic) {
super();
this.surfaceHolder = surfaceHolder;
this.gameView = gameView;
this.gameLogic = gameLogic;
}
#Override
public void run() {
while (this.running) {
this.canvas = null;
try {
this.canvas = this.surfaceHolder.lockCanvas();
synchronized (this.surfaceHolder) {
this.gameView.update();
this.gameView.draw(this.canvas);
this.gameLogic.update();
}
} catch (Exception e) {
} finally {
if (this.canvas != null) {
try {
this.surfaceHolder.unlockCanvasAndPost(this.canvas);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
public void setRunning (boolean isRunning) {
this.running = isRunning;
}
}
OBSTACLE
public class Obstacle {
private static final int GAP_MIN_X = 300;
private static int GAP_MAX_X;
private static final int GAP_WIDTH = 250;
private GameView gameView;
private int displayHeight;
private Bitmap obstacleLeft;
private Bitmap obstacleRight;
private int leftX;
private int rightX;
private int y;
private boolean passed;
public Obstacle (Bitmap image, GameView gameView, int displayWidth, int displayHeight) {
this.gameView = gameView;
this.displayHeight = displayHeight;
this.obstacleLeft = this.flip(image);
this.obstacleRight = image;
GAP_MAX_X = displayWidth - GAP_MIN_X;
final int randomX = new Random().nextInt((GAP_MAX_X - GAP_MIN_X) + 1) + GAP_MIN_X;
this.leftX = randomX - this.obstacleLeft.getWidth() - (GAP_WIDTH / 2);
this.rightX = randomX + (GAP_WIDTH / 2);
this.y = 0 - this.obstacleLeft.getHeight();
this.passed = false;
}
private Bitmap flip (Bitmap image) {
Matrix m = new Matrix();
m.preScale(-1, 1);
Bitmap result = Bitmap.createBitmap(image, 0, 0, image.getWidth(), image.getHeight(), m, false);
result.setDensity(DisplayMetrics.DENSITY_DEFAULT);
return result;
}
/**
* Those getters are used for collision
*/
public int getLeftX () {
return this.leftX;
}
public int getRightX () {
return this.rightX;
}
public int getY () {
return this.y;
}
public int getWidth () {
return this.obstacleLeft.getWidth();
}
public int getHeight () {
return this.obstacleLeft.getHeight();
}
public boolean hasPassed () {
return this.passed;
}
public void setAsPassed () {
this.passed = true;
}
public void draw (Canvas canvas) {
canvas.drawBitmap(this.obstacleLeft, this.leftX, this.y, null);
canvas.drawBitmap(this.obstacleRight, this.rightX, this.y, null);
}
public void update () {
if (! (GameLogic.gameState == GameState.GAMEOVER)) {
this.y += 8;
if (this.y > this.displayHeight) {
this.gameView.removeObstacle(this);
}
}
}
}
Basically, what I want is to have the same result. But without lag and with obstacles going at the same speed no matter which phone the game is running on.
If inside your Obstacle.update() function, you change your Y incrementation from the constant integer 8 to something that is proportional to the time interval that the update function is called, it will be the same speed on any device. You could, for example, calculate the variation based on the difference between the time on the last update() call and the current update call
long speed = 100; //you should add this to adjust the speed of the incrementing
long delta = System.currentTimeMillis();
public void update () {
delta = speed*(System.currentTimeMillis() - delta);
if (! (GameLogic.gameState == GameState.GAMEOVER)) {
this.y += delta;
if (this.y > this.displayHeight) {
this.gameView.removeObstacle(this);
}
}
}
This way, you delta variable will ever be something that varies with the time interval between the last call and the current call beacause System.currentTimeMillis() returns the current time in miliseconds

Android: Low frame rate

I have created an application that holds 7 different mini games. One of these mini games has always run fine, well, it always had some frame issues usually running at 6fps. I ran this game recently and realized the frame rate is now pretty much unplayable. I don't what caused this issue and can anyone recommend a fix to improve the frame rate?
The game uses many different classes to be created, it is a surface view. Copying all the classes here will be a lot of code so I will just post the class that creates the surface.
Any help with improving an application frame rate would be helpful thank you.
public class GamePanel extends SurfaceView implements SurfaceHolder.Callback
{
public static final int WIDTH = 856;
public static final int HEIGHT = 480;
public static final int MOVESPEED = -5;
private long missileStartTime;
private MainThread thread;
private Background bg;
private Player player;
private ArrayList<Missile> missiles;
private Random rand = new Random();
int score = 0;
private final Context context;
public GamePanel(Context context)
{
super(context);
this.context = context;
//add the callback to the surfaceholder to intercept events
getHolder().addCallback(this);
thread = new MainThread(getHolder(), this);
//make gamePanel focusable so it can handle events
setFocusable(true);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height){}
#Override
public void surfaceDestroyed(SurfaceHolder holder){
boolean retry = true;
int counter = 0;
while(retry && counter<1000)
{
counter++;
try{thread.setRunning(false);
thread.join();
retry = false;
}catch(InterruptedException e){e.printStackTrace();}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder){
bg = new Background(BitmapFactory.decodeResource(getResources(), R.drawable.nightskyresize));
player = new Player(BitmapFactory.decodeResource(getResources(), R.drawable.pilot), 65, 25, 1);
missiles = new ArrayList<Missile>();
missileStartTime = System.nanoTime();
//we can safely start the game loop
thread.setRunning(true);
thread.start();
}
#Override
public boolean onTouchEvent(MotionEvent event)
{
if(event.getAction()==MotionEvent.ACTION_DOWN){
if(!player.getPlaying())
{
player.setPlaying(true);
}
else
{
player.setUp(true);
}
return true;
}
if(event.getAction()==MotionEvent.ACTION_UP)
{
player.setUp(false);
return true;
}
return super.onTouchEvent(event);
}
public void update()
{
if(player.getPlaying()) {
bg.update();
player.update();
//add missiles on timer
long missileElapsed = (System.nanoTime()-missileStartTime)/10000000;
if(missileElapsed >(2000 - player.getScore()/4)){
System.out.println("making missile");
//first missile always goes down the middle
if(missiles.size()==0)
{
missiles.add(new Missile(BitmapFactory.decodeResource(getResources(),R.drawable.
missile),WIDTH + 10, HEIGHT/2, 45, 15, player.getScore(), 1));
}
else
{
missiles.add(new Missile(BitmapFactory.decodeResource(getResources(),R.drawable.missile),
WIDTH+10, (int)(rand.nextDouble()*(HEIGHT)),45,15, player.getScore(),1));
}
//reset timer
missileStartTime = System.nanoTime();
}
//loop through every missile and check collision and remove
for(int i = 0; i<missiles.size();i++)
{
//update missile
missiles.get(i).update();
if(collision(missiles.get(i),player))
{
Intent i1 = new Intent (context, main_menu.class);
context.startActivity(i1);
missiles.remove(i);
player.setPlaying(false);
break;
}
//remove missile if it is way off the screen
if(missiles.get(i).getX()<-100)
{
score++;
missiles.remove(i);
break;
}
}
}
if(score == 100){
Intent i1 = new Intent (context, main_menu.class);
context.startActivity(i1);
}
}
public boolean collision(GameObject a, GameObject b)
{
if(Rect.intersects(a.getRectangle(),b.getRectangle()))
{
return true;
}
return false;
}
#Override
public void draw(Canvas canvas)
{
final float scaleFactorX = getWidth()/(WIDTH*1.f);
final float scaleFactorY = getHeight()/(HEIGHT*1.f);
if(canvas!=null) {
final int savedState = canvas.save();
canvas.scale(scaleFactorX, scaleFactorY);
bg.draw(canvas);
player.draw(canvas);
//draw missiles
for(Missile m: missiles)
{
m.draw(canvas);
}
drawText(canvas);
canvas.restoreToCount(savedState);
}
}
public void drawText(Canvas canvas)
{
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setTextSize(30);
paint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
canvas.drawText("DISTANCE: " + (player.getScore()*3), 10, HEIGHT - 10, paint);
}
}
I also got the log to print out the frame rate, this was the result.
Any ideas on the cause of this? the fps is the 0.0, this usually would say around 6.0 or 7.0.
This is an odd question, but where I have music it sounds like there is two versions playing over each other, like the application is running two instances of itself. is this possible?
This is the problem

Drawing shapes one after another on Android's Canvas

Sorry if this question was asked before but I looked around and couldn't really find an answer.
So I'm drawing things onto a SurfaceView using a thread to update any changes made to the screen, and I also have an array of rectangles. How can I draw the rectangles, one after another, and by the end of it, have all of them on the screen? I thought a for loop in the run() method where everything's drawn would've worked, but it just ends up drawing them all at once (which I can understand why). Then, I tried to put a Thread.sleep after every draw in the for loop, but it just waits until after all the rects are drawn before drawing to the canvas. (again, makes sense since the canvas isn't unlocked until after the for loop). If I wanted, say, a two second pause between drawing rects, how could I do that?
Thanks
Edit: Here is the SurfaceView. the pause() and resume() methods are called in the onPause and onResume methods of the activity for which it is the view.
class TestView extends SurfaceView implements Runnable{
SurfaceHolder holder;
Thread t;
Rect[] rectArray;
public TestView(Context context) {
super(context);
holder = getHolder();
rectArray = shapes.getRectArray();
}
#Override
public void run() {
while(true){
if(!holder.getSurface().isValid())
continue;
Paint p = new Paint();
p.setColor(Color.BLACK);
p.setStrokeWidth(10)
Canvas c = holder.lockCanvas(null);
c.drawARGB(255, 255, 255, 255);
for(int i = 0; i<rectArray.length; i++){
c.drawRect(i,p);
}
holder.unlockCanvasAndPost(c);
}
}
public void pause(){
}
public void resume(){
t = new Thread(this);
t.start();
}
}
I'd probably abstract the thread and SurfaceView and do a basic "game loop" so I have full control over what gets drawn when.
Below is the game loop part:
public class GameLoopThread extends Thread
{
private TestView view;
private boolean running = false;
public GameLoopThread(TestView view)
{
this.view = view;
}
public void setRunning(boolean run)
{
running = run;
}
#SuppressLint("WrongCall")
#Override
public void run()
{
long startTime = System.currentTimeMillis();
while (running)
{
Canvas c = null;
//call update with the number of milliseconds that have passed since the last loop iteration
view.update(System.currentTimeMillis() - startTime);
startTime = System.currentTimeMillis();
try
{
c = view.getHolder().lockCanvas();
synchronized (view.getHolder())
{
//call onDraw so my surface draws the rectangles
view.onDraw(c);
}
}
finally
{
if (c != null)
{
view.getHolder().unlockCanvasAndPost(c);
}
}
}
}
}
Here is my new surface view:
public class TestView extends SurfaceView
{
private long totalElapsedTime = 0;
private Rect[] rectArray;
private int rectCount = 0;
private Paint p;
private GameLoopThread gameLoopThread;
public TestView(Context context)
{
super(context);
rectArray = shapes.getRectArray();
p = new Paint();
p.setColor(Color.BLACK);
p.setStrokeWidth(10)
gameLoopThread = new GameLoopThread(this);
holder = getHolder();
holder.addCallback(new SurfaceHolder.Callback()
{
#Override
public void surfaceDestroyed(SurfaceHolder holder)
{
boolean retry = true;
gameLoopThread.setRunning(false);
while (retry)
{
try
{
gameLoopThread.join();
retry = false;
}
catch (InterruptedException e)
{
}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder)
{
gameLoopThread.setRunning(true);
gameLoopThread.start();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
}
}
public void update(long elapsedTime)
{
totalElapsedTime += elapsedTime;
//increase the rectCount every second
rectCount = totalElapsedTime / 1000;
if(rectCount > rectArray.length)
{
rectCount = rectArray.length;
}
}
#Override
public void onDraw(Canvas canvas)
{
canvas.drawARGB(255, 255, 255, 255);
//draw my rectangles here
for(int i = 0; i < rectCount; i++)
{
canvas.drawRect(i,p);
}
}

Android: How can I rotate an image from the center?

I'm trying to rotate this bitmap in the very center by "R0" degrees. But it doesn't rotate in the center. It rotates from the upper left corner.
Here's my code:
public class MainActivity extends Activity{
Player ourView;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ourView = new Player(this);
setContentView(ourView);
}
protected void onPause() {
super.onPause();
ourView.pause();
}
protected void onResume() {
super.onResume();
ourView.resume();
}
}
Here's the other class:
public class Player extends SurfaceView implements Runnable {
Canvas canvas = new Canvas();
SurfaceHolder ourHolder;
Thread ourThread = null;
boolean isRunning = true;
public Player(Context context) {
super(context);
ourHolder = getHolder();
ourThread = new Thread(this);
ourThread.start();
}
public void pause() {
isRunning = false;
while(true){
try{
ourThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
}
ourThread = null;
}
public void resume() {
isRunning = true;
}
public void run() {
while(isRunning) {
if(!ourHolder.getSurface().isValid())
continue;
canvas = ourHolder.lockCanvas();
canvas.drawRGB(30, 30, 200);
MainPlayer player = new MainPlayer();
player.execute();
ourHolder.unlockCanvasAndPost(canvas);
}
}
}
And this is the class in which the bitmap gets rotated:
public class MainPlayer{
Canvas canvas = new Canvas();
Context context;
float x=160;
float y=455;
float k=160;
float l=455;
float R0 = 150;
public void execute(){
draw();
}
public void draw(){
Matrix matrix = new Matrix();
Bitmap bitmap = (Bitmap) BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
matrix.setRotate(R0);
Bitmap b = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
canvas.drawBitmap(b, x, y, null);
}
}
Thanks very much.

Adding a new enemy every x amount of seconds - Android Game Dev

I have been following along with the tutorials from:
http://www.edu4java.com/en/androidgame/androidgame.html
Where I stand now is that I am able to populate the screen with a variety of sprites and each character will begin at a random position and they will walk in a random direction.
My objective is to add a new sprite every X amount of seconds but I am not entirely sure how to do this.
Currently my GameView is set up like this:
public class GameView extends SurfaceView {
private GameLoopThread gameLoopThread;
private List<Sprite> sprites = new ArrayList<Sprite>();
private List<tempSprite> temps = new ArrayList<tempSprite>();
private long lastClick;
private Bitmap bmpBlood;
public GameView(Context context) {
super(context);
gameLoopThread = new GameLoopThread(this);
getHolder().addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
gameLoopThread.setRunning(false);
while (retry) {
try {
gameLoopThread.join();
retry = false;
} catch (InterruptedException e) {}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
createSprites();
gameLoopThread.setRunning(true);
gameLoopThread.start();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
}
});
bmpBlood = BitmapFactory.decodeResource(getResources(), R.drawable.image);
}
private void createSprites() {
sprites.add(createSprite(R.drawable.image));
sprites.add(createSprite(R.drawable.image));
sprites.add(createSprite(R.drawable.image));
sprites.add(createSprite(R.drawable.image));
sprites.add(createSprite(R.drawable.image));
sprites.add(createSprite(R.drawable.image));
sprites.add(createSprite(R.drawable.image));
sprites.add(createSprite(R.drawable.image));
sprites.add(createSprite(R.drawable.image));
sprites.add(createSprite(R.drawable.image));
sprites.add(createSprite(R.drawable.image));
sprites.add(createSprite(R.drawable.image));
}
private Sprite createSprite(int resouce) {
Bitmap bmp = BitmapFactory.decodeResource(getResources(), resouce);
return new Sprite(this, bmp);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.BLACK);
for (int i = temps.size() - 1; i >= 0; i--) {
temps.get(i).onDraw(canvas);
}
for (Sprite sprite : sprites) {
sprite.onDraw(canvas);
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (System.currentTimeMillis() - lastClick > 300) {
lastClick = System.currentTimeMillis();
float x = event.getX();
float y = event.getY();
synchronized (getHolder()) {
for (int i = sprites.size() - 1; i >= 0; i--) {
Sprite sprite = sprites.get(i);
if (sprite.isCollision(x, y)) {
sprites.remove(sprite);
temps.add(new tempSprite(temps, this, x, y, bmpBlood));
break;
}
}
}
}
return true;
}
}
`
As you can see, my sprites are being created in createSprites() - however, I am unsure how to create a time to increase the number of sprites.
Could someone please help as I am not sure how to add this into the game loop.
Thanks.
You can use a Thread for creation of new sprites and in a loop, add Thread.sleep(1000) line between invoke method declaration and adding new sprite to sprites ArrayList. Just like:
private void createSprites(int x) {
new Thread(new Runnable() {
public void run() {
for(int i = 0; i < x; i++) {
sprites.add(createSprite(R.drawable.image));
try
{
Thread.sleep(1000); //Waits for 1 second
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}).start();
}
where x is the variable of seconds. So this will create X sprites as a second passes, while your game is still working on background.
Create another thread, timer task, or handler and have that run periodically. Make sure you synchronize your collection properly and only call re draw on the GUI thread.

Categories