-
Notifications
You must be signed in to change notification settings - Fork 0
/
Projectile.swift
135 lines (109 loc) · 3.51 KB
/
Projectile.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//
// Projectile.swift
// StepQuest
//
// Created by Max Hakin on 12/12/2023.
//
import Foundation
import SpriteKit
class Projectile: SKNode {
var imageFile: String
var damage: Int
var damageRadius: CGFloat
var moveSpeed: CGFloat
var projImage: SKSpriteNode
var target: Enemy
var lastPos: CGPoint = CGPoint(x: 0, y: 0)
enum ProjectileType {
case bullet1
case bullet2
case bullet3
case bomb1
case bomb2
case bomb3
var stats: (imageFile: String, damage: Int, damageRadius: CGFloat, moveSpeed: CGFloat) {
switch self {
case .bullet1:
return ("bullet1", 30, 20, 200)
case .bullet2:
return ("bullet1", 45, 25, 210)
case .bullet3:
return ("bullet2", 60, 30, 220)
case .bomb1:
return ("bomb1", 50, 50, 150)
case .bomb2:
return ("bomb1", 65, 60, 160)
case .bomb3:
return ("bomb2", 80, 70, 170)
}
}
}
var projectile: ProjectileType
init(projectileType: String, target: Enemy) {
switch projectileType {
case "bullet1":
projectile = .bullet1
case "bullet2":
projectile = .bullet2
case "bullet3":
projectile = .bullet3
case "bomb1":
projectile = .bomb1
case "bomb2":
projectile = .bomb2
case "bomb3":
projectile = .bomb3
default:
projectile = .bullet1
}
let stats = projectile.stats
imageFile = stats.imageFile
damage = stats.damage
damageRadius = stats.damageRadius
moveSpeed = stats.moveSpeed
projImage = SKSpriteNode(imageNamed: imageFile)
self.target = target
super.init()
self.zPosition = 4
addChild(projImage)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func update() {
}
func damageEnemy() {
target.takeDamage(damage: damage)
}
func move(deltaTime: TimeInterval) {
// Calculate the distance between the current position and the target
let dx = target.position.x - position.x
let dy = target.position.y - position.y
let distance = hypot(dx, dy)
// Calculate the angle between current position and target position
let angle = atan2(dy, dx)
// Rotate projectile to face target
projImage.zRotation = angle + .pi / 2
// Calculate the x and y components of the velocity
let velocityX = cos(angle) * moveSpeed
let velocityY = sin(angle) * moveSpeed
// Move the projectile
let deltaX = velocityX * CGFloat(deltaTime)
let deltaY = velocityY * CGFloat(deltaTime)
position.x += deltaX
position.y += deltaY
// Check if the projectile has reached the target, if it has damage target and remove
if distance <= moveSpeed * CGFloat(deltaTime) {
damageEnemy()
removeFromParent()
}
// Fixes a bug of frozen projectiles
if lastPos == self.position {
removeFromParent()
}
lastPos = self.position
}
deinit {
print("Projectile has been removed")
}
}