Hi everyone.
A few days ago I implemented a level select screen in my game. While it does let you choose your level; it has brought to my attention the fact that I'm not cleaning up something properly. If you start a level, press back, start a different level, press back and start a third level; the third level only takes up about half of the screen (leaving the level select screen on the other half) and after a few seconds it crashes.
Here's the relevant code:
//Inside my main menu activity
//function bound to the new game button
public void buttonNewGameClick(View v)
{
startActivityForResult(new Intent(this, ArenaSelect.class), ActivityIndex.ArenaSelect);
}
//ActivityIndex is a class containing public static final ints that provide an index number for each of the activities in the game (its basically an enum).
//Inside the ArenaSelect activity
//There is one of these functions bound to each level selection button
public void buttonLevel1Click(View v)
{
setResult(1);
finish();
}
//Back to the MainMenu activity
//This function is triggered when the ArenaSelect activity finishes.
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if(requestCode == ActivityIndex.ArenaSelect)
{
Intent i = new Intent(this, Game.class);
i.putExtra("Arena", resultCode);
startActivity(i);
}
}
//Inside the Game activity
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
switch((Integer)getIntent().getExtras().get("Arena"))
{
case ArenaIndex.Level1:
{
mArena = new Level1(getBaseContext());
break;
}
//case for every other level
}
setContentView(mArena);
}
//Level1 (and all other levels) is a class that extends Arena. All that it does is specify how the level's terrain is initialized.
//This is the declaration of the Arena class:
public abstract class Arena extends SurfaceView implements SurfaceHolder.Callback
//In the Arena Constructor
SurfaceHolder holder = getHolder();
holder.addCallback(this);
mGameLoop = new GameLoop(this, holder);
mGameLoop.start();
//Finally we've reached the main game loop
//Inside the GameLoop class
//The constructor
public GameLoop(Arena arena, SurfaceHolder holder)
{
mTime = System.nanoTime();
mArena = arena;
mSurfaceHolder = holder;
}
//The run() function
//It pretty much just updates the arena then draws it repeatedly.
public void run()
{
mRunning = true;
while(mRunning)
{
CalculateDeltaT();
mTime = System.nanoTime();
mArena.Update(deltaT);
mCanvas = mSurfaceHolder.lockCanvas();
if (mCanvas != null)
{
mArena.Draw(mCanvas);
mSurfaceHolder.unlockCanvasAndPost(mCanvas);
}
double delay = 1 / 30 - deltaT;
if(delay > 0)
{
try
{
sleep((long)delay);
}
catch (InterruptedException e) { Logger.getLogger(GameLoop.class.getName()).log(Level.SEVERE, "Failed GameLoop.sleep()", e); }
}
}
}
//The only real clean up code I have is inside Arena.
public void surfaceDestroyed(SurfaceHolder holder)
{
mGameLoop.mRunning = false;
try
{
mGameLoop.join();
}
catch (InterruptedException e) { Logger.getLogger(Arena.class.getName()).log(Level.SEVERE, "Failed Arena.surfaceDestroyed()", e); }
}
So that's pretty much the structure of my game (I hope it wasn't too confusing). The other thing I've noticed is that if you load a level, press home and open up a task manager (I'm using the one that came with the recent Galaxy S update); it says that my game is using over 10% of the CPU and shows its name in red (which I assume is bad for an app that should be doing nothing).
Can anyone see what I'm doing wrong? Also; does anyone have any suggestions on how I could better structure the flow of the program (this is my first Android app and I'm open to suggestions and criticism).
A few days ago I implemented a level select screen in my game. While it does let you choose your level; it has brought to my attention the fact that I'm not cleaning up something properly. If you start a level, press back, start a different level, press back and start a third level; the third level only takes up about half of the screen (leaving the level select screen on the other half) and after a few seconds it crashes.
Here's the relevant code:
//Inside my main menu activity
//function bound to the new game button
public void buttonNewGameClick(View v)
{
startActivityForResult(new Intent(this, ArenaSelect.class), ActivityIndex.ArenaSelect);
}
//ActivityIndex is a class containing public static final ints that provide an index number for each of the activities in the game (its basically an enum).
//Inside the ArenaSelect activity
//There is one of these functions bound to each level selection button
public void buttonLevel1Click(View v)
{
setResult(1);
finish();
}
//Back to the MainMenu activity
//This function is triggered when the ArenaSelect activity finishes.
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if(requestCode == ActivityIndex.ArenaSelect)
{
Intent i = new Intent(this, Game.class);
i.putExtra("Arena", resultCode);
startActivity(i);
}
}
//Inside the Game activity
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
switch((Integer)getIntent().getExtras().get("Arena"))
{
case ArenaIndex.Level1:
{
mArena = new Level1(getBaseContext());
break;
}
//case for every other level
}
setContentView(mArena);
}
//Level1 (and all other levels) is a class that extends Arena. All that it does is specify how the level's terrain is initialized.
//This is the declaration of the Arena class:
public abstract class Arena extends SurfaceView implements SurfaceHolder.Callback
//In the Arena Constructor
SurfaceHolder holder = getHolder();
holder.addCallback(this);
mGameLoop = new GameLoop(this, holder);
mGameLoop.start();
//Finally we've reached the main game loop
//Inside the GameLoop class
//The constructor
public GameLoop(Arena arena, SurfaceHolder holder)
{
mTime = System.nanoTime();
mArena = arena;
mSurfaceHolder = holder;
}
//The run() function
//It pretty much just updates the arena then draws it repeatedly.
public void run()
{
mRunning = true;
while(mRunning)
{
CalculateDeltaT();
mTime = System.nanoTime();
mArena.Update(deltaT);
mCanvas = mSurfaceHolder.lockCanvas();
if (mCanvas != null)
{
mArena.Draw(mCanvas);
mSurfaceHolder.unlockCanvasAndPost(mCanvas);
}
double delay = 1 / 30 - deltaT;
if(delay > 0)
{
try
{
sleep((long)delay);
}
catch (InterruptedException e) { Logger.getLogger(GameLoop.class.getName()).log(Level.SEVERE, "Failed GameLoop.sleep()", e); }
}
}
}
//The only real clean up code I have is inside Arena.
public void surfaceDestroyed(SurfaceHolder holder)
{
mGameLoop.mRunning = false;
try
{
mGameLoop.join();
}
catch (InterruptedException e) { Logger.getLogger(Arena.class.getName()).log(Level.SEVERE, "Failed Arena.surfaceDestroyed()", e); }
}
So that's pretty much the structure of my game (I hope it wasn't too confusing). The other thing I've noticed is that if you load a level, press home and open up a task manager (I'm using the one that came with the recent Galaxy S update); it says that my game is using over 10% of the CPU and shows its name in red (which I assume is bad for an app that should be doing nothing).
Can anyone see what I'm doing wrong? Also; does anyone have any suggestions on how I could better structure the flow of the program (this is my first Android app and I'm open to suggestions and criticism).