我正在制作一个游戏,玩家我想避免球进入屏幕。球将从任何角度进入,当球员与另一个球接触时,它就会结束。我唯一的问题是玩家的运动。我希望它有点像着名的蛇游戏,而玩家不会像蛇一样留下痕迹。因此,我希望玩家以某个方向以恒定速度移动,当玩家触摸屏幕的左侧时,玩家向左移动,当玩家触摸右侧时,玩家向右移动。但是当玩家接触到任何一方时,玩家不应该像90度或其他东西那样移动,它应该轻柔地移动到任何一方。因此,如果玩家想要移动90度,他/她将不得不将手指放在屏幕上更长时间。
在此视频中,您可以准确了解我希望玩家如何移动。虽然你可以忽略玩家留下的痕迹。 https://www.youtube.com/watch?v=GhwaZvsNAA0
这里有我的代码:
随机生成球的随机类:
import Foundation
import CoreGraphics
public extension CGFloat {
public static func randomBetweenNumbers(firstNum: CGFloat, secondNum:
CGFloat) -> CGFloat {
return CGFloat(arc4random()) / CGFloat(UINT32_MAX) * abs(firstNum -
secondNum) + firstNum
}
}
玩家类:
import SpriteKit
struct ColliderType {
static let Player: UInt32 = 1
static let Score: UInt32 = 2
static let Enemy: UInt32 = 3
}
class Player: SKSpriteNode {
func initialize() {
self.name = "Player"
self.zPosition = 1
self.anchorPoint = CGPoint(x: 0.5, y: 0.5)
self.physicsBody = SKPhysicsBody(circleOfRadius: self.size.height /
2)
self.physicsBody?.affectedByGravity = false
self.physicsBody?.categoryBitMask = ColliderType.Player
self.physicsBody?.collisionBitMask = ColliderType.Enemy
self.physicsBody?.contactTestBitMask = ColliderType.Score |
ColliderType.Enemy
}
}
这是gameplayscene类:
import SpriteKit
class GameplayScene: SKScene, SKPhysicsContactDelegate {
var player = Player()
var ball = SKSpriteNode()
var ballIsTouched = false
var scoreLabel = SKLabelNode()
var score = 0
var counter = Timer()
override func didMove(to view: SKView) {
initialize()
}
override func update(_ currentTime: TimeInterval) {
}
override func touchesBegan(_ touches: Set<UITouch>, with event:
UIEvent?) {
for touch in touches {
let location = touch.location(in: self)
if atPoint(location).name == "Retry" {
self.removeAllActions()
self.removeAllChildren()
initialize()
}
if atPoint(location).name == "Quit" {
let mainmenu = MainMenuScene(fileNamed: "MainMenuScene")
mainmenu!.scaleMode = .aspectFill
self.view?.presentScene(mainmenu!, transition:
SKTransition.fade(withDuration: TimeInterval(1)))
}
}
}
func didBegin(_ contact: SKPhysicsContact) {
var firstBody = SKPhysicsBody()
var secondBody = SKPhysicsBody()
if contact.bodyA.node?.name == "Player" {
firstBody = contact.bodyA
secondBody = contact.bodyB
} else {
firstBody = contact.bodyB
secondBody = contact.bodyA
}
if firstBody.node?.name == "Player" && secondBody.node?.name ==
"Score" {
incrementCoinScore()
secondBody.node?.removeFromParent()
}
if firstBody.node?.name == "Player" && secondBody.node?.name ==
"Enemy" {
playerDied()
firstBody.node?.removeFromParent()
}
}
func initialize() {
score = 0
physicsWorld.contactDelegate = self
createPlayer()
createBackground()
spawnEnemy1()
spawnEnemy2()
spawnEnemy3()
spawnEnemy4()
createLabel()
counter = Timer.scheduledTimer(timeInterval: TimeInterval(1),
target: self, selector: "incrementScore", userInfo: nil, repeats: true)
}
func createPlayer() {
player = Player(imageNamed: "Player")
player.initialize()
player.position = CGPoint(x: 0, y: 0)
self.addChild(player)
}
func createBackground() {
let bg = SKSpriteNode(imageNamed: "BG")
bg.name = "BG"
bg.anchorPoint = CGPoint(x: 0.5, y: 0.5)
bg.position = CGPoint(x: 0, y: 0)
self.addChild(bg)
}
func createEnemy1() {
let ball = SKSpriteNode(imageNamed: "Orange")
ball.name = "Enemy"
ball.anchorPoint = CGPoint(x: 0.5, y: 0.5)
ball.zPosition = 1
ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.size.height /
2)
ball.physicsBody?.categoryBitMask = ColliderType.Enemy
ball.physicsBody?.affectedByGravity = false
ball.physicsBody?.isDynamic = false
ball.position.y = self.size.height + 100
ball.position.x = CGFloat.randomBetweenNumbers(firstNum: -345,
secondNum: 345)
self.addChild(ball)
let destination = self.frame.height * 2
let move = SKAction.moveTo(y: -destination, duration:
TimeInterval(10))
let remove = SKAction.removeFromParent()
ball.run(SKAction.sequence([move, remove]), withKey: "MoveEnemy1")
}
func spawnEnemy1() {
let spawn = SKAction.run({ () -> Void in
self.createEnemy1()
})
let delay = SKAction.wait(forDuration: TimeInterval(1))
let sequence = SKAction.sequence([spawn, delay])
self.run(SKAction.repeatForever(sequence), withKey: "SpawnEnemy1")
}
func createEnemy2() {
let ball = SKSpriteNode(imageNamed: "Green")
ball.name = "Enemy"
ball.anchorPoint = CGPoint(x: 0.5, y: 0.5)
ball.zPosition = 1
ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.size.height /
2)
ball.physicsBody?.categoryBitMask = ColliderType.Enemy
ball.physicsBody?.affectedByGravity = false
ball.physicsBody?.isDynamic = false
ball.position.y = -self.size.height + 100
ball.position.x = CGFloat.randomBetweenNumbers(firstNum: -345,
secondNum: 345)
self.addChild(ball)
let destination = self.frame.height * 2
let move = SKAction.moveTo(y: destination, duration:
TimeInterval(10))
let remove = SKAction.removeFromParent()
ball.run(SKAction.sequence([move, remove]), withKey: "MoveEnemy2")
}
func spawnEnemy2() {
let spawn = SKAction.run({ () -> Void in
self.createEnemy2()
})
let delay = SKAction.wait(forDuration: TimeInterval(1))
let sequence = SKAction.sequence([spawn, delay])
self.run(SKAction.repeatForever(sequence), withKey: "SpawnEnemy2")
}
func createEnemy3() {
let ball = SKSpriteNode(imageNamed: "Blue")
ball.name = "Enemy"
ball.anchorPoint = CGPoint(x: 0.5, y: 0.5)
ball.zPosition = 1
ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.size.height /
2)
ball.physicsBody?.categoryBitMask = ColliderType.Enemy
ball.physicsBody?.affectedByGravity = false
ball.physicsBody?.isDynamic = false
ball.position.x = -self.size.width + 200
ball.position.y = CGFloat.randomBetweenNumbers(firstNum: -637,
secondNum: 637)
self.addChild(ball)
let destination = self.frame.height * 2
let move = SKAction.moveTo(x: destination, duration:
TimeInterval(10))
let remove = SKAction.removeFromParent()
ball.run(SKAction.sequence([move, remove]), withKey: "MoveEnemy3")
}
func spawnEnemy3() {
let spawn = SKAction.run({ () -> Void in
self.createEnemy3()
})
let delay = SKAction.wait(forDuration: TimeInterval(1))
let sequence = SKAction.sequence([spawn, delay])
self.run(SKAction.repeatForever(sequence), withKey: "SpawnEnemy3")
}
func createEnemy4() {
let ball = SKSpriteNode(imageNamed: "Yellow")
ball.name = "Enemy"
ball.anchorPoint = CGPoint(x: 0.5, y: 0.5)
ball.zPosition = 1
ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.size.height /
2)
ball.physicsBody?.categoryBitMask = ColliderType.Enemy
ball.physicsBody?.affectedByGravity = false
ball.physicsBody?.isDynamic = false
ball.position.x = self.size.width + 200
ball.position.y = CGFloat.randomBetweenNumbers(firstNum: -637,
secondNum: 637)
self.addChild(ball)
let destination = self.frame.height * 2
let move = SKAction.moveTo(x: -destination, duration:
TimeInterval(10))
let remove = SKAction.removeFromParent()
ball.run(SKAction.sequence([move, remove]), withKey: "MoveEnemy4")
}
func spawnEnemy4() {
let spawn = SKAction.run({ () -> Void in
self.createEnemy4()
})
let delay = SKAction.wait(forDuration: TimeInterval(1))
let sequence = SKAction.sequence([spawn, delay])
self.run(SKAction.repeatForever(sequence), withKey: "SpawnEnemy4")
}
func createLabel() {
scoreLabel.zPosition = 3
scoreLabel.position = CGPoint(x: -320, y: 600)
scoreLabel.fontName = "Verdana"
scoreLabel.fontSize = 70
scoreLabel.text = "0"
self.addChild(scoreLabel)
}
func incrementScore() {
score += 1
scoreLabel.text = String(score)
}
func incrementCoinScore() {
score += 5
}
func playerDied() {
counter.invalidate()
let highscore = GameManager.instance.getHighscore()
if highscore < score {
GameManager.instance.setHighscore(highscore: score)
}
let retry = SKSpriteNode(imageNamed: "Retry")
let quit = SKSpriteNode(imageNamed: "Quit")
retry.name = "Retry"
retry.anchorPoint = CGPoint(x: 0.5, y: 0.5)
retry.position = CGPoint(x: -150, y: -50)
retry.zPosition = 2
retry.setScale(0)
quit.name = "Quit"
quit.anchorPoint = CGPoint(x: 0.5, y: 0.5)
quit.position = CGPoint(x: 150, y: -50)
quit.zPosition = 2
quit.setScale(0)
let scaleUp = SKAction.scale(to: 1, duration: TimeInterval(0.5))
retry.run(scaleUp)
quit.run(scaleUp)
self.addChild(retry)
self.addChild(quit)
}
}
答案 0 :(得分:0)
我必须多次阅读你的问题以了解你的想法。但是因为我玩了#34; achtung die曲线&#34;回到过去,它终于成了感觉。这是你想要的一个工作实例。复制 - 粘贴 - 检查
随意询问您是否完全理解
class Player: SKSpriteNode {
let playerSpeed = 3
let turnRate:CGFloat = 0.03
var isAlive = true
// this is the initializer for the class. when you make an instance
// of your class, this function will be called. and this is were you setup your player.
init() {
//create a texture for your player
let texture = SKTexture(imageNamed: "player")
//setup other stuff you already have in your own code.
// when you create an instance in your createPlayer function do like this
// let player = Player()
// player.position = CGPoint(x: 0, y: 0)
//self.addChild(player)
// note that you do not need to call the init manually.
// since your player class is an subclass of SKSpriteNode you have to call super.init().
// This is the initializer of your superclass (SKSpriteNode),
// I would suggest you read more about subclassing and this will make sens.
super.init(texture: texture, color: UIColor.clear, size:texture.size())
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func turnLeft(){
// add to the current rotation by a factor of turnRate
self.run(SKAction.rotate(byAngle: turnRate, duration: 0))
}
func turnRight(){
// subtract from the current rotation by a factor of turnRate
self.run(SKAction.rotate(byAngle: -turnRate, duration: 0))
}
func move(){
// this gives us a position in the scene space that is 3 points(or what ever value playerSpeed is)
// infront of the player. basicly we convert (x:0, y:3) from the player coordinates. to the scene coordinate.
// Even when the player rotates in the scene. the (x:0, y:3) is allways the same in the player coordinate.
let newPosition = convert(CGPoint(x:0, y:playerSpeed), to: scene!)
self.position = newPosition
}
}
class GameScene: SKScene {
let player = Player()
var shouldTurnLeft = false
var shouldTurnRight = false
override func didMove(to view: SKView) {
addChild(player)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touchLocation = touches.first?.location(in: self)
if (touchLocation?.x)! > 0{
shouldTurnRight = true
}
else if (touchLocation?.x)! < 0{
shouldTurnLeft = true
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
shouldTurnLeft = false
shouldTurnRight = false
}
override func update(_ currentTime: TimeInterval) {
// if the player is alive. move the player every frame
if player.isAlive{
player.move()
if shouldTurnLeft {
player.turnLeft()
}
if shouldTurnRight{
player.turnRight()
}
}
// Called before each frame is rendered
}
}