Dalibor
Dalibor

Reputation: 163

How to apply a SKPhysicsBody to a bezier curve?

I'm creating a motocross game where I have a curved ground on which the player should drive. My code for creating the ground looks like this:

    let path = UIBezierPath()
    let startPoint = CGPoint(x: 0.0, y: self.playerCamera.position.x + 50)
    let endPoint = CGPoint(x: self.frame.width, y: self.playerCamera.position.x + 50)

    path.moveToPoint(startPoint)
    path.addCurveToPoint(endPoint, controlPoint1: CGPoint(x: 200.0, y: 100), controlPoint2: CGPoint(x: 400.0, y: -100))


    let myShape = SKShapeNode()
    myShape.path = path.CGPath
    myShape.lineWidth = 20


    myShape.physicsBody = SKPhysicsBody(edgeLoopFromPath: path.CGPath)
    myShape.physicsBody?.categoryBitMask = CollisionCategories.Ground
    myShape.physicsBody?.contactTestBitMask = CollisionCategories.Player

    myShape.physicsBody?.dynamic = false
    myShape.physicsBody?.affectedByGravity = false
    myShape.physicsBody?.allowsRotation = false


    self.addChild(myShape)

My problem is that the player drives on the curve as if it would be a rectangle instead of following the curve.

How can I apply the actual curve or path as the PhyicsBody?

Upvotes: 2

Views: 669

Answers (3)

Samuli Viitasaari
Samuli Viitasaari

Reputation: 635

There's a way to do this without 3rd party tools, I think. The piece of code may not be very beautiful or something you'll be the most proud of, but it's easy and quick.

Two steps. First, convert the bezier to a texture: func texture(from node: SKNode) -> SKTexture? https://developer.apple.com/reference/spritekit/skview/1520114-texture

Then, convert the texture to a physics body: init(texture: SKTexture, size: CGSize) https://developer.apple.com/reference/spritekit/skphysicsbody/1519690-init

Upvotes: 1

Coder1000
Coder1000

Reputation: 4461

SOLUTION:

I think it is impossible to do it without the assistance of a tool.

Please have a look at this: http://avionicsdev.esy.es/article.php?id=13&page=1


TOOL:

You can use this tool to achieve the desired effect:

http://insyncapp.net/SKPhysicsBodyPathGenerator.html

"This tool will let us draw a path and then returns code that will help us draw that path into Xcode" (excerpt from the first link)


METHODOLOGY:

You may have to screen cap your UIBezierPath and convert it to a Sprite, but I am not certain it is necessary. Have a look at the explanations of the tool.


SOLUTION 2:

Change Game Engine.

In my opinion, you might be able to find a way to achieve what you want, but it won't be a simple and straightforward solution. On the other hand, other game engines are more complete and should provide you all you need without having to use "tricks" to achieve what you want.

I hope I am wrong and SpriteKit is indeed more complete than that, but it doesn't look like it.

Use Unity instead of SpriteKit.

SpriteKit is great for relatively simple games, but it has certain limitations and you just found one it seems.

Unity is a full fledged Game Engine which should better suit your needs.

Or have a look at Cocos2D: http://cocos2d.spritebuilder.com/ if you want to keep using Swift (You might have to learn C# to use Unity).

Upvotes: 1

dragoneye
dragoneye

Reputation: 701

i think you can create any type of game in any engine its does not matter its unity cocos2d cocos2dx sprite kit unreal engine spritekit. spritekit is full function engine for your game check out these methods

  • bodyWithTexture:size:
  • bodyWithTexture:alphaThreshold:size:

create a zigzag hill texture and apply one of these method now you can see a hill body with curved path now take a deep breath and think about how motor bike climb on a hill and move up and down solution is create a joint based bike apply torque force in it.

Upvotes: -1

Related Questions