Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Author
Message
BatVink
Moderator
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Gods own County, UK
Posted: 8th Jun 2011 11:00
Using Contact Listener

If I'm using a contact listener, should I still be iterating through the contacts...

While B2GetContact()...

or is there a different way to do it using the listener? I'm having a couple of problems that may be down to combining two opposing methods and reading data that has moved on.

baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 9th Jun 2011 15:17
I have a question I don't think I have asked before...

Is there a command or return from another command similar to "b2GetBodyExists()"?

I don't want to have to loop through a thousand objects to check whether they need to be excluded from certain checks and a simple "exists" check would save me a lot of cpu useage.

BatVink
Moderator
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Gods own County, UK
Posted: 9th Jun 2011 15:47
I think b2GetWorldFirstBody() answers your question, which seems to be no due to the way they are stored...

Quote: "Each world has a linked list containing all the bodies belonging to that world. This function returns the first body in that list.

A linked list is a structure where each item in the list has a pointer to the next item. This means that it's very fast to add and remove items, but you cannot quickly get an item by its index. If you want to loop through all the items in the list, you should start with the first body, and call b2GetNextBody() to move on to the next one in the list. It returns zero to indicate the end of the list.
"


baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 9th Jun 2011 16:19
Oh well, I think I have a fairly quick way to check my objects even if it's not ideal. I have the bodyID's stored in an array and I'm looping through the array checking for a none zero figure, when I've checked an existing body I increase a counter which I then check against the number of bodies so I quit the loop if I've checked them all already...

Not great but it seams pretty quick

BatVink
Moderator
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Gods own County, UK
Posted: 9th Jun 2011 19:36
Quote: "I have the bodyID's stored in an array and I'm looping through the array checking for a none zero figure"


Snap! I only have 24 objects to loop through so it's not a big deal. I also exit the loop as soon as I've identified the 2 objects involved in the collision.

baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 10th Jun 2011 00:11
I did already ask that question and Diggsey answered:
Quote: "Just use 'b2GetObjectType' on the ID. It will return the same as 'b2ObjectType_None()' if the object doesn't exist. Otherwise it will return a value indicating the type of object. (See the help for more info)"


martianxx
13
Years of Service
User Offline
Joined: 19th Feb 2011
Location:
Posted: 21st Jun 2011 21:19
Hi I think this is the right place to post a problem with the box 2D plugin. If not I am sorry, could you say where?

Anyway I am using the plugin in a 2D game I am making and have added a "foot sensor" to my characters feet, atm my character is a simple square polygon and the sensor is underneath the bottom side of the square. I am using the b2FindBodyContacts footSensor, b2GetContact() and b2GetContactIsTouching() calls to work out when my player is on the ground (to alter jump mechanic). It seems to work but the problem is that it only works in certain places. See video. The places it doesnt work seem to be near the ends of the edges making up the outline of the level. Here is the code I am using. The call to this function is in the main loop.



Video to see what happens as its kinda hard to explain:
Video

I reckon it's something I am doing rather than a plugin problem so here is some extra code that may be wrong.



the fixture filter is to stop it collidong with the player. The map is made up of edges as it's all straigt lines mostly. Hope I have given enough info.
martianxx
13
Years of Service
User Offline
Joined: 19th Feb 2011
Location:
Posted: 22nd Jun 2011 19:51
Solved this, I wasn't getting all the data in the list since I was using an if statement over a while loop.
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 23rd Jun 2011 11:56
@Diggsey, when I run use the following code I get an error when I delete a body during the loop that I am using an invalid bodyID. The error occurs on the line where I delete the body. Can you tell me what might be going wrong from this code or do you need to see more? It checks for a certain body and deletes it:

Really I just want to know if you can delete a body while performing this check/loop or if I'm doing the loop wrong?

BatVink
Moderator
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Gods own County, UK
Posted: 23rd Jun 2011 14:00
I think that whenever you delete a body, you will need to another b2GetWorldFirstBody as the list has changed. Also, I don't understand why b2GetNextBody needs a BodyID parameter? I think it needs the WorldId here, not bodyId.

HOWEVER...you are just deleting one body. When you get a hit, shouldn't you follow it with an EXIT to drop out of the checking loop?

baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 23rd Jun 2011 14:31
Quote: "I think that whenever you delete a body, you will need to another b2GetWorldFirstBody as the list has changed. Also, I don't understand why b2GetNextBody needs a BodyID parameter? I think it needs the WorldId here, not bodyId."

Maybe but the help file says:
Quote: "NextBodyId = b2GetNextBody(BodyId as Integer)"


Quote: "HOWEVER...you are just deleting one body. When you get a hit, shouldn't you follow it with an EXIT to drop out of the checking loop?"

That's just a quick example I whipped up. The full version goes through all the bodies deleting whichever ones satisfy certain criteria. I guess I'll have to add a variable that the function passes back so the function can be run through until nothing is deleted... IE:

A clumsy example I know but my code is somewhat more complicated... it's for my worms clone where I'm checking for debris objects being below the edge of the screen.

Diggsey
18
Years of Service
User Offline
Joined: 24th Apr 2006
Location: On this web page.
Posted: 23rd Jun 2011 14:55
Bodies are stored as a linked list so each one has the ID of the previous and next body. Using b2GetNextBody is failing because you're passing in a body which was just deleted. To solve it call b2GetNextBody at the start of the loop instead:


[b]
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 23rd Jun 2011 15:13
Thanks Diggsey!

That's working really nicely now... I'm loving this plugin. Hope you like my game when it's done. I'm calling it "Versus" for now. Although I may go back to "Ham and Eggs got Beef!"

BatVink
Moderator
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Gods own County, UK
Posted: 23rd Jun 2011 16:47
Quote: "it's for my worms clone where I'm checking for debris objects being below the edge of the screen."


Ah I see. I've used the callBack function for this. Then you are simply checking if the single collision is with the "screen floor body" and if it is, delete the body. Unfortunately the callback can't delete bodies (For safety I guess), so I add the objects to be deleted to an array, and delete them in the normal game cycle.



martianxx
13
Years of Service
User Offline
Joined: 19th Feb 2011
Location:
Posted: 24th Jun 2011 18:51
Is there any reason that if the x velocity of a body is set to an extreme value (like i am using 2000). The mode remains stationary. I have a print b2GetBodyLinearVelocityX(body) statement that tells me it is set to the correct value it just remains stationary. If i change the Y value it moves up/down and if i change the x value in certaint conditional statements it changes. For example I change the x velocity when i move left/right and it works, but set it to an extreme value in the main loop and nothing... Any suggestions welcome. David
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 24th Jun 2011 18:56
Could it be down to a lot of friction?

Is it a dynamic object as kinematic objects work differently?

That's all I can think of off the top of my head...

Diggsey
18
Years of Service
User Offline
Joined: 24th Apr 2006
Location: On this web page.
Posted: 24th Jun 2011 19:18
Make sure the body is awake (b2SetBodyIsAwake) and make sure you aren't repositioning it every loop. If you constantly set its position directly the physics engine doesn't have a chance to step in.

[b]
Ranietz
AGK Gold Backer
19
Years of Service
User Offline
Joined: 2nd Sep 2004
Location: Norway
Posted: 28th Jun 2011 16:06
Hi

Is the box2d plugin any good for 2d platform games? I mean for jumping and collisions. Or is it just overkill to use it and it's better to code it all with the native DBPro commands?
BatVink
Moderator
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Gods own County, UK
Posted: 28th Jun 2011 17:18
You could use Kinematic bodies in Box2D for a platformer.

baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 28th Jun 2011 17:41
I'm using dynamic bodies as characters in my worms clone. I'll attach a 'working' version as soon as I figure some details out but here's my movement code:


I use forces for horizontal movement and a linear velocity for vertical. It works pretty well. Also it means the characters react to other dynamic objects...

Ranietz
AGK Gold Backer
19
Years of Service
User Offline
Joined: 2nd Sep 2004
Location: Norway
Posted: 28th Jun 2011 17:54
Thanks. I'll buy it and see what it can do.
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 28th Jun 2011 19:24 Edited at: 28th Jun 2011 19:26
Here is a very buggy but playable version of my WIP which I can't decide a name for. The attached is called "Farm Fury" but I'm thinking of opening it up to different modable characters and simply calling it "Vs"...

Hope you get the idea for making 2D platformers!

Keys:
Left/Right - Move
Space - Jump
1->4 - Choose weapon
Enter - Fire/Release

Attachments

Login to view attachments
Diggsey
18
Years of Service
User Offline
Joined: 24th Apr 2006
Location: On this web page.
Posted: 29th Jun 2011 12:36
Box2D is perfect for platformers. Here are some suggestions to make life easier (I've written a fairly advanced platformer myself and these are the tricks I used):

- Use a dynamic body for the player, but set to non-rotatable. That way it still responds to gravity but it won't get knocked over.

- Make the bottom corners of the player angled as though they've been cut off. Only a couple of pixels is needed but it stops you from getting stuck if platforms don't line up perfectly.

- Box2D provides some useful functions like raycasting and point testing that you can use to get effects such as hanging onto ledges and to detect if you are on the ground.

- Jumping can be done by checking if the player is on the ground, and if so, apply a strong upward impulse. Gravity will take care of the rest. Make sure you only apply the impulse once each jump.

[b]
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 29th Jun 2011 12:54
I don't know if anyone here tried my demo but it also uses raycasting in the grappling hook function. By making my character dynamic (I used a circle shape and set quite high friction so he doesn't slip off small slopes) I just added a distance joint between him and the point where the raycast hits to get a grappling hook and rope effect. Also you can edit the distance to climb up or down the rope and add impulse to swing!

Box2D takes a lot of headaches away making a game like this and runs soooo fast, I'm getting over 9K+ loops per second for this demo with a decoupled display loop! I may have to clip it so my PC can relax a little...

Ranietz
AGK Gold Backer
19
Years of Service
User Offline
Joined: 2nd Sep 2004
Location: Norway
Posted: 29th Jun 2011 19:59
Thanks everyone.

I'm going through the pinball tutorial right now. I don't understand much yet but I'll get there.

@baxslash: I tried your demo and it looks like a fun game. Good work! And it's great to see what other people can do with box2d.
Ranietz
AGK Gold Backer
19
Years of Service
User Offline
Joined: 2nd Sep 2004
Location: Norway
Posted: 30th Jun 2011 05:16
One question for Diggsey about the pinball tutorial. You say you use Inkscape to make the table and then export the node coordinates. How do you do that? I found the coordinates in the XML editor in Inkscape but the y coordinates are all messed up. I'm not talking about them being flipped but when the x/y coordinates should be 0,0 they are instead 0,1053 or something like that.

Maybe this is a bit off topic but could you please explain a bit more on how you exported the coordinates from Inkscape?
Diggsey
18
Years of Service
User Offline
Joined: 24th Apr 2006
Location: On this web page.
Posted: 30th Jun 2011 13:56
If your image is 1054 pixels high, then that would make sense though.

This is what I did:
- Select the path to be exported.
- Open XML editor
- Copy coordinates from the "d" field
- Do a search/replace to convert it to data statements

[b]
Ranietz
AGK Gold Backer
19
Years of Service
User Offline
Joined: 2nd Sep 2004
Location: Norway
Posted: 30th Jun 2011 15:30
Thanks for the reply Diggsey.
The image is 768 pixels high. I do the same thing as you do but the y coordinates are still messed up.

If I make a simple path with 2 nodes and snap those nodes to a grid set to pixels the coordinates of the nodes are (when I look at the tool bar) 0,0 and 20,20 but when I open the XML editor the coordinates are (in the "d" field) 0,1052.3622 and 20,1032.3622. Any idea about what I do wrong?
Diggsey
18
Years of Service
User Offline
Joined: 24th Apr 2006
Location: On this web page.
Posted: 30th Jun 2011 16:17
Just make the Y coordinates equal to 1052.3622 minus the original Y coordinate, so:
0, 1052.3622 -> 0, 0
20, 1032.3622 -> 20, 20

[b]
Ranietz
AGK Gold Backer
19
Years of Service
User Offline
Joined: 2nd Sep 2004
Location: Norway
Posted: 30th Jun 2011 16:36 Edited at: 30th Jun 2011 16:47
Ok, thanks, I'll try that. I just thought I had messed up some settings in Inkscape.

Edit: And now I started a new Inkscape project and the coordinates are suddenly correct. weird...
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 6th Jul 2011 18:25 Edited at: 6th Jul 2011 18:28
Diggsey, any chance of a feature request to save me some Mb on my game?

Could you add "b2SetBodyImageMirror"?

I'm having to add reverse versions of literally hundreds of images at the moment where it might be possible to have a simple mirror flag in Box2D... maybe I missed how to do it and it already exists but I did look.

EDIT: Might be better as an overload on "b2SetBodyTransform"?

BatVink
Moderator
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Gods own County, UK
Posted: 6th Jul 2011 22:08 Edited at: 6th Jul 2011 22:14
I have the following error:

Quote: "Attempted to explicitely delete an implicit object"


It is caused by this line:

if b2GetObjectType(arrBody(n).body) <> b2ObjectType_None() then b2deletebody arrBody(n).body


The checks I perform should make this failsafe, I would have thought? I checked the Body IDs and Body types:

Quote: "
Body ID = 62299424 : Object Type = 2
Body ID = 63166744 : Object Type = 2
Body ID = 62325416 : Object Type = 2
Body ID = 62352608 : Object Type = 2
Body ID = 63163920 : Object Type = 2
"


This tells me that it failed on the 5th of 20 objects. All objects were "in play", there were no objects deleted mid-game to confuse the issue. The body that causes the issue appears to be random.

I can play once, delete the bodies then delete the world. This ALWAYS succeeds. Creating the world for a second and subsequent times causes the error when deleting the bodies after the game. The number of games it takes to cause the problem is also random.

[EDIT] I can also get the error by using b2DeleteWorld() with a world that still contains bodies. I thought this was a quick way to destroy everything?

Baxslash has mentioned this error before, so I'll reiterate the last answer to start off...

Quote: "The error "Attempted to explicitly delete an implicit object" means that you tried to delete an object (such as a shape) which you didn't create. Only ever delete objects which you created.

Box2D gives you access to certain objects which were automatically created by the engine (and will eventually be deleted by it). To make sure you don't delete one of them by accident, it keeps a list of these 'protected' objects and shows this error in case you do try to delete it.

In this case, I suspect that you are deleting a shape which you found using the 'b2GetFixtureShape' command. Don't do this. When you create a fixture and pass in a shape to use, the fixture automatically makes its own copy of the shape so that you can reuse the original. When you delete the fixture, the shape it owns will also be deleted, but you shouldn't try to delete it yourself (or you'd end up with a fixture without a shape)"


Diggsey
18
Years of Service
User Offline
Joined: 24th Apr 2006
Location: On this web page.
Posted: 7th Jul 2011 01:20
@baxslash
Good idea. I'll add it for the next update.

@BatVink
It definitely seems like a bug in the plugin. Only shape IDs are ever added to the protected list, so it must be that a shape is being added and then deleted without its ID being removed from the protected list, and then a body is created that happens to have the same ID as that shape had. I'm still not sure exactly how it's happening but I'll track it down.

Do you have any example code I can use to debug it? (If it helps I promise I won't look too closely or share it with anyone. I just need it to compile against a debug version of the plugin)

[b]
BatVink
Moderator
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Gods own County, UK
Posted: 7th Jul 2011 01:37
It's impossible to give a concise example, as I use a library of functions that equates to 11,000 lines of code. But if this helps, this is how I create the 20 bodies, it may help to know that some bodies can have multiple fixtures. I have tried to delete fixtures then delete bodies to resolve the problem but that also fails.

Iterate around array of bodies and call createBody for each one:



And the createBody function:



Diggsey
18
Years of Service
User Offline
Joined: 24th Apr 2006
Location: On this web page.
Posted: 7th Jul 2011 02:32
I think I may have found the cause. Box2D tells me when a fixture is deleted implicitly because a body is deleted, but it might not do it when you delete the world, assuming that I'll clear all my data as well.

You said it happens after a random number of worlds are created and deleted. Is it possible that a body still existed when the world was deleted the time immediately before the crash?

[b]
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 7th Jul 2011 11:31
Quote: "Good idea. I'll add it for the next update."

You are a legend!! It'll reduce the size of my game and leave me a lot more memory to play with

danjo
18
Years of Service
User Offline
Joined: 29th Dec 2005
Location:
Posted: 11th Jul 2011 05:39 Edited at: 11th Jul 2011 05:40
im kind of confused with setting a scrolling world in box2d.
for example; a pinball table which is 800x2400 - viewed in a window 800x600, so the table will be scrolled up and down.

the pinball exmaple is easy enough to follow, but is on 1 static screen/table.

can someone advise how to go about making a taller table, that extends beyond the visible screen.
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 11th Jul 2011 15:44 Edited at: 11th Jul 2011 16:32
I thought I'd share a simple object maker with you all. You can use it to build polygon shapes for your game.

All you do is load the image for your object and click where you want the vertices for the polygon shape. It will produce a simple text file which you can hard code into your game or load from a folder when your game starts.

You just need to remember to pick points in a clockwise direction and don't make concave shapes!! You can add additional fixtures by pressing (+) that's the one next to backspace.

I am working on a simple algorithm to check for concave points being added so it could start a new fixture automatically but it works as it is.

Here's some sample code to load an object as a static poly shape:


Sorry if the code is incomplete but it's just an example of how you might use it. Works nicely in my game...

The text file format is as follows:


If anyone wants any help using it just shout...

Here's a screenshot of it in action:


Attachments

Login to view attachments
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 11th Jul 2011 15:52 Edited at: 11th Jul 2011 16:15
Quote: "can someone advise how to go about making a taller table, that extends beyond the visible screen."

Yes, if you use the "b2SetScreenTransform" command you can edit the view quite dramatically including the position, scale and even the angle of what you are looking at.

I found that if I store some global floats called camX, camY, camAng and camScale I can edit the view very easily:



Attachments

Login to view attachments
danjo
18
Years of Service
User Offline
Joined: 29th Dec 2005
Location:
Posted: 11th Jul 2011 16:34
ah yes, thanks
Ranietz
AGK Gold Backer
19
Years of Service
User Offline
Joined: 2nd Sep 2004
Location: Norway
Posted: 11th Jul 2011 17:39 Edited at: 11th Jul 2011 18:04
@baxslash
I haven't looked too closely on your object maker code but I think you can do the following to avoid having to always draw the polygon in clockwise order:

In "case 3" of your code replace

with:


then do the same for the rest of the "cases"

Edit: way off topic, but how do I make the code in the code box on the forum appear with colors?
Edit2: yay it works! Thanks baxslash
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 11th Jul 2011 17:49 Edited at: 11th Jul 2011 17:54
@Ranietz, thanks. I'll take a look at that!

Never seen that command before

Answer: Just write it like this "code lang=dbp" inside the first set of code brackets...

Since I'm in a sharing mood here is the code for the object maker too! You'll need d3d, a2 and the Matrix utility dll's at the very least to compile it though


Ranietz
AGK Gold Backer
19
Years of Service
User Offline
Joined: 2nd Sep 2004
Location: Norway
Posted: 12th Jul 2011 05:42
baxslash' object maker project got me thinking. If you want to create a complex polygon shaped object you have to split it up into several parts, right? But how do you combine those parts together?
So far I've been creating a separate body/shape/fixture for each part and then glued them together using a weld joint. Is that the way to do it or is there a simpler way?
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 12th Jul 2011 10:32
Quote: "baxslash' object maker project got me thinking. If you want to create a complex polygon shaped object you have to split it up into several parts, right? But how do you combine those parts together?
So far I've been creating a separate body/shape/fixture for each part and then glued them together using a weld joint. Is that the way to do it or is there a simpler way?"

I added the code in the post with the download but you can add as many fixtures as you like to a body, no need to make a new body for each part.

Diggsey
18
Years of Service
User Offline
Joined: 24th Apr 2006
Location: On this web page.
Posted: 12th Jul 2011 13:37
You can have multiple fixtures on a single body

[b]
Ranietz
AGK Gold Backer
19
Years of Service
User Offline
Joined: 2nd Sep 2004
Location: Norway
Posted: 12th Jul 2011 18:01
I got it now. Thanks guys. I knew there had to be a simpler way.
Ranietz
AGK Gold Backer
19
Years of Service
User Offline
Joined: 2nd Sep 2004
Location: Norway
Posted: 13th Jul 2011 06:02 Edited at: 13th Jul 2011 06:10
I wrote this little program to make polygon object with as many sides you want. concave, convex, clockwise or counter-clockwise. Do as you want as long as no lines are crossing.
There was a bug in there but I can't replicate it so maybe it just... works.

Enjoy

Edit: There is a bug in there but I haven't found it yet...

baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 13th Jul 2011 10:28
Nice work Ranietz, I'll have a play and see how it works. I was going to us a perpendicular distance check to check for concave / convex but haven't gotten around to it as my version works well enough to get me through. I may have to crib some code from you though

Ranietz
AGK Gold Backer
19
Years of Service
User Offline
Joined: 2nd Sep 2004
Location: Norway
Posted: 13th Jul 2011 17:36
Quote: " Nice work Ranietz, I'll have a play and see how it works. I was going to us a perpendicular distance check to check for concave / convex but haven't gotten around to it as my version works well enough to get me through. I may have to crib some code from you though "


Thanks. Fell free to use the code any way you want.
Diggsey
18
Years of Service
User Offline
Joined: 24th Apr 2006
Location: On this web page.
Posted: 13th Jul 2011 18:46
@baxslash + BatVink
You can find the new update in your order history

[b]

Login to post a reply

Server time is: 2024-04-26 23:18:34
Your offset time is: 2024-04-26 23:18:34