How to make a PhysicsBody based on Alpha Values - objective-c

Suppose there there is a scene as follows:
There is a scene with the same size as the frame of the device. The scene has a red ball, which is able to move throughout the 'world'. This world is defined by black and white areas, where the ball is ONLY able to move in the area that is white. Here is a picture to help explain:
Parts of the black area can be erased, as if the user is drawing with white color over the scene. This would mean that the area in which the ball can be moved is constantly changing. Now, how would one go about implementing a physicsBody for the an edge between the white and black areas?
I tried redefining the physicsBody every time it is changed, but once the shape becomes complex enough, this isn't a viable solution at all. I tried creating a two-dimensional array of 'boxes' that are invisible and specify whether most of the area within each box is white or black, and if the ball touched a box that was black, it would be pushed back. However, this required heavy rendering and iterating over the array too much. Since my original array contained boxes a little bigger than a pixel, I tried making these boxes bigger to smooth the motion a little, but this eventually caused part of the ball to be stopped by white areas and appear to be inside the black area. This was undesired, since the user could feel invisible barriers that they seemed to be hitting.
I tried searching for other methods to implement this 'destructible terrain' type scene, but the solutions that I found and tried were using other game engines. To further clarify, I am using Objective-C and Apple's SpriteKit framework; and I am not looking for a detailed class full of code, but rather some pseudo-code or implementation ideas that would lead me to a solution.
Thank you.

If your deployment target is iOS 8, this may be what you're looking for...
+ bodyWithTexture:alphaThreshold:size:
Here's a description from Apple's documentation
Creates a physics body from the contents of a texture. Only texels
that exceed a certain transparency value are included in the physics
body.
where a texel is a texture element. You will need to convert an image to the texture before creating the SKPhysicsBody.
I'm not sure if it will allow for a hole in the middle like your drawing. If not, I suspect you can connect two physics bodies, a left half and a right half, to form the hole.

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.

Trace a ccsprite cocos2d-iphone

I have a layer with a sprite of a simple black donut. I want the user to be able to draw on the sprite in a different color (which I've managed to do without any problem using CCRenderTexture).
My question is how I can calculate whether the image has been traced at least 95% (meaning, find out when 95% of the black pixels are now the new color). I've tried methods like taking a screenshot of the layer and counting the number of black pixels, but it hasn't worked that well (using this solution: https://stackoverflow.com/a/1262893/1577738).
It would be even better if I could just change the color of each pixel as it's touched (to avoid issues with coloring out of the lines). I could theoretically just split the donut into like 10 sprites and change that section's color if the user touches it, but that seems ridiculous if I give the user options to use a bunch of different colors.
Am I going about this the wrong way? Your suggestions are much appreciated!
Reading pixel colors will be rather inaccurate and slow. I suggest dividing the area into smaller rectangles (ie 8x8 or 4x4) and then flag each as "visited" when the user draws on it. If most rectangle areas are flagged, the user has drawn on most parts of the texture.

how to make a circular line of sight in cocos2d tile map

I have a problem about cocos2d tile maps.
My aim is to make a circular line of sight that when player moves around, it must only see its around in circle but not see the rest. I have tried many things and successed it in rectangular area but I couldn't succeed it in circular area.
I am waiting for your answers.
Thanks for your help.
If you help me immidiately, I will appreciate.
Use rectangular area and add an alpha mask with round gradient as a child of the player to make the visible part round.
E.g.
with fading
without fading
Edit.
The green layer is the fog. Only a square of it is uncovered ("I have tried many things and successed it in rectangular area"). The red layer is the circular vision map. It covers some of the visible squares and so the user sees uncovered circle.

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.

App graphic making (transparent and no extra spaces)

I am a coder but not a graphic maker. I can decently produce graphics that meet the quality standards visually although I cannot produce graphics that will technically "work." This is what I mean:
I am using CGRectIntersectsRect for colliding images. My image has SOME extra space which I have made completely transparent using Adobe PhotoShop but even if this extra transparent space is not visible, when the two images collide, it will look like you will be hitting nothing as this extra invisible transparent space is PART of the image and when CGRectIntersectsRect is called it detects touch between two images. So if the other image touches the transparent space, CGRectIntersectsRect is called and my code is executed. I only want my code to be executed if it hits the actual COLOR space of the image. Here is two things that could help me through that, they follow through with questions.
Learn how to make NO EXTRA SPACE on an image in photoshop. How could I do this, tutorials?
CGRectIntersectsRect only called when touching a color part of an image. A way to do this?
Thank you guys!
Regarding your question #1, it depends. All images are rectangular, all. So, if your sprite is rectangular, you can crop it in Photoshop to just the rectangular area. But if you want to handle, say, a circle ball, then you can't do such thing as "remove extra space". Your circle ball will always be stored in a rectangular image, with transparent space on the corners.
Learn how to make NO EXTRA SPACE on an image in photoshop. How could I do this, tutorials?
You can manually select an area using the Rectangular Marquee Tool and Image > Crop or automatically trim the image based on an edge pixel color using Image > Trim.
CGRectIntersectsRect only called when touching a color part of an image. A way to do this?
You can use pixel-perfect collisions or create better bounding shapes for your game objects. For example, instead of using pixel-perfect collision for a spaceship like this one, you could use a triangle for the wings, a rectangle for the body, and a triangle for the head.
Pixel-perfect collision
One way you could implement it would be to
Have an blank image in memory.
Draw visible pixels from one image in blue (#0000ff).
Draw visible pixels from the other image in red (#ff0000).
If there's any purple pixels in the image (#ff00ff), then there's an intersection.
Alternative collision detection solution
If your game is physics-based, then you can use a physics engine like Box2D. You can use circles, rectangles, and polygons to represent all of your game objects and it'll give you accurate results without unnecessary overhead.
For collision detection for non-rectangular shapes, you should look into one of the many game and/or physics libraries available for iOS. Cocos2d coupled with Box2d or chipmunk are popular choices.
If you want to do it yourself, you'll need to start with something like a custom CGPath tracing the actual shape of each object, then use a function like CGPathContainsPoint (that's from memory, it may be wrong). But it is not a simple job. Angry birds uses box2d, AFAIK.