Im trying to create an explosion that when a certain object is hit, objects in the nearby radius also get destroyed. For example, in a brick breaker game, the ball hits a brick and then the brick explodes but also explodes 2 bricks in every direction as well. How can this be accomplished? Any help is appreciated.
There are lots of ways to do this, but the spritekit way is to create a blast sprite node. You can animate it as needed with SKAction and use the same SpriteKit Physics Contact logic as with other sprites.
Add a physics contact category bit mask for the blast nodes.
When an event occurs that should create the blast, call a method that creates a blast node at the point of the event.
Set the blast node position to the point.
Add any actions to the blast node.
Add the blast node to the scene.
Its actions will run.
In the physics contact delegate method, didBeginContact: you test for for contact with any nodes of categories that should react to contacting the blast node.
If contact is made, basic thing is to tell the contacted node to removeFromeParent.
Once you have that working, you can get fancy.
Your blast node should probably get a physics body of a circle based on a CGPath.
You should probably experiment with actions that scale it up and down.
You can get more sophisticated by adding actions that provide animation, sound etc to the destruction of the other nodes, prior to removing them.
If they are custom subclasses, it's a good time for a protocol that defines the method name to be blown up and removed. Then have each class implement that.
Sounds like work but keeps your game logic code clean.
This overall process is going to be common and one you will get familiar with.
Related
I have a sprite hanging from a rope in SpriteKit. I have the rope pinned to an object I'd like to slide back and fourth (to simulate the rope being attached to a track or conveyor belt). Imagine clothes hanging on the revolving rack of a dry cleaners store. Similar to that!
Anyway, I can't figure out the proper way to move my rope as if it its connected to the track.
Pinning the rope to another (track) object and moving that track object doesn't seem to work. I can't apply move actions to a sprite that has physics (without the simulation getting all messed up).
I've also tried adjusting the track objects velocity directly to (2,0) in the update method (Including all the other update callbacks SpriteKit surfaces). The only problem is the weight of the rope and attached object eventually pull the track object down. I think this happens because didSimulatePhysics happens no matter what.
Any suggestions on how to move my sprite on a rope along a track?
Thanks in advance!
So in my Space Invaders game, all collisions were working perfectly until I added a physics body created from a edgeChainFromPath which is a single line to represent the ground (an SKShapeNode created from 2 points). Now my invader bombs (which move via SKAction) notify when they hit the ground but my invaders (moved in update() by manually updating their positions) do not. My ship missiles (also moved by SKAction) DO notify when contacting an invader.
Question : if a physicsBody is moved manually and comes into contact with another physicsBody, is didBeginContact not called? (All physics interactions - bitMasks, delegates etc - are set correctly). I'm thinking the answer is 'No it's not' because that's the only explanation and makes sense picturing how Sprite/Kit probably works. I.e. A contact occurs when the SK engine itself moves a node and realises that it's physicsBody is being drawn on top of another physicsBody.
Edit - just realised that I have other physicsBodies in my scene that are stationary and that the invaders DO collide with, so it's not an SKAction thing. The difference might be that the new node I've added is an edge-based body belonging to an SKShapeNode, rather than a volume-based body for a SKSPriteNode, but nothing in the documentation that I can find states that this shouldn't work.
New question : Do volume-based bodies being moved manually not collide with stationary edge-based bodies?
Ok - my bad. The invaders' physicsBodies had dynamic=false. Every other sprite was dynamic, so all other collisions were working. My new shape was an edge-based body which also are dynamic=false.
Made that one change and all is Ok. I need to update my checkPhysics() routine to test for this.
Edit: I really should have seen this earlier - checkPhysics() was not printing that invader notifies when contacting ground, which I just put down to a glitch that I'd fix later. Whereas checkPhysics() deliberately doesn't report on nodes with dynamic=false. I think that when I wrote the function, I assumed that you'd set dynamic=false deliberately to not be involved in collision/contact detection. I should change it to print a warning.
The context:
In my SKScene I have:
1) a few sprites with no physics controlled by touch using touchesMoved: which instantly changes sprite position property based on touch location,
2) one sprite that while colliding with the others changes its physicsBody.velocity instantly.
That's all - no other fancy processing.
The issue:
I found occasional and random stuttering all of the sprites independently without any FPS dropping.
The questions:
In the context of my performance issue:
1) Is there any reason to update sprite position or velocity in update: method rather than update them instantly?
2) Is there any sense to use SKAction rather than changing directly position or velocity property?
3) If 2 then can make any difference running SKActions instantly or run them in update: method?
Apple says about
update:
method:
This is the primary place to implement your own in-game simulation, including input handling, artificial intelligence, game scripting, and other similar game logic. Often, you use this method to make changes to nodes or to run actions on nodes.
but nothing more like "must,..." or "should, because...".
4) Isn't SpriteKit done like all the changes made to the nodes instantly are processed in respective loop update phase or do I have always go to the appropriate loop method to make/fire changes there to avoid any rendering performance loss or interference?
I am trying to make a game with SpriteKit where the main character shoots a 'rope' and swings through the level (Think spiderman-ish). I have no problem making the rope and having it attached to the player and different sprites but I don't really know how to go about the 'shooting' part.
My current rope is built similar to this (https://www.youtube.com/watch?v=7jWdcbmnmKQ&hd=1) where I have several separate parts connected using SKPhysicsJointPin. I have tried several different approaches to shoot the rope, both with applyImpulse/Force and SKActions, but none works smoothly.
To sum it up:
- What is best practice for creating a rope that can extend in a specific direction?
I'm fine with just general pointers in the right direction since this is all to learn and I don't think I really need completed code for it.
General pointer:
Shoot a physics body in the way you need it to "fly" (the bullet)
In didSimulatePhysics assign the bullet's position to the rope's first node
In theory this should extend the rope while shooting, without affecting the trajectory of the bullet.
You may need to add more rope segments as the distance between the bullet and the weapon/player increases, otherwise the rope may be huddled too tightly together at the start of the bullet's flight path, causing physics to behave unexpectedly. Though adding rope segments in-flight may cause issues in its own right.
One solution could be to disable physics for the rope until a certain distance has been reached or the bullet "hit" something. Until then the rope could be considered a straight line and rope segment nodes positioned accordingly along a straight line between bullet and weapon.
Instead of using the physics engine to move your extending rope (applyImpulse), try moving the rope's end in a straight line at a fixed speed until it hits a target. Just a thought!
The game I'm designing uses multiple nested CCSprites, so that when the parent sprite moves, rotates, scales, etc. the child sprite does as well, automatically, and so do its grandchildren.
It works great but bogs down very quickly since I haven't implemented batch nodes, currently it's making over 4000 draw calls at once which is obviously not optimal.
However as far as I know the only way to use batch nodes is to make all the sprites a child of the batch node. I thought maybe I could add each parent to the batch node and then add the rest as children of that one but that doesn't work.
Any ideas? I'd like to avoid having to manually calculate the position, rotation, scale, etc of each child sprite every time its parent moves, which at the moment seems to be the only way I can think of to make this work.
Looks like you CAN in fact nest children inside a ccsprite and have them be a part of the batch node, as long as the parent is a child of the batch node. When I first tried this I'd simply forgotten to change "spriteWithFile:" to "spriteWithSpriteFrameName:" when I created the children of one of the sprites. Now it works perfetly, all in one batch node, with one draw call. Hooray!