
Hallo allerseits! Im Vorgriff auf den Start des Kurses
„iOS-Entwickler. Grundkurs “haben wir eine weitere
offene Lektion organisiert . Dieses Webinar richtet sich an Personen, die Erfahrung in der Entwicklung in beliebigen Sprachen und Plattformen haben, aber die Swift-Sprache lernen und die Entwicklung für iOS beherrschen möchten. In der Lektion haben wir die
Syntax und die Schlüsselkonstrukte der Swift-Sprache eingehend untersucht und uns mit den wichtigsten Entwicklungswerkzeugen vertraut gemacht.
Die Teilnehmer des Webinars lernten:
- Was ist die Swift-Sprache, was sind ihre Merkmale?
- Wie die Xcode-Entwicklungsumgebung Ihnen den Einstieg erleichtert
- wie man ein einfaches Spiel für iOS erstellt.
Das Webinar wurde von
Alexei Sobolevsky , einem iOS-Entwickler bei Yandex, durchgeführt.
Mach es selbst Schlange
Für die Arbeit haben wir die integrierte Entwicklungsumgebung
Xcode verwendet . Dies ist eine praktische, kostenlose und funktionale Umgebung, die von Apple erstellt wurde.
Gleich zu Beginn haben wir ein neues Projekt erstellt und den Grundsatz der „Spiel“ -Dateien ausgewählt:

Ohne weiteres nannten sie das Projekt „Snake“. Alle Einstellungen wurden standardmäßig beibehalten, um sicherzustellen, dass sich SpriteKit in der Zeile Game Technology befindet.
Details zur Erstellung des Projekts.Nachdem Sie die oben genannten Aktionen ausgeführt haben, wird im linken Teil des Fensters eine Liste der Dateien angezeigt, die automatisch für unser Projekt erstellt wurden. Eine der wichtigsten Dateien ist
AppDelegate.swift , mit deren Hilfe das System mit unserem Code kommunizieren kann, wenn wichtige Ereignisse für die Anwendung
vorliegen (Starten, Drücken, Klicken auf den Link usw.). Code dieser Datei:
Ebenso wichtige Dateien sind
GameScene.swift und
GameViewController.swift . Die GameScene-Klasse erstellt die Szene, und der GameViewController ist für einen Bildschirm der angezeigten Anwendung verantwortlich (ein Bildschirm - ein GameViewController). Natürlich wird diese Regel nicht immer unterstützt, aber im Allgemeinen funktioniert sie. Da unsere Anwendung recht einfach ist, haben wir nur einen GameViewController. Beginnen wir mit ihm.
Schreiben eines GameViewControllers
Wir werden den Standardcode löschen. Der View Controller verfügt über verschiedene Methoden, die je nach Status des Bildschirms funktionieren. Zum Beispiel wird
viewDidLoad()
ausgelöst, wenn alle Bildschirmelemente bereits geladen wurden und der Bildschirm
viewDidLoad()
auf dem Smartphone angezeigt wird. Da wir ein Spiel haben, müssen wir die Spielszene in unserem View Controller platzieren (hier läuft die Schlange und alle anderen Ereignisse des Spiels treten auf).
Erstellen Sie eine Szene:
let scene = GameScene(size: view.bounds.size)
let ist eine Konstante und ein Schlüsselwort. Swift verwendet auch das Schlüsselwort var, das zum Definieren einer Variablen erforderlich ist. Mit
var können wir den Wert von Variablen viele Male ändern, während das Programm ausgeführt wird. Mit let können wir den Wert von Variablen nach der Initialisierung nicht ändern.
Jetzt müssen wir sicherstellen, dass die Ansicht, in der wir die erstellte Szene platzieren, dem gewünschten Typ entspricht. Verwenden Sie dazu das
Guard- Konstrukt - dies ist dasselbe, als
if
, nur umgekehrt (falls nicht):
guard let skView = view as? SKView else { return }
Nachdem wir sichergestellt haben, dass das Bildschirmelement dem gewünschten Typ entspricht, fügen wir unsere Szene hinzu:
skView.presentScene(scene)
Sie müssen auch die Anzahl der Bilder pro Sekunde (FPS) anzeigen:
skView.showsFPS = true
Zeigen Sie dann die Anzahl der Elemente aller Art in der Szene an:
skView.showsNodeCount = true
Lassen Sie die Elemente unabhängig von ihrer Reihenfolge in der Hierarchie der Elemente auf dem Bildschirm angezeigt werden:
skView.ignoresSiblingOrder = true
Und vergessen Sie nicht, dass unsere Szene auf die gesamte Bildschirmbreite ausgedehnt werden sollte:
scene.scaleMode = .resizeFill
Hier ist der endgültige Code für die Datei
GameViewController.swift :
import UIKit import SpriteKit import GameplayKit class GameViewController: UIViewController { override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() setup() } private func setup() { guard let skView = view as? SKView else { return } let scene = GameScene(size: view.bounds.size) skView.showsFPS = true skView.showsNodeCount = true skView.ignoresSiblingOrder = true scene.scaleMode = .resizeFill skView.presentScene(scene) } }
Details zum Erstellen der Datei GameViewController.swift.Wir haben die Szene erstellt, aber sie ist leer. Wenn wir den Emulator jetzt ausführen, wird nur ein schwarzer Bildschirm angezeigt.
Eine GameScene schreiben
Wie beim letzten Mal löschen wir den größten Teil des Codes und nehmen dann
die erforderlichen Einstellungen für die Szene vor . Es hat auch seine eigenen Methoden. Da wir beispielsweise unsere Szene zum ViewController hinzugefügt haben, benötigen wir die
didMove()
-Methode:
override func didMove(to view: SKView) { setup(in: view) }
Wenn das Spiel beginnt, wird die
Update()
-Methode für jeden Frame aufgerufen:
override func update(_ currentTime: TimeInterval) { snake?.move() }
Und wir brauchen auch einige Handler, um auf den Bildschirm zu tippen:
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { guard let touchedNode = findTouchedNode(with: touches) else { return }
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) { guard let touchedNode = findTouchedNode(with: touches) else { return }
Wie Sie wissen, ist Swift berühmt für das Vorhandensein von
syntaktischem Zucker . Syntaktischer Zucker - dies sind technische Aspekte, die das Leben des Entwicklers vereinfachen und das Schreiben von Code beschleunigen. All dies hilft sehr beim Aufbau der Szene, was wir jetzt tun werden. Stellen Sie zunächst die Farbe ein:
backgroundColor = SKColor.white
Da die Schlange in einem Flugzeug arbeitet, benötigen wir keine Physik, und Sie können sie ausschalten, damit die Schlange nicht aufgrund der Schwerkraft herunterfällt. Außerdem brauchen wir das Spiel nicht zum Drehen usw.:
physicsWorld.gravity = .zero physicsWorld.contactDelegate = self physicsBody = SKPhysicsBody(edgeLoopFrom: frame) physicsBody?.allowsRotation = false physicsBody?.categoryBitMask = CollisionCategories.edgeBody physicsBody?.collisionBitMask = CollisionCategories.snake | CollisionCategories.snakeHead view.showsPhysics = true
Erstellen Sie nun die Schaltflächen:
let counterClockwiseButton = ControlsFactory.makeButton(at: CGPoint(x: scene.frame.minX + 30, y: scene.frame.minY + 50), name: .counterClockwiseButtonName) addChild(counterClockwiseButton) let clockwiseButton = ControlsFactory.makeButton(at: CGPoint(x: scene.frame.maxX - 90, y: scene.frame.minY + 50), name: .clockwiseButtonName) addChild(clockwiseButton)
Wenn Sie einen Code geschrieben haben, sollten Sie überlegen, ob der Code verbessert oder überarbeitet werden kann, damit er in Zukunft
wiederverwendet werden
kann . Schauen Sie, wir haben grundsätzlich zwei Schaltflächen auf dem Bildschirm, für deren Erstellung derselbe Code verwendet wird. Dieser Code kann also in einer separaten Funktion entfernt werden.
Erstellen Sie dazu eine neue Klasse und entsprechend die Datei
ControlsFactory.swift mit dem folgenden Code:
import SpriteKit final class ControlsFactory { static func makeButton(at position: CGPoint, name: String) -> SKShapeNode { let button = SKShapeNode() button.path = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: 45, height: 45)).cgPath button.position = position button.fillColor = .gray button.strokeColor = UIColor.lightGray.withAlphaComponent(0.7) button.lineWidth = 10 button.name = name return button } }
Um einen zufälligen Apfel zu zeichnen, den unsere Schlange „frisst“,
erstellen Sie die Apple-Klasse und die
Apple.swift- Datei:
import SpriteKit final class Apple: SKShapeNode { let diameter: CGFloat = 10 convenience init(at point: CGPoint) { self.init() path = UIBezierPath(ovalIn: CGRect(x: -diameter/2, y: -diameter/2, width: diameter, height: diameter)).cgPath fillColor = .red strokeColor = UIColor.red.withAlphaComponent(0.7) lineWidth = 5 position = point physicsBody = SKPhysicsBody(circleOfRadius: diameter / 2, center: .zero) physicsBody?.categoryBitMask = CollisionCategories.apple } }
Und wir beschreiben unseren Apfel mit der Funktion
createApple()
in
GameScene.swift :
private func createApple() { let padding: UInt32 = 15 let randX = CGFloat(arc4random_uniform(UInt32(gameFrameRect.maxX) - padding) + padding) let randY = CGFloat(arc4random_uniform(UInt32(gameFrameRect.maxY) - padding) + padding) let apple = Apple(at: CGPoint(x: randX, y: randY).relative(to: gameFrameRect)) gameFrameView.addChild(apple) }
Nun, für die Schlange ist die Wende gekommen. Es besteht aus zwei Teilen: dem Körper (
SnakeBodyPart.swift ) und dem Kopf (
SnakeHead.swift ).
SnakeBodyPart.swift Code:
import SpriteKit class SnakeBodyPart: SKShapeNode { init(at point: CGPoint, diameter: CGFloat = 10.0) { super.init() path = UIBezierPath(ovalIn: CGRect(x: -diameter/2, y: -diameter/2, width: diameter, height: diameter)).cgPath fillColor = .green strokeColor = UIColor.green.withAlphaComponent(0.7) lineWidth = 5 position = point physicsBody = SKPhysicsBody(circleOfRadius: diameter - 4, center: .zero) physicsBody?.isDynamic = true physicsBody?.categoryBitMask = CollisionCategories.snake physicsBody?.contactTestBitMask = CollisionCategories.edgeBody | CollisionCategories.apple } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } }
SnakeHead.swift Code:
import SpriteKit final class SnakeHead: SnakeBodyPart { init(at point: CGPoint) { super.init(at: point, diameter: 20) physicsBody?.categoryBitMask = CollisionCategories.snakeHead physicsBody?.contactTestBitMask = CollisionCategories.edgeBody | CollisionCategories.apple } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } }
Wir werden Sie jedoch nicht mit einer Beschreibung jeder Zeile
langweilen ,
da die Details zum Erstellen der GameScene.swift-Datei und anderer Klassen im Video gut angezeigt werden. Wir bieten nur den endgültigen Code von
GameScene.swift an :
import SpriteKit import GameplayKit class GameScene: SKScene { var gameFrameRect: CGRect = .zero var gameFrameView: SKShapeNode! var startButton: SKLabelNode! var stopButton: SKLabelNode! var snake: Snake? override func didMove(to view: SKView) { setup(in: view) } override func update(_ currentTime: TimeInterval) { snake?.move() } override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { guard let touchedNode = findTouchedNode(with: touches) else { return } if let shapeNode = touchedNode as? SKShapeNode, touchedNode.name == .counterClockwiseButtonName || touchedNode.name == .clockwiseButtonName { shapeNode.fillColor = .green if touchedNode.name == .counterClockwiseButtonName { snake?.moveCounterClockwise() } else if touchedNode.name == .clockwiseButtonName { snake?.moveClockwise() } } else if touchedNode.name == .startButtonName { start() } else if touchedNode.name == .stopButtonName { stop() } } override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { guard let touchedNode = findTouchedNode(with: touches) else { return } if let shapeNode = touchedNode as? SKShapeNode, touchedNode.name == .counterClockwiseButtonName || touchedNode.name == .clockwiseButtonName { shapeNode.fillColor = .gray } } override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) { guard let touchedNode = findTouchedNode(with: touches) else { return } if let shapeNode = touchedNode as? SKShapeNode, touchedNode.name == .counterClockwiseButtonName || touchedNode.name == .clockwiseButtonName { shapeNode.fillColor = .gray } }
Das Ergebnis war das einfachste Snake-Spiel:

Wir haben ungefähr anderthalb Stunden gebraucht, um das Spiel zu schreiben. Wenn Sie Programmierkenntnisse in Swift erwerben möchten, wiederholen Sie alle Schritte selbst. Übrigens erhalten Sie
hier vollen Zugriff auf alle Codedateien, die in diesem Projekt verwendet wurden.