I need to destroy one of the body's after collision in JBox2D android game. I found that JBox2D world become locked when body's become in contact. I wanted to destroy one of the body after collision. Can i get any call back after world released lock ?. I found an option that adding the body's into an array for destroying it. But when to destroy the body ?. I am not using andengine/libgdx in this game. Find my collision listener class below,
private class CollisionListener implements ContactListener {
#Override
public void beginContact(Contact contact) {
Object fixtureA = contact.getFixtureA().getUserData();
Object fixtureB = contact.getFixtureB().getUserData();
Body mBodyA = contact.getFixtureA().getBody();
Body mBodyB = contact.getFixtureB().getBody();
if (fixtureA instanceof Bullet) {
destroyBalloonBody(mBodyB);
}
if (fixtureB instanceof Bullet) {
destroyBalloonBody(mBodyA);
}
}
#Override
public void endContact(Contact contact) {
}
#Override
public void postSolve(Contact contact, ContactImpulse contactImpulse) {
}
#Override
public void preSolve(Contact contact, Manifold manifold) {
}
}
public void destroyBalloonBody(Body balloon){
//Can i start a new thread which is having a loop until the world become release for destroying the body
//Or
//Do i need to add the body to a deletionArrayList to destroy it.
}
I believe the problem is that you are trying to remove the body during a collision callback.
From the Box2D Manual:
It is tempting to implement game logic that alters the physics world
inside a contact callback. For example, you may have a collision that
applies damage and try to destroy the associated actor and its rigid
body. However, Box2D does not allow you to alter the physics world
inside a callback because you might destroy objects that Box2D is
currently processing, leading to orphaned pointers.
That is to say, you should not destroy bodies inside of a collision callback.
You should store off the references to the bodies you wish to destroy and destroy them using the World reference after the update cycle.
Was this what you needed?
Related
i have an android mobile app and im trying to check if a specific LatLng is at water, so im using google static map api to get an image of the location, and then to check if the image is blue.
im using this code -
private boolean result;
public boolean IsWater(LatLng position)
{
imageView = (ImageView) this.findViewById(R.id.imageView);
checkText= (TextView) this.findViewById(R.id.checkText);
String lati = Double.toString(position.latitude);
String longi = Double.toString(position.longitude);
String url = "http://maps.googleapis.com/maps/api/staticmap?center="+lati+"," + longi + "&zoom=20&size=1x1&style=element:labels%7Cvisibility:off&style=element:geometry.stroke%7Cvisibility:off";
Picasso.with(MainActivity.this).load(url)
.into(imageView, new com.squareup.picasso.Callback() {
#Override
public void onSuccess() {
Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
int pixel = bitmap.getPixel(0, 0);
int blueValue = Color.blue(pixel);
if(blueValue>250)
result =true;
}
#Override
public void onError() {
result =false;
}
});
return result;
}
the problem, i think, is that it is not synchronized, and IsWater get to the last line and return a null for result before the onSuccess kicks in...
any thoughts?
Picasso loads images on a background thread by default. The operation you are running is asynchronous. Therefore, it does not block your method from returning result before the onSuccess callback has been called.
The problem is Picasso is running Async. within the calling method "isWater", so what ends up happening is the method will return 'false' because instead of waiting on Picasso to finish because it isn't in serial execution. This is due to the function call's stack frame being popped off the stack once it reaches the return statement.
What you need to do is the following by using a Target.
// make sure to set Target as strong reference
private Target loadtarget;
public void loadBitmap(String url) {
if (loadtarget == null){
loadtarget = new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
// do something with the Bitmap
handleLoadedBitmap(bitmap);
}
#Override
public void onBitmapFailed() {
}
};
}
Picasso.with(this).load(url).into(loadtarget);
}
public void handleLoadedBitmap(Bitmap b) {
// do something here
}
This code was taken from here, and should offer you some insight on how to get it work for your goal.
A Target is essentially an object that holds the bitmap you need so it is still in memory. Generally used for custom view objects though as a field. Here is documentation Target docs
Asynchronous execution is one of the hardest things to wrap ones head (and subsequently ones code) around. In all of the JavaScript frameworks I've used, the network communication is done in a background thread. The intended effect is that the User Interface thread is left free to keep the user from thinking that things locked up. Mouse-overs and tool-tips will all still work, while a background thread is dragging data out of a slow server.
The code patterns, on the other hand, aren't as nicely shaped.
My problem is/was still basically thinking linearly, or functionally, instead of embracing the event-driven nature of modern JavaScript: Passing a function to an asynchronous method to completely handle that response. Not just return a value, but perform the full task that the value was needed for. The callback can call the other functions to assist with that task, and may be able to fill in a cache (of whatever sort) so that other functions that may need this data do not necessarily have to wait for another response. This often (to me) feels backwards from the logic pattern I was following to solve the original purpose of the code.
I've stumbled on this pattern-flip many times, coming from C/C++ as my first programming language. It can sometimes help to avoid the anonymous function pattern of callback definition and define one's callback functions with names, then pass the name to the asynchronous call, but that is extra steps and extra memory use in the long run. The big hurdle is thinking in terms of Event and EventHandler, versus function and data.
I hope this helps a little.
I have two bodies(A,B). I want B follows A. I can change B position with setTransfrom() function to A position. But I have to change B's position in every frame rate. So I have to use something like contact listener. When I use normal object in Andengine, it has this function below instead of contactlistener.
this.foot = new Rectangle(this.getX(), this.getY(), 8, 10, ResourcesManager.getInstance().vbom){
#Override
protected void onManagedUpdate(float pSecondsElapsed)
{
// super.onManagedUpdate(pSecondsElapsed);
this.setPosition(body.getPosition().x*PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT+1,
body.getPosition().y*PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT-15);
}
};
I mean I can set this kind of listener when I am creating it.Is there any option for box2d body? I mean something like that:
this.footBody=PhysicsFactory.createBoxBody(this.mPhysicsWorld, this.foot, BodyType.DynamicBody, footFixtureDef){
#Override
protected void onManagedUpdate(float pSecondsElapsed)
{
// super.onManagedUpdate(pSecondsElapsed);
this.setPosition(body.getPosition().x*PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT+1,
body.getPosition().y*PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT-15);
}
};
The poisition updates of physics bodies is managed by the Box2D library. But you can register an additional update handler to your scene and tell the box2D world what you want done during that update.
this.scene.registerUpdateHandler(new IUpdateHandler() {
#Override
public void onUpdate(float pSecondsElapsed) {
// TODO Auto-generated method stub
//Your code to run here!
}
So if you maintain a list of references to the bodies in your world, you should be able to apply forces or set their positions on each tick of the game.
If you want to make sure you update the world before or after the box2D world step, you could event call
mBox2dWorld.onUpdate(pSecondsElapsed);
from within your own update handler, instead of registering the world as an updateHandler itself.
Here are a couple of less practical suggestions as well:
Or to do that the box2D way you could use a joint. I depends on the following behavior you want.
OR... you don't even have object B as part of the Box2D world, perhaps, and just manage the following behavior outside of box2D. Does it need to collide with stuff?
I use functions for canvas like drawCircle and drawPoint in android.
This works fine.
But the problem now is to draw these different items with a delay, so it looks like an animation.
What kind of mechanism should I use? Have tried with async but I dont like that way of doing it.
Should I use some kind of timer that just draw with an interval or is there other clever ways to do this?
I use this strategy, first I declare a Handler and a Runnable that way:
private final Observable mObservable = new Observable();
private final static int TIME_STEP_MS = 5;
private final Handler mHandler = new Handler();
private final Runnable mTimeManager = new Runnable()
{
public void run()
{
mObservable.notifyObservers(TIME_STEP_MS);
mHandler.postDelayed(mTimeManager, TIME_STEP_MS);
}
};
Then when I want to start my time manager I just call the mTimeManager.run() and it will start to notify my Observer s (previously added) periodically.
If you need for some reason stop the timer or something you just do that:
mHandler.removeCallbacks(mTimeManager);
[ EDIT - More complete code ]
Ok than let's make it clearer, first I made a custom Observable object like that [that's optional]:
private final Observable mObservable = new Observable()
{
public void notifyObservers()
{
setChanged();
super.notifyObservers();
};
#Override
public void notifyObservers(Object data)
{
setChanged();
super.notifyObservers(data);
};
};
the reason for that is just because I can't call setChanged() outside Observable class - it's protected, if it's not changed it doesn't notify any observer.
The other declarations keep the same as shown before, now I need to start this TimeManager somewhere, my app is a LiveWallpaper and I make all rendering stuff into a class that extends a Thread but you don't need that necessarily, I made a method called resumeDrawing(), this one is called right after super.start(); at my #Override of public synchronized void start() from Thread class, the method looks like that:
public void resumeDrawing()
{
if (!mTimeManagerRunning) // just a boolean field in my class
{
System.err.println("Resuming renderer."); // just for debug
mTimeManager.run();
mTimeManagerRunning = true;
}
else
{
System.err.println("Renderer already running."); // just for debug
}
}
and it's dual:
public void pauseDrawing()
{
if (mTimeManagerRunning)
{
System.err.println("Pausing renderer.");
mHandler.removeCallbacks(mTimeManager);
mTimeManagerRunning = false;
}
else
{
System.err.println("Renderer already paused.");
}
}
Ok, now we can start and stop the time manager, but who's listening? Nobody! so let's add'em: On the constructor of my Renderer I add some Observer s to my mObservable object, one of those is the Renderer itself, so my renderer extends Thread and implements Observer:
#Override // from Observer interface
public void update(Observable arg0, Object arg1)
{
mElapsedMsRedraw += (Integer) arg1;
if (mElapsedMsRedraw >= mDrawingMsPerFrame)
{
mElapsedMsRedraw = 0;
drawEm(); // refresh the canvas and stuff
}
}
to add observers you simply do mObservable.addObserver(THE_OBJECT - Implements Observer)
you can see that I don't re-render my stuff each time I'm notified, that's because I use this TimeManager for other thinks than just refresh the Canvas like updating the position of the objects I want to draw just internally.
So, what you need to slow down the drawing is to change the way your objects change internally while the time passes, I mean your circles and points etc, or you can chance your time step, I recommend the first one.
Was it clearer? I hope it helps.
I would use a timer, or create Animations. You can create Animations that will do all sorts of things including changing transparency over time.
Here's the Android Documentation for Animation Resources
I believe there may be sophisticated ways of doing this, but for my needs I used a simple method that has a lot of advantages:
I first create records of coordinates (and any other data needed) for every point of the drawing -- instead of drawing the points on the spot -- and then reproduce them using a timer (Android handler, preferably). This also offers a lot of possibilities while actual drawing: pause, go faster/slower, go backwards, ...
I don't know if this method can be used for complicated drawings, but it is fine for drawing shapes, curves, surfaces, etc.
I'm using AndEngine and Box2d to make a game. Sprites/bodies are randomly generated and placed on the scene. I know I can calculate the areas and see if they overlap, but this seems taxing. Is there an easy way to detect if a sprite/body is being created inside of another? Something like:
boolean outside = false;
while(!outside){
try{
randx = random.nextInt(650) + 25;
randy = random.nextInt(400) + 25;
sprite = new Sprite(randx,randy,spriteTR,getVertexBufferObjectManager())
scene.attachChild(sprite);
outside = true;
}catch(){}
Or will a try/catch not work?
Yes, what you need to do is to create both sprites, and then do your collision detection. There is an easy way to do this and a more complex way through box2d.
The easy way:
sprite1.collidesWith(sprite2);
Which should return true if the two sprites are in contact with each other.
Through Box2d you would use something called a ContactListener to detect collision.
ContactListener contactListener = new ContactListener()
{
#Override
public void beginContact(Contact contact)
{
}
#Override
public void endContact(Contact contact)
{
}
#Override
public void preSolve(Contact contact, Manifold oldManifold)
{
}
#Override
public void postSolve(Contact contact, ContactImpulse impulse)
{
}
};
Inside beginContact, you will want to do your code for randomizing the locations of the sprites again (or whatever other algorithm you want to employ). The other methods give you additional functionality, for example you can employ endContact when the two objects stop overlapping each other.
For more information and a detailed tutorial see: http://www.andengine.org/forums/tutorials/contact-listener-t5903.html
I have a little problem with ChangeableText in AndEngine. I want to know how to update it's text without freezing the screen? For now I'm using this way, but it's freezing my phone for maybe 2-3 seconds :
private void removeFace(final Sprite face) {
hm = getIconNames();
if(face.getUserData().equals("petrol")){
elapsedText.setText(hm.get(25));
final PhysicsConnector facePhysicsConnector = this.mPhysicsWorld.getPhysicsConnectorManager().findPhysicsConnectorByShape(face);
this.mPhysicsWorld.unregisterPhysicsConnector(facePhysicsConnector);
this.mPhysicsWorld.destroyBody(facePhysicsConnector.getBody());
this.mScene.unregisterTouchArea(face);
this.mScene.detachChild(face);
} else {
}
System.gc();
}
Any ideas how to do that?
Remember that when you detachChild you should do this in thread because if you don't it can causes errors. Use this construction
runOnUpdateThread(new Runnable(){
#Override
public void run() {
if(yourSprite.hasParent())
scene.detachChild(yourSprite);
}});
You can put there all code if you want then your phone shouldn't freez
private void removeFace(final Sprite face) {
runOnUpdateThread(new Runnable(){
#Override
public void run() {
hm = getIconNames();
if(face.getUserData().equals("petrol")){
elapsedText.setText(hm.get(25));
final PhysicsConnector facePhysicsConnector = this.mPhysicsWorld.getPhysicsConnectorManager().findPhysicsConnectorByShape(face);
this.mPhysicsWorld.unregisterPhysicsConnector(facePhysicsConnector);
this.mPhysicsWorld.destroyBody(facePhysicsConnector.getBody());
this.mScene.unregisterTouchArea(face);
this.mScene.detachChild(face);
} else {
}
System.gc();
}});
}
Thats probably because you are fetching some information while setting the text.
What you should do is, get your
String hm = hm.get(25); //What ever the correct object is or variable. im guessing its a string or int.
Then
pass it to the Changeable text to be set.
elapsedText.setText(hm); //If its a int make sure you do String.valueOf(hm);
The only 3 methods here that have the possibility to take long are getIconNames() and get(), and System.gc()
The others are usually methods that return immediately, or have a very low complexity. For example, getPhysicsConnectorManager() returns immediately. findPhysicsConnectorByShape, unregisterPhysicsConnector, unregisterTouchArea and detachChild all have complexity of O(n), (And most of the others methods also have complexity of O(1) or O(n)).
I recommend you to look in the LogCat and when System.gc() is called, you will see a Log.i (blue) message of the tag of dalvikvm which will begin with GC_EXPLICIT and will give you some information about how long did the garbage collection took, etc....
If that GC call isn't taking the time, it must be your 2 methods, getIconNames() and hm.get(). You can put a Log.d message after each code line, which will write the last code line executed. This way you can follow the times.