Menu from the Contre Jour app - ios

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.

Related

Draw circle and drag touch around SKSpriteNode

I am making a Sprite Kit game where the player (basically a stickman) has a running animation and a parallax scrolling background.
Now I have enemies that come near my player. To destroy these enemies sometimes I have to touch the enemies node to launch a rocket or attack them with an attack button or just jump over them.
Everything is working fine, but I want to add some extra moves to destroy them. I want some enemies that you can just destroy if you have drawn a whole circle around them. So imagine they come and you make a circle and then my player launch a laser or something. The problem is I have no idea where to start.
I haven't found anything on the internet. If it's too complicated or almost impossible how about touching my player node and dragging to the enemy?
EDIT: I think I have to create a custom GestureRecognizer that recognizes if a circle is drawn around a sprite and then runs the code. I don't know how this works ?
Yes, it's too complex. Not just from a coding point of view, but also from that of the player's experience.
Anything that requires complex gestures over a large amount of glass is annoying for the player because they're never going to have the same experience. Their finger's moisture and oil content always changes, as does the ambient temperature and cleanliness of their screen.
So big gestures required to be performed quickly (a gaming input like this) will sometimes be fun and smooth, and other times degrade as an experience based on the nature of the above properties.
Best to avoid them for a game's best possible experience.
If you must do it, there's two ways to research how.
Seek out "custom gesture" creation and utilisation through documentation and google, etc.
Think about using some kind of array to store all the points where the player's finger moves through during that circle gesture and attempt to discern if an enemy is within that space and then act accordingly.
--- probably other ways, too. But these jump to mind.

Moving the scene: SKAction animation or anchorPoint in update method?

My game is based on two screens (A & B) side by side, but the device screen can only display one of them at a time.
A is for example at position (0, 0) and B is at (320, 0)
I tried two solutions to switch from A to B:
First, I place the whole scene into one node, the MainNode. To switch
from A to B, simply set MainNode position to (0, -320).
Other solution, more elegant IMHO (but not for LearnCoco2D who uses the Coco2D library), is to move the scene anchorPoint to (0, -1)
Now, if I want to go from A to B with an animation, these two solutions must be adapted:
By using a SKAction
[Main runAction:[SKAction moveToY:-320 duration:0.1]];
By animating anchorPoint in the update method
if(anchorY > -1) anchorY -= 0.1;
These two solutions works (despite a linear SKAction::timingMode does not render a linear translation properly), but I wonder which is the best in term of optimization, and elegance. Documentation is welcomed ;)
EDIT:
Apparently, my question is not clear (maybe due to my english level).
In few words, my question is: What exactly are the best practices for scrolling a scene?
I am surprised (0, -1) doesn't throw a huge exception. According to the docs you get a range from 0 to 1. This could cause issues in the future. See the docs here
Changing your position sounds like a more elegant way of handling it. however changing it to negative -320 in a span of 1/10th of a second is rather quick and could explain why it looks funny. Also if you aren't making sure you are only calling that once it will look really odd. I would make sure that it is only getting called once and maybe using a bool to toggle if it should be moved instead of checking a position.
If you are going back and forth a lot from one screen to another this might be an ok solution. However if you are looking to scale this to a much larger map where you are going to transition several times to new screens I would recommend a different approach all together. Like creating a new node off screen when you need it and transition a parent node then pop the old node off.
I hope that helps.
Edit
Now that the question is "what exactly are the best practices for scrolling a scene".
I would recommend what LearnCoco2D mentioned in the comment and what I eluded to in my original answer.
Add a sub node to your scene that will handle positioning (lets call it mapNode)
Add any sprites that represent the scene to the mapNode
Move just the MapNode position on update
In the past I have built my Scenes in a similar fashion and have handled the scene position based on the player position in the update loop. I was able to keep the player in the center of the screen as he walked around the map. Might be getting off subject, but that is what I found the best practice for handling scrolling a scene from my experience. The project I am working on can be viewed here
I hope that answers your question.

Handling very fast moving objects in Sprite Kit

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?

handling finger detection on small objects

The application I am working on requires a 4px bar height with a full screen size width. I need to be able to select this 4px bar and move it around. I also can not change the size of this bar it has to be 4px in height.
This wouldn't be that big of an issue if I wasn't using OpenGL to create the object. OpenGL obviously does not have its own selection features so I am needing to program my own.
Initially after research I built a color selector to identify the object. How my color selector works is what ever x and y my finger touch returns from touchesBegan: is the pixel I grab from a screenshot of the OpenGL View. The issue with this is finger location is not precise at all. If I use the mouse it works perfect...
I decided to maybe loop through a buffer zone of the selected x and y but unfortunately a screenshot of the OpenGL view has antialiasing happens to the image when it's stored in memory and the buffer returns several shade of my objects color. I could possibly do a comparative color look up, to see if its in the range of colors but that seems overly complicated with how much I have already had to do. Plus cycling through the buffer zone isn't quick.
I also have thought maybe just remembering the location of my line on the screen and if my finger is close to that location just know that that's the one I want to select and move it around.
The future of this application can have up to 4 lines just like this so, I want something more secure then just knowing the location of where it is in memory.
What better way is there out there of handling selection of small objects?
How about maintaining an array of frames for the four objects, but expand the heights to something more manageable (8px or bigger)? Then, a touch within the larger region could be compared against the array (using CGRectContainsPoint). If you get a hit, then "snap to" the center point of the smaller (4px) rectangle before beginning the drag.
I do something like this by maintaining a list of "drop targets" for drag & drop, where it snaps to the drop target when it gets pretty close. Don't know if I'm conveying the idea very well, but it ought to work.
If the four 4px rectangles are going to be contiguous or very close together, you'll have to be able to make the selected one stand out or the user won't be able to tell which they're dragging -- but you could do that by making it bigger (maybe 6-8 px) then bringing it to the front so it overlays its adjacent neighbors.
More of an idea than an answer I guess.
John,
I would suggest a different approach. As you've discovered, touches in iOS are very imprecise. Apple usually suggests that the "hit box" for your controls be at least 40x40 points. I've gone as small as 30x30 points, but that starts to get hard.
What I would suggest you do is to factor your code so the app knows where the line is, and keeps track of it as a logical object. Then in your touch handler, interpret touches based on a large "buffer area" around the things you want the user to be able to move. If you just have a single horizontal bar, this should work great. Where you'll get into trouble is if you have multiple, thin horizontal bars that are close together. In that case you might need to rethink your app design and find another way to solve the problem.
As for the implementation details, you might add a pan gesture recognizer to your OpenGL view, and have it notify the OpenGL view of touch and drag actions. Then your OpenGL view can use knowledge of where your draggable objects are to decide how to interpret the touches.

Quartz2D good way to Draw point or line on touch?

I'm trying to develop an app that requires drawing based on user touch. I'm using Quartz2D and CoreGraphics for drawing, now I'm wondering what's a good way to manage the points that i'm drawing? Currently I'm adding each touchMoved point to an array and setNeedsDisplay them on every move. This lags the system very fast. So Therefore I'm wondering if anyone know a good way to draw smoothly with user touch for a good amount of time? Thanks!
Touch events are fired very frequently. since quartz2d is slow your system will saturate.
several options
Switch to opengl ^^ (bu that is an overkill)
don't do a draw on every single event. put you touch to sleep (acutally thats an android soluiton so I'm not sure its good for Iphone), only draw 1 out of x lines.
store the coordinates of your touch somewhere and when your app is ready to refresh the ui, get the current values stored and do you draw.
another solution I had put in place is to test if the new position had actually moved of more that a certain amount from the las draw (lets say 1~3 px) this way I avoid refreshing and redrawing if the updated position was to small.
This are just pointers, there might be a better option for you case ^^

Resources