Mit Passion und Hingabe entwickle ich als Freiberuflicher neben meinem Job diverse Apps.
Endlich fertig. Drop Shopper In App Preview!
Drop Shopper navigation
Do
15
Feb
2018
In Game Preview
Jimmy rennt in seiner Welt!
Hier zeige ich mal eine Preview wie das Game später aussehen wird.
Jimmy rennt in einer Welt aus Plattformen und Fallen. Hier sammelt Jimmy Coins und Super Coins.
Wenn Jimmy alle Super Coins eines Levels einsammelt bekommt Jimmy ein Extra Leben geschenkt.
Jimmy hat ein wenig Parcours Style. Jimmy rennt, springt und performt double jumps um die Hindernisse zu Überwinden. Jimmy nutzt Springfedern um richtig hoch zu springen und schwing mit Seilen über größere Distanzen als er springen kann.
Super Jimmy.
Bis hierher war es ein schönes Stück Arbeit.
Jimmy lebt in einer simulierten Welt in der physikalische Gesetze mittels Physics Engine implementiert und berechnet werden. Coins können eigesammelt werden, Jimmy kann springen, double jumpen und mit einem Gleitschirm auch größere Distanzen überwinden.
Sowas muss alles animiert, programmiert und implementiert werden.
Die Plattformen werden über so genannte Tiles in Jimmy's Welt transferiert. Damit Jimmy nicht durch diese hindurch fällt, wir jedem Tile ein PhysicsBody verpasst. Dies geschieht beim einlesen der Tiles. Dabei werden mit Hilfe zweier Schleifen die Tiles in X-Richtung und Y-Richtung durchlaufen. Jedem Tile, dass über UserData als "ground" markiert wurde wird so ein Physics Body verpasst.
In SpriteKit kann man hierfür einen Editor nutzen. Die Tiles aus dem Editor werden dann als SKTileMapNode eingelesen.
Das schaut dann etwa so aus:
if let levelNode = SKNode.unarchiveFromFile(file: level) {
mapNode = levelNode
mapNode.zPosition = GameConstants.ZPositions.worldZ
addChild(mapNode)
}
//get tile map
if let groundTiles = mapNode.childNode(withName: GameConstants.StringConstants.groundTilesString) as? SKTileMapNode {
tileMap = groundTiles
tileMap.scale(to: frame.size, width: false, multiplier: 1.0)
/*add physicsBody to all ground tiles
The function iterates all tiles im Tilmap with userData Type of "ground"
and adds a physiscs Body */
PhysicsHelper.addPhysicsBody(to: tileMap, and: "ground")
Die Physics Helper Klasse erzeugt dann eine Physikalisch feste Linie zwischen zwei Koordinaten meiner Tiles:
static func addPhysicsBody(to tileMap: SKTileMapNode, and tileInfo: String) {
let tileSize = tileMap.tileSize
//determine type of tile in tilemap
//iterate all rows
for row in 0..<tileMap.numberOfRows {
var tiles = [Int]()
//iterate all columns
for column in 0..<tileMap.numberOfColumns {
let tiledefinition = tileMap.tileDefinition(atColumn: column, row: row)
let isUsedTile = tiledefinition?.userData?[tileInfo] as? Bool
if isUsedTile ?? false { tiles.append(1) }
else { tiles.append(0) }
}
if tiles.contains(1) {
var platform = [Int]()
for (index,tile) in tiles.enumerated() {
if tile == 1 && index < (tileMap.numberOfColumns - 1) { platform.append(index) }
else if !platform.isEmpty {
let x = CGFloat(platform[0]) * tileSize.width
let y = CGFloat(row) * tileSize.height
let tileNode = GroundNode(with: CGSize(width: tileSize.width * CGFloat(platform.count), height: tileSize.height))
tileNode.position = CGPoint(x: x, y: y)
tileNode.lightingBitMask = 1
tileNode.shadowCastBitMask = 1
tileNode.shadowedBitMask = 1
tileNode.anchorPoint = CGPoint.zero
tileMap.addChild(tileNode)
platform.removeAll()
}
}
}
}
}
Hier gibt es ein kleines Problem. Jimmy kann so nicht von unten auf die Platformen springen, da er sich hier immer den Kopf stossen würde.
Daher müssen wir der Welt erklären, dass die Physikalische feste Linie nur dann aktiv ist, wenn Jimmy sich oberhalb der Platform befindet.
Dies macht man am besten in der didSimulatePhysics Methode des GameLoops.
Hierbei handelt es sich um eine Methode die bei jedem Durchlauf eines GameLoops aufgerufen wird nachdem die PhysicsEngine Ihre Berechnungen in der simulierten Welt durchgeführt hat.
//MARK: - didSimulantePhysics
override func didSimulatePhysics() {
//activate tilemap platforms PhysicsBodys
for node in tileMap[GameConstants.StringConstants.groundNodeName] {
if let groundNode = node as? GroundNode {
let groundY = (groundNode.position.y + groundNode.size.height) * tileMap.yScale
let playerY = jimmy.position.y - jimmy.size.height / 3
groundNode.isActivatedBody = playerY > groundY
}
}
Do
15
Feb
2018
Jimmy's Welt
Auch hier muss ich aufgrund meiner beschränkten künstlerischen Fähigkeiten auf bestehende Assets ausweichen. Zum Glück gibt es hier mittlerweile ein wenig Angebot.
Ja Jimmy, auch Deine Welt ist zum größten Teil käuflich erworben.
Do
15
Feb
2018
Making of "Running Jimmy"
Die Wahl der Entwicklungsumgebung
Da ich mich im Moment ziemlich gut mit Swift und XCode auskenne, ist meine Wahl für das erste iOS Game auf XCode und SpriteKit gefallen.
Dies schränkt meine Möglichkeiten auf das Apple Universum ein. Das heißt, das das fertige Spiel leicht auf Mac, iOS und Apple TV zu portieren ist. Android, PC, XBox und Playstation Versionen können mit XCode und SpriteKit nicht erstellt werden.
Für zukünftige Projekte werde ich mir Unity etwas näher ansehen. Hier wird mit C# gearbeitet und es sollte möglich sein leicht auf alle genannten Systeme zu portieren.
Di
08
Mär
2016
Cloud Kit in School Manager
Da hätten wir eine weitere App in der Entwicklung
So schauts beim Entwickeln einer App aus.
Wahnsinnig viel Code und Dateien.
Ich bin selber immer wieder von der Menge an Daten überrascht.