
مرحبا بالجميع! تحسبا لإطلاق الدورة التدريبية
"المطور iOS. بالطبع الأساسي " نظمنا
درسا مفتوحا آخر. تم تصميم هذا الويبينار للأشخاص الذين لديهم خبرة في تطوير أي لغة ومنصات ، ولكنهم يرغبون في تعلم لغة سويفت وإتقان تطوير نظام iOS. في هذا الدرس ، درسنا بالتفصيل
التركيب اللغوي والتراكيب الأساسية للغة سويفت ، للتعرف على أدوات التطوير الرئيسية.
المشاركون في الندوة المستفادة:
- ما هي لغة سويفت ، ما هي معالمها؟
- كيف تساعدك بيئة تطوير Xcode على البدء
- كيفية إنشاء لعبة بسيطة لنظام التشغيل iOS.
تم إجراء الندوة عبر الويب بواسطة
أليكسي سوبولفسكي ، مطور نظام iOS في ياندكس.
تفعل ذلك بنفسك الأفعى
للعمل ، استخدمنا
بيئة التطوير المتكاملة
Xcode . هذه بيئة مريحة ومجانية وعملية تم إنشاؤها بواسطة Apple.
في البداية ، أنشأنا مشروعًا جديدًا واخترنا المجموعة الأساسية من ملفات "اللعبة":

دون مزيد من اللغط ، أطلقوا على المشروع "الأفعى". تم ترك جميع الإعدادات بشكل افتراضي ، مع التأكد من أن SpriteKit كان في خط Game Technology.
تفاصيل إنشاء المشروع.بعد تنفيذ الإجراءات المذكورة أعلاه ، سيتم عرض قائمة الملفات التي تم إنشاؤها تلقائيًا لمشروعنا في الجزء الأيسر من النافذة. أحد أهم الملفات هو
AppDelegate.swift ، والذي يساعد النظام على التواصل مع الكود الخاص بنا عندما تكون هناك أي أحداث مهمة للتطبيق (التشغيل ، الضغط ، الضغط على الرابط ، إلخ). رمز هذا الملف:
نفس القدر من الأهمية هي
GameScene.swift و
GameViewController.swift . فئة GameScene تنشئ المشهد ، و GameViewController مسؤول عن شاشة واحدة من التطبيق الذي نراه (شاشة واحدة - واحدة GameViewController). بالطبع ، هذه القاعدة غير مدعومة دائمًا ، لكنها تعمل بشكل عام. نظرًا لأن تطبيقنا بسيط للغاية ، فلن يكون لدينا سوى GameViewController واحد. لنبدأ معه.
كتابة GameViewController
سنقوم بحذف الكود الافتراضي. تحتوي وحدة التحكم في العرض على العديد من الطرق التي تعمل وفقًا لحالة الشاشة. على سبيل المثال ،
viewDidLoad()
تشغيل
viewDidLoad()
عندما تكون جميع عناصر الشاشة قد تم تحميلها بالفعل ، وكانت الشاشة على وشك الظهور على الهاتف الذكي. نظرًا لأن لدينا لعبة ، نحتاج إلى وضع مشهد اللعبة في وحدة التحكم في طريقة العرض الخاصة بنا (هذا هو المكان الذي سيتم فيه تشغيل الثعبان وجميع أحداث اللعبة الأخرى).
إنشاء مشهد:
let scene = GameScene(size: view.bounds.size)
دعنا ثابت وكلمة رئيسية. يستخدم Swift أيضًا var الكلمة الأساسية ، وهو مطلوب لتعريف متغير. باستخدام
var ، يمكننا تغيير قيمة المتغيرات عدة مرات أثناء تنفيذ البرنامج. باستخدام let ، لا يمكننا تغيير قيمة المتغيرات بعد التهيئة.
نحتاج الآن إلى التأكد من أن العرض الذي سنضع فيه المشهد الذي تم إنشاؤه يتوافق مع النوع المرغوب. للقيام بذلك ، استخدم بنية
الحماية - وهذا هو نفسه كما
if
، فقط في الاتجاه المعاكس (إن لم يكن):
guard let skView = view as? SKView else { return }
بعد التأكد من تطابق عنصر الشاشة مع النوع المطلوب ، نضيف مشهدنا إليه:
skView.presentScene(scene)
تحتاج أيضًا إلى إظهار عدد الإطارات في الثانية (FPS):
skView.showsFPS = true
ثم عرض عدد العناصر من جميع الأنواع على الساحة:
skView.showsNodeCount = true
ودعونا نجعل العناصر تظهر على الشاشة بغض النظر عن ترتيبها في التسلسل الهرمي للعناصر:
skView.ignoresSiblingOrder = true
ولا تنس أن مشهدنا يجب أن يمتد إلى العرض الكامل للشاشة:
scene.scaleMode = .resizeFill
فيما يلي الرمز النهائي لملف
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) } }
تفاصيل إنشاء ملف GameViewController.swift.لذلك ، أنشأنا المشهد ، لكنه فارغ ، لذا إذا قمنا بتشغيل المحاكي الآن ، فلن نرى سوى شاشة سوداء.
كتابة GameScene
مثل آخر مرة ، نقوم بحذف معظم الكود ، ثم
نقوم بتنفيذ الإعدادات اللازمة للمشهد . كما أن لديها طرقها الخاصة. على سبيل المثال ، نظرًا لأننا أضفنا مشهدنا إلى ViewController ، فإننا نحتاج إلى طريقة
didMove()
:
override func didMove(to view: SKView) { setup(in: view) }
علاوة على ذلك ، عند بدء اللعبة ، يتم استدعاء أسلوب
Update()
لكل إطار:
override func update(_ currentTime: TimeInterval) { snake?.move() }
ونحتاج أيضًا إلى بعض معالجات النقر على الشاشة:
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 }
كما تعلمون ، تشتهر سويفت بوجود
السكر النحوي . السكر النحوي - هذه هي الجوانب الفنية التي تبسط حياة المطور ، وتسريع كتابة التعليمات البرمجية. كل هذا يساعد كثيراً في إعداد المشهد ، وهو ما سنفعله الآن. بادئ ذي بدء ، قم بتعيين اللون:
backgroundColor = SKColor.white
نظرًا لأن الثعبان يعمل في الطائرة ، فنحن لا نحتاج إلى الفيزياء ، ويمكنك إيقاف تشغيله حتى لا يسقط الثعبان بسبب الجاذبية. أيضا ، نحن لسنا بحاجة إلى أن تدور اللعبة ، إلخ:
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
الآن قم بإنشاء الأزرار:
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)
عند كتابة جزء من الكود ، يجب عليك التفكير فيما إذا كان يمكن تحسين الكود أو إعادة تشكيله بحيث يمكن
إعادة استخدامه في المستقبل. انظر ، لدينا أساسا زرين على الشاشة ، يتم إنشاء نفس الكود لهما. لذلك ، يمكن إخراج هذا الرمز في وظيفة منفصلة. للقيام بذلك ، قم
بإنشاء فئة جديدة ، وبالتالي ، ملف
ControlsFactory.swift مع التعليمات البرمجية التالية:
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 } }
لرسم تفاحة عشوائية بأن "
ثعباننا " سوف "يأكل" ، قم
بإنشاء فئة Apple وملف
Apple.swift :
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 } }
ونحن نصف
createApple()
دالة
createApple()
في
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) }
حسنا ، لقد حان دور الأفعى. وسوف يتكون من جزأين: الجسم (
SnakeBodyPart.swift ) والرأس (
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 الكود:
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") } }
ومع ذلك ، لن نحمل لك وصفًا لكل سطر ،
لأن تفاصيل إنشاء ملف GameScene.swift والفئات الأخرى يتم عرضها جيدًا في الفيديو. نحن نقدم فقط لرؤية الكود النهائي لـ
GameScene.swift :
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 } }
وكانت النتيجة أبسط لعبة الأفعى:

استغرقنا حوالي ساعة ونصف الساعة لكتابة اللعبة. إذا كنت ترغب في الحصول على مهارات البرمجة في Swift ، كرر جميع الخطوات بنفسك. بالمناسبة ، ستحصل
هنا على حق الوصول الكامل إلى جميع ملفات التعليمات البرمجية التي تم استخدامها في هذا المشروع.