Handling very fast moving objects in Sprite Kit - ios

I have an object that is moving very fast (max velocity 900). When it reaches max speed it starts to create trailing objects or motion blur.
But I just want it to be the object moving fast. I am running on 60 fps.
I like the speed of the object but I don't like how its getting rendered (motion blur). How do I handle this?
This object bounces all around the screen with a restitution of 1.02, because I want to make it pick up speed as it keeps bouncing. I want to make it go faster thats why I did the 1.02 restitution.

The motion blur may simply be due to the LCD display having an "afterglow". So the position the object was in the previous frame is still a little brighter in the next frame because it takes some time for the crystals inside the LCD to return to the unlit state.
This causes "motion blur" on any moving object on the screen, and is of course more noticeable the faster the object moves. You may even be able to make out multiple versions of the same objects at different light levels trailing behind the object's position.
This effect may also depend somewhat on the device and model, and is often called 'ghosting'.
Regardless, there's nothing you can do about the "motion blur" caused by the LCD screen's afterglow effect. Here's a good article explaining the effects and their causes.

Hmm... you'll have trouble getting it to render smoothly.
At that speed (900 points per second) it will move 15 points every FRAME if running at 60 fps. That's a significant amount to move in such a short amount of time. In about 1/3 of a second it will travel entirely across the screen.
I'm guessing it will be getting to the limit of the ability of the hardware. Both the processor, the screen and your actual eyes. I imagine you'll also hit physics errors too with it possibly escaping through walls etc...
Can you show a video of how it is currently behaving?

Related

Wierd gaps appearing in between SKSpriteNode - swift

Note: I have tried this answer: Gap between SKSpriteNodes in SpriteKit collision detection
I am getting gaps in between my SKSpriteNodes, after 5 minutes of letting my game run. Here is my code to make the node:
let tileNode = SKSpriteNode(imageNamed: "world1Tile\(tileNumber).png")
tileNode.position.x = x
tileNode.position.y = y
tileNode.size.width = 128
tileNode.size.height = 128
tileNode.zPosition = 10
tileNode.physicsBody = SKPhysicsBody(rectangleOf: tileNode.size)
tileNode.physicsBody!.isDynamic = false
tileNode.physicsBody!.restitution = 0
tileNode.physicsBody!.allowsRotation = false
tileNode.name = "Tile"
row.append(tileNode)
When I remove the physics body, it is running fine. Here is are some images to show you what I mean:
This image has a physics body, and was taken after immediately after running the app.
This image was taken 5 minutes after running the app.
Why is this happening? I assume it has something to do with the physics body, because my app looks exactly like the first picture, even an hour after running the app if there is no physics body. What physics body property should I change to stop this from happening? Any help would be appreciated.
I had a similar issue not too long ago, where gaps were appearing between nodes that were tiled (although I didn't use physics). Based on this answer, I found that if you want perfect alignment between nodes, it is best to ensure that the positions of nodes as well as the nodes' width and height are whole numbers.
I would suggest to round-off the x and y values of the position of tileNode and see if it will make any difference .
I'm guessing there is no gap. you probably have 'showPhysics' to true in your gameviewcontroller, and the line appears as a gap to me.
compare position with and without the pb to verify.
I had similar problem where gaps between sprites started appearing after around 5 minutes of scrolling with constant speed (game with infinite scroll). I did not use physics and I even had all positions, widths, heights rounded to integer value. I was scrolling the camera and adding new sprites one right after another and everything was working fine except after around 5 minutes of that infinite scrolling gaps begin to appear just as in your case. I spent some time in looking for a solution and it turned out that the problem was that when positions of my objects were becoming big that is in my case X position in the scene was around 150000 then those gaps started to appear and also I noticed that this problem occurred only on devices which had to scale the scene. I was using aspect fill with default scene size for iPhone 6 resolution and those gaps only appeared on iPhone 5 but on iPhone 6 I did not notice them. I was able to fix that issue by subtracting some constant value from X position of all objects (including camera position) from time to time so that everything on the scene relatively did not change position to the camera and look the same but actually absolute positions were changed to keep them low. I guess that larger position values like 150000 and scene scaling cause some floating point rounding issue in SpriteKit and that is why gaps are then becoming visible.
So based on my experience if you have similar gaps I recommend using integer values for all positions, widths, heights and additionally keep values of objects positions of all objects low.
For future reference in case someone is still searching for this, here are my experiences:
If tiles have PhysicsBodies, they are prone to making gaps. A solution for me was making a blank SKNode as a child of the tile, and assigning the PhysicsBody to that.
If possible, make sure bit masks are set in a way that tiles can't collide with each other.
As stated in a previous answer, make sure all measurements are integers and rounded in a way that doesn't leave a one unit gap between them.
A related problem is also SpriteKit's PhysicsBody drifting. There are some threads about this (e.g. https://forums.developer.apple.com/thread/27057 ), and it seems to be abug. In my case, the problem was a combination of PhysicsBodies causing random small gaps, and the drifting making some of them larger. The steps above removed the small gaps. Unfortunately the only workaround for the drifting problem in my case was to only generate PhysicsBodies for nodes that are within a certain distance from the player and destroying them after they are left behind.
For future reference for anyone who needs, I found an different answer specific to my problem. As JohnV said, I may need to round of values when setting the position, but when running the code, I found out that I also need to do that when running SKActions.

SpriteKit Animation - Keeping Sprites Fixed

I am animating some frames of a monster jumping and swinging a sword, and the frames are such that the width gets bigger or smaller as he swings the sword (the monster standing is 500 width, but his sword, fully extended to the left, adds another 200 width, thus he varies from 500 to 700 or more in width)
I originally took each frame, which is on a transparent background, and used the Photoshop magic wand tool to select just the monster. I then saved these frames like that, and when I used them to animate, the monster warped and changed sizes (it looked bad).
The original frames had a large 1000 x 1000 transparent background surrounding him, and as a result it always kept him "bound" so that it never warped.
My question is what is a good way to create frames of animation where the sprite inside might change size or width as he's moving so that there is no warping?
If I have to use a large border of transparent pixels, is that the recommended approach? I'm noticing that for my animation, each monster takes up about 3 - 5MB. I plan on potentially having a lot of these people ultimately, so i'm wondering if this is the best approach (using large 900 x 900 images all the time, plus I'll be using more for 2x and 1x). So all of this seems like it could spiral out of control to 4 or 5GB.
What are other people doing when making animations that require different poses and positions? Just fixing the frames with borders that are as small as possible?
Thanks!
You should probably change the approach to animation and use inverse kinematics instead. Take a look at this and Ray's tutorial.

Why does SpriteKit physics performance seem to depend on what's rendered on the 1st frame?

This is something I've been struggling with for a while now, and I'm really hoping someone can shed some light on the issue. Basically, I have a scene with a bunch of colliding SKPhysicsBodies. If I put the camera in the middle of the action on the very first frame of animation, the entire simulation runs at about 17fps indefinitely. However, if on the very first frame of animation I start the camera off-screen such that nothing (or very little) is drawn that first frame, and then move the camera to the middle of the action on the 2nd frame, then the simulation runs at 60fps.
The simulation is exactly the same in both cases. Nothing is different other than what sprites are culled on the very first frame, yet that seems to make all the difference for the rest of the simulation's performance.
This has proven 100% reproducible in every case I come up with, so in order to make sure that my game runs at 60fps, I have to "prime" the camera by starting it way, way off-screen, render a frame, and then move the camera to where I really want it to be. If I don't do that, the game runs at a cripplingly low frame rate and will never speed up.

Menu from the Contre Jour app

I'm trying to do a menu like the one that "Contre Jour" game has, with 3 elements spinning in a circle when user drags left and right. I'm using CALayers with CATransforms to position them in a 3d spinning wheel (no problem so far).
I need a way (maybe with NSTimers?) to calculate in-between values, because CoreAnimation just interpolates values, but if you NSLog them, it's just gonna show the start and the end, or just the end. I need all the in-between values, I need to snap the wheel movement when I release the finger (touches ends)in one position (there are 3 elements, each one shoud be at 120 degrees.
My guess and am quite sure I'm correct is that they are using a game engine such as Unity3D or Cocos2D or any other of the many to manage their sprites, animations, textures, physics and basically everything. Trying to replicate it outside of game engine will most likely result in crummy performance and a lot of hair pulling. I would suggest looking into a dedicated game engine and give it a shot there.
I am not sure I understand exactly what Contre Jour does with the spinners, anyway, I think that a reasonable approach for your case is using a UIPanGestureRecognizers to update the status of your spinning wheels according to the panning.
Now, it is not clear what you do to animate the spinning wheel (if you could provide some code, this would help understanding exactly what you are trying to do), but the idea would be this: instead of specifying an animation ending point far away from the starting point (and letting Core Animation do all the handling for you, even when the dragging has stopped), you would only modify the status of the spinning wheel in small increments.
If your only issue is stopping the animation when the dragging stops, you could try calling removeAnimationForKey on your layer to halt a specific animation.
Look into CADisplayLink. This works very much like an NSTimer, except its refresh rate is tied to that of the display, so your animations will be smoother than if you were to use timers. This will allow you to calculate all the in-between values and update your control.
I'm not clear what you are asking, but I do have one insight for you: To get the in-between values of an in-flight animation, query the layer's presentationLayer property. the property that's being animated will have a value that's a close approximation of it's on-screen appearance at the moment you fetch the value.

Cocos 2D - Moving Sprites on a tiled map

I'm trying to move a sprite around a CCTMXMap in a smooth fashion. I've figured out how (using CCActions) to move from tile to tile, but I get gaps in my animation (it pauses for a frame while it reevaluates which direction to walk). I've tried moving the character in a scheduled update: method, but that gets messy when you try and restrict the sprite to only moving from tile to tile. Any suggestions on how to get the clean, consistent animation without messy manual animation using update?
Yes, don't use actions. You'll always have the 1-frame delay problem when using CCActions.
Moving the sprite in update is really pretty simple. Especially if you restrict movement to a speed (points per frame) that is clearly divisible by the tile size. For example if your tiles are 40x30, then horizontal speeds of 1,2,4,8,10 would work fine. Vertically 1,2,3,5,6,10 would work.
Update the position by this number, cast it down to int, compare it with the destination location:
if ((int)currentPos.x == (int)targetPos.x && (int)currentPos.y == (int)targetPos.y)
{
NSLog(#"I'm there!");
}
The reason for casting to int is to avoid rounding errors in floating point values.
Another solution would be - especially if your character can only move in one direction at a time - to figure out the number of frames it will take him to get there. If the character has to move 40 points to the right, and he moves at 4 points per frame, it'll take him 10 frames. Then just count the number of frames (how many times the update method ran) and if it reaches 10 (or 0 if you count down) then you know that the character has arrived without needing to check his position.

Resources