Box2D and wrapping worlds - iphone

I really stuck at implementing wrapping world with Box2D. I want to create game object appearing from left when it hides to the right and vice versa and the same for top-down.
My idea is to use object wich contains NSArray with 9 elements for superposition matrix (it's a quantum state when object exists at different locations at the same time, isn't it?).
Every element must contain the body. It covers all situations and has a more clear logic for me. For example, if my object doesn't touch any edges it holds only one "center" body (4th element). If it touches right edge i add "left-warped" body to 3rd element.
The main problem is creating body without adding to the world. First i must just add it to the array and then safely proccess adding outside of
world->Step();
For example… In collision logic (pseudocode)
[self.bodies addObjectAtIndex:index] = [self masterBody];
where
-(b2Body*)masterBody;
returns a template (master copy) for object body. But i can't write this method because there is only one
world->CreateBody(&bodyDef);
method and i must use it to create fixtures.
I can create separately only definition of the body, but full creation (with fixtures) can't be made without adding it to the world. But adding to the world msut be processed outside physics step.
Any ideas? Use separate world for storing template bodies of every game object?

Related

Why does parenting an object in the hierarchy produce different results then parenting via script?

Parenting GIF (for visual)
When parenting an object using the hierarchy you click and drag that object and place it into another game object.
When parenting an object using a script, it looks something like this
myObject.transform.SetParent(parentObject, false);
Now, if you watch the GIF you will see that the two different methods of parenting produce different results for the child objects transform values. The resulting position and scale are different for the child object depending on which approach to object parenting is used.
How do you get the same results produced when parenting in the hierarchy via click and drag, when parenting by script?
EDIT: Forgot to add that when watching the gif, you can see the click and drag parenting first and watch the transform values change. I then control Z to undo the change, click into the scene view, and execute a button press that sets the parent of the 'blue' game object to 'myObject'. Note, you will see the transform values don't change when parenting is done via the latter method.
If we check Unity's API documentation for the SetParent() method we can better understand how this method works. In my case I was using the method that used two parameters:
parent:
The parent Transform to use
worldPositionStays:
When false the object keeps its local orientation rather than its global
For my question, there are two simple solutions:
Set the worldPositionStays parameter to true so that the parent-relative position, scale and rotation are modified such that the child object keeps the same world space position, rotation and scale as before, or
Use the SetParent() method with only the parent parameter, effectively yields the exact same result as setting worldPositionStays to true.

pygame-create multiple different instances of sprites [duplicate]

I'm having trouble with getting new sprites to be added. I'm looking for something along the lines of:
def duplicate(sprites):
for d in sprites:
if d.energy >= d.max_energy * 0.9:
d.energy = d.energy / 2
new_d = d.duplicate()
so if 1 sprite had its 'energy' above 90% of its 'max_energy', its energy would be cut in half and now there would be a second sprite that was identical to the first. I'm not sure how to pull that off though.
In general, you need to implement the duplicate method and construct a new instance of the Sprite object in the method.
Another solution is to use the Python copy module. deepcopy can create a deep copy of an object. Unfortunately this cannot be used for pygame.sprite.Sprite objects, as theimage attribute is a pygame.Surface, which cannot be copied deeply. Therefore, a deepcopy of a Sprite will cause an error.
Unless you have nor any other attribute that needs to be copied deeply, you can make a shallow copy of the Sprite. The rect attribute is a pygame.Rect object. The copy of the Sprite needs its own rectangle, so you have to generate a new rectangle instance. Fortunately a pygame.Rect object can be copied by pygame.Rect.copy:
import copy
new_d = copy.copy(d)
new_d.rect = d.rect.copy()

Creating a class to run a single action on multiple sprites

I'm trying to rotate numerous sprites (about 48 different ones) around an arbitrary point (using this article: http://indiedevstories.com/2012/08/14/custom-cocos2d-action-rotating-sprite-around-arbitrary-point/ ) and I managed to create the custom category for it, but it only works on a single sprite. I've looked around on the site and tried to use runAction:[action copy] but it makes the copies rotating points crazy numbers for some reason. Then I tried to create a method for the actions and just call the method, but I keep getting errors for that as well. I've tried so many different solutions but no luck.
So my question is, is there a way I can create another class that holds all of my sprites, and then run a single method to run an action on all of the sprites of the class?
Assuming you have an array called spriteArray containing all sprites you wish to rotate, it's as simple as:
for(CCSprite *sprite in spriteArray)
{
CCRotateAroundBy *rotateAround = [CCRotateAroundBy actionWithDuration:1.0 angle:90 rotationPoint:screenCenter];
[sprite runAction:rotateAround];
}

Stop body from moving. Chipmunk on iPhone

I have a cpBody with single cpShape that floats in my scene colliding with other bodies et c. How can I easily make this body stay in one place and act kind like a static obstacle staying in one place so it's not longer moving but still colliding with other bodies.
I just want to stop body from moving when user taps on it. That's why I'm asking. I'm not an expert in Chipmunk but I think it must be easy.
The way you'd do this with the public API is to remove the body and shape from the space. Create a new static body with the same position/rotation as the old dynamic body. Use cpShapeSetBody() to change the body to the new static one, and then readd the shape to the space.
You can call cpBodySetMass to INFINITY, and force the object to sleep with cpBodySleep. This is how a static object is implemented internally (at least about the mass).
EDIT
I am not sure whether you need to call cpBodySleep after this or not, but I don't think it hurts to call.
Modify cpBody.h and put #define CP_ALLOW_PRIVATE_ACCESS 1 at the beginning. Then from cpBody*, access ->node.idleTime and set it to INFINITY.
EDIT 2
The above solution is a working solution, but not very good in term of SE practice. It is better to define a function that makes the object static or dynamic so that you can call without disabling private property for the whole object.

Creating pointer Attributes in cocos2d iPhone

I am working on a game. There are balls that fall from the top of the screen, and the player has to catch them, as the are caught they stack ontop of one another. I have a method that creates each new ball and adds it to an Array that i use to move the sprites. Problem is that the after they collide I need them to stop moving, since the array is called on to move them they all move. And if i try to make them stop they all stop. So I was hoping to create a pointer attribute if ther is such a think, for example "sprite.position" I need a new attribute that i can check like a boolean. I was hoping to create a attribute like sprite.hasCollided and if it returns YES then the ball should no longer move. Is this possible or is there a better way to do it?
Thanks
Tanner
I would suggest you create a ball object. And add the boolean as as part of the object.
CCNodes (and, by inheritence, CCSprites) have a userData property, which is a void*. You can use this to relate a custom object to a cocos2d object. Keep in mind if you use the userData option, you will, in most cases, need to allocate any memory when you create/assign the sprite, and release it when you are done.
int* myInt = (int*)malloc(sizeof(int));
*myInt = 0;
sprite.userData = myInt;
//some time later, when you are done with the sprite
free(sprite.userData);
As an improvement on the userData property, you can do what xuanweng suggests and create a ball object containing various game-related properties for the balls, and assign an instance of this to each of your ball CCSprites using the method above.