I have recently been pursuing game development as a hobby, and decided that in order to learn the in's and out's of game development, that I should create a game and render everything myself (without the use of a game engine). This has proven rather complicated, however I am making great progress. I did, however, run in to an issue that I think might be related to the way Android phones render their graphics and will need some clarification on this issue.
The Problem
My game contains a series of balls in a cannon; when the user presses the screen, the cannon launches the balls and the engine (that I am implementing) handles the updates to the location information and collision detection from there. Now, before I had implemented collision detection my game ran very smoothly and responsively, however when I told the engine to only draw the bead if it is within the bounds, and "bounce" it off the wall otherwise, it would seem that the engine loop now takes a significantly longer amount of time to run.
This would be fine, if it were not for the latency it is providing to the user experience. For example, when the screen is touched now, it takes ~2 seconds for the ball to be displayed as moving around the screen, and sometimes it does not appear at all. Previously, the reaction was instantaneous.
Further, when I comment out the collision detection portion of my physics engine, it resumes its usual responsive behavior.
What I Think Is Causing This Behavior
Note: I have recanted this assumption (see 'Debugging Information' below)
I think that since I do not have a frame limiter implemented for my game, and that it is rendering as fast as the hardware will allow it, that it is drawing so many old frames (in some buffer, maybe?) to the screen that it is busy drawing while it should be updating physics. Although my debugging thus far has not indicated that this is the case, I cannot seem to reach any other conclusion.
Some Code
Note that this code is going to be rather confusing to understand not knowing what everything does. I simply included it in case anyone was particular about having some code to work with. The variables are clarified below the excerpt.
PhysicsEngine.updateBeadPositions(float):
private void updateBeadPositions(float delta){
//Update all of the beads currently on the board.
beads = control.getBoard().getValues();
temp_x = 0.0f;
temp_y = 0.0f;
//For each row...
for(Bead[] row : beads){
//For each bead...
for(Bead bead : row){
//If this bead exists...
if(bead != null){
temp_y = (float) (bead.getYCoordinate() * bead.getYVelocity() * delta);
//If the coordinates are within the bounds of the game
if(outwithVerticalBounds(temp_y, control.getBoard())){
//Set the X coordinate equal to the distance * the time differential (delta).
bead.setXCoordinate(temp_x);
//Set the X coordinate equal to the distance * the time differential (delta).
bead.setYCoordinate(temp_y);
}
}
}
}
//If the cannon Bead has been set...
if(control.getCannon().getReleased() != null){
//Update the cannon bead
if(control.getCannon().getReleased().getXVelocity() == PhysicsEngine.VELOCITY_STATIC && control.getCannon().getReleased().getYVelocity() == PhysicsEngine.VELOCITY_STATIC){
control.getCannon().getReleased().setXCoordinate(control.getCannon().getX());
control.getCannon().getReleased().setYCoordinate(control.getCannon().getY() - Cannon.PIVOT_Y_OFFSET);
}
else{
temp_x = control.getCannon().getReleased().getXCoordinate() + (control.getCannon().getReleased().getXVelocity() * delta);
temp_y = control.getCannon().getReleased().getYCoordinate() + (control.getCannon().getReleased().getYVelocity() * delta);
//TODO: Commented out collision checkers!
//If the horizontal coordinates are within the bounds of the game
if(!outwithHorizontalBounds(temp_x, control.getBoard())){
//If the vertical coordinates are within the bounds of game
if(!outwithVerticalBounds(temp_y, control.getBoard())){
//Set the X coordinate equal to the distance * the time differential (delta).
control.getCannon().getReleased().setXCoordinate(temp_x);
//Set the X coordinate equal to the distance * the time differential (delta).
control.getCannon().getReleased().setYCoordinate(temp_y);
}
//Otherwise...
else{
//Bounds off the wall in the y direction
control.getCannon().getReleased().setYVelocity(-1.0f * control.getCannon().getReleased().getYVelocity());
}
}
//Otherwise...
else{
//Bounce off the wall in the x direction (flip the x velocity)
control.getCannon().getReleased().setXVelocity(-1.0f * control.getCannon().getReleased().getXVelocity());
}
}
}
}
Here, the variables are defined as:
control
is a reference to my game controller. It packages the majority of the game code.beads
is a reference to the 2D array that contains the beads on the board currently (excluding the one that is moving)delta
is the time differential between previous calls to the physics engine, and the current call
See the comments within the code for any other explanations.
PhysicsEngine.outwithHorizontalBounds(float, Board):
private boolean outwithHorizontalBounds(float x, Board board){
//If the horizontal values are within the bounds...
if(x > (board.getRight() - bead_radius)){
return true;
}
if(x < (board.getLeft() + bead_radius)){
return true;
}
//Otherwise, it is not.
return false;
}
The method outwithVerticalBounds(float, Board)
is of equivalent functionality, but in the y-direction.
My Question
What about collision detection would cause screen rendering to be inhibited so drastically? I know it is a very intensive operation, but my debugging has shown that the physics updates are completing at the same times as the draws.
Debugging Information
Last Updated: 29 Jan 2013 4:27PM EST
Here is an aggregation of the debugging information that I have obtained thus far. I will update this as time progresses:
The
update()
method within my engine, takes, on average, only.018 ms
to execute. Usually, the delay jumps up to0.020 ms
, when I tap the screen to release the bead.After comparing the times of the draws and the game updates, it would appear that I was correct: they are occurring simultaneously. Thus, this could not be the issue, right?
The
FPS
of the game is roughly87
, it spikes randomly to (at the low end)60 FPS
, however this spike is not related to the releasing of the bead. There are noFPS
drawbacks to doing this. This makes sense since the only part that increases its complexity after the bead is released is theupdate()
call, drawing still happens as fast as possible.After further testing, it has become apparent that this is not the case that the screen is lagging behind the physics. I tested this with a simple boolean flag wherein the screen background would become white when i touched it, and this happens immediately. Thus, there must be some other cause for the bead not drawing. I will update soon.
Supplemental Information
Here is some supplemental information that should help you understand my circumstances:
I am testing this on a Google Nexus 7.
There are quite a few beads on the map that are being updated at once (about 30), but only one of them is moving.
Usually, after the bead starts moving (after the initial delay and if it actually draws), is continues to move in a very smooth manner.
It is important to note that I have other UI elements on the screen that update in reaction to the touch event. For instance, the bead loaded in the cannon becomes a new bead when the screen is touched (signifying that it has been released), but the mobile bead is simply not drawn.