How I can I delete sprites without obstructing the physics in SpriteKit? - objective-c

I want to make a game in which sprites fall from the sky and stack up on the floor, however when there is a lot of layers the camera will move up so you can continue playing. After a while more and more rows of sprites will become invisible as the camera moves up. I want to delete these unused sprite-nodes to keep the performance as good as possible. But when I delete the nodes at the bottom of the stack, won't the entire thing collapse? Or should I detect when the bottom row is unused and then turn off physics for the row above it so it wont fall down and won't affect the rows above it or something of that nature.
I haven't actually made any code yet, I just wanna have a good idea of what I'm doing before I start the wrong way.

Yeah I totally agree, you would really have to be clever about it. Well setting the background image coordinates and looping the background for a "continuous scroll effect" would be Step NO.1 Then using particle physics or actually rendering Nodes would be Step NO.2 The tricky part like you said would be getting the ones below the scene to be destroyed, but I think that if you try and set boundaries, and maybe an if statement that runs the destruction of the particles below the boundaries. So the particles fall down slowly pile up but as the scene scrolls upwards the particles will be destroyed when the their anchor point goes below the x,y boundaries you set and thus keeping those still visible in the scene alive... That would be my way of going about it.

Related

How to move the sprite with the movement of background?

I am working on a tilemap based game in cocos2d in which the player moves in four directions and I have used four images for the movement of player for example left,right,top and down. My problem is that when my background map change its position or move to other position then my sprite does not change its position. Can anyone tell me how to move a sprite with the movement of background.
Use a CCNode to contain both the background and the sprites for your players. Instead of moving the background, move that node.
There are a couple of ways to handle tilemap based games, and neither of them are very convenient. One way is to leave your character in the center of the screen at all times and move the background underneath it. If your character moves 'right', you simply slide the background to the left, and vice versa. This will give the illusion that the character moves around the map, when in reality it remains centered. Under this paradigm you must remember to convert all detection / collisions into the world's space, and not just the screen space. If you don't convert everything, then your 'range' of collision / detection is limited to the size of the screen.
The second method is to pan the camera over the world. You still keep the character in the middle of the screen, but it actually moves around in the world, and the camera follows. This makes the most intuitive sense to me because it allows you to view the game world as you see the real world. It is also much easier to deal with collisions because the position of the character and the world 'just work' and don't have to be converted. The downside here is that Cocos2D doesn't make it easy to use CCCamera, and the documentation is a little thin in that respect.
In your particular case, it sounds like you have a CCLayer problem. If your character is inside the layer you are moving, it will indeed remain in the same place relative to the map (as you are describing). Instead, float the character in a different layer on top of the map.
You could use a scrolling Parallex and then add the sprite onto the same layer as the background. They will move together.

Reduce overhead for sprite outside the screen

For my game I am working on a 2 player mode where the player can swipe left to see what the other player is doing. Effectively 2 iPhone screens.
My question is, are any sprites, particles outside the screen (I.e. for player 2) being rendered and processed as if they are on screen? If so, is there a way to get cocos2d to handle these differently so that they do not slow down the overall game performance? (fps)
The only way i know to lower overhead is to make the sprite.visible property NO, in which case the draw wont be computed at all. Off-screen sprites will be drawn if they are set as visible. Also, before making any 'FPS' related decision, make certain you verify what you get on real devices. You will find that the simulator falls very short, performance wise.
If you set the visible property to NO, it will indeed reduce overhead. If a sprite is outside the screen, it will still draw itself (so yes, you can set it to NO to reduce some overhead). But in any case, regardless of the visible property value, all sprites will still consume some memory and such.
If they have animations, they will keep on playing. You can unschedule those sprites and free some more processing.
A question I made regarding this visible property may help you: Does the .visible property affect performance?

CCParallax for a moving background

I got a tiled map and I want to make lava lakes. I wish to have some kind of lava texture image on the background looping diagonally slowly. I could make it with four 960x640 images and move all of them diagonally etc. But when I do, a black/white line appears between each...
... and someone suggested me "CCParallax". I have never used it and am not sure if it really can achieve the effect I am seeking.
Also note that as the player moves on the map, the parallax will need to simulate that as well etc.
So my question is, what would you do for this effect? Four looping images or "CCParallax"?
CCParallaxNode is pretty limited because you can't specify endless parallax scrolling without modifying the class. It also doesn't quite fit your use case.
Using four 960x640 images is wasteful. Just to make some lakes underneath the background this is overkill and will negatively affect performance.
The solution depends a bit on how big the lakes are. For example, if these are just 1 or 3x3 tiles in size you could add a textured sprite underneath each lake. If on the other hand your tilemap consists mostly of a few narrow pathways while the rest is lava lakes, then you need a different approach.
You might want to try GL_REPEAT to repeat a single sprite's texture over a defined area. That allows you to use a relatively small texture, for example 64x64, that will be repeated over the rectangle you specified.
You can then modify the sprite's position each frame to scroll the texture. Every time the sprite has moved 64 pixels in horizontal or vertical direction, you subtract 64 pixels (sprite.contentSize.width) from the sprite's position to reset it back to its original state. That means the sprite will never move further than 64 pixels from its initial position in any direction but you still get smooth scrolling.

How to code a random movement in limited area

I have a limited area (screen) populated with a few moving objects (3-20 of them, so it's not like 10.000 :). Those objects should be moving with a constant speed and into random direction. But, there are a few limitation to it:
objects shouldn't exit the area - so if it's close to the edge, it should move away from it
objects shouldn't bump onto each other - so when one is close to another one it should move away (but not get too close to different one).
On the image below I have marked the allowed moves in this situation - for example object D shouldn't move straight up, as it would bring it to the "wall".
What I would like to have is a way to move them (one by one). Is there any simple way to achieve it, without too much calculations?
The density of objects in the area would be rather low.
There are a number of ways you might programmatically enforce your desired behavior, given that you have such a small number of objects. However, I'm going to suggest something slightly different.
What if you ran the whole thing as a physics simulation? For instance, you could set up a Box2D world with no gravity, no friction, and perfectly elastic collisions. You could model your enclosed region and populate it with objects that are proportionally larger than their on-screen counterparts so that the on-screen versions never get too close to each other (because the underlying objects in the physics simulation will collide and change direction before that can happen), and assign each object a random initial position and velocity.
Then all you have to do is step the physics simulation, and map its current state into your UI. All the tricky stuff is handled for you, and the result will probably be more believable/realistic than what you would get by trying to come up with your own movement algorithm (or if you wanted it to appear more random and less believable, you could also just periodically apply a random impulse to a random object to keep things changing unpredictably).
You can use the hitTest: method of UIView
UIView* touchedView=[self.superview hitTest:currentOrigin withEvent:nil];
In This method you have to pass the current origin of the ball and in second argument you can pass nil.
that method will return the view with which the ball is hited.
If there is any hit view you just change the direction of the ball.
for border you can set the condition for the frame of the ball if the ball go out of the boundary just change the direction of the ball.

How to set/corrent the resting position of UIScrollView contents after it has scrolled

I am implementing a view similar to a Table View which contains rows of data. What I am trying to do is that after scrolling, each row snaps to a set of correct positions so the boundaries of the top and bottom row are completely visible - and not trimmed as it normally happens. Is there a way to get the scroll destination before the scrolling starts? This way I will be able to correct the final y-position, for example, in multiples of row height.
I asked the same question a couple of weeks ago.
There is definitely no public API to determine the final resting Y offset of a scroll deceleration. After researching it further, I wasn't able to figure out Apple's formula for how they manage deceleration. I gathered a bunch of data from scrolling events, recording the beginning velocity and how far the deceleration traveled, and from that made some rough estimates of where it was likely to stop.
My goal was to predict well in advance where it would stop, and to convert the deceleration into a specific move to an offset. The problem with this technique is that scrollRectToVisible:animated: always occurs over a set period of time, so instead of the velocity the user expects from a flick gesture, it's either much faster or much slower, depending on the strength of the flick.
Another choice is to observe the deceleration and wait until it slows down to some threshold, then call scrollRectToVisible:animated:, but even this is difficult to get "just right."
A third choice is to wait until the deceleration completes on its own, check to see if it happened to stop at your desired offset multiple, and then adjust if not. I don't care for this personally, as you either coast to a stop and then speed up or coast to a stop and reverse direction.