Add RollkofferSimulator iOS SpriteKit arcade game

Complete implementation of a 2D top-down arcade collector game where players
control a rolling suitcase through an airport, collecting good dogs and green
people while avoiding bad dogs and gray people.

Features:
- Touch & drag controls for suitcase movement
- Automatic scrolling airport floor with tile pattern
- 4 entity types: good dogs (small/big), bad dogs, green/gray humans
- Spawn system with configurable distribution rates
- Collision detection with visual feedback effects
- Score tracking with high score persistence
- 90-second time limit with 10 dogs + 5 humans goal
- 3 lives system with invincibility frames
- Menu, Game, GameOver, and Victory scenes
- German UI text (Created by Ingo K.)

Technical:
- iOS 15+ with SpriteKit framework
- Modular architecture with Nodes, Managers, Scenes
- Physics-based collision detection
- UserDefaults for score persistence
This commit is contained in:
Claude
2025-12-19 16:47:49 +00:00
parent 8d4afcf0ad
commit 9e501cc4e8
22 changed files with 3228 additions and 0 deletions
@@ -0,0 +1,58 @@
//
// EntityType.swift
// RollkofferSimulator
//
// Created by Ingo K.
//
import Foundation
/// Types of dogs in the game
enum DogType {
case smallGood // 40x40, gold brown, +10 points
case bigGood // 70x70, gold brown, +25 points
case bad // 55x55, red outlined, -1 life
var points: Int {
switch self {
case .smallGood: return Constants.pointsSmallGoodDog
case .bigGood: return Constants.pointsBigGoodDog
case .bad: return 0
}
}
var isHarmful: Bool {
return self == .bad
}
var countsTowardGoal: Bool {
return self == .smallGood || self == .bigGood
}
}
/// Types of humans in the game
enum HumanType {
case green // 50x80, green, +15 points
case gray // 50x80, gray, -1 life
var points: Int {
switch self {
case .green: return Constants.pointsGreenHuman
case .gray: return 0
}
}
var isHarmful: Bool {
return self == .gray
}
var countsTowardGoal: Bool {
return self == .green
}
}
/// All entity types for spawn system
enum EntityType {
case dog(DogType)
case human(HumanType)
}
+103
View File
@@ -0,0 +1,103 @@
//
// GameState.swift
// RollkofferSimulator
//
// Created by Ingo K.
//
import Foundation
/// Possible game states
enum GameStateType {
case startScreen
case playing
case paused
case gameOver
case victory
}
/// Manages the current game state and statistics
class GameState {
// MARK: - Properties
private(set) var currentState: GameStateType = .startScreen
private(set) var score: Int = 0
private(set) var lives: Int = Constants.startLives
private(set) var dogsCollected: Int = 0
private(set) var humansCollected: Int = 0
private(set) var timeRemaining: TimeInterval = Constants.gameTime
var isInvincible: Bool = false
// MARK: - Computed Properties
var hasWon: Bool {
return dogsCollected >= Constants.targetDogs &&
humansCollected >= Constants.targetHumans
}
var hasLost: Bool {
return lives <= 0 || (timeRemaining <= 0 && !hasWon)
}
// MARK: - State Management
func setState(_ state: GameStateType) {
currentState = state
}
func reset() {
score = 0
lives = Constants.startLives
dogsCollected = 0
humansCollected = 0
timeRemaining = Constants.gameTime
isInvincible = false
currentState = .playing
}
// MARK: - Score Management
func addPoints(_ points: Int) {
score += points
}
func collectDog() {
dogsCollected += 1
}
func collectHuman() {
humansCollected += 1
}
// MARK: - Lives Management
func loseLife() -> Bool {
guard !isInvincible else { return false }
lives -= 1
return true
}
// MARK: - Time Management
func updateTime(delta: TimeInterval) {
timeRemaining = max(0, timeRemaining - delta)
}
// MARK: - Formatted Strings
var formattedTime: String {
let seconds = Int(timeRemaining)
return "\(seconds)s"
}
var formattedScore: String {
return "SCORE: \(score)"
}
var formattedDogs: String {
return "🐕 \(dogsCollected)/\(Constants.targetDogs)"
}
var formattedHumans: String {
return "👤 \(humansCollected)/\(Constants.targetHumans)"
}
var formattedLives: String {
return String(repeating: "❤️", count: lives)
}
}