I'm trying to make a small mini game where you drag a ball around the screen and every 10 seconds a ball gets added in that follows you. so far the you can drag a ball around the screen and a ball follows you, but when another ball gets added in the balls group together. I think this is because the ball is following me depending on how fast I'm going. so is there a certain way in which I can have the balls follow me at a certain speed constantly, like 10 pixels a second or something, and that should prevent the balls from grouping together.
I am currently working on the score so it should soon go up every second you survive. and you die if you touch one of the balls.
below is the code and a short gif of my current code
!(https://gyazo.com/1d6a56527bfd0884e8a26cff730f4e03)
import SpriteKit
import GameplayKit
struct physicsCatagory{
static let me : UInt32 = 0x1 << 1
static let enemy : UInt32 = 0x1 << 2
}
class GameScene: SKScene, SKPhysicsContactDelegate {
private func makeEnemyName() -> String {
enemyCounter += 1
return "enemy\(enemyCounter)"
}
private func addEnemyToDict(enemy: SKSpriteNode, target: SKSpriteNode) {
if let name = enemy.name { spriteDictionary[name] = (enemy, target) }
else { print("enemy not found") }
}
private func removeEnemyFromDict(enemy: SKSpriteNode) {
if let name = enemy.name { spriteDictionary[name] = nil }
else { print("enemy not removed from dictionary!") }
}
private func moveFollowerToTarget(_ sprites: FollowerAndTarget) {
let action = SKAction.move(to: sprites.target.position, duration: 1)
sprites.follower.run(action)
}
private func allEnemiesMoveToTarget() {
for sprites in spriteDictionary.values {
moveFollowerToTarget(sprites)
}
}
let enemySpeed: CGFloat = 300
var me = SKSpriteNode()
// Tuple to keep track of enemy objects:
typealias FollowerAndTarget = (follower: SKSpriteNode, target: SKSpriteNode)
// [followerName: (followerSprite, targetSprite):
var spriteDictionary: [String: FollowerAndTarget] = [:]
// Give each enemy a unique name for the dictionary:
var enemyCounter = 0
var died = Bool()
override func didMove(to view: SKView) {
createScene()
}
func createEnemy () {
if died == true{
}
else {
let enemy = SKSpriteNode(imageNamed: "enemy1")
enemy.name = makeEnemyName()
addEnemyToDict(enemy: enemy, target: me)
moveFollowerToTarget((follower: enemy, target: me))
enemy.size = CGSize(width: 60, height: 60)
enemy.position = CGPoint(x:667, y: 200)
enemy.physicsBody?.restitution = 0.5
enemy.physicsBody = SKPhysicsBody(circleOfRadius: 60)
enemy.physicsBody?.affectedByGravity = false
enemy.zPosition = 2
enemy.physicsBody?.linearDamping = 0
enemy.physicsBody?.isDynamic = true
enemy.physicsBody?.categoryBitMask = physicsCatagory.enemy
enemy.physicsBody?.collisionBitMask = physicsCatagory.me
enemy.physicsBody?.contactTestBitMask = physicsCatagory.me
addChild(enemy)
}
}
func didBegin(_ contact: SKPhysicsContact) {
let firstBody = contact.bodyA
let secondBody = contact.bodyB
if firstBody.categoryBitMask == physicsCatagory.me && secondBody.categoryBitMask == physicsCatagory.enemy || firstBody.categoryBitMask == physicsCatagory.enemy && secondBody.categoryBitMask == physicsCatagory.me {
died = true
restartScene()
}
}
var lose: SKLabelNode!
func restartScene(){
self.removeAllChildren()
self.removeAllActions()
died = false
if let nextScene = GameScene(fileNamed: "menuScene"){
nextScene.scaleMode = self.scaleMode
let transition = SKTransition.fade(withDuration: 1)
view?.presentScene(nextScene, transition: transition)
}
}
func createScene(){
me = self.childNode(withName: "me") as! SKSpriteNode
me.physicsBody = SKPhysicsBody(circleOfRadius: 20)
me.physicsBody?.affectedByGravity = false
me.physicsBody?.categoryBitMask = physicsCatagory.me
me.physicsBody?.collisionBitMask = physicsCatagory.enemy
me.zPosition = 2
self.physicsWorld.contactDelegate = self
let border = SKPhysicsBody (edgeLoopFrom: self.frame)
border.friction = 0
self.physicsBody = border
run(SKAction.repeatForever(SKAction.sequence([SKAction.run(createEnemy), SKAction.wait(forDuration: 4.0)])))
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches{
let location = touch.location(in: self)
me.run(SKAction.moveTo(x: location.x, duration: 0))
me.run(SKAction.moveTo(y: location.y, duration: 0))
allEnemiesMoveToTarget()
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches{
let location = touch.location(in: self)
me.run(SKAction.moveTo(x: location.x, duration: 0))
me.run(SKAction.moveTo(y: location.y, duration: 0))
allEnemiesMoveToTarget()
}
}
override func update(_ currentTime: TimeInterval) {
// Will iterate through dictonary and then call moveFollowerToTarget()
// thus giving each enemy a new movement action to follow.
allEnemiesMoveToTarget()
}
}