I am using bodyWithLoopFromRect to create invisible borders on my simulator.
But when I run, the borders don't seem to be made on the left and right sides of the screen. My sprite bounces off the top and bottom of the screen, but it just leaves the screen when it goes on left or right side of the screen.
Heres my code:
-(void)didMoveToView:(SKView *)view {
self.backgroundColor = [SKColor blueColor];
SKSpriteNode *ball = [SKSpriteNode spriteNodeWithImageNamed:#"ball"];
self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
self.physicsWorld.gravity=CGVectorMake (0,10);
ball.position = CGPointMake(self.size.width/2, self.size.height/2 );
ball.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:ball.frame.size.width/2];
[self addChild:ball];
}
What do I do so that the left and right borders are also made?
Thanks
Related
I'm kind of new with SpriteKit and I'm having some troubles with the physics, I've tried many things to make a SKSpriteNode move with a force or an impulse but it never moves, only gravity affects it when i set it.
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
self.anchorPoint = CGPointMake(0.5, 0.5);
myWorld = [SKNode node];
[self addChild:myWorld];
SKSpriteNode* map = [SKSpriteNode spriteNodeWithImageNamed:#"grass"];
[myWorld addChild:map];
self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:map.frame];
self.physicsBody.friction = 0.0f;
self.physicsBody.categoryBitMask = 2;
self.physicsWorld.gravity = CGVectorMake(0.0, 0.0);
self.physicsWorld.contactDelegate = self;
pointOfView = [SKSpriteNode spriteNodeWithColor:[UIColor colorWithWhite:1 alpha:0.2] size:CGSizeMake(300, 548)];
[myWorld addChild:pointOfView];
pointOfView.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:pointOfView.frame.size];
pointOfView.physicsBody.friction = 0.0f;
pointOfView.physicsBody.restitution = 1.0f;
pointOfView.physicsBody.linearDamping = 0.0f;
pointOfView.physicsBody.allowsRotation = NO;
pointOfView.physicsBody.collisionBitMask = 2;
pointOfView.physicsBody.categoryBitMask = 3;
[pointOfView.physicsBody applyImpulse:CGVectorMake(10.0f, -10.0f)];
}
return self;
}
Here is most of my code in my main scene, there's nothing else except some empty methods like update or touchesBegan.. Am I missing something ? I've tried so many things, i'm starting to lose it haha
Thanks very much for any help !
It's a bit late, but the answer is here: Not able to apply impulse to SKSpriteNode physics body
The problem is that you've created a physics body with bodyWithEdgeLoopFromRect; this creates a static physics body which won't respond to applyImpulse. You need to add the physics body using bodyWithRectangleOfSize: instead.
pointOfView.physicsBody.dynamic = YES;
The dynamic property decides if a sprite should be affected by physics forces.
you have written wrong code your pointOfView not affected by gravity you are just applying a small impusle on it.
change this line self.physicsWorld.gravity = CGVectorMake(0.0, 0.0) to self.physicsWorld.gravity = CGVectorMake(0.0, -9.8); if u looking for negative gravity towards up direction and CGVectorMake(0.0, 9.8) if you looking for positive gravity towards downwards. and try to apply impulse after a interval [pointOfView.physicsBody applyImpulse:CGVectorMake(10.0f, -10.0f)];
SO following an IOS game tutorial, its IO7 as not many for 8 are out yet.
The following code is supposed to be a ball bouncing around but only bounces on the top and bottom of the screen, if it hits the side edges the ball goes of screen
#import "GameScene.h"
#implementation GameScene
-(void)didMoveToView:(SKView *)view {
/* Setup your scene here */
self.backgroundColor =[SKColor whiteColor];
self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
self.physicsWorld.gravity = CGVectorMake(0, 0);
SKSpriteNode *ball = [SKSpriteNode spriteNodeWithImageNamed:#"ball"];
ball.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMidY(self.frame));
ball.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:ball.frame.size.width/2];
//ball.physicsBody.friction = 0;
ball.physicsBody.linearDamping = 0;
ball.physicsBody.restitution = 1;
[self addChild:ball];
CGVector myVector = CGVectorMake(0, 5);
[ball.physicsBody applyImpulse:myVector];
}
-(void)update:(CFTimeInterval)currentTime {
/* Called before each frame is rendered */
}
#end
There has to be something simple here but i can't seem to find an answer on stack overflow
Use NSLog to check the size of your view: NSLog(#"%f,%f",self.size.width,self.size.height);
There is a problem with SpriteKit that causes the view dimensions to be off of what you expect. If this is what is happening in your case, then make sure to change the size of your view to the correct one:
-(void)didMoveToView:(SKView *)view {
/* Setup your scene here */
self.size = self.view.frame.size;
self.backgroundColor =[SKColor whiteColor];
self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
self.physicsWorld.gravity = CGVectorMake(0, 0);
SKSpriteNode *ball = [SKSpriteNode spriteNodeWithImageNamed:#"ball"];
ball.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMidY(self.frame));
ball.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:ball.frame.size.width/2];
//ball.physicsBody.friction = 0;
ball.physicsBody.linearDamping = 0;
ball.physicsBody.restitution = 1;
[self addChild:ball];
CGVector myVector = CGVectorMake(50, 20);
[ball.physicsBody applyImpulse:myVector];
}
-(void)update:(CFTimeInterval)currentTime {
/* Called before each frame is rendered */
}
I am having trouble trying to create platforms alongside a invisible line that is in the middle, I want it to have an SKPhysicsBody so that when passed through by the Hero Character, it increases the score, yet I can't seem to imagine the code the would work, specifically how to create the line with it being in the middle of the platform at all times, especially when the platform decides to move. Any tip would be greatly helpful.
|
|
________|_________
| | |
| | |
|________|_________|
This is one way to implement what you described.
- (void) didMoveToView:(SKView *)view
{
// Show outline of physics bodies for debugging purposes.
self.view.showsPhysics = YES;
self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
self.backgroundColor = [SKColor colorWithRed:0.15 green:0.15 blue:0.3 alpha:1.0];
SKSpriteNode *platform = [SKSpriteNode spriteNodeWithColor:[SKColor blueColor] size:CGSizeMake(128, 64)];
platform.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:platform.size];
platform.position = CGPointMake(CGRectGetMidX(self.frame),
CGRectGetMidY(self.frame));
[self addChild:platform];
SKSpriteNode *line = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(2, 128)];
// Line is invisible
line.hidden = YES;
// physicsBody of line
line.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:line.size];
// Position line...adjust this accordingly
line.position = CGPointMake(platform.position.x, platform.position.y+line.size.height/4);
[self addChild:line];
// Connect nodes with physics joint
[self connectNode1:platform toNode2:line];
[platform.physicsBody applyImpulse:CGVectorMake(100.0, 0)];
}
This method connects two sprite nodes, at their midpoint, with a physics joint.
- (void) connectNode1:(SKSpriteNode *)node1 toNode2:(SKSpriteNode *)node2
{
CGPoint midPoint = CGPointMake((node1.position.x + node2.position.x)/2,
(node1.position.y + node2.position.y)/2);
SKPhysicsJointFixed *joint = [SKPhysicsJointFixed jointWithBodyA:node1.physicsBody
bodyB:node2.physicsBody
anchor:midPoint];
[self.physicsWorld addJoint:joint];
}
Make the line a child of the object using the - (void)addChild:(SKNode *)node as referenced in the SKNode Class Reference.
If you do not want a child/parent relationship you can tie the line to the object like this:
line.position = CGPointMake(object.position.x+10, object.position.y+10)
where +10 is any value you need it to be. If the 'object' moves you will have to update the line's position during the update: method to keep track with the object's position.
I'm creating a game where i'm creating an SKSpriteNode at the bottom. Cause i want to make a buttom higher than the actually bottom cause of grass as the background. The problem is after I've created the physics body and my moving SKSpriteNode makes contact with the bottom. the bottom SpriteNode that i've created will move.
How can i make the bottom sprite node which has the function as being the bottom edge, not move at all. By that i mean that it cant change position.
My code:
SKSpriteNode *bottom = [SKSpriteNode spriteNodeWithColor:[SKColor clearColor] size:CGSizeMake(self.frame.size.width*2, 98)];
bottom.physicsBody.dynamic = NO;
bottom.position = CGPointMake(0, 0);
[self addChild:bottom];
bottom.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:bottom.size];
You have to set the dynamic property of the physics body to NO. You are doing it before you actually create a physics body. That's why it does not have any effect. Change your code to:
SKSpriteNode *bottom = [SKSpriteNode spriteNodeWithColor:[SKColor clearColor]
size:CGSizeMake(self.frame.size.width*2, 98)];
bottom.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:bottom.size];
bottom.physicsBody.dynamic = NO;
bottom.position = CGPointMake(0, 0);
[self addChild:bottom];
And it should work.
I have created my SKScene subclass which sets the anchorpoint and then adds one SKSpriteNode for the world, the world has multiple SKSpriteNodes for the obstacles, player etc. I am also centering on the
The problem I am having is that as I have set the anchorpoint of the scene to (0.5, 0.5), the position of any child node that I add to the world starts at the center of the world. How do I fix the postion of the nodes so that position = (0,0) will be at the bottom left of the world node and any child nodes added to it, instead of the center?
#implementation LevelScene
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
NSLog(#"width:%f height:%f", self.view.bounds.size.width, self.view.bounds.size.height);
// set the physics body
self.physicsWorld.gravity = CGVectorMake(0,-5);
self.physicsWorld.contactDelegate = self;
self.anchorPoint = CGPointMake(0.5, 0.5);
NSMutableDictionary *plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"LevelScene" ofType:#"plist"]];
NSString *backgroundImage = [plistDict objectForKey:#"background"];
// add a node that holds the background
background = [SKSpriteNode spriteNodeWithTexture:[SKTexture textureWithImageNamed:backgroundImage] size:CGSizeMake(1024, 768)];
background.position = CGPointMake(0, 0);
[self addChild:background];
world = [SKSpriteNode spriteNodeWithColor:[SKColor brownColor] size:CGSizeMake(1024, 768)];
world.position = CGPointMake(0, 0); // this should be bottom-left
world.size = CGSizeMake(1024, 768);
world.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:world.frame];
world.physicsBody.categoryBitMask = worldCategory;
[self addChild:world];
// load in the game tiles (these are non-dynamic tiles the player can use)
[self loadInTiles];
// add in game object to the world skspritenode - this just creates a subclass of skspritenode and sets position to 0,0
[self addGameObject:CGPointMake(0, 0)];
...
}
// ...setup functions, input handling, etc
-(void)didSimulatePhysics {
// setup the player to move depending on their direction
[player updatePosition];
[self centreOnNode:player];
}
-(void)centreOnNode: (SKSpriteNode *)node {
CGPoint cameraPositionInScene = [node.scene convertPoint:node.position fromNode:node.parent];
CGFloat x = node.parent.position.x - cameraPositionInScene.x;
CGFloat y = node.parent.position.y - cameraPositionInScene.y;
NSLog(#"camera x:%f y:%f", x, y);
NSLog(#"world frame origin x:%f y:%f", world.frame.origin.x, world.frame.origin.y);
node.parent.position = CGPointMake(x, y);
}
If you want to set the world sprite's origin to the bottom left side, just set it's anchor point.
world.anchorPoint = CGPointMake(0,0);
With this, the world sprite's coordinate system will be just like that of the scene's default.
Make sure to remove the line:
self.anchorPoint = CGPointMake(0.5, 0.5);
Replace this row:
world.position = CGPointMake(0, 0);
by this:
world.position = CGPointMake(-CGRectGetMidX(self.frame), -CGRectGetMidY(self.frame));
(0,0) is the center of the scene, since you set anchor point of the SKScene to (0.5,0.5)