Pull to refresh

Введение в Cocos2D-Swift

Ажиотаж после презентации нового языка программирования от Apple немного стих, хотя статей с уроками становится все больше. Разработчики кроссплатформенного (именно так он позиционируется) движка для создания игр Cocos2D сделали решительный шаг навстречу переменам и решили переименовать свой движок из Cocos2D-iPhone в Cocos2D-Swift, а также официально стали поддерживать Swift.
No developer in the Apple community could have missed the announcement at WWDC about Swift and the new direction iOS development is going. The Cocos2D and SpriteBuilder teams are very excited about Swift. During the last couple of days we have been evaluating the new language and its implications for Cocos2D. Today we are happy to announce that we will add official support for Swift after it has been publicly released by Apple. We believe so strongly in this new direction that we are taking the opportunity to rename Cocos2D-iPhone to Cocos2D-Swift.

К сожалению, на официальном сайте нет ничего по поводу написания Cocos2D-Swift приложений с применением Swift (видимо, документацию обновить не успели). Я нашел лишь один туториал, который пошагово описывает данную интеграцию, но даже он приводил ко множеству ошибок.

Всех заинтересовавшихся прошу под кат.

Step by step guide


  • Шаг 1: Загрузите и установите дистрибутив с официального сайта (последняя стабильная версия — 3.1.0)
  • Шаг 2: Откройте Xcode 6 и создайте новый проект iOS — cocos2d v3.x — cocos2d iOS
  • Шаг 3: Щелкаем по названию проекта, идем в Build Phases — Link Binary With Libraries и добавляем следующие библиотеки:
    • GLKit.framework
    • AudioToolbox.framework
    • CoreText.framework
    • AVFoundation.framework
    • QuartzCore.framework
    • UIKit.framework
    • OpenGLES.framework
    • CoreGraphics.framework
    • OpenAL.framework
    • libz.dylib
    • libObjectiveChipmunk.a
    По идее, все должно работать без добавления данных библиотек, так что неизвестно — баг это, или фича. Все библиотеки можно переместить в новую группу (File — New — Group).
  • Шаг 4: Удаляем следующие файлы (медленно избавляемся от Objective-C кода). В дальнейшем мы пересоздадим их Swift-аналоги.
    • AppDelegate.h/m
    • IntroScene.h/m
    • HelloWorldScene.h/m
    • main.m
  • Шаг 5: Вместо удаленных файлов создаем (содержимое и его разбор немного ниже):
    • Main.swift
    • IntroScene.swift
    • HelloWorldScene.swift
  • Шаг 6: Создаем файл <имя проекта>-Bridging-Header.h (например: AngrySanta-Bridging-Header.h). Bridging header позволяет использовать Objective-C код внутри вашего .swift проекта. Его содержимое:
    #import "cocos2d.h"
    #import "cocos2d-ui.h"
    
    Подробнее о bridging header можно почитать в официальном руководстве от Apple или на StackOverflow.
  • Шаг 7: Компилируем и запускаем.

Содержимое файлов


Main.swift
import Foundation

@UIApplicationMain class ApplicationDelegate : CCAppDelegate, UIApplicationDelegate {
    
    override func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]!) -> Bool {
        setupCocos2dWithOptions([CCSetupShowDebugStats: true]);
        return true;
    }
    
    override func startScene() -> (CCScene)
    {
        // после инициализации движка запускаем сцену
        return IntroScene();
    }
}


IntroScene.swift
import Foundation

/**
*  The intro scene
*  Note, that scenes should now be based on CCScene, and not CCLayer, as previous versions
*  Main usage for CCLayer now, is to make colored backgrounds (rectangles)
*
*/
class IntroScene : CCScene {
    
    init()
    {
        super.init()
        
        // Create a colored background (Dark Grey)
        let background:CCNodeColor = CCNodeColor(color: CCColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 1.0))
        addChild(background)
        
        
        // Hello world
        let label:CCLabelTTF = CCLabelTTF(string: "Hello World", fontName: "Chalkduster", fontSize: 36.0)
        label.color = CCColor.redColor()
        label.positionType = CCPositionType(xUnit: CCPositionUnit.Normalized, yUnit: CCPositionUnit.Normalized, corner: CCPositionReferenceCorner.TopLeft);
        label.position = CGPoint(x: 0.5, y: 0.5) // Middle of scre
        addChild(label)
        
        // Helloworld scene button
        let helloWorldButton:CCButton = CCButton(title: "[ Start ]", fontName: "Verdana-Bold", fontSize: 18.0)
        helloWorldButton.positionType = CCPositionType(xUnit: CCPositionUnit.Normalized, yUnit: CCPositionUnit.Normalized, corner: CCPositionReferenceCorner.TopLeft);
        helloWorldButton.position = CGPoint(x: 0.5, y: 0.35)
        helloWorldButton.setTarget(self, selector: "onSpinningClicked:")
        addChild(helloWorldButton)
        
    }
    
    func onSpinningClicked(sender:AnyObject)
    {
        // start spinning scene with transition
        CCDirector.sharedDirector().replaceScene(HelloWorldScene(), withTransition: CCTransition(pushWithDirection: CCTransitionDirection.Left, duration: 1.0))
    }
}


HelloWorldScene.swift
import Foundation

/**
*  The main scene
*/
class HelloWorldScene : CCScene {
    
    let _sprite:CCSprite?
        
    init()
    {
        super.init()
        
        // Enable touch handling on scene node
        userInteractionEnabled = true
        
        // Create a colored background (Dark Grey)
        var background:CCNodeColor = CCNodeColor(color: CCColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 1.0))
        addChild(background)
        
        // Add a sprite
        _sprite = CCSprite(imageNamed: "Icon-72.png")

        _sprite!.position = CGPoint(x: self.contentSize.width/2, y: self.contentSize.height/2)
        addChild(_sprite)
        
        // Animate sprite with action
        let actionSpin:CCActionRotateBy = CCActionRotateBy(duration: 1.5, angle: 360)
        _sprite?.runAction(actionSpin)
        
        // Create a back button
        let backButton:CCButton = CCButton(title: "[ Menu ]", fontName: "Verdana-Bold", fontSize: 18.0)
//            CCPositionTypeMake(CCPositionUnit.Normalized, CCPositionUnit.Normalized, CCPositionReferenceCorner.BottomLeft)
        backButton.positionType = CCPositionType(xUnit: CCPositionUnit.Normalized, yUnit: CCPositionUnit.Normalized, corner: CCPositionReferenceCorner.TopLeft);
        backButton.position = CGPoint(x: 0.85, y: 0.95) // Top Right of screen
        backButton.setTarget(self, selector: "onBackClicked:")
        addChild(backButton)
        
    }
    
    deinit
    {
        // clean up code goes here
    }
    
    override func onEnter()
    {
        // always call super onEnter first
        super.onEnter()
        
        // In pre-v3, touch enable and scheduleUpdate was called here
        // In v3, touch is enabled by setting userInterActionEnabled for the individual nodes
        // Per frame update is automatically enabled, if update is overridden
    }
    
    override func onExit()
    {
        // always call super onExit last
        super.onExit()
    }
    
    override func touchBegan(touch: UITouch!, withEvent event: UIEvent!)
    {
        let touchLoc:CGPoint = touch.locationInNode(self)
        
        // Log touch location
        println("Move sprite to \(NSStringFromCGPoint(touchLoc))")
        
        // Move our sprite to touch location
        let actionMove:CCActionMoveTo = CCActionMoveTo(duration: 1.0, position: touchLoc)
        _sprite!.runAction(actionMove)
    }
    
    func onBackClicked(sender:AnyObject)
    {
        // back to intro scene with transition
        CCDirector.sharedDirector().replaceScene(IntroScene(), withTransition: CCTransition(pushWithDirection: CCTransitionDirection.Right, duration: 1.0))
        
    }
}


Читаемость, по сравнению с Objective-C, возросла в разы. В плане производительности заметных изменений нет, так как разработчики еще не выпустили полноценную Swift версию. Если будут возникать какие-то вопросы по коду — пишите в комментарии, постараюсь ответить.

Итог


Конечно, меня привлекает перспектива разработки игр на Swift, с дальнейшим портированием под Android с помощью Apportable, но что на счет поддержки Windows Phone и других платформ? В данном случае лучше будет воспользоваться cocos2d-x C++ версией, так как Javascript версия не обеспечивает должного уровня производительности.

Всем удачного Swift — кодинга.
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.