load level dynamically using andengine in android - android

I am developing a game using andEngine in android, I've developed animated sprites background, platforms and scores. for loading level, I've made a
.lvl
extension file in which I've defined platforms, player and obstacles at fixed positions. I want to know is there anything provided by andEngine so that I can dynamically load obstacles, platforms, coins and other objects rather than loading any file, my aim is to keep my game-world going as long as my player is alive.
I think I am clear.
Thanks!!!

I would like to point you to investigate "TimerHandler" as your dynamic time handler (Defining how often to attach another object/entity.
With a time handler in place, you can assign nearly any int/double/float value of an object/entity with MathUtils.random(min, max).
Example:
TimerHandler objectTimerHandler = new TimerHandler(1f, true, new ITimerCallback() {
#Override
public void onTimePassed(TimerHandler pTimerHandler) {
int timerSeconds = 0;
timerSeconds++;
final Sprite object1 = new Sprite(0, 0, resourcesManager.object1_region, vbom);
if (timerSeconds == MathUtils.random(1, 4))
{
attachChild(object1);
object1.setX(MathUtils.random(0, 480));
}
});
registerUpdateHandler(objectTimerHandler);
So, the TimeHandler "objectHandler" is called every 1 seconds defined by the 1f variable.
An integer counter "timerSeconds" is setup as a base.
The Sprite object/entity is initialized.
Now the "magic": the if boolean is in place to set a sense of true randomness. So here's the math... Every second passed, add a "timerSecond". Then, IF "timerSecond" is EQUAL to a random number between 1-4, then attach the sprite "object1" and set it's X position, also on a random range 0-480.
In reality, this means for every 1 second passed, there is a 1/4 chance that this sprite will be created/attached. (this can be altered to any desired chance range by changing that random range max value. EG: MathUtils.random(1, 100) <-- this would state a 1 in 100 chance to spawn the sprite each second.)
The 2nd to last line closes the Timehandler code, and the last line registers the Timehandler to the class/scene/entity/engine (ect..).

Related

Doing position calculation in onDraw it's faster than in game loop thread... why?

I'm developing a simple game which uses normal android views, not openGL or other apis, simply uses views and moves them on the scren. I have a game loop which calls to AsteroidManager.updateAsteroidsPositions() which iterates in all the screen asteroids calculating it's possitions.
After that, the thread, calls to a AsteroidManager.invalidateAsteroids() method using runOnUiThread() method, because in Android you need to manipulate views on the main thread. AsteroidManager.invalidateAsteroids() method simply iterates all the asteroids and set's x,y positions to the view and calls invalidate().
The problem is that I disscovered that it gives a much more smooth and faster behaviour if you put the logic of calculatePositions inside the onDraw method of the view. Doing that, the logic of calculating possitions is not being done in the game loop thread... its being done in the main UI thread!!
How is that possible? It is breaking all the game development logic... about doing the position calculations on Game Loop thread instead of other places like main thread or onDraws...
This the slower original code:
AsteroidManager class:
public void updateAsteroidsPositions(){
for (int i = 0; i<onScreenAsteroids.size(); i++){
onScreenAsteroids.get(i).updatePosition();
}
}
public void invalidateAsteroids() {
for (int i = 0; i<onScreenAsteroids.size(); i++){
onScreenAsteroids.get(i).invalidate();
}
}
Asteroid Class:
public void updatePosition(){
currentScale = (Float) scaleX.getAnimatedValue();
factor = currentScale/MAX_SCALE;
//adding a minimum of factor, because with too low factor the movement is not realistic
if (factor < 0.250f)
factor = 0.250f;
x = x-((float)GameState.getInstance().getJoyX()*factor);
y = y-((float)GameState.getInstance().getJoyY()*factor);
}
public void invalidate(){
view.setX(x);
view.setY(y);
view.invalidate();
}
this is the trick done in Asteroid class which does the behaviour of the game smooth and faster:
Asteroid Class:
public Asteroid(Bitmap bitmap, Context context) {
view = new ImageView(context){
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
currentScale = (Float) scaleX.getAnimatedValue();
factor = currentScale/MAX_SCALE;
//adding a minimum of factor, because with too low factor the movement is not realistic
if (factor < 0.250f)
factor = 0.250f;
x = x-((float)GameState.getInstance().getJoyX()*factor);
y = y-((float)GameState.getInstance().getJoyY()*factor);
view.setX(x);
view.setY(y);
}
};
view.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
view.setImageBitmap(bitmap);
}
public void updatePosition(){
}
public void invalidate(){
view.invalidate();
}
If you have too many items in onScreenAsteroids list it takes some time to execute updatePosition() for each of them. Try to use single method for them:
public void updateAndInvalidateAsteroidsPositions(){
for (int i = 0; i<onScreenAsteroids.size(); i++){
onScreenAsteroids.get(i).updatePosition();
onScreenAsteroids.get(i).invalidate();
}
}
Not all games need game loop. Thread switching has its own cost.
Game Loop separates game state from rendering. Ideally the game loop has the responsibility to processes all the onscreen objects in the game and objects have the responsibility to draw itself in its place. This way we have central place to react to events(mouse click, user touch etc) and update view positions and views have the responsibility to draw themselves at updated position.
For eg consider that we have 10 moving asteroids on screen and we are updating them in onDraw(), now two of them collide, but asteroid1 does not know position of asteroid2, so how will they detect collision? By game logic the game loop knows position of all 10 asteroids, it can detect collision. If don't care about messy code, then collision can be detected in onDraw also. But consider following...
If two are colliding , then we need to check if some other asteroid is near by collision region, if so then how much impact? Mess increases linearly...
After collision we decide to show collision graphic effects. Mess increases exponentially....
Asteroids collided, game state = 'EXPLOSIONS IN THE SKY', user gets a call, game goes to background, game state is to be saved, but our asteroids are master of their own destiny, now we need to provide every asteroid's state to our activity and save it in onPause(). Its all mess now...
User returns after few hours, we can't welcome them directly with 'EXPLOSIONS IN THE SKY', need to rewind to the state where asteroids are about to collide and then show BANG-BANG... Mess goes ALL HELL BREAK LOOSE.....
Views are slaves and they should not be empowered.
Where to display view, its dimens? -> comes from outside.
What to draw in view? -> comes from outside/ can have little say here.
How to animate view? -> comes from outside.
Coming to your particular case, you are using both versions differently, in onDraw() case you are directly invalidating asteroid's (first one is drawn instantly) whereas in game loop case you are first computing all asteroid's position and then invalidating, I don't know how many asteroids you have but if they are significant number, then this coupled with thread switching costs, may trick you to believe onDraw() is faster.

Android OpenGL previous frame re-appear for split moment when calling update

I have just started using the OpenGL ES 2 for android for my little game and have encountered a problem on redrawing the screen on each frame.
I have setup a loop on my Renderer's onDrawFrame, just a simple [ updateGameLogic() -> drawGame() ] or Thread.sleep() loop based on the time lapsed from last drawGame call.
Currently the updateGameLogic() method simply translate the camera to the +ve X direction (the game is 2d).
In the drawGame() call, I first clear my screen with GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT). Then I have 3 glBindTexture and glDrawElements calls for drawing 3 categories of objects with different texture atlas.
Here comes the problem, in between each frame drawn on screen, there is a blink of the previous frame appearing which is undesired and makes the game look dizzy. Precisely, say the game is just about to draw frame 3 from frame 2, right before frame 2 vanish and frame 3 appearing, there is a split moment where frame 1 is displayed.
I thought this may be due to the way the GLSurfaceView is buffered by the system so I experimented with calling multiple glClear before drawing but everything stays the same. Would be grateful if someone can provide some explanation / solution to the problem, and what I have done wrong, thanks. (basically paragraph 2 to 4 is all my code so I have not posted it, unless requested)
From the clarification in the comment, it sounds like you have something like this in your code:
public void onDrawFrame(GL10 gl) {
long currentTime = SystemClock.elapsedRealtime();
long deltaTime = currentTime - mLastFrameTime;
if (deltaTime < 33) {
Thread.sleep(33 - deltaTime);
return;
}
mLastFrameTime = currentTime;
updateGameLogic(deltaTime);
drawGame();
}
This will indeed cause problems. When onDrawFrame() is called, you have to render a frame. You can't just return without drawing anything. The caller will assume that you rendered a frame in any case, and it will end up being presented on the screen. If you decide not to render anything, whatever happened to be in the surface you were supposed to draw to will be presented. There's no telling what this will be, but it's quite likely that it's an old frame from 2-3 frames earlier.
If you want to artificially throttle the frame rate, e.g. to save power, unfortunately there's no very good way to do this in Android. Using sleeps in onDrawFrame() is kind of dirty (and inherently unreliable, IMHO), but it might be necessary in this case. The key is that either before or after you sleep, you still need to render a frame. As a first attempt, I would try tweaking the above to something like this:
public void onDrawFrame(GL10 gl) {
long currentTime = SystemClock.elapsedRealtime();
long deltaTime = currentTime - mLastFrameTime;
if (deltaTime < 33) {
Thread.sleep(33 - deltaTime);
currentTime = SystemClock.elapsedRealtime();
deltaTime = currentTime - mLastFrameTime;
}
mLastFrameTime = currentTime;
updateGameLogic(deltaTime);
drawGame();
}
Note that while there is still an artificial delay, there is no early return in the code anymore.
There are probably more robust variations of this idea for throttling the redraws to 30 fps. Some searching on SO or the rest of the internet should reveal previous discussions.

Using Android timers to implement graphical movement

I'm using opengl with android. I am just playing around and trying to learn some stuff and I've decided to make a simple game where there are falling triangles and you have to tap them to "collect" them (Don't steal my idea! xD).
I am using an Android Timer like this:
Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
float[] p1Temp = mTriangle.getP1();
float[] p2Temp = mTriangle.getP2();
float[] p3Temp = mTriangle.getP3();
mTriangle.changeCoords(new float[] {p1Temp[0], p1Temp[1] - 0.01f, p1Temp[2],
p2Temp[0], p2Temp[1] - 0.01f, p2Temp[2],
p3Temp[0], p3Temp[1] - 0.01f, p3Temp[2]});
if (mTriangle.getP1()[1] <= -1.0f ||
mTriangle.getP2()[1] <= -1.0f ||
mTriangle.getP3()[1] <= -1.0f) {
t.cancel();
}
}
}, 0, 40);
So basically what this code is doing is this: there is a timer, and every 40 milliseconds, the y coordinate of every vertex of the falling triangle is decremented. This process stops when it hits the bottom of the screen (i.e. hit the ground).
My question is this, I'm new to using openGL in android, is this the correct way to handle "movement" of objects etc? Or are there methods I'm supposed to use to implement animation/movement.
The most common approach I have seen is somewhat different. It's more typical to update the animation while preparing to render each frame, and base the update on the amount of time that has passed since the last frame.
Since distance is velocity multiplied by time, you do this by assigning a velocity vector to each of your objects. Then when it's time to update the animation, you take the time difference since the last update, and the increment you apply to your positions is the time difference multiplied by the velocity. The velocity is constant as long as you just use a linear motion, but can also change over time for more complex animations, e.g. due to gravity, collision with other objects, etc.
If you're using OpenGL on Android, you're probably using a GLSurfaceView for your rendering. By default, the GLSurfaceView will already invoke your rendering function continuously, up to 60 fps if your rendering can keep up with the display refresh rate.
What you roughly do is keep the time when the last frame was rendered as a member variable in your GLSurfaceView.Renderer implementation. Then each time onDraw() is called, you get the new time, and subtract the last frame time from this time to get the time increment. Then you store away the new time in your member variable, multiply the time increment by the velocity, and add the result to your positions.
After the positions are updated, you render your objects as you normally would.
To give you the outline, the following is a slightly adapted piece of (pseudo-)code I copied from my answer to a similar question (Android timing in OpenGL ES thread is not monotonic):
public void onDrawFrame(GL10 gl) {
currentTime = SystemClock.elapsedRealtime()
deltaTime = currentTime - lastFrameTime
lastFrameTime = currentTime
update animation based on deltaTime
draw frame
}
Where lastFrameTime is a member variable, currentTime a local variable.

onManagedUpdate never changes pSecondsElapsed - AndEngine

I have a Sprite, which is a ball, and it is falling properly, acording with my FixedStepPhysicsWorld options. But I would like a vector follow this ball as it is falling.
So I decided to override the onManagedUpdate sprite's method.
After lots of tests, I just got 1 vector drawn, then I realized that the pSecondsElapsed, were not being incremented.
Here is my code:
#Override
public void onPopulateScene(Scene pScene,
OnPopulateSceneCallback pOnPopulateSceneCallback) throws Exception {
sPlayer= new Sprite(200,0, playerTextureRegion, this.mEngine.getVertexBufferObjectManager()){
#Override
protected void onManagedUpdate(float pSecondsElapsed) {
super.onManagedUpdate(pSecondsElapsed);
Log.d("<<<<<<<<<<<,>>>>>>>>>"+pSecondsElapsed+","");
}
The output is the following:
11-07 21:14:32.242: D/<<<<<<<<<<<,>>>>>>>>0.02 (23720): [MainActivity.java:359:onManagedUpdate()]
11-07 21:14:32.257: D/<<<<<<<<<<<,>>>>>>>>0.02 (23720): [MainActivity.java:359:onManagedUpdate()]
11-07 21:14:32.281: D/<<<<<<<<<<<,>>>>>>>>0.02 (23720): [MainActivity.java:359:onManagedUpdate()]
My Engine is like:
#Override
public Engine onCreateEngine(final EngineOptions pEngineOptions) {
return new FixedStepEngine(pEngineOptions, 50);
}
QUESTION:
1 - Why pSecondsElapsed is not changing?
2 - I want to draw vectors for each position of this ball. Should I detach and atach a new Line each time this method(onManagedUpdate) is called?
The API tried to make that clear by calling it "Seconds Elapsed" which means "seconds passed" since the last time the update was called. It's not a cumulative number, but instead the number of milliseconds since the function was last called.
If you want to maintain a cumulative count, you will need to add pSecondsElapsed to a counter variable on each call of that function.
The reason pSecondsElapsed is not changing is due to two conditions being true.
1) You are using a FixedStepOption with the frame rate set to 50.
2) The android you tested it on had the capability to run at 50 frames per second.
This results in it running 50 FPS which results in .02 of a second elapsed per frame. (1 second divided by 50 frames). You can test this by changing the 50 to 25 and expect to get .04 (1 second divided by 25 frames).
Where it becomes important is if the hardware cannot support the frame rate you specify. In this case, it is likely it varies due to needing to do more work in certain situations of your app. (For example if you create an explosion the FPS may drop due to the extra sprites).
To properly support hardware that cannot keep up with the framerate you specify, you can use the pSecondsElapsed to account for the variance. (for example by multiplying the distance times the variance in elapsed time vs specified time).

Detaching all instances of a sprite AndEngine

I'm building a tank game using AndEngine that has multiple levels, but I'm not using multiple scenes, I'm sticking to 1 Main Game Scene that should reset and modify itself when the user beats the level.
I'm able to successfully modify the scene, but I'm having an issue with removing the enemies. There are multiple instances of an enemy sprite that the user has to kill, but when the user successfully completes the requirement to advance a level(killing x number of enemies), the enemies aren't reset; the instances from the previous level haven't been removed from the screen.
As a result, when a user is on Level 2, there might still be 3 or 4 enemies roaming around from Level 1 that the user didn't need to kill.
I tried using detachChild to remove the enemy from the screen and attachChild to instantly add them back, but when the next level started, the enemies wouldn't spawn.
How can I remove all instances of the enemy sprite that are currently on the screen without affecting the spawning?
when you are starting the game you have to create different layers(Entities) like gameLayer,
background Layer, HUD Layer... .So that you can update the items based on the situation.
This process make you unload resources smoothly when level is completed.
Coming to your requirement ... add every sprite instance to array list when it is created.
Remove all these as follows
public static void removeSprites(List<Sprite> spriteList, IEntity scene){
for(int i = spriteList.size() - 1; i >= 0; i--) {
final Sprite sprite = spriteList.get(i);
scene.detachChild(sprite);
spriteList.remove(i);
}
spriteList = null;
System.gc();
}
you must also unload Texture Atlases in your game
Well, try to use this method: sprite.detachchildren()

Categories

Resources