"Collision Map" in SpriteKit [closed] - ios

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I'm building a 2D game using SpriteKit and this is what I would like to achieve.
Imagine a vertically scrolling SKSpriteNode which represents a tall building. Building is represented using simple image and has a physics body set with + (SKPhysicsBody *)bodyWithTexture:(SKTexture*)texture size:(CGSize)size; (introduced with iOS 8) so it is closely following the building's path.
Some parts of the building are special. Colliding with those parts should be yielding a special collision action. For example, touching the wall of the building would fire an action 1 but touching any of the windows would fire an action 2.
What I haven't been able to do is in some way define those "special blocks" of the building.
I was thinking about making some kind of a "Collision Map" for each of the building's sprite images which would be basically a transparent image with non-transparent blocks determining a collideable parts of the building. Simple example shown bellow (left: building image, right: collision map image):
The problem with this approach is that when setting a SKPhysicsBody on a "Collision Map" image like the one above, the body is not applied to all blocks but it wraps around just one of those separate blocks. In other words: one physics body can be applied to only one, continuous block in image.
To conclude, I would like to know which approach are you using when determining non-continuous collision maps.
P.s.: building's SKSpriteNode is represented with multiple unique texture images which are scrolling vertically, one after another.
Thank you in advance.

Just an idea:
Can't you use two Sprites for the building which are positioned at the same place:
- one represents the physics body of your building (the left one from your image)
- invert your collision map image to get a single physics body block. The special areas should overlap the non special area by one pixel
Hope you understood what I mean. It's just an idea

Related

iOS: How to partially change the color of text [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I was playing with iOS built-in Compass app and the UI do make me curious.
Here is the interesting part:
The color of text (even the circle) can be partially and dynamically changed.
I have made a lot of search, but the results are all about attributed string. How to implement the effect like this?
Edited:
I have tried to add two UILabels (whiteLabel and blackLabel) as whitelabel at the bottom and blackLabel at the top with the same frame. Then I set the circle as the mask of blackLabel.
The problem is 'whiteLabel' is totally covered by blackLabel, and if the circle do not intersect with 'blackLabel', both labels are not visible.
I imagine that there are two "14" labels in the same place. The bottom one is white and unmasked, and the top one is black and has a layer mask that contains two circles, so it's only visible where the circles are.
Achieving this has most probably nothing to do with NSAttributedStrings, like Woodstock said.
I'd say it's the UILabel's layer that is recolored live, depending on what other layer it intersects with, and the overlaying area of said intersection.
Once you figure those common points, you just apply a mask that inverts colors from there.
Now it's a little bit more complicated than that since there appears to be two circles (hence two layers to find intersections with), but in the end, it's "just a list of coordinates" that the label's coordinates intersects or not.
That could be an interesting exercise ; it would probably take me a decent amount of tries to mimic that behaviour, but I'm pretty confident my reasoning is on point. (get it? :o)

How can I throw in sprites from both sides of the screen in Swift? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I am trying to apply a sort of impulse onto a sprite and have it thrown onto the screen from the side. However, when it is after the screen I want the impulse to stop and for the regular physics to be applied to it, so I would be able to drag it around. Its difficult to explain but if anyone can help out it would be very much appreciated. Thanks!
Apple docs show that a we can influence the physicsBody of a sprite with these instance methods:
- applyForce:
- applyTorque:
- applyForce:atPoint:
- applyImpulse:
- applyAngularImpulse:
- applyImpulse:atPoint:
As for "throwing it on the screen from the side", you can have the sprite spawn outside your current skViews bounds, and have the force be applied to it accordingly (if the sprite is located outside the north side of the screen, you'll want to applyImpulse downward).
With respect to "regular physics" upon entrance of the skView, you can have a check in update:(CFTimeInterval)currentTime for those types of sprites entering the skViews frame OR define a protocol within your sprite's class, and have your SKScene subclass conform to that protocol; then have your sprite fire a method when entering a certain frame (skView.frame), which your SKScene will be able to respond to. You can then apply counter forces or impulses to that sprite.

Interact with complex figure in iOS

I need to be able to interact with a representation of a cilinder that has many different parts in it. When the users taps over on of the small rectangles, I need to display a popover related to the specific piece (form).
The next image demonstrates a realistic 3d approach. But, I repeat, I need to solve the problem, the 3d is NOT required (would be really cool though). A representation that complies the functional needs will suffice.
The info about the parts to make the drawing comes from an API (size, position, etc)
I dont need it to be realistic really. The simplest aproximation would be to show a cilinder in a 2d representation, like a rectangle made out of interactable small rectangles.
So, as I mentioned, I think there are (as I see it) two opposite approaches: Realistic or Simplified
Is there a way to achieve a nice solution in the middle? What libraries, components, frameworks that I should look into?
My research has led me to SceneKit, but I still dont know if I will be able to interact with it. Interaction is a very important part as I need to display a popover when the user taps on any small rectangle over the cylinder.
Thanks
You don't need any special frameworks to achieve an interaction like this. This effect can be achieved with standard UIKit and UIView and a little trigonometry. You can actually draw exactly your example image using 2D math and drawing. My answer is not an exact formula but involves thinking about how the shapes are defined and break the problem down into manageable steps.
A cylinder can be defined by two offset circles representing the end pieces, connected at their radii. I will use an orthographic projection meaning the cylinder doesn't appear smaller as the depth extends into the background (but you could adapt to perspective if needed). You could draw this with CoreGraphics in a UIView drawRect.
A square slice represents an angle piece of the circle, offset by an amount smaller than the length of the cylinder, but in the same direction, as in the following diagram (sorry for imprecise drawing).
This square slice you are interested in is the area outlined in solid red, outside the radius of the first circle, and inside the radius of the imaginary second circle (which is just offset from the first circle by whatever length you want the slice).
To draw this area you simply need to draw a path of the outline of each arc and connect the endpoints.
To check if a touch is inside one of these square slices:
Check if the touch point is between angle a from the origin at a.
Check if the touch point is outside the radius of the inside circle.
Check if the touch point is inside the radius of the outside circle. (Note what this means if the circles are more than a radius apart.)
To find a point to display the popover you could average the end points on the slice or find the middle angle between the two edges and offset by half the distance.
Theoretically, doing this in Scene Kit with either SpriteKit or UIKit Popovers is ideal.
However Scene Kit (and Sprite Kit) seem to be in a state of flux wherein nobody from Apple is communicating with users about the raft of issues folks are currently having with both. From relatively stable and performant Sprite Kit in iOS 8.4 to a lot of lost performance in iOS 9 seems common. Scene Kit simply doesn't seem finished, and the documentation and community are both nearly non-existent as a result.
That being said... the theory is this:
Material IDs are what's used in traditional 3D apps to define areas of an object that have different materials. Somehow these Material IDs are called "elements" in SceneKit. I haven't been able to find much more about this.
It should be possible to detect the "element" that's underneath a touch on an object, and respond accordingly. You should even be able to change the state/nature of the material on that element to indicate it's the currently selected.
When wanting a smooth, well rounded cylinder as per your example, start with a cylinder that's made of only enough segments to describe/define the material IDs you need for your "rectangular" sections to be touched.
Later you can add a smoothing operation to the cylinder to make it round, and all the extra smoothing geometry in each quadrant of unique material ID should be responsive, regardless of how you add this extra detail to smooth the presentation of the cylinder.
Idea for the "Simplified" version:
if this representation is okey, you can use a UICollectionView.
Each cell can have a defined size thanks to
collectionView:layout:sizeForItemAtIndexPath:
Then each cell of the collection could be a small rectangle representing a
touchable part of the cylinder.
and using
collectionView:(UICollectionView *)collectionView
didSelectItemAtIndexPath:(NSIndexPath *)indexPath
To get the touch.
This will help you to display the popover at the right place:
CGRect rect = [collectionView layoutAttributesForItemAtIndexPath:indexPath].frame;
Finally, you can choose the appropriate popover (if the app has to work on iPhone) here:
https://www.cocoacontrols.com/search?q=popover
Not perfect, but i think this is efficient!
Yes, SceneKit.
When user perform a touch event, that mean you knew the 2D coordinate on screen, so your only decision is to popover a view or not, even a 3D model is not exist.
First, we can logically split the requirement into two pieces, determine the touching segment, showing right "color" in each segment.
I think the use of 3D model is to determine which piece of data to show in your case if I don't get you wrong. In that case, the SCNView's hit test method will do most of work for you. What you should do is to perform a hit test, take out the hit node and the hit's local 3D coordinate of this node, you can then calculate which segment is hit by this touch and do the decision.
Now how to draw the surface of the cylinder would be the only left question, right? There are various ways to do, for example simply paint each image you need and programmatically and attach it to the cylinder's material or have your image files on disk and use as material for the cylinder ...
I think the problem would be basically solved.

Motion paths drawn by finger [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I am interested in making path with finger (like connecting objects) between two elements. I am not sure how would I start on this.
I know that I could use Bezier path to create lines, but I am not sure how to create that line with finger. Does anyone have some good example?
I tried to google it, but I can't find anything like that made.
Thanks
I answered a question recently about slow/laggy performance on a similar setup. I.E. Drawing UIBezierPaths in CALayer. The answer contains a subclass of UIView which you can drop into a storyboard and will pretty much get you started. The header file is not shown in the answer, but it is literally a subclass of UIView (just add a UIView Subclass to your project). You should be able to copy the rest into your implementation file. Obviously you'll want to take out the performance testing code.
touchesMoved drawing in CAShapeLayer slow/laggy
If you simply want to Add a single line, you just need to get the starting point in touchesBegan, and build the path in touchesMoved. The commitCurrentRendering simply renders the touch points accumulated, then clears the UIBezierPath. This improves the performance as there wass a notable slowdown when UIBezierPath reached around 2000 points (touchesMoved will feed you a succession of points as your finger moves).

Drawing lines in cocos2d

I'm trying to draw lines in Cocos2d using touches.
I had a system where it would just add a small sprite where you touched, but it's working terribly. So I've been trying to find a way to draw actual lines using a method like ccDrawLine, but every tutorial I find seems to leave out something, and I just can't figure it out.
I've found this tutorial, Drawing line on touches moved in COCOS2D but I don't understand a few things about that.
It seems to reference the same variable from two different files, so I don't understand how it's doing that. (The naughtyTouchArray variable)
I can't find a complete guide on drawing lines, so sorry for the codeless question, but I'm getting frustrated.
Thanks.
The answer you've linked in your question provides good solution to your problem. There is no "two different files". Just two different methods of one layer. One method (ccTouchesMoved:withEvent:) handles touches and fill the array of points to be connected to each other one-by-one with lines. From cocos2d documentation, all drawing must be placed in the draw method of the node. So, another (draw) method just draws lines according to the given array. Cocos2d is based on OpenGL and it fully redraws scene every tick, so you cannot just draw new line. You had to draw all of them.
Or any other node can draw your array in it's draw method, so you can simply pass stored array of points from the layer, that detects touches, to this node.

Resources