Reputation: 11
I am working on an iPhone game. Basically if hero hits an obstacle gave over. Now I want add jump ability to my hero. But when I use "physicsBody = SKPhysicsBody(rectangleOfSize: size)" for the ground, as soon as game starts and hero appears on the ground "func didBeginContact(contact: SKPhysicsContact){ gameOver() }" method makes game over.Here is my implementations of hero, ground and gamescene. Can you guys please help me to make hero jump and land on the ground. Thanks in advance.
// AKHero.swift
// Run Hero
import Foundation
import SpriteKit
class AKHero: SKSpriteNode{
var body:SKSpriteNode!
var arm: SKSpriteNode!
var leftFoot: SKSpriteNode!
var rightFoot: SKSpriteNode!
var leftpupil: SKSpriteNode!
var rightpupil: SKSpriteNode!
var isUpsideDown = false
init(){
let size = CGSizeMake(35, 45)
super.init(texture: nil, color: UIColor.clearColor(), size: size)
loadAppearance()
loadPhysicsBoadyWithsize(size)
}
func loadPhysicsBoadyWithsize(size: CGSize){
physicsBody = SKPhysicsBody(rectangleOfSize: size)
physicsBody?.categoryBitMask = heroCategory
physicsBody?.contactTestBitMask = obstacleCategory
physicsBody?.usesPreciseCollisionDetection = true
physicsBody?.affectedByGravity = false
}
func jump(){
self.physicsBody?.applyImpulse(CGVectorMake(0, 15))
physicsBody?.affectedByGravity = true
}
// GameScene.swift
// Run Hero
import SpriteKit
class GameScene: SKScene, SKPhysicsContactDelegate {
var movingGround: AKMovingGround!
var hero: AKHero!
var cloudGenerator: AKCloudGenerator!
var obstacleGenerator: AKObstacleGenerator!
var coinGenerator: AKCoinGenerator!
var isStarted = false
var isGameOver = false
override func didMoveToView(view: SKView) {
backgroundColor = UIColor(red: 159.0/255.0, green: 201.0/255.0 , blue: 244.0/255.0 , alpha: 1.0)
func addMovingGround(){
movingGround = AKMovingGround(size: CGSizeMake(view!.frame.width, kAKGroundHeight))
movingGround.position = CGPointMake(0, view!.frame.size.height/2)
addChild(movingGround)
}
//add hero
func addHero(){
hero = AKHero()
hero.position = CGPointMake(70, movingGround.position.y + movingGround.frame.size.height/2 + hero.frame.size.height/2)
addChild(hero)
hero.breathe()
}
func addPhysicsWorld() {
physicsWorld.contactDelegate = self
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
if isGameOver {
restart()
}
else if !isStarted {
start()
}
else{
hero.flipHero()
//hero.jump()
}
}
// MARK: - SKPhysicsContactDelegate
func didBeginContact(contact: SKPhysicsContact) {
if !isGameOver{
println("didBeginContact")
gameOver()
}
}
//
// AKMovingGround.swift
// Run Hero
//
// Created by Alican Karamil on 24/08/15.
// Copyright (c) 2015 Alican Karamil. All rights reserved.
//
import Foundation
import SpriteKit
class AKMovingGround: SKSpriteNode{
let NUMBER_OF_SEGMENTS = 20
let COLOR_ONE = UIColor(red: 88.0/255.0, green: 148.0/255, blue: 87.0/255.0, alpha: 1.0)
let COLOR_TWO = UIColor(red: 120.0/255.0, green:195.0/255.0, blue: 118.0/255.0, alpha: 1.0)
init (size: CGSize){
super.init(texture: nil, color: UIColor.brownColor(), size: CGSizeMake(size.width*2, size.height))
anchorPoint = CGPointMake(0, 1.5)
//anchorPoint = CGPointMake(0, 0.5)
for var i = 0; i < NUMBER_OF_SEGMENTS; i++ {
var segmentColor: UIColor!
if i % 2 == 0{
segmentColor=COLOR_ONE
}else{
segmentColor=COLOR_TWO
}
let segment = SKSpriteNode(color: segmentColor, size: CGSizeMake(self.size.width/CGFloat(NUMBER_OF_SEGMENTS), self.size.height))
segment.anchorPoint = CGPointMake(0.0, 0.5)
segment.position = CGPointMake(CGFloat(i)*segment.size.width, 0)
addChild(segment)
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func start(){
let moveleft = SKAction.moveByX(-frame.size.width/2, y: 0, duration: 1.0)
let resetPosition = SKAction.moveToX(0, duration: 0.0)
let moveSequence = SKAction.sequence([moveleft, resetPosition])
//runAction(moveSequence, completion: nil)
runAction(SKAction.repeatActionForever(moveSequence))
}
func stop(){
removeAllActions()
}
}
Upvotes: 1
Views: 462
Reputation: 620
Your problem is that didBeginContact()
hasn't been assigned a specific contact, so any contact at all gets rendered into that function, including between the player and the ground.
To fix this, you'll have to create specific categoryBitMasks. For more information on that, check out the Apple Docs. When you've done that, you'll need to specify which categoryBitMasks you want to detect collisions with, on the player. That way, if it hits the ground, nothing happens, but if it hits the obstacle, game over. To do this, you'll have to specify the player's physicsBody?.categoryBitMask
, then set its physicsBody?.contactTestBitMask
and its physicsBody?.collisionBitMask
.
In didBeginContact()
, specify which contact to look for with if-statements. Try and see if this Youtube video helps you. Or maybe this one.
Upvotes: 1