Stop body from moving. Chipmunk on iPhone - 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.

Related

Instantiating object with physics on Canvas

I've been trying to instantiate simple object on my canvas that would show added score value with some small visual and then fall down with gravity for a while before disappearing.
I Cant in any way make it visible as UI element.
It is spawning at ridicolous position where canvas objects are physically. and even if i instantiate it as a child of my Ui element it has RectTransform but is not visible by camera as Ui element.
in my script "scoreValue" is ui element under which i'd want it to be instantiated,scoreVisualisationSpawnPoint is normal object with trasnform position i used earlier.
How to instantiate object on canvas at certain position in canvas for it to be visible?
Here is my not-working code:
public void CreateAddScoreVisualisation(int addedScore)
{
GameObject effect;
effect = Instantiate(addScoreVisialisation, scoreVisualisationSpawnPoint, scoreValue.transform.rotation,scoreValue.transform);
effect.GetComponent<RectTransform>().position = scoreValue.rectTransform.position;
effect.GetComponent<ScoreVisualisation>().scoreText.text = addedScore.ToString();
}
That can be tricky at times, but are you sure this is the right approach at all?
I'd suggest have your object permanently there so you can set it up as you wish with the inspector and then in the start function, call gameObject.SetActive(false) to disable it.
Then instead of instantiating, activate it.
This will also be more performant by the way because small, inactive objects don't cost much but instantiating and destroying is relatively expensive.

How to duplicate a sprite in sprite kit and have them behave differently

I've been working on a IOS mobile game and I wanted to take an object,duplicate it, and have the copies move all over the screen. I've looked through Google to find things relevant to this but they were all in Objective C or just didn't have what I was looking for. I want to know how to do this in Swift and SpriteKit.
If you are working with SKSpriteNode you can copy it and all it's current properties with:
let copiedNode = nodeToCopy.copy() as! SKSpriteNode
You will still need need to add copiedNode to your scene. copiedNode will also continue to run any actions that nodeToCopy was running. You can cancel them with copiedNode.removeAllActions().
Note that the documentation for the protocol NSCopying reads exactly:
Protocol
NSCopying
A protocol that objects adopt to provide functional
copies of themselves.
The exact meaning of “copy” can vary from class to class, but a copy
must be a functionally independent object with values identical to the
original at the time the copy was made...
Indeed, in the case of SKSpriteNode, Apple have interpreted that idea so that the copy() function "spawns" another instance of the item, exactly as in any game engine.
(So, for SKSpriteNode copy() works identically to the sense of Instantiate in Unity, say.)
As mogelbuster points out below, there is nowhere in the Apple documentation that they state "The spawn command in Apple is copy()" but in fact they have interpreted this "The exact meaning of “copy” can vary from class to class" in exactly that way for SKNode, since indeed it's a game engine and it's the only meaningful sense of copy there.
It's worth noting that the most completely typical way to work in games is: for your say rocketShips, you would have one "model" of your rocketShip, say modelRocketShip. The model simply sits offscreen, or is perhaps marked as invisible or inactive. You never use the model in the game, it just sits there. When you spawn rocketShips, you just dupe the model. (So in Apple that's modelRocketShip.copy() and then set the position etc.)
You can define a function to create and return a sprite :
func createSprite()->SKSpriteNode{
let sprite = SKSpriteNode(...)//Use the init function in the SKSpriteNode class
//Add some code to define the sprite's property
return sprite
}
And call this function to get some sprites that have the same property:
let spriteOne = createSprite()
let spriteTwo = createSprite()
Then you can add different SKActions to each of them so that they can behave differently.
Once you have multiple SKSpriteNodes, you can also control them by using EnumerateChildNodesWithName (assuming all your nodes have the same name) to go through all of them do do what you want in the update() function.
On a more advanced level, you could subclass SKSpriteNode and incorporate your own behaviour in your custom class.

how to remove a UIView from the collision behavior in swift

I have been programming a Break Out app for my swift class and I have been able to figure out everything except for how to remove one of the top paddles from the collision behavior. If someone could tell me how to remove something from the collisionBehavior's array of items, that would be great. Thank you.
Set the dynamic flag to false?
The default value is YES. If the value is NO, the physics body ignores all forces and impulses applied to it. This property is ignored on edge-based bodies; they are automatically static.
SKPhysicsBody Class Reference

Box2D and wrapping worlds

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?

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.