Я создаю новое игровое приложение в коде! Я создал несколько пузырьков, используя spriteKit. Я использовал текстуру для этого. Они беспорядочно летают по игровому полю. Когда они пересекаются друг с другом, они должны столкнуться и изменить свой путь.
Первая проблема: конечно, изображение пузыря в форме круга. Но при столкновении пузырьки касаются друг друга не в виде круга, а в виде квадрата
Вторая проблема: они цепляются друг за друга, я думаю, что это проблема первой проблемы!
Если вы знаете, как решить эту проблему, пожалуйста, помогите мне, потому что я не могу найти решение этой проблемы. Я думаю, что эту проблему можно решить с помощью маски, но я не знаю как. Большое спасибо)
это мой bubbleClass:
class SKButton: SKSpriteNode{
private var buttonTexture:SKTexture
override init(texture: SKTexture?, color: UIColor, size: CGSize) {
self.buttonTexture = texture!
super.init(texture:buttonTexture , color: .black, size: buttonTexture.size())
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}}
Это ViewController:
class GameViewController: UIViewController {
@IBOutlet weak var mySKView: SKView!
override func viewDidLoad() {
super.viewDidLoad()
if let view = mySKView {
let scene = GameScene(size: CGSize(width: 2048, height: 1536))
scene.scaleMode = .aspectFill
view.presentScene(scene)
view.ignoresSiblingOrder = true
view.showsFPS = true
view.showsNodeCount = true
}
}}
это GameScene:
class GameScene: SKScene {
private var arrayBubbles = [SKButton?]()
private var arrayVelosity = [CGPoint]()
private var bubbleMovePointsPerSecX = [CGFloat]()
private var bubbleMovePointsPerSecY = [CGFloat]()
private var currentVelosity:CGPoint!
private var lastUpdateTime: TimeInterval = 0
private var dt: TimeInterval = 0
private let min = 0
private let max = 3
private let bubbleTexture = SKTexture(imageNamed: "bubble")
private let playableRect: CGRect!
lazy var background: SKSpriteNode = {
let back = SKSpriteNode(imageNamed: "back")
back.position = CGPoint(x: self.size.width/2, y: size.height/2)
back.anchorPoint = CGPoint(x: 0.5, y: 0.5)
back.zPosition = -1
return back
}()
lazy var bubble1: SKButton = {
var button = SKButton(texture: bubbleTexture, color: .clear, size: bubbleTexture.size())
button.position = CGPoint(x: size.width/2, y: size.height - (size.height/3))
button.setScale(0)
button.zPosition = 1
button.name = "bubble1"
return button
}()
lazy var bubble2: SKButton = {
var button = SKButton(texture: bubbleTexture, color: .clear, size: bubbleTexture.size())
button.position = CGPoint(x: size.width/3, y: size.height/2)
button.setScale(0)
button.zPosition = 1
button.name = "bubble2"
return button
}()
lazy var bubble3: SKButton = {
var button = SKButton(texture: bubbleTexture, color: .clear, size: bubbleTexture.size())
button.position = CGPoint(x: size.width - (size.width/3), y: size.height/2)
button.setScale(0)
button.zPosition = 1
button.name = "bubble3"
return button
}()
override init(size: CGSize) {
let playableHeight = size.width/(16.0/9.0)
let playableMargin = (size.height - playableHeight)/2
playableRect = CGRect(x: 0, y: playableMargin, width: size.width, height: playableHeight)
super.init(size:size)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func didMove(to view: SKView) {
addChilds()
appendBubblesToArray()
setRandomBubbleSpead()
appendVelosityToArray()
showApearBubble()
}
private func addChilds(){
addChild(background)
addChild(bubble1)
addChild(bubble2)
addChild(bubble3)
}
private func appendBubblesToArray(){
arrayBubbles.append(bubble1)
arrayBubbles.append(bubble2)
arrayBubbles.append(bubble3)
}
private func setRandomBubbleSpead(){
for _ in min..<arrayBubbles.count{
let randomSpeadX = CGFloat.random(in: -200..<200)/CGFloat(Double.pi)
bubbleMovePointsPerSecX.append(randomSpeadX)
let randomSpeadY = CGFloat.random(in: -200..<200)/CGFloat(Double.pi)
bubbleMovePointsPerSecY.append(randomSpeadY)
}
}
private func appendVelosityToArray(){
for index in min..<arrayBubbles.count{
currentVelosity = CGPoint(x: bubbleMovePointsPerSecX[index], y: bubbleMovePointsPerSecY[index])
arrayVelosity.append(currentVelosity)
}
}
private func showApearBubble(){
let apearBubble = SKAction.scale(to: 1, duration: 0.5)
let action = [apearBubble]
bubble1.run(SKAction.sequence(action))
bubble2.run(SKAction.sequence(action))
bubble3.run(SKAction.sequence(action))
}
override func didEvaluateActions() {
checkColisions()
}
private func checkColisions(){
enumerateChildNodes(withName: "//*") { [weak self] node, _ in
guard let self = self else { return }
switch node.name{
case "bubble1":
self.checkBubbleIntersection(self.bubble1)
break
case "bubble2":
self.checkBubbleIntersection(self.bubble2)
break
case "bubble3":
self.checkBubbleIntersection(self.bubble3)
break
default:
return
}
}
}
private func hitBubble(_ index: Int){
arrayVelosity[index].y = -arrayVelosity[index].y
arrayVelosity[index].x = -arrayVelosity[index].x
}
private func checkBubbleIntersection(_ firstBubble: SKButton){
for bubble in arrayBubbles {
if firstBubble.name != bubble!.name{
if firstBubble.frame.insetBy(dx: 80,dy: 80).intersects(bubble!.frame){
guard let indexBubble = self.arrayBubbles.firstIndex(of: bubble) else { return }
self.hitBubble(indexBubble)
}
}
}
}
override func update(_ currentTime: TimeInterval) {
if lastUpdateTime > 0{
dt = currentTime - lastUpdateTime
} else{
dt = 0
}
lastUpdateTime = currentTime
for bubble in arrayBubbles{
if bubble != nil {
guard let index = arrayBubbles.firstIndex(of: bubble) else { return }
moveSprite(sprite: arrayBubbles[index]!, velosity: arrayVelosity[index])
boundsCheckBubbles(sprite: arrayBubbles[index]!, index: index)
}
}
}
private func moveSprite(sprite: SKButton, velosity: CGPoint){
let amountToMove = CGPoint(x: velosity.x * CGFloat(dt), y: velosity.y * CGFloat(dt))
sprite.position = CGPoint(x: sprite.position.x + amountToMove.x,
y: sprite.position.y + amountToMove.y)
}
private func boundsCheckBubbles(sprite: SKButton, index: Int){
let bottomLeft = CGPoint(x: 80, y: playableRect.minY)
let topRight = CGPoint(x: size.width-80, y: playableRect.maxY)
if sprite.position.x <= bottomLeft.x{
sprite.position.x = bottomLeft.x
arrayVelosity[index].x = -arrayVelosity[index].x
}
if sprite.position.x >= topRight.x{
sprite.position.x = topRight.x
arrayVelosity[index].x = -arrayVelosity[index].x
}
if sprite.position.y <= bottomLeft.y{
sprite.position.y = bottomLeft.y
arrayVelosity[index].y = -arrayVelosity[index].y
}
if sprite.position.y >= topRight.y{
sprite.position.y = topRight.y
arrayVelosity[index].y = -arrayVelosity[index].y
}
}}