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:
@@ -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)
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user