I have been trying to find, but did not succeed. Is there a way to change physicsworld gravity property in such way, that objects would not be attracted towards the bottom of the screen, but to the centre of it instead?
Use an SKFieldNode for that. Just place it at the center of your map and disable gravity by putting code in that sets the gravity to zero (CGVector(0,0))
I would give you code, but I don't use Objective C, so I don't know the exact syntax for it. I can give it a shot though... [physicsBody setGravity: CGVector(0,0)]; PLEASE NOTE I HAVE NO IDEA IF THAT IS CORRECT SYNTAX
EDIT:
The asker requested an example of SKFieldNode in Swift, so here it goes.
For the question asked, what you would do is create a Radial Gravity Field node at the center. This code goes in GameScene.swift (or .m if you're using Objective C, and make sure you change the syntax to Obj-C).
let gravField = SKFieldNode.radialGravityField(); // Create grav field
gravField.position.x = size.width/2; // Center on X axis
gravField.position.y = size.height/2; // Center on Y axis (Now at center of screen)
addChild(gravField); // Add to world
You are probably looking for a SKFieldNode. There are a couple of different types so you will have to read the docs. The one you are probably looking for is called radialGravityField.
Related
I am making a basic app that pushes shapes across the screen and detects collision with Sprite Kit. My first attempt was using moveTo on the nodes. The issue I had was with collision, the objects would rotate around each other instead of bounce.
Therefore I found I need to use applyForce OR applyImpulse.
In this situation I have a circle for example that is position off screen at its start of life. We then determine a target exit point, and want to 'flick'/'push' the node in that direction.
I cannot figure out how to applyImpulse towards the target end position I have as a CGPoint. I need to get this to a CGVector but I am not sure what needs to be done. I had a look around and found some Ray tuts but they just show applyForce or moveTo. I am not sure how to calculate this.
I found a site that explains 2D physics well.
http://www.rodedev.com/tutorials/gamephysics/
With this I worked out what the angle needed to be and have a speed that I can control and it works well.
You can move an object by changing manually the x and y position so you can reach your end point. In the update function you change yourObject.position.x and yourObject.position.y if I have understood correctly your question. If not please be more explicit. Hope that helps.
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.
I am newbie in IOS Gaming, and i need to create a game using Sprite Kit framework for functionality similar to angry bird pulley system, and also wants to find the distance the object is travelled from the pulley to its landing.
Can anyone help me out with this, i would be thankfull for it.
Thanks in advance.
One way you could code a slingshot effect would to use a starting point on the screen at let's say (x=100,y=100). You would display a SpriteNode of a slingshot with the Y centered at the (100,100).
The next step would be to use touchesBegan:withEvent: in the area of the slingshot to let your code know the player is looking to shoot the slingshot.
You would use touchesMoved:withEvent: to track how far back (how much tension) the player is pulling back from the slingshot.
The release would be triggtouchesEnded:withEvent. Based on how far the touch began (x=100) and how far back is was released (for example x=30), you can apply force like this:
float forceUsed = startTouchX - endTouchX;
[_projectile.physicsBody applyForce:CGVectorMake(forceUsed, 0)];
If you are looking to angle the shot you would also have to track Y and use that variable instead of the 0 above.
As for calculating distance between 2 points on the screen, it boils down to x and y coordinates. Subtract objectA.position.x from objectB.position.x
Things can get a lot more complex of course but that all depends on what you want to do in your code. Hope this helps.
P.S. The touches above are all part of the UIResponder Class.
Recently I have a new project that uses Box2D as physics engine. And I am having some trouble with the body's position.
I want to draw images on the sprite, so I just use body.GetPosition as image's position. But I found that body.GetPosition returns the same value as body.GetWorldCenter, and I just wondering that I did something wrong.
I use box2d flash 2.1a in my project. And I currently subtract this position with half-width and half-height to walk around. Also, can you tell me if there is some way to solve my problem or draw the image in the correct positon in Box2D.
Thank you.
update
so sorry to post before read manual.
after RTM I got that body has two points,first is origin point and the second is center of mass ,so a regular shape's world center is always the same as it's origin point. sorry to post is.
Have you set the image in the userdata for the body? Your getting the body's position but you need to have a function that runs each world tick that can set the images position to the new location. Box2d is just numbers defining a simulation. Those numbers are constantly updating so the image needs to have position set each time there is a game tick. Hope this helps
I feel stupid asking this question, but I can not find a clear answer anywhere (or much of an answer at all) so I feel I must ask. Is there anyone out there who can explain clearly how the parallaxRatio of CCParallaxNode works?
I have checked the source of CCParallaxNode and it does not explain it at all. I have searched the internet and stackOverflow extensively. I have tried to do good old trial and error. I'm still confused.
[parallaxLayer addChild:backgroundEffect_subtleRed z:100 parallaxRatio:ccp(0.5, 0.5) positionOffset:backgroundEffect_subtleRed.position];
In this piece of code I am trying to add a particle emitter to a parallaxLayer and have it move somewhat like you would expect an object on a parallax layer to move. Unfortunately I do not see the particles at all. I have had this problem anytime I try to add anything to a parallaxNode when I want it to move. I have been using CCParallaxNode to create static UI layers, but have not been able to use them for what they were built to do.
In summary:
parallaxRatio takes a CGPoint. What do the floats in the CGPoint apply to? Are they ratios of x and y in relation to the window? Are they (parallaxLayerMovementInRelationTo, parentNode)? A working piece of example code would be very helpful.
Thank you.
To quote from a cocos2d book I own:
[paraNode addChild:para1 z:1 parallaxRatio:CGPointMake(0.5f, 0) positionOffset:topOffset];
[paraNode addChild:para2 z:2 parallaxRatio:CGPointMake(1, 0) positionOffset:topOffset];
[paraNode addChild:para3 z:4 parallaxRatio:CGPointMake(2, 0) positionOffset:midOffset];
[paraNode addChild:para4 z:3 parallaxRatio:CGPointMake(3, 0) positionOffset:downOffset];
"The CCParallaxNode is created like any other node, but its children are added using a special initializer. With it you specify the parallax ratio, which is a CGPoint used as a multiplier for any movement of the CCParallaxNode In this case, para1 would move at half the speed, para2 at the normal speed, para3 at double the speed of the CCParallaxNode, and so on"
So basically, its the ratio that the individual layers are moved in the relation to the movement of the whole CCParallaxNode.