У меня много проблем с выяснением, почему мой снаряд не будет снимать изображение Люка. Я пробовал много разных методов, чтобы попытаться противостоять этому, но ни одна из стратегий, похоже, не сработала. Мне бы очень хотелось заранее получить руководство и извинения за количество кода.
Я пытался изменить расположение некоторых элементов, но, что бы я ни пытался, снаряд не будет отображаться. Я, честно говоря, не уверен, что еще можно попробовать.
import SpriteKit
import GameplayKit
import AVFoundation
import CoreMotion
func +(left: CGPoint, right: CGPoint) -> CGPoint {
return CGPoint(x: left.x + right.x, y: left.y + right.y)
}
func -(left: CGPoint, right: CGPoint) -> CGPoint {
return CGPoint(x: left.x - right.x, y: left.y - right.y)
}
func *(point: CGPoint, scalar: CGFloat) -> CGPoint {
return CGPoint(x: point.x * scalar, y: point.y * scalar)
}
func /(point: CGPoint, scalar: CGFloat) -> CGPoint {
return CGPoint(x: point.x / scalar, y: point.y / scalar)
}
#if !(arch(x86_64) || arch(arm64))
func sqrt(a: CGFloat) -> CGFloat {
return CGFloat(sqrtf(Float(a)))
}
#endif
extension CGPoint {
func length() -> CGFloat {
return sqrt(x*x + y*y)
}
func normalized() -> CGPoint {
return self / length()
}
}
class GameScene: SKScene {
struct PhysicsCategory {
static let none : UInt32 = 0
static let all : UInt32 = UInt32.max
static let enemy : UInt32 = 0b1 // 1 This is a way of
saying each of the 32-bits in the integer represents a single
category
(and hence you can have 32 categories max).
static let projectile: UInt32 = 0b10 // 2 Same as 1
}
// let Interaction:UInt32 = 0x1 << 1
// let CollisionCategory:UInt32 = 0x1 << 0
var boxlabel:SKShapeNode!
var starfield:SKEmitterNode!
var player: SKSpriteNode!
var player2 : SKSpriteNode!
var ScoreLabel: SKLabelNode!
var score: Int = 0 {
didSet {
ScoreLabel.text = "Score: \(score)"
}
}
var seconds = 120
@objc var timer: Timer?
override func didMove(to view: SKView) {
func main() {
// Create sprite
let enemy = SKSpriteNode(imageNamed: "luke")
enemy.physicsBody = SKPhysicsBody(rectangleOf: enemy.size) //
This allows the card size to be equal to a rectangle
enemy.physicsBody?.isDynamic = true // This says that the
physics engine will not control the card
enemy.physicsBody?.categoryBitMask = PhysicsCategory.enemy// 3
Set the category bit mask to be the main category defined earlier
enemy.physicsBody?.contactTestBitMask =
PhysicsCategory.projectile // 4 contactTestBitMask indicates when
categories this object notify the contact listener when they
intersect.
You choose projectiles here
enemy.physicsBody?.collisionBitMask = PhysicsCategory.none // 5
collisionBitMask indicates what categories of objects this object
that
the physics engine handle contact responses to (i.e. bounce off
of).
You don't want the monster and projectile to bounce off each other
—
it's OK for them to go right through each other in this game — so
you
set this to .none.
// Determine where to spawn the card along the Y axis
let actualY = random(min: enemy.size.width/2, max: size.width -
enemy.size.width/2)
// Position the card slightly off-screen along the right edge,
// and along a random position along the Y axis as calculated
above
enemy.position = CGPoint(x: actualY, y: size.width +
enemy.size.width/2)
// Add the card to the scene
addChild(enemy)
// Determine speed of the card
let actualDuration = random(min: CGFloat(2.0), max:
CGFloat(6.0))
// Create the actions
let actionMove = SKAction.move(to: CGPoint(x: actualY, y: -
enemy.size.width/10),
duration:
TimeInterval(actualDuration))
let actionMoveDone = SKAction.removeFromParent()
enemy.run(SKAction.sequence([actionMove, actionMoveDone]))
}
player = SKSpriteNode(imageNamed: "spaceship-modified")
// The line below with the numbers 45, 25 and 540 are also stubs
player.position = CGPoint(x: self.frame.size.width/45, y:
player.frame.size.height/25 - 410)
addChild(player)
physicsWorld.gravity = .zero
physicsWorld.contactDelegate = self
run(SKAction.repeatForever(
SKAction.sequence([
SKAction.run(main),
SKAction.wait(forDuration: 1.0)
])
))
func random() -> CGFloat {
return CGFloat(Float(arc4random()) / 4294967295)
}
func random(min: CGFloat, max: CGFloat) -> CGFloat {
return random() * (max - min) + min
}
func touchesEnded(_ touches: Set<UITouch>, with event:
UIEvent?) {
// 1 - Choose one of the touches to work with
guard let touch = touches.first else {
return
}
let touchLocation = touch.location(in: self)
// 2 - Set up initial location of projectile
let projectile = SKSpriteNode(imageNamed: "projectile")
projectile.position = player.position
projectile.physicsBody = SKPhysicsBody(circleOfRadius:
projectile.size.width/2)
projectile.physicsBody?.isDynamic = true
projectile.physicsBody?.categoryBitMask =
PhysicsCategory.projectile
projectile.physicsBody?.contactTestBitMask =
PhysicsCategory.enemy
projectile.physicsBody?.collisionBitMask = PhysicsCategory.none
projectile.physicsBody?.usesPreciseCollisionDetection = true
// 3 - Determine offset of location to projectile
let offset = touchLocation - projectile.position
// 4 - Bail out if you are shooting down or backwards
if offset.x < 0 { return }
// 5 - OK to add now - you've double checked position
addChild(projectile)
// 6 - Get the direction of where to shoot
let direction = offset.normalized()
// 7 - Make it shoot far enough to be guaranteed off screen
let shootAmount = direction * 1000
// 8 - Add the shoot amount to the current position
let realDest = shootAmount + projectile.position
// 9 - Create the actions
let actionMove = SKAction.move(to: realDest, duration: 4.0)
let actionMoveDone = SKAction.removeFromParent()
projectile.run(SKAction.sequence([actionMove, actionMoveDone]))
}
}
}
func projectileDidCollideWithMonster(projectile: SKSpriteNode,
enemy: SKSpriteNode) {
print("Hit")
projectile.removeFromParent()
enemy.removeFromParent()
}
extension GameScene: SKPhysicsContactDelegate {
func didBegin(_ contact: SKPhysicsContact) {
// 1
var firstBody: SKPhysicsBody
var secondBody: SKPhysicsBody
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
firstBody = contact.bodyA
secondBody = contact.bodyB
} else {
firstBody = contact.bodyB
secondBody = contact.bodyA
}
// 2
if ((firstBody.categoryBitMask & PhysicsCategory.enemy != 0) &&
(secondBody.categoryBitMask & PhysicsCategory.projectile != 0)) {
if let enemy = firstBody.node as? SKSpriteNode,
let projectile = secondBody.node as? SKSpriteNode {
projectileDidCollideWithMonster(projectile: projectile, enemy:
enemy )
}
}
}
}
Нет сообщений об ошибках, но снаряд должен стрелять "Люк"