I am developing a game with swift Sprite kit. But I've got a problem, as you can see in the picture I have a number of physical blocks with the same size aligned. When I slide this block above the others sometimes he gets stuck or do small jumps.
It seems that the physical bodies sometimes overlap.
Anyone know how I can fix it to have a continuous and without inprecision movement?
Some physics characteristics:
player.physicsBody?.friction = 0.0
player.physicsBody?.restitution = 0.00
player.physicsBody?.linearDamping = 0.1
player.physicsBody?.angularDamping = 0.0
player.physicsBody?.allowsRotation = false
player.physicsBody?.velocity.dx = 0
player.physicsBody?.velocity.dy = 0
player.physicsBody?.categoryBitMask = heroCategory
player.physicsBody?.contactTestBitMask = enemyCategory
player.physicsBody?.density = 2.3
The problem appears to be just a slight imperfection of physics engine (and hey, it's a simulation, and not completely accurate, I've run into this kind of thing before). I see that you are preventing rotation of the player, so you can change the physics body of the square player into a circle. This should be something like:
player.physicsBody = SKPhysicsBody(circleOfRadius: 10)
Replace 10 with the proper radius of your player. This should smooth out the bumps you are encountering.
How are you sliding the block?
I've had the same problem and I was able to solve it sliding my hero using SKAction to run a code block that changes the hero's velocity or by just simple running an SKAction.moveBy. Your SKAction should'nt be attempting to push your block against the ground. An action to move the block only in the x direction.
You can also smooth the surface by making sure your physicsBody(s) of ground blocks are not overlapping. Introduce a gap of 1-2 points. Or maybe group tiles with a single physicsBody. This may help as well.
Related
I need to move a SpriteNode across the frame. I am currently having the issue of it having glitches while doing so (losing a couple of frames? not really sure). What I need is for the object to travel horizontally without a fixed direction x destination so that if x is offset by some impact the object does not attempt to return to its initialized x coordinate.
Here is how that part of the code looks like right now:
`spaceRock.physicsBody?.affectedByGravity = false
spaceRock.physicsBody = SKPhysicsBody(texture: (spaceRock?.texture)!,
size:(spaceRock.size))
spaceRock.zPosition = 1
spaceRock.position=CGPoint(x: xSpawnPosition, y:
Double(self.size.height/2+(spaceRock.size.height)))
spaceRock.physicsBody!.isDynamic = true
spaceRock.physicsBody!.allowsRotation = true
spaceRock.physicsBody!.categoryBitMask = 00000001
spaceRock.physicsBody!.contactTestBitMask = 00000010
addChild(spaceRock)
spaceRock.physicsBody?.applyTorque(CGFloat(randTorque))
//spaceRock.run(SKAction.moveTo(y: -self.size.height-
spaceRock.size.height, duration: rockTravelTime))`
The comment is what I have been using up until this point.
Thank you for the help!
You are mixing physics simulation (SKPhysicsBody) and direct movement of the Sprite (SKAction.moveTo) - although you may be able to do that to achieve special effects, in general they will fight each other and cause problems.
If you need your objects to move realistically, then use an SKPhysicsBody and apply forces (Torque, thrust etc.) to move it. This will be quite complex to program and has a significant processing overhead.
If you prefer to move your sprites directly then get rid of the SKPhysicsBody and your moveTo should then work fine.
I'm fairly new to swift, and have been working on a game for fun, and i'm running into something I can't quite get my head around.
When the run button is pressed, the character moves forward with the following function
func move(dt: CGFloat) {
position.x += moveRate * dt
}
And when the jump button is pressed, the character jumps with the following function
func jump() {
physicsBody?.applyImpulse(CGVector(dx: 0, dy: jumpRate))
run(jumpAnimation!)
}
both work fine, but consider this senario. The player is running, and then they jump while still moving. While in the air, the player releases the move button and the player's x position stops dead. This obviously feels very unnatural, and i would like the player's x position to ease out.
Now i have also played with moving the character with physicsBody?.applyForce(CGVector(dx: 1000, dy: 0)) which would give that effect, but he seems to just gain more and more speed and you don't get a constant rate or "max speed" so to speak.
Could anybody share some insight with me? I'd love to learn anything I can about spritekit and game development in general. Thanks!
You should try to set the velocity instead of setting the X position. When setting the position you bypass all the physics behaviors.
You should also try to set it only when you actually press a button.
func move(dt: CGFloat) {
if Math.abs(moveRate) > 0.1 { // If player initiates movement. You can increase the value 0.1 if you want to filter move values
velocity = CGVector(dx: moveRate, dy: veloxity.dy)
}
}
It your character moves indefinitely like in space, linearDamping will be useful. it's used to simulate air friction, so values closer to 1 means more friction and values closer to 0 means less friction.
linearDamping = 0.85
Also, this way, moveRate isn't dt dependent but it should be lowered.
Try it, I haven't tested it yet, but that's basically how I would do it.
There are two schools of thought on platformer game "physics".
Don't use physics, do everything with positional incrementation.
Do everything with physics, since positional changes mess up physics
Since you're using physics for jumping, and physics jumping is fun:
There are three ways to create movement in a physics system:
Set the velocity as and when required. This is what Crazyrems is suggesting
Apply impulses as needed to increase and decrease rates of movement
Apply forces over time that increase or decrease rates of movement
Use fields to induce motion (too complex for this, and messy, but fun)
What you're attempting, with your physicsBody?.applyForce(CGVector(dx: 1000, dy: 0)) is the application of force over time. Number 3 in the list above. The longer you continue applying this force the faster the character moves.
Each of these techniques can be made to work, but they all need compensation for their various limitations and methodologies of simulation.
In the case of your approach, you need monitor speed and to set a maximum speed. Having reached maximum speed, if the player is still holding the button, only provide enough force to maintain speed (assuming you're using some form of constant resistance to slow the character).
Monitoring speed combined with force-over-time creates interesting acceleration trait possibilities - like very strong initial acceleration and then taper off acceleration as the player nears their maximum speed.
Slowing down when the player releases the button is the next focus. In all these approaches you need something that slows the player. This can be the application of opposing forces, or the use of friction or damping, as provided by the physics engine.
I am building an endless runner game where platforms appear at random intervals and then scroll right to left across the screen.
I have a sprite that jumps up vertically using
- (void)makeCharacterJump {
[self.spriteCaveman.physicsBody applyImpulse:CGVectorMake(0.0f, 80.0f)];
}
The problem is that the effect of gravity on the sprite means that it falls quite quickly and cant make the gap between the platforms.
What I would like to do is slightly slow down the effect of gravity on the falling sprite so it creates the impression of slightly floating down.
Any ideas?
If the character is the only node affected by gravity then you can change the scene’s gravity with:
self.physicsWorld.gravity = CGVectorMake(0, desiredGravity);
If it is not then you’ll have to play with the character’s physics body properties: friction, linearDamping or angularDamping values.
Hope that helps.
I am building a game where the player sprite bounces around the GameScene. When the user taps the screen, the player sprite should stick to the next wall it hits. How can I completely remove all the energy from the sprite so that it no longer moves?
What attributes should I change? I have tried setting:
restitution() = 0
but this does not help.
I am looking for an answer for SpriteKit in Swift.
Thanks for any help.
You are talking about a node's velocity. It's dx and dy values to be exact.
yourNode.physicsBody?.velocity = CGVectorMake( 0, 0 )
the above will set your node's x and y axis velocity to zero.
I am trying to make simple game with ball but how to make display to have frame around to avoid ball getting out of display ?
I want to have small hole in that frame so ball eventually can get out. I done this like putting couple rectangles ( with width or height 1px and other dimension is larger ) around display but when ball has large speed it pass through wall. Is there better solution for this.
Add physics body to the frame so that the ball will not pass through it
local topWall = display.newRect(0,0,display.contentWidth,2)
physics.addBody( topWall, "static", { friction = 0.5, bounce = 0 } )
Don't forget to start the physics engine "physics.start()" on the top of your code
P.S just modify the the topFrameand create another three walls on both side and on the bottom.
just make rect wider like 300px.
also you can try to set parameter ball.isBullet = true it will tell physics engine to keep eye on ball to avoid getting it through walls