I'm trying to position my sprite at the bottom center of the phone
this is the function I call from didMoveToScene to add the player, my scene is anchored at 0.5, 0.5. The tileMapNode is positioned at 0, -800 to center it in the scene and it is anchored at 0.5, 0.5 also. no matter where I position the player, it is still dead center of the phone. What am I doing wrong.
func addPlayer() {
player = Player(imageNamed: GameConstants.StringConstants.playerImageName)
player.name = String(GameConstants.StringConstants.playerName)
player.anchorPoint = CGPoint(x: 0.5, y: 0.5)
player.position = CGPoint(x: (scene?.frame.midX)!, y: (scene?.frame.minY)!)
player.xScale = 1
player.yScale = 1
player.zPosition = GameConstants.ZPositions.playerZ
player.lightingBitMask = 1
PhysicsHelper.addPhysicsBody(to: player, with: GameConstants.StringConstants.playerName)
addAttackArea()
scene?.addChild(player)
lightsCameraAction()
player.playerState = .idle
}
Here is the complete GameScene file. How can I know when the scene is loading? I'm an old school programmer. Haven't written any code in about 24 years :). things have changed a little.
import SpriteKit
//MARK:--------------------------Global Variables
enum GameState {
case playing, paused, finished
}
// MARK: ----------------------------------GameScene
class GameScene: SKScene, SKPhysicsContactDelegate {
// MARK: -----------------------------------Movement Variables
let movePointsPerSecond: CGFloat = 250.0
var velocity = CGVector(dx: 0.0, dy: 0.0)
var lastUpdateTime: CFTimeInterval = 0
// MARK: ----------------------------------Gesture Recognizer
let singleTapRec = UITapGestureRecognizer()
let lightNode: SKLightNode = SKLightNode()
let cameraNode: SKCameraNode = SKCameraNode()
let gameScene: SKScene = SKScene()
var gameState = GameState.playing {
willSet {
switch newValue {
case .playing:
player.playerState = .idle
case .finished:
player.playerState = .idle
case .paused:
scene?.isPaused = true
}
}
}
// MARK: ---------------------------------didMove to view
override func didMove(to view: SKView) {
physicsWorld.contactDelegate = self
switch gameState {
case .playing:
setupGestures()
addPlayer()
addEnemy()
addEnemy()
addEnemy()
addEnemy()
addEnemy()
addEnemy()
case .paused:
scene?.isPaused = true
default:
break
}
}
// MARK: ---------------------Touches Section
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
// var touchedLocation = CGPoint()
switch gameState {
case .playing:
//if let touch = touches.first {
//let touchLocation = touch.location(in: self)
// touchedLocation = touchLocation
player.playerState = .idle
// moveAndRotate(spriteNode: player, toPosition: touchedLocation)
// }
case .paused:
scene?.isPaused = true
default:
break
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
var touchedLocation = CGPoint()
switch gameState {
case .playing:
if let touch = touches.first {
let touchLocation = touch.location(in: self)
touchedLocation = touchLocation
player.playerState = .walking
moveAndRotate(spriteNode: player, toPosition: touchedLocation)
}
case .paused:
scene?.isPaused = true
default:
break
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
removeAllActions()
switch gameState {
case .playing:
player.playerState = .idle
player.removeAction(forKey: "RotateAction")
case .paused:
scene?.isPaused = true
default:
break
}
}
// MARK:------------------------------------Physics contact
func didBegin(_ contact: SKPhysicsContact) {
var enemyIndex = 0
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
if contact.bodyA.node?.name != "Player" && contact.bodyA.node?.name != "AttackArea" {
let node = contact.bodyA.node
enemyIndex = findEnemy(contactName: (node?.name)!)
} else {
let node = contact.bodyB.node
enemyIndex = findEnemy(contactName: (node?.name)!)
}
enemyID = enemyIndex
switch contactMask {
case GameConstants.PhysicsCategory.attackAreaCategory | GameConstants.PhysicsCategory.enemyCategory:
handleEnemyContact(entity: enemyIndex)
case GameConstants.PhysicsCategory.playerCategory | GameConstants.PhysicsCategory.enemyCategory:
handleEnemyContact(entity: enemyIndex)
default:
break
}
}
func didEnd(_ contact: SKPhysicsContact) {
}
// MARK: ---------------------Update Section
override func update(_ currentTime: CFTimeInterval) {
let deltaTime = max(1.0 / 30, currentTime - lastUpdateTime)
lastUpdateTime = currentTime
update(dt: deltaTime)
}
func update(dt: CFTimeInterval) {
if player.playerState == .walking {
let newX = player.position.x + velocity.dx * CGFloat(dt)
let newY = player.position.y + velocity.dy * CGFloat(dt)
player.position = CGPoint(x: newX, y: newY)
cameraNode.position = player.position
lightNode.position = player.position
newAttack.position = player.position
}
}
}
forgot to add the game scene extension.
import SpriteKit
// MARK: ----------------------------------Enumerations
enum Animation: String {
case Walking, Idle, Attacking, Waiting
}
enum RewardType: String {
case LevelUp, MagicItem, DefeatEnemy, DefeatBoss, CompleteQuest
}
enum Dice: Int {
case d20, d10, d8, d6, d4
}
// MARK: ----------------------------------GLobal Variables
var player: Player!
var enemy: Enemy!
let textureName: String = GameConstants.StringConstants.playerImageName
let playerTexture: SKTexture = SKTexture(imageNamed: GameConstants.StringConstants.playerImageName)
var playerPosition: CGPoint = CGPoint(x: 0, y: 0)
let attackAreaTexture: SKTexture = SKTexture(imageNamed: "AttackCircle")
var requiredXPForNextLevel = 0
let enemyTexture: SKTexture = SKTexture(imageNamed: GameConstants.StringConstants.enemyImageName)
var playerIsAttacking: Bool = false
var enemyIsAttacking: Bool = false
var playerIsDead: Bool = false
var enemyIsDead: Bool = false
var enemies: [Enemy] =
var enemyID: Int = 0
var newAttack: SKSpriteNode!
extension GameScene {
//MARK:--------------------------------------------Add Player
func addPlayer() {
player = Player(imageNamed: GameConstants.StringConstants.playerImageName)
player.name = String(GameConstants.StringConstants.playerName)
player.anchorPoint = CGPoint(x: 0.5, y: 0.5)
player.position = CGPoint(x: 0, y: 0)
player.xScale = 1
player.yScale = 1
player.zPosition = GameConstants.ZPositions.playerZ
player.lightingBitMask = 1
PhysicsHelper.addPhysicsBody(to: player, with: GameConstants.StringConstants.playerName)
addAttackArea()
scene!.addChild(player)
lightsCameraAction()
player.playerState = .idle
}
//MARK:------------------------------------Lights and Camera
func lightsCameraAction() {
let lightNode: SKLightNode = setupLighting()
addChild(lightNode)
let cameraNode: SKCameraNode = setupCamera()
addChild(cameraNode)
}
//MARK:-------------------------------------------Add Enemy
func addEnemy() {
let enemyIndex = enemyID
enemy = Enemy(imageNamed: GameConstants.StringConstants.enemyImageName )
enemies.append(enemy)
let randomX = Int.random(in: -100 ..< 1500)
let randomY = Int.random(in: -100 ..< 1500)
let currentEnemy = enemies[enemyIndex]
currentEnemy.name = "Enemy(enemyIndex + 1)"
currentEnemy.stats.id = enemyID
currentEnemy.position = CGPoint(x: randomX, y: randomY)
currentEnemy.xScale = 1
currentEnemy.yScale = 1
currentEnemy.zPosition = GameConstants.ZPositions.enemyZ
currentEnemy.lightingBitMask = 1
PhysicsHelper.addPhysicsBody(to: currentEnemy, with: GameConstants.StringConstants.enemyName)
addChild(currentEnemy)
enemyID += 1
}
//MARK:-------------------------------Attack
func addAttackArea() {
newAttack = SKSpriteNode(texture: attackAreaTexture, color: UIColor.clear, size: player.size)
newAttack.name = GameConstants.StringConstants.attackAreaName
newAttack.position = player.position
newAttack.size.width = player.size.width + 75
newAttack.size.height = player.size.height + 75
newAttack.zPosition = player.zPosition - 1
PhysicsHelper.addPhysicsBody(to: newAttack, with: GameConstants.StringConstants.attackAreaName)
addChild(newAttack)
}
func attack() {
player.playerState = .attacking
playerIsAttacking = true
if enemyIsDead {
playerIsAttacking = false
}
}
//MARK:----------------------------Gestures
func setupGestures() {
singleTapRec.addTarget(self, action: #selector(singleTap))
singleTapRec.numberOfTouchesRequired = 1
singleTapRec.numberOfTapsRequired = 1
view!.addGestureRecognizer(singleTapRec)
}
@objc func singleTap() {
attack()
}
func cleanUp() {
for gesture in (view?.gestureRecognizers)! {
view?.removeGestureRecognizer(gesture)
}
}
//MARK:-------------------------Lighting and Camera
func setupLighting() -> SKLightNode {
lightNode.lightColor = UIColor.white
lightNode.ambientColor = UIColor.black
lightNode.shadowColor = UIColor.black
lightNode.falloff = 1.5
lightNode.zPosition = GameConstants.ZPositions.objectZ
lightNode.alpha = 1
lightNode.position = player.position
return lightNode
}
func setupCamera() -> SKCameraNode {
camera = cameraNode
cameraNode.position = player.position
return cameraNode
}
//MARK:-----------------------------Handle Enemy Contact
func handleEnemyContact(entity: Int) {
//var currentEnemy = enemies[entity]
if enemies.count != 0 {
if enemies[entity].stats.hp <= 0 {
enemyIsDead = true
//handlePlayerReward(level: enemyLevel)
enemies[entity].removeFromParent()
enemies.remove(at: entity)
} else {
print("nAttacking: (enemies[entity].name as Any)")
print("enemyHP: (enemies[entity].stats.hp)")
enemies[entity].stats.hp -= 1
}
}
}
//MARK:-------------------------------------Find Enemy
func findEnemy(contactName: String) -> Int {
var enemiesIndex = 0
var enemyIndex = 0
for _ in enemies {
let entityName = enemies[enemiesIndex].name
if entityName == contactName {
enemyIndex = enemiesIndex
enemies[enemyIndex].stats.id = enemyIndex
} else {
enemiesIndex += 1
}
}
return enemyIndex
}
//MARK:-------------------------------------Player Reward
func handlePlayerReward(level: Int) {
/*
let playerXP = userData?.value(forKey: "PlayerXP") as? Int
let newPlayerXP = (level * 10) + playerXP!
if newPlayerXP > requiredXPForNextLevel {
levelUp()
}
userData?["PlayerXP"] = newPlayerXP as Any
*/
}
//MARK:-----------------------------------------Level Up
func levelUp() {
/*
var enemyLevel = userData?.value(forKey: "(enemyID)Level") as! Int
let playerXP = userData?.value(forKey: "PlayerXP") as! Int
let newPlayerXP = (enemyLevel * 10) + playerXP
enemyLevel += 1
userData?["P{layerXP"] = newPlayerXP
userData?["(enemyID)Level"] = enemyLevel
requiredXPForNextLevel = requiredXPForNextLevel * 2
*/
}
//MARK-----------------------------------Roll Dice
func rollDice(die: Dice) -> Int {
switch die {
case .d20:
let d20 = Int(arc4random_uniform(20)) + 1
return d20
case .d10:
let d10 = Int(arc4random_uniform(10)) + 1
return d10
case .d8:
let d8 = Int(arc4random_uniform(8)) + 1
return d8
case .d6:
let d6 = Int(arc4random_uniform(6)) + 1
return d6
case .d4:
let d4 = Int(arc4random_uniform(4)) + 1
return d4
}
}
//MARK:-------------------------------Move and Rotate
func moveAndRotate(spriteNode: SKSpriteNode, toPosition position: CGPoint) {
let angle = atan2(position.y - spriteNode.position.y, position.x - spriteNode.position.x)
let rotateAction = SKAction.rotate(toAngle: angle + CGFloat.pi / 2, duration: 0, shortestUnitArc: true)
if let _ = spriteNode.action(forKey: "RotateAction") {
spriteNode.removeAction(forKey: "RotateAction")
spriteNode.run(rotateAction, withKey: "RotateAction")
} else {
spriteNode.run(rotateAction, withKey: "RotateAction")
}
let offsetX = position.x - spriteNode.position.x
let offsetY = position.y - spriteNode.position.y
let normal = simd_normalize(simd_double2(x: Double(offsetX), y: Double(offsetY)))
velocity = CGVector(dx: CGFloat(normal.x) * movePointsPerSecond, dy: CGFloat(normal.y) * movePointsPerSecond)
}
/*
func whoIsThis(entity: String) {
if entity != player.name! {
print("Entity: (entity)")
print("EnemyID: (enemyID)")
print("EnemyHP: (String(describing: userData?.value(forKey: "HP")))")
print("EnemyName: (String(describing: enemy.name))")
} else {
print("Entity: (entity)")
print("PlayerHP: (String(describing: userData?.value(forKey: "HP")))")
print("PlayerName: (String(describing: player.name))")
}
}
*/
}
swift sprite-kit skspritenode
|
show 2 more comments
this is the function I call from didMoveToScene to add the player, my scene is anchored at 0.5, 0.5. The tileMapNode is positioned at 0, -800 to center it in the scene and it is anchored at 0.5, 0.5 also. no matter where I position the player, it is still dead center of the phone. What am I doing wrong.
func addPlayer() {
player = Player(imageNamed: GameConstants.StringConstants.playerImageName)
player.name = String(GameConstants.StringConstants.playerName)
player.anchorPoint = CGPoint(x: 0.5, y: 0.5)
player.position = CGPoint(x: (scene?.frame.midX)!, y: (scene?.frame.minY)!)
player.xScale = 1
player.yScale = 1
player.zPosition = GameConstants.ZPositions.playerZ
player.lightingBitMask = 1
PhysicsHelper.addPhysicsBody(to: player, with: GameConstants.StringConstants.playerName)
addAttackArea()
scene?.addChild(player)
lightsCameraAction()
player.playerState = .idle
}
Here is the complete GameScene file. How can I know when the scene is loading? I'm an old school programmer. Haven't written any code in about 24 years :). things have changed a little.
import SpriteKit
//MARK:--------------------------Global Variables
enum GameState {
case playing, paused, finished
}
// MARK: ----------------------------------GameScene
class GameScene: SKScene, SKPhysicsContactDelegate {
// MARK: -----------------------------------Movement Variables
let movePointsPerSecond: CGFloat = 250.0
var velocity = CGVector(dx: 0.0, dy: 0.0)
var lastUpdateTime: CFTimeInterval = 0
// MARK: ----------------------------------Gesture Recognizer
let singleTapRec = UITapGestureRecognizer()
let lightNode: SKLightNode = SKLightNode()
let cameraNode: SKCameraNode = SKCameraNode()
let gameScene: SKScene = SKScene()
var gameState = GameState.playing {
willSet {
switch newValue {
case .playing:
player.playerState = .idle
case .finished:
player.playerState = .idle
case .paused:
scene?.isPaused = true
}
}
}
// MARK: ---------------------------------didMove to view
override func didMove(to view: SKView) {
physicsWorld.contactDelegate = self
switch gameState {
case .playing:
setupGestures()
addPlayer()
addEnemy()
addEnemy()
addEnemy()
addEnemy()
addEnemy()
addEnemy()
case .paused:
scene?.isPaused = true
default:
break
}
}
// MARK: ---------------------Touches Section
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
// var touchedLocation = CGPoint()
switch gameState {
case .playing:
//if let touch = touches.first {
//let touchLocation = touch.location(in: self)
// touchedLocation = touchLocation
player.playerState = .idle
// moveAndRotate(spriteNode: player, toPosition: touchedLocation)
// }
case .paused:
scene?.isPaused = true
default:
break
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
var touchedLocation = CGPoint()
switch gameState {
case .playing:
if let touch = touches.first {
let touchLocation = touch.location(in: self)
touchedLocation = touchLocation
player.playerState = .walking
moveAndRotate(spriteNode: player, toPosition: touchedLocation)
}
case .paused:
scene?.isPaused = true
default:
break
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
removeAllActions()
switch gameState {
case .playing:
player.playerState = .idle
player.removeAction(forKey: "RotateAction")
case .paused:
scene?.isPaused = true
default:
break
}
}
// MARK:------------------------------------Physics contact
func didBegin(_ contact: SKPhysicsContact) {
var enemyIndex = 0
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
if contact.bodyA.node?.name != "Player" && contact.bodyA.node?.name != "AttackArea" {
let node = contact.bodyA.node
enemyIndex = findEnemy(contactName: (node?.name)!)
} else {
let node = contact.bodyB.node
enemyIndex = findEnemy(contactName: (node?.name)!)
}
enemyID = enemyIndex
switch contactMask {
case GameConstants.PhysicsCategory.attackAreaCategory | GameConstants.PhysicsCategory.enemyCategory:
handleEnemyContact(entity: enemyIndex)
case GameConstants.PhysicsCategory.playerCategory | GameConstants.PhysicsCategory.enemyCategory:
handleEnemyContact(entity: enemyIndex)
default:
break
}
}
func didEnd(_ contact: SKPhysicsContact) {
}
// MARK: ---------------------Update Section
override func update(_ currentTime: CFTimeInterval) {
let deltaTime = max(1.0 / 30, currentTime - lastUpdateTime)
lastUpdateTime = currentTime
update(dt: deltaTime)
}
func update(dt: CFTimeInterval) {
if player.playerState == .walking {
let newX = player.position.x + velocity.dx * CGFloat(dt)
let newY = player.position.y + velocity.dy * CGFloat(dt)
player.position = CGPoint(x: newX, y: newY)
cameraNode.position = player.position
lightNode.position = player.position
newAttack.position = player.position
}
}
}
forgot to add the game scene extension.
import SpriteKit
// MARK: ----------------------------------Enumerations
enum Animation: String {
case Walking, Idle, Attacking, Waiting
}
enum RewardType: String {
case LevelUp, MagicItem, DefeatEnemy, DefeatBoss, CompleteQuest
}
enum Dice: Int {
case d20, d10, d8, d6, d4
}
// MARK: ----------------------------------GLobal Variables
var player: Player!
var enemy: Enemy!
let textureName: String = GameConstants.StringConstants.playerImageName
let playerTexture: SKTexture = SKTexture(imageNamed: GameConstants.StringConstants.playerImageName)
var playerPosition: CGPoint = CGPoint(x: 0, y: 0)
let attackAreaTexture: SKTexture = SKTexture(imageNamed: "AttackCircle")
var requiredXPForNextLevel = 0
let enemyTexture: SKTexture = SKTexture(imageNamed: GameConstants.StringConstants.enemyImageName)
var playerIsAttacking: Bool = false
var enemyIsAttacking: Bool = false
var playerIsDead: Bool = false
var enemyIsDead: Bool = false
var enemies: [Enemy] =
var enemyID: Int = 0
var newAttack: SKSpriteNode!
extension GameScene {
//MARK:--------------------------------------------Add Player
func addPlayer() {
player = Player(imageNamed: GameConstants.StringConstants.playerImageName)
player.name = String(GameConstants.StringConstants.playerName)
player.anchorPoint = CGPoint(x: 0.5, y: 0.5)
player.position = CGPoint(x: 0, y: 0)
player.xScale = 1
player.yScale = 1
player.zPosition = GameConstants.ZPositions.playerZ
player.lightingBitMask = 1
PhysicsHelper.addPhysicsBody(to: player, with: GameConstants.StringConstants.playerName)
addAttackArea()
scene!.addChild(player)
lightsCameraAction()
player.playerState = .idle
}
//MARK:------------------------------------Lights and Camera
func lightsCameraAction() {
let lightNode: SKLightNode = setupLighting()
addChild(lightNode)
let cameraNode: SKCameraNode = setupCamera()
addChild(cameraNode)
}
//MARK:-------------------------------------------Add Enemy
func addEnemy() {
let enemyIndex = enemyID
enemy = Enemy(imageNamed: GameConstants.StringConstants.enemyImageName )
enemies.append(enemy)
let randomX = Int.random(in: -100 ..< 1500)
let randomY = Int.random(in: -100 ..< 1500)
let currentEnemy = enemies[enemyIndex]
currentEnemy.name = "Enemy(enemyIndex + 1)"
currentEnemy.stats.id = enemyID
currentEnemy.position = CGPoint(x: randomX, y: randomY)
currentEnemy.xScale = 1
currentEnemy.yScale = 1
currentEnemy.zPosition = GameConstants.ZPositions.enemyZ
currentEnemy.lightingBitMask = 1
PhysicsHelper.addPhysicsBody(to: currentEnemy, with: GameConstants.StringConstants.enemyName)
addChild(currentEnemy)
enemyID += 1
}
//MARK:-------------------------------Attack
func addAttackArea() {
newAttack = SKSpriteNode(texture: attackAreaTexture, color: UIColor.clear, size: player.size)
newAttack.name = GameConstants.StringConstants.attackAreaName
newAttack.position = player.position
newAttack.size.width = player.size.width + 75
newAttack.size.height = player.size.height + 75
newAttack.zPosition = player.zPosition - 1
PhysicsHelper.addPhysicsBody(to: newAttack, with: GameConstants.StringConstants.attackAreaName)
addChild(newAttack)
}
func attack() {
player.playerState = .attacking
playerIsAttacking = true
if enemyIsDead {
playerIsAttacking = false
}
}
//MARK:----------------------------Gestures
func setupGestures() {
singleTapRec.addTarget(self, action: #selector(singleTap))
singleTapRec.numberOfTouchesRequired = 1
singleTapRec.numberOfTapsRequired = 1
view!.addGestureRecognizer(singleTapRec)
}
@objc func singleTap() {
attack()
}
func cleanUp() {
for gesture in (view?.gestureRecognizers)! {
view?.removeGestureRecognizer(gesture)
}
}
//MARK:-------------------------Lighting and Camera
func setupLighting() -> SKLightNode {
lightNode.lightColor = UIColor.white
lightNode.ambientColor = UIColor.black
lightNode.shadowColor = UIColor.black
lightNode.falloff = 1.5
lightNode.zPosition = GameConstants.ZPositions.objectZ
lightNode.alpha = 1
lightNode.position = player.position
return lightNode
}
func setupCamera() -> SKCameraNode {
camera = cameraNode
cameraNode.position = player.position
return cameraNode
}
//MARK:-----------------------------Handle Enemy Contact
func handleEnemyContact(entity: Int) {
//var currentEnemy = enemies[entity]
if enemies.count != 0 {
if enemies[entity].stats.hp <= 0 {
enemyIsDead = true
//handlePlayerReward(level: enemyLevel)
enemies[entity].removeFromParent()
enemies.remove(at: entity)
} else {
print("nAttacking: (enemies[entity].name as Any)")
print("enemyHP: (enemies[entity].stats.hp)")
enemies[entity].stats.hp -= 1
}
}
}
//MARK:-------------------------------------Find Enemy
func findEnemy(contactName: String) -> Int {
var enemiesIndex = 0
var enemyIndex = 0
for _ in enemies {
let entityName = enemies[enemiesIndex].name
if entityName == contactName {
enemyIndex = enemiesIndex
enemies[enemyIndex].stats.id = enemyIndex
} else {
enemiesIndex += 1
}
}
return enemyIndex
}
//MARK:-------------------------------------Player Reward
func handlePlayerReward(level: Int) {
/*
let playerXP = userData?.value(forKey: "PlayerXP") as? Int
let newPlayerXP = (level * 10) + playerXP!
if newPlayerXP > requiredXPForNextLevel {
levelUp()
}
userData?["PlayerXP"] = newPlayerXP as Any
*/
}
//MARK:-----------------------------------------Level Up
func levelUp() {
/*
var enemyLevel = userData?.value(forKey: "(enemyID)Level") as! Int
let playerXP = userData?.value(forKey: "PlayerXP") as! Int
let newPlayerXP = (enemyLevel * 10) + playerXP
enemyLevel += 1
userData?["P{layerXP"] = newPlayerXP
userData?["(enemyID)Level"] = enemyLevel
requiredXPForNextLevel = requiredXPForNextLevel * 2
*/
}
//MARK-----------------------------------Roll Dice
func rollDice(die: Dice) -> Int {
switch die {
case .d20:
let d20 = Int(arc4random_uniform(20)) + 1
return d20
case .d10:
let d10 = Int(arc4random_uniform(10)) + 1
return d10
case .d8:
let d8 = Int(arc4random_uniform(8)) + 1
return d8
case .d6:
let d6 = Int(arc4random_uniform(6)) + 1
return d6
case .d4:
let d4 = Int(arc4random_uniform(4)) + 1
return d4
}
}
//MARK:-------------------------------Move and Rotate
func moveAndRotate(spriteNode: SKSpriteNode, toPosition position: CGPoint) {
let angle = atan2(position.y - spriteNode.position.y, position.x - spriteNode.position.x)
let rotateAction = SKAction.rotate(toAngle: angle + CGFloat.pi / 2, duration: 0, shortestUnitArc: true)
if let _ = spriteNode.action(forKey: "RotateAction") {
spriteNode.removeAction(forKey: "RotateAction")
spriteNode.run(rotateAction, withKey: "RotateAction")
} else {
spriteNode.run(rotateAction, withKey: "RotateAction")
}
let offsetX = position.x - spriteNode.position.x
let offsetY = position.y - spriteNode.position.y
let normal = simd_normalize(simd_double2(x: Double(offsetX), y: Double(offsetY)))
velocity = CGVector(dx: CGFloat(normal.x) * movePointsPerSecond, dy: CGFloat(normal.y) * movePointsPerSecond)
}
/*
func whoIsThis(entity: String) {
if entity != player.name! {
print("Entity: (entity)")
print("EnemyID: (enemyID)")
print("EnemyHP: (String(describing: userData?.value(forKey: "HP")))")
print("EnemyName: (String(describing: enemy.name))")
} else {
print("Entity: (entity)")
print("PlayerHP: (String(describing: userData?.value(forKey: "HP")))")
print("PlayerName: (String(describing: player.name))")
}
}
*/
}
swift sprite-kit skspritenode
I am going to say scene?.frame.midX is 0 because your scene size is 0 at this moment in time
– Knight0fDragon
Nov 13 '18 at 2:54
scene size is set to 1080, 1960 ?
– Zbud68
Nov 13 '18 at 3:06
yes but at the time you are creating player, it may not be set yet
– Knight0fDragon
Nov 13 '18 at 3:07
I've added the entire GameScene file, not sure how to know when the scene is loading.
– Zbud68
Nov 13 '18 at 3:16
This code makes no sense
– Knight0fDragon
Nov 13 '18 at 3:20
|
show 2 more comments
this is the function I call from didMoveToScene to add the player, my scene is anchored at 0.5, 0.5. The tileMapNode is positioned at 0, -800 to center it in the scene and it is anchored at 0.5, 0.5 also. no matter where I position the player, it is still dead center of the phone. What am I doing wrong.
func addPlayer() {
player = Player(imageNamed: GameConstants.StringConstants.playerImageName)
player.name = String(GameConstants.StringConstants.playerName)
player.anchorPoint = CGPoint(x: 0.5, y: 0.5)
player.position = CGPoint(x: (scene?.frame.midX)!, y: (scene?.frame.minY)!)
player.xScale = 1
player.yScale = 1
player.zPosition = GameConstants.ZPositions.playerZ
player.lightingBitMask = 1
PhysicsHelper.addPhysicsBody(to: player, with: GameConstants.StringConstants.playerName)
addAttackArea()
scene?.addChild(player)
lightsCameraAction()
player.playerState = .idle
}
Here is the complete GameScene file. How can I know when the scene is loading? I'm an old school programmer. Haven't written any code in about 24 years :). things have changed a little.
import SpriteKit
//MARK:--------------------------Global Variables
enum GameState {
case playing, paused, finished
}
// MARK: ----------------------------------GameScene
class GameScene: SKScene, SKPhysicsContactDelegate {
// MARK: -----------------------------------Movement Variables
let movePointsPerSecond: CGFloat = 250.0
var velocity = CGVector(dx: 0.0, dy: 0.0)
var lastUpdateTime: CFTimeInterval = 0
// MARK: ----------------------------------Gesture Recognizer
let singleTapRec = UITapGestureRecognizer()
let lightNode: SKLightNode = SKLightNode()
let cameraNode: SKCameraNode = SKCameraNode()
let gameScene: SKScene = SKScene()
var gameState = GameState.playing {
willSet {
switch newValue {
case .playing:
player.playerState = .idle
case .finished:
player.playerState = .idle
case .paused:
scene?.isPaused = true
}
}
}
// MARK: ---------------------------------didMove to view
override func didMove(to view: SKView) {
physicsWorld.contactDelegate = self
switch gameState {
case .playing:
setupGestures()
addPlayer()
addEnemy()
addEnemy()
addEnemy()
addEnemy()
addEnemy()
addEnemy()
case .paused:
scene?.isPaused = true
default:
break
}
}
// MARK: ---------------------Touches Section
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
// var touchedLocation = CGPoint()
switch gameState {
case .playing:
//if let touch = touches.first {
//let touchLocation = touch.location(in: self)
// touchedLocation = touchLocation
player.playerState = .idle
// moveAndRotate(spriteNode: player, toPosition: touchedLocation)
// }
case .paused:
scene?.isPaused = true
default:
break
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
var touchedLocation = CGPoint()
switch gameState {
case .playing:
if let touch = touches.first {
let touchLocation = touch.location(in: self)
touchedLocation = touchLocation
player.playerState = .walking
moveAndRotate(spriteNode: player, toPosition: touchedLocation)
}
case .paused:
scene?.isPaused = true
default:
break
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
removeAllActions()
switch gameState {
case .playing:
player.playerState = .idle
player.removeAction(forKey: "RotateAction")
case .paused:
scene?.isPaused = true
default:
break
}
}
// MARK:------------------------------------Physics contact
func didBegin(_ contact: SKPhysicsContact) {
var enemyIndex = 0
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
if contact.bodyA.node?.name != "Player" && contact.bodyA.node?.name != "AttackArea" {
let node = contact.bodyA.node
enemyIndex = findEnemy(contactName: (node?.name)!)
} else {
let node = contact.bodyB.node
enemyIndex = findEnemy(contactName: (node?.name)!)
}
enemyID = enemyIndex
switch contactMask {
case GameConstants.PhysicsCategory.attackAreaCategory | GameConstants.PhysicsCategory.enemyCategory:
handleEnemyContact(entity: enemyIndex)
case GameConstants.PhysicsCategory.playerCategory | GameConstants.PhysicsCategory.enemyCategory:
handleEnemyContact(entity: enemyIndex)
default:
break
}
}
func didEnd(_ contact: SKPhysicsContact) {
}
// MARK: ---------------------Update Section
override func update(_ currentTime: CFTimeInterval) {
let deltaTime = max(1.0 / 30, currentTime - lastUpdateTime)
lastUpdateTime = currentTime
update(dt: deltaTime)
}
func update(dt: CFTimeInterval) {
if player.playerState == .walking {
let newX = player.position.x + velocity.dx * CGFloat(dt)
let newY = player.position.y + velocity.dy * CGFloat(dt)
player.position = CGPoint(x: newX, y: newY)
cameraNode.position = player.position
lightNode.position = player.position
newAttack.position = player.position
}
}
}
forgot to add the game scene extension.
import SpriteKit
// MARK: ----------------------------------Enumerations
enum Animation: String {
case Walking, Idle, Attacking, Waiting
}
enum RewardType: String {
case LevelUp, MagicItem, DefeatEnemy, DefeatBoss, CompleteQuest
}
enum Dice: Int {
case d20, d10, d8, d6, d4
}
// MARK: ----------------------------------GLobal Variables
var player: Player!
var enemy: Enemy!
let textureName: String = GameConstants.StringConstants.playerImageName
let playerTexture: SKTexture = SKTexture(imageNamed: GameConstants.StringConstants.playerImageName)
var playerPosition: CGPoint = CGPoint(x: 0, y: 0)
let attackAreaTexture: SKTexture = SKTexture(imageNamed: "AttackCircle")
var requiredXPForNextLevel = 0
let enemyTexture: SKTexture = SKTexture(imageNamed: GameConstants.StringConstants.enemyImageName)
var playerIsAttacking: Bool = false
var enemyIsAttacking: Bool = false
var playerIsDead: Bool = false
var enemyIsDead: Bool = false
var enemies: [Enemy] =
var enemyID: Int = 0
var newAttack: SKSpriteNode!
extension GameScene {
//MARK:--------------------------------------------Add Player
func addPlayer() {
player = Player(imageNamed: GameConstants.StringConstants.playerImageName)
player.name = String(GameConstants.StringConstants.playerName)
player.anchorPoint = CGPoint(x: 0.5, y: 0.5)
player.position = CGPoint(x: 0, y: 0)
player.xScale = 1
player.yScale = 1
player.zPosition = GameConstants.ZPositions.playerZ
player.lightingBitMask = 1
PhysicsHelper.addPhysicsBody(to: player, with: GameConstants.StringConstants.playerName)
addAttackArea()
scene!.addChild(player)
lightsCameraAction()
player.playerState = .idle
}
//MARK:------------------------------------Lights and Camera
func lightsCameraAction() {
let lightNode: SKLightNode = setupLighting()
addChild(lightNode)
let cameraNode: SKCameraNode = setupCamera()
addChild(cameraNode)
}
//MARK:-------------------------------------------Add Enemy
func addEnemy() {
let enemyIndex = enemyID
enemy = Enemy(imageNamed: GameConstants.StringConstants.enemyImageName )
enemies.append(enemy)
let randomX = Int.random(in: -100 ..< 1500)
let randomY = Int.random(in: -100 ..< 1500)
let currentEnemy = enemies[enemyIndex]
currentEnemy.name = "Enemy(enemyIndex + 1)"
currentEnemy.stats.id = enemyID
currentEnemy.position = CGPoint(x: randomX, y: randomY)
currentEnemy.xScale = 1
currentEnemy.yScale = 1
currentEnemy.zPosition = GameConstants.ZPositions.enemyZ
currentEnemy.lightingBitMask = 1
PhysicsHelper.addPhysicsBody(to: currentEnemy, with: GameConstants.StringConstants.enemyName)
addChild(currentEnemy)
enemyID += 1
}
//MARK:-------------------------------Attack
func addAttackArea() {
newAttack = SKSpriteNode(texture: attackAreaTexture, color: UIColor.clear, size: player.size)
newAttack.name = GameConstants.StringConstants.attackAreaName
newAttack.position = player.position
newAttack.size.width = player.size.width + 75
newAttack.size.height = player.size.height + 75
newAttack.zPosition = player.zPosition - 1
PhysicsHelper.addPhysicsBody(to: newAttack, with: GameConstants.StringConstants.attackAreaName)
addChild(newAttack)
}
func attack() {
player.playerState = .attacking
playerIsAttacking = true
if enemyIsDead {
playerIsAttacking = false
}
}
//MARK:----------------------------Gestures
func setupGestures() {
singleTapRec.addTarget(self, action: #selector(singleTap))
singleTapRec.numberOfTouchesRequired = 1
singleTapRec.numberOfTapsRequired = 1
view!.addGestureRecognizer(singleTapRec)
}
@objc func singleTap() {
attack()
}
func cleanUp() {
for gesture in (view?.gestureRecognizers)! {
view?.removeGestureRecognizer(gesture)
}
}
//MARK:-------------------------Lighting and Camera
func setupLighting() -> SKLightNode {
lightNode.lightColor = UIColor.white
lightNode.ambientColor = UIColor.black
lightNode.shadowColor = UIColor.black
lightNode.falloff = 1.5
lightNode.zPosition = GameConstants.ZPositions.objectZ
lightNode.alpha = 1
lightNode.position = player.position
return lightNode
}
func setupCamera() -> SKCameraNode {
camera = cameraNode
cameraNode.position = player.position
return cameraNode
}
//MARK:-----------------------------Handle Enemy Contact
func handleEnemyContact(entity: Int) {
//var currentEnemy = enemies[entity]
if enemies.count != 0 {
if enemies[entity].stats.hp <= 0 {
enemyIsDead = true
//handlePlayerReward(level: enemyLevel)
enemies[entity].removeFromParent()
enemies.remove(at: entity)
} else {
print("nAttacking: (enemies[entity].name as Any)")
print("enemyHP: (enemies[entity].stats.hp)")
enemies[entity].stats.hp -= 1
}
}
}
//MARK:-------------------------------------Find Enemy
func findEnemy(contactName: String) -> Int {
var enemiesIndex = 0
var enemyIndex = 0
for _ in enemies {
let entityName = enemies[enemiesIndex].name
if entityName == contactName {
enemyIndex = enemiesIndex
enemies[enemyIndex].stats.id = enemyIndex
} else {
enemiesIndex += 1
}
}
return enemyIndex
}
//MARK:-------------------------------------Player Reward
func handlePlayerReward(level: Int) {
/*
let playerXP = userData?.value(forKey: "PlayerXP") as? Int
let newPlayerXP = (level * 10) + playerXP!
if newPlayerXP > requiredXPForNextLevel {
levelUp()
}
userData?["PlayerXP"] = newPlayerXP as Any
*/
}
//MARK:-----------------------------------------Level Up
func levelUp() {
/*
var enemyLevel = userData?.value(forKey: "(enemyID)Level") as! Int
let playerXP = userData?.value(forKey: "PlayerXP") as! Int
let newPlayerXP = (enemyLevel * 10) + playerXP
enemyLevel += 1
userData?["P{layerXP"] = newPlayerXP
userData?["(enemyID)Level"] = enemyLevel
requiredXPForNextLevel = requiredXPForNextLevel * 2
*/
}
//MARK-----------------------------------Roll Dice
func rollDice(die: Dice) -> Int {
switch die {
case .d20:
let d20 = Int(arc4random_uniform(20)) + 1
return d20
case .d10:
let d10 = Int(arc4random_uniform(10)) + 1
return d10
case .d8:
let d8 = Int(arc4random_uniform(8)) + 1
return d8
case .d6:
let d6 = Int(arc4random_uniform(6)) + 1
return d6
case .d4:
let d4 = Int(arc4random_uniform(4)) + 1
return d4
}
}
//MARK:-------------------------------Move and Rotate
func moveAndRotate(spriteNode: SKSpriteNode, toPosition position: CGPoint) {
let angle = atan2(position.y - spriteNode.position.y, position.x - spriteNode.position.x)
let rotateAction = SKAction.rotate(toAngle: angle + CGFloat.pi / 2, duration: 0, shortestUnitArc: true)
if let _ = spriteNode.action(forKey: "RotateAction") {
spriteNode.removeAction(forKey: "RotateAction")
spriteNode.run(rotateAction, withKey: "RotateAction")
} else {
spriteNode.run(rotateAction, withKey: "RotateAction")
}
let offsetX = position.x - spriteNode.position.x
let offsetY = position.y - spriteNode.position.y
let normal = simd_normalize(simd_double2(x: Double(offsetX), y: Double(offsetY)))
velocity = CGVector(dx: CGFloat(normal.x) * movePointsPerSecond, dy: CGFloat(normal.y) * movePointsPerSecond)
}
/*
func whoIsThis(entity: String) {
if entity != player.name! {
print("Entity: (entity)")
print("EnemyID: (enemyID)")
print("EnemyHP: (String(describing: userData?.value(forKey: "HP")))")
print("EnemyName: (String(describing: enemy.name))")
} else {
print("Entity: (entity)")
print("PlayerHP: (String(describing: userData?.value(forKey: "HP")))")
print("PlayerName: (String(describing: player.name))")
}
}
*/
}
swift sprite-kit skspritenode
this is the function I call from didMoveToScene to add the player, my scene is anchored at 0.5, 0.5. The tileMapNode is positioned at 0, -800 to center it in the scene and it is anchored at 0.5, 0.5 also. no matter where I position the player, it is still dead center of the phone. What am I doing wrong.
func addPlayer() {
player = Player(imageNamed: GameConstants.StringConstants.playerImageName)
player.name = String(GameConstants.StringConstants.playerName)
player.anchorPoint = CGPoint(x: 0.5, y: 0.5)
player.position = CGPoint(x: (scene?.frame.midX)!, y: (scene?.frame.minY)!)
player.xScale = 1
player.yScale = 1
player.zPosition = GameConstants.ZPositions.playerZ
player.lightingBitMask = 1
PhysicsHelper.addPhysicsBody(to: player, with: GameConstants.StringConstants.playerName)
addAttackArea()
scene?.addChild(player)
lightsCameraAction()
player.playerState = .idle
}
Here is the complete GameScene file. How can I know when the scene is loading? I'm an old school programmer. Haven't written any code in about 24 years :). things have changed a little.
import SpriteKit
//MARK:--------------------------Global Variables
enum GameState {
case playing, paused, finished
}
// MARK: ----------------------------------GameScene
class GameScene: SKScene, SKPhysicsContactDelegate {
// MARK: -----------------------------------Movement Variables
let movePointsPerSecond: CGFloat = 250.0
var velocity = CGVector(dx: 0.0, dy: 0.0)
var lastUpdateTime: CFTimeInterval = 0
// MARK: ----------------------------------Gesture Recognizer
let singleTapRec = UITapGestureRecognizer()
let lightNode: SKLightNode = SKLightNode()
let cameraNode: SKCameraNode = SKCameraNode()
let gameScene: SKScene = SKScene()
var gameState = GameState.playing {
willSet {
switch newValue {
case .playing:
player.playerState = .idle
case .finished:
player.playerState = .idle
case .paused:
scene?.isPaused = true
}
}
}
// MARK: ---------------------------------didMove to view
override func didMove(to view: SKView) {
physicsWorld.contactDelegate = self
switch gameState {
case .playing:
setupGestures()
addPlayer()
addEnemy()
addEnemy()
addEnemy()
addEnemy()
addEnemy()
addEnemy()
case .paused:
scene?.isPaused = true
default:
break
}
}
// MARK: ---------------------Touches Section
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
// var touchedLocation = CGPoint()
switch gameState {
case .playing:
//if let touch = touches.first {
//let touchLocation = touch.location(in: self)
// touchedLocation = touchLocation
player.playerState = .idle
// moveAndRotate(spriteNode: player, toPosition: touchedLocation)
// }
case .paused:
scene?.isPaused = true
default:
break
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
var touchedLocation = CGPoint()
switch gameState {
case .playing:
if let touch = touches.first {
let touchLocation = touch.location(in: self)
touchedLocation = touchLocation
player.playerState = .walking
moveAndRotate(spriteNode: player, toPosition: touchedLocation)
}
case .paused:
scene?.isPaused = true
default:
break
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
removeAllActions()
switch gameState {
case .playing:
player.playerState = .idle
player.removeAction(forKey: "RotateAction")
case .paused:
scene?.isPaused = true
default:
break
}
}
// MARK:------------------------------------Physics contact
func didBegin(_ contact: SKPhysicsContact) {
var enemyIndex = 0
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
if contact.bodyA.node?.name != "Player" && contact.bodyA.node?.name != "AttackArea" {
let node = contact.bodyA.node
enemyIndex = findEnemy(contactName: (node?.name)!)
} else {
let node = contact.bodyB.node
enemyIndex = findEnemy(contactName: (node?.name)!)
}
enemyID = enemyIndex
switch contactMask {
case GameConstants.PhysicsCategory.attackAreaCategory | GameConstants.PhysicsCategory.enemyCategory:
handleEnemyContact(entity: enemyIndex)
case GameConstants.PhysicsCategory.playerCategory | GameConstants.PhysicsCategory.enemyCategory:
handleEnemyContact(entity: enemyIndex)
default:
break
}
}
func didEnd(_ contact: SKPhysicsContact) {
}
// MARK: ---------------------Update Section
override func update(_ currentTime: CFTimeInterval) {
let deltaTime = max(1.0 / 30, currentTime - lastUpdateTime)
lastUpdateTime = currentTime
update(dt: deltaTime)
}
func update(dt: CFTimeInterval) {
if player.playerState == .walking {
let newX = player.position.x + velocity.dx * CGFloat(dt)
let newY = player.position.y + velocity.dy * CGFloat(dt)
player.position = CGPoint(x: newX, y: newY)
cameraNode.position = player.position
lightNode.position = player.position
newAttack.position = player.position
}
}
}
forgot to add the game scene extension.
import SpriteKit
// MARK: ----------------------------------Enumerations
enum Animation: String {
case Walking, Idle, Attacking, Waiting
}
enum RewardType: String {
case LevelUp, MagicItem, DefeatEnemy, DefeatBoss, CompleteQuest
}
enum Dice: Int {
case d20, d10, d8, d6, d4
}
// MARK: ----------------------------------GLobal Variables
var player: Player!
var enemy: Enemy!
let textureName: String = GameConstants.StringConstants.playerImageName
let playerTexture: SKTexture = SKTexture(imageNamed: GameConstants.StringConstants.playerImageName)
var playerPosition: CGPoint = CGPoint(x: 0, y: 0)
let attackAreaTexture: SKTexture = SKTexture(imageNamed: "AttackCircle")
var requiredXPForNextLevel = 0
let enemyTexture: SKTexture = SKTexture(imageNamed: GameConstants.StringConstants.enemyImageName)
var playerIsAttacking: Bool = false
var enemyIsAttacking: Bool = false
var playerIsDead: Bool = false
var enemyIsDead: Bool = false
var enemies: [Enemy] =
var enemyID: Int = 0
var newAttack: SKSpriteNode!
extension GameScene {
//MARK:--------------------------------------------Add Player
func addPlayer() {
player = Player(imageNamed: GameConstants.StringConstants.playerImageName)
player.name = String(GameConstants.StringConstants.playerName)
player.anchorPoint = CGPoint(x: 0.5, y: 0.5)
player.position = CGPoint(x: 0, y: 0)
player.xScale = 1
player.yScale = 1
player.zPosition = GameConstants.ZPositions.playerZ
player.lightingBitMask = 1
PhysicsHelper.addPhysicsBody(to: player, with: GameConstants.StringConstants.playerName)
addAttackArea()
scene!.addChild(player)
lightsCameraAction()
player.playerState = .idle
}
//MARK:------------------------------------Lights and Camera
func lightsCameraAction() {
let lightNode: SKLightNode = setupLighting()
addChild(lightNode)
let cameraNode: SKCameraNode = setupCamera()
addChild(cameraNode)
}
//MARK:-------------------------------------------Add Enemy
func addEnemy() {
let enemyIndex = enemyID
enemy = Enemy(imageNamed: GameConstants.StringConstants.enemyImageName )
enemies.append(enemy)
let randomX = Int.random(in: -100 ..< 1500)
let randomY = Int.random(in: -100 ..< 1500)
let currentEnemy = enemies[enemyIndex]
currentEnemy.name = "Enemy(enemyIndex + 1)"
currentEnemy.stats.id = enemyID
currentEnemy.position = CGPoint(x: randomX, y: randomY)
currentEnemy.xScale = 1
currentEnemy.yScale = 1
currentEnemy.zPosition = GameConstants.ZPositions.enemyZ
currentEnemy.lightingBitMask = 1
PhysicsHelper.addPhysicsBody(to: currentEnemy, with: GameConstants.StringConstants.enemyName)
addChild(currentEnemy)
enemyID += 1
}
//MARK:-------------------------------Attack
func addAttackArea() {
newAttack = SKSpriteNode(texture: attackAreaTexture, color: UIColor.clear, size: player.size)
newAttack.name = GameConstants.StringConstants.attackAreaName
newAttack.position = player.position
newAttack.size.width = player.size.width + 75
newAttack.size.height = player.size.height + 75
newAttack.zPosition = player.zPosition - 1
PhysicsHelper.addPhysicsBody(to: newAttack, with: GameConstants.StringConstants.attackAreaName)
addChild(newAttack)
}
func attack() {
player.playerState = .attacking
playerIsAttacking = true
if enemyIsDead {
playerIsAttacking = false
}
}
//MARK:----------------------------Gestures
func setupGestures() {
singleTapRec.addTarget(self, action: #selector(singleTap))
singleTapRec.numberOfTouchesRequired = 1
singleTapRec.numberOfTapsRequired = 1
view!.addGestureRecognizer(singleTapRec)
}
@objc func singleTap() {
attack()
}
func cleanUp() {
for gesture in (view?.gestureRecognizers)! {
view?.removeGestureRecognizer(gesture)
}
}
//MARK:-------------------------Lighting and Camera
func setupLighting() -> SKLightNode {
lightNode.lightColor = UIColor.white
lightNode.ambientColor = UIColor.black
lightNode.shadowColor = UIColor.black
lightNode.falloff = 1.5
lightNode.zPosition = GameConstants.ZPositions.objectZ
lightNode.alpha = 1
lightNode.position = player.position
return lightNode
}
func setupCamera() -> SKCameraNode {
camera = cameraNode
cameraNode.position = player.position
return cameraNode
}
//MARK:-----------------------------Handle Enemy Contact
func handleEnemyContact(entity: Int) {
//var currentEnemy = enemies[entity]
if enemies.count != 0 {
if enemies[entity].stats.hp <= 0 {
enemyIsDead = true
//handlePlayerReward(level: enemyLevel)
enemies[entity].removeFromParent()
enemies.remove(at: entity)
} else {
print("nAttacking: (enemies[entity].name as Any)")
print("enemyHP: (enemies[entity].stats.hp)")
enemies[entity].stats.hp -= 1
}
}
}
//MARK:-------------------------------------Find Enemy
func findEnemy(contactName: String) -> Int {
var enemiesIndex = 0
var enemyIndex = 0
for _ in enemies {
let entityName = enemies[enemiesIndex].name
if entityName == contactName {
enemyIndex = enemiesIndex
enemies[enemyIndex].stats.id = enemyIndex
} else {
enemiesIndex += 1
}
}
return enemyIndex
}
//MARK:-------------------------------------Player Reward
func handlePlayerReward(level: Int) {
/*
let playerXP = userData?.value(forKey: "PlayerXP") as? Int
let newPlayerXP = (level * 10) + playerXP!
if newPlayerXP > requiredXPForNextLevel {
levelUp()
}
userData?["PlayerXP"] = newPlayerXP as Any
*/
}
//MARK:-----------------------------------------Level Up
func levelUp() {
/*
var enemyLevel = userData?.value(forKey: "(enemyID)Level") as! Int
let playerXP = userData?.value(forKey: "PlayerXP") as! Int
let newPlayerXP = (enemyLevel * 10) + playerXP
enemyLevel += 1
userData?["P{layerXP"] = newPlayerXP
userData?["(enemyID)Level"] = enemyLevel
requiredXPForNextLevel = requiredXPForNextLevel * 2
*/
}
//MARK-----------------------------------Roll Dice
func rollDice(die: Dice) -> Int {
switch die {
case .d20:
let d20 = Int(arc4random_uniform(20)) + 1
return d20
case .d10:
let d10 = Int(arc4random_uniform(10)) + 1
return d10
case .d8:
let d8 = Int(arc4random_uniform(8)) + 1
return d8
case .d6:
let d6 = Int(arc4random_uniform(6)) + 1
return d6
case .d4:
let d4 = Int(arc4random_uniform(4)) + 1
return d4
}
}
//MARK:-------------------------------Move and Rotate
func moveAndRotate(spriteNode: SKSpriteNode, toPosition position: CGPoint) {
let angle = atan2(position.y - spriteNode.position.y, position.x - spriteNode.position.x)
let rotateAction = SKAction.rotate(toAngle: angle + CGFloat.pi / 2, duration: 0, shortestUnitArc: true)
if let _ = spriteNode.action(forKey: "RotateAction") {
spriteNode.removeAction(forKey: "RotateAction")
spriteNode.run(rotateAction, withKey: "RotateAction")
} else {
spriteNode.run(rotateAction, withKey: "RotateAction")
}
let offsetX = position.x - spriteNode.position.x
let offsetY = position.y - spriteNode.position.y
let normal = simd_normalize(simd_double2(x: Double(offsetX), y: Double(offsetY)))
velocity = CGVector(dx: CGFloat(normal.x) * movePointsPerSecond, dy: CGFloat(normal.y) * movePointsPerSecond)
}
/*
func whoIsThis(entity: String) {
if entity != player.name! {
print("Entity: (entity)")
print("EnemyID: (enemyID)")
print("EnemyHP: (String(describing: userData?.value(forKey: "HP")))")
print("EnemyName: (String(describing: enemy.name))")
} else {
print("Entity: (entity)")
print("PlayerHP: (String(describing: userData?.value(forKey: "HP")))")
print("PlayerName: (String(describing: player.name))")
}
}
*/
}
swift sprite-kit skspritenode
swift sprite-kit skspritenode
edited Nov 13 '18 at 3:40
Zbud68
asked Nov 13 '18 at 2:31
Zbud68Zbud68
258
258
I am going to say scene?.frame.midX is 0 because your scene size is 0 at this moment in time
– Knight0fDragon
Nov 13 '18 at 2:54
scene size is set to 1080, 1960 ?
– Zbud68
Nov 13 '18 at 3:06
yes but at the time you are creating player, it may not be set yet
– Knight0fDragon
Nov 13 '18 at 3:07
I've added the entire GameScene file, not sure how to know when the scene is loading.
– Zbud68
Nov 13 '18 at 3:16
This code makes no sense
– Knight0fDragon
Nov 13 '18 at 3:20
|
show 2 more comments
I am going to say scene?.frame.midX is 0 because your scene size is 0 at this moment in time
– Knight0fDragon
Nov 13 '18 at 2:54
scene size is set to 1080, 1960 ?
– Zbud68
Nov 13 '18 at 3:06
yes but at the time you are creating player, it may not be set yet
– Knight0fDragon
Nov 13 '18 at 3:07
I've added the entire GameScene file, not sure how to know when the scene is loading.
– Zbud68
Nov 13 '18 at 3:16
This code makes no sense
– Knight0fDragon
Nov 13 '18 at 3:20
I am going to say scene?.frame.midX is 0 because your scene size is 0 at this moment in time
– Knight0fDragon
Nov 13 '18 at 2:54
I am going to say scene?.frame.midX is 0 because your scene size is 0 at this moment in time
– Knight0fDragon
Nov 13 '18 at 2:54
scene size is set to 1080, 1960 ?
– Zbud68
Nov 13 '18 at 3:06
scene size is set to 1080, 1960 ?
– Zbud68
Nov 13 '18 at 3:06
yes but at the time you are creating player, it may not be set yet
– Knight0fDragon
Nov 13 '18 at 3:07
yes but at the time you are creating player, it may not be set yet
– Knight0fDragon
Nov 13 '18 at 3:07
I've added the entire GameScene file, not sure how to know when the scene is loading.
– Zbud68
Nov 13 '18 at 3:16
I've added the entire GameScene file, not sure how to know when the scene is loading.
– Zbud68
Nov 13 '18 at 3:16
This code makes no sense
– Knight0fDragon
Nov 13 '18 at 3:20
This code makes no sense
– Knight0fDragon
Nov 13 '18 at 3:20
|
show 2 more comments
1 Answer
1
active
oldest
votes
If I am following your code correctly the issue could be that you are centering the camera on your player in your update loop.
If you want him to be at the bottom of the screen you will want to offset this position not set it directly on your player's position otherwise he will always be in the center no matter where you move him.
//cameraNode.position = player.position
let yOffset = player.position.y+scene.height/2-player.size.height/2
cameraNode.position = CGPoint(player.position.x, yOffset) //might get you want you want.
That did it, thanks so much. I never even considered that.
– Zbud68
Nov 19 '18 at 5:39
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53272928%2fim-trying-to-position-my-sprite-at-the-bottom-center-of-the-phone%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
If I am following your code correctly the issue could be that you are centering the camera on your player in your update loop.
If you want him to be at the bottom of the screen you will want to offset this position not set it directly on your player's position otherwise he will always be in the center no matter where you move him.
//cameraNode.position = player.position
let yOffset = player.position.y+scene.height/2-player.size.height/2
cameraNode.position = CGPoint(player.position.x, yOffset) //might get you want you want.
That did it, thanks so much. I never even considered that.
– Zbud68
Nov 19 '18 at 5:39
add a comment |
If I am following your code correctly the issue could be that you are centering the camera on your player in your update loop.
If you want him to be at the bottom of the screen you will want to offset this position not set it directly on your player's position otherwise he will always be in the center no matter where you move him.
//cameraNode.position = player.position
let yOffset = player.position.y+scene.height/2-player.size.height/2
cameraNode.position = CGPoint(player.position.x, yOffset) //might get you want you want.
That did it, thanks so much. I never even considered that.
– Zbud68
Nov 19 '18 at 5:39
add a comment |
If I am following your code correctly the issue could be that you are centering the camera on your player in your update loop.
If you want him to be at the bottom of the screen you will want to offset this position not set it directly on your player's position otherwise he will always be in the center no matter where you move him.
//cameraNode.position = player.position
let yOffset = player.position.y+scene.height/2-player.size.height/2
cameraNode.position = CGPoint(player.position.x, yOffset) //might get you want you want.
If I am following your code correctly the issue could be that you are centering the camera on your player in your update loop.
If you want him to be at the bottom of the screen you will want to offset this position not set it directly on your player's position otherwise he will always be in the center no matter where you move him.
//cameraNode.position = player.position
let yOffset = player.position.y+scene.height/2-player.size.height/2
cameraNode.position = CGPoint(player.position.x, yOffset) //might get you want you want.
answered Nov 15 '18 at 2:39
Skyler LaurenSkyler Lauren
3,35531327
3,35531327
That did it, thanks so much. I never even considered that.
– Zbud68
Nov 19 '18 at 5:39
add a comment |
That did it, thanks so much. I never even considered that.
– Zbud68
Nov 19 '18 at 5:39
That did it, thanks so much. I never even considered that.
– Zbud68
Nov 19 '18 at 5:39
That did it, thanks so much. I never even considered that.
– Zbud68
Nov 19 '18 at 5:39
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53272928%2fim-trying-to-position-my-sprite-at-the-bottom-center-of-the-phone%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
I am going to say scene?.frame.midX is 0 because your scene size is 0 at this moment in time
– Knight0fDragon
Nov 13 '18 at 2:54
scene size is set to 1080, 1960 ?
– Zbud68
Nov 13 '18 at 3:06
yes but at the time you are creating player, it may not be set yet
– Knight0fDragon
Nov 13 '18 at 3:07
I've added the entire GameScene file, not sure how to know when the scene is loading.
– Zbud68
Nov 13 '18 at 3:16
This code makes no sense
– Knight0fDragon
Nov 13 '18 at 3:20