Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions QuackFight/Sources/Entities/ProjectileEntity.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,28 @@ class ProjectileEntity: GKEntity {
// Issue #38: Attach all 4 components
// SpriteComponent handles the visual node
let spriteComponent = SpriteComponent(imageName: imageName)

// Issue #94: Add a visual trail
let trail = SKEmitterNode()
trail.particleTexture = SKTexture(imageNamed: "spark") // Will safely fallback to a square if "spark" is missing
trail.particleBirthRate = 60
trail.particleLifetime = 0.4
trail.particlePositionRange = CGVector(dx: 10, dy: 10)
trail.particleScale = 0.2
trail.particleScaleSpeed = -0.5
trail.particleAlpha = 0.8
trail.particleAlphaSpeed = -2.0
trail.particleColor = .white
trail.particleColorBlendFactor = 1.0
trail.emissionAngleRange = .pi * 2
trail.particleSpeed = 10
trail.zPosition = -1 // Render behind the projectile

// We add the trail to the sprite component so it travels with the bread
// To make particles linger in world space, the `ThrowSystem` or `GameScene` could set `trail.targetNode = scene`.
trail.name = "trailEmitter"
spriteComponent.node.addChild(trail)

addComponent(spriteComponent)

// TransformComponent handles position/rotation data
Expand Down
3 changes: 3 additions & 0 deletions QuackFight/Sources/Scenes/GameScene.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ class GameScene: SKScene {
entity.update(deltaTime: dt)
}

// Render System (End of frame synchronization)
RenderSystem.shared.update(entities: self.entities, deltaTime: dt)

self.lastUpdateTime = currentTime
}

Expand Down
36 changes: 35 additions & 1 deletion QuackFight/Sources/Systems/Render/RenderSystem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,38 @@
import SpriteKit
import GameplayKit


final class RenderSystem {

static let shared = RenderSystem()
private init() {}

func update(entities: [GKEntity], deltaTime: TimeInterval) {
for entity in entities {
guard let spriteComp = entity.component(ofType: SpriteComponent.self),
let transformComp = entity.component(ofType: TransformComponent.self) else {
continue
}

// 1. Sync Position
spriteComp.node.position = transformComp.position

// 2. Sync Facing (PlayerEntity specific)
if let player = entity as? PlayerEntity {
spriteComp.node.xScale = abs(spriteComp.node.xScale) * player.facing
}

// 3. Sync Rotation
// If the entity has velocity (e.g. Bread), point it along its trajectory.
if let velocityComp = entity.component(ofType: VelocityComponent.self) {
let dx = velocityComp.vector.dx
let dy = velocityComp.vector.dy
if dx != 0 || dy != 0 {
spriteComp.node.zRotation = atan2(dy, dx)
}
} else {
// Default transform rotation
spriteComp.node.zRotation = transformComp.rotation
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@
trajectoryNode.lineWidth = 4.0
trajectoryNode.alpha = 0.6 // Agak transparan agar tidak menutupi karakter
trajectoryNode.zPosition = 10 // Pastikan garis berada di atas background
// Make it a dashed/dotted line
trajectoryNode.strokeTexture = SKTexture(imageNamed: "spark") // Optional
let pattern: [CGFloat] = [10.0, 10.0]

Check warning on line 58 in QuackFight/Sources/Systems/Render/TrajectoryRenderSystem.swift

View workflow job for this annotation

GitHub Actions / build

immutable value 'pattern' was never used; consider replacing with '_' or removing it

Check warning on line 58 in QuackFight/Sources/Systems/Render/TrajectoryRenderSystem.swift

View workflow job for this annotation

GitHub Actions / build

immutable value 'pattern' was never used; consider replacing with '_' or removing it

Check warning on line 58 in QuackFight/Sources/Systems/Render/TrajectoryRenderSystem.swift

View workflow job for this annotation

GitHub Actions / build

immutable value 'pattern' was never used; consider replacing with '_' or removing it

Check warning on line 58 in QuackFight/Sources/Systems/Render/TrajectoryRenderSystem.swift

View workflow job for this annotation

GitHub Actions / build

immutable value 'pattern' was never used; consider replacing with '_' or removing it
// Note: SKShapeNode doesn't support lineDashPattern natively unless using CGPath stroking,
// Actually it's easier to use CGPath(dashingWithPhase:lengths:) when drawing.
}

/// Jangan lupa panggil ini sekali saat GameScene baru mulai dimuat (didMove)
Expand Down Expand Up @@ -104,6 +109,7 @@
}
}

trajectoryNode.path = path
let dashedPath = path.copy(dashingWithPhase: 0, lengths: [10.0, 10.0])
trajectoryNode.path = dashedPath
}
}
Loading