Skip to content
This repository has been archived by the owner on Feb 15, 2021. It is now read-only.

artcom/mobile-spark

Repository files navigation

Spark


Was ist Spark?

Spark ist ein graphikorientiertes Framework for iOS und Android. Es basiert auf openGL ES2.0 und ermöglicht durch seinen Komponentenaufbau eine produktive Anwendungsentwicklung. Das strukturelle Layout wird durch XML-Dateien beschrieben, während das Verhalten der Komponenten durch optionalen C++ Sourcecode implementiert wird. Der Spark-Anwendungscode ist plattformübergreifend, d.h. ein Spark-Projekt kann sowohl Android- als auch iOS-Applikationen erzeugen.

Merkmale:

  • XML-Layout-Dateien mit C++ Implementierungen
  • 2D- und 3D-Unterstützung
  • Widget- und Komponentensystem
  • Event-System
  • obj-Loader
  • Sound und Animation
  • HTTP-Konnektivität
  • unterstützt Sensoren und Camera

Voraussetzungen

für Android:

  • Hardware: Androidgerät mit openGL 2.0 Unterstützung
  • Android-Version: 2.3 (Gingerbread) und höher
  • Entwicklungssystem: Linux, Windows, Mac OSX
  • Software: Android SDK Rev.9, Android NDK, GIT, cygwin(nur Windows), C++ Boost Libraries, beliebiger Editor oder IDE

für iOS:

  • Hardware: iPad, iPad2, iPhone 3GS oder höher
  • iOS-Version: 3.0 und höher
  • Entwicklungssystem: Mac OSX
  • Software: XCode 5.0, GIT, C++ Boost Libraries
  • sonstiges: iOS Developer Account (für Deployment)

Installation

Linux / Mac

  • erstelle neuen Spark-Ordner

    $ cd ~/dev $ mkdir mobile-spark $ cd mobile-spark

  • checkout Repository:

    $ git clone git://github.com/artcom/mobile-spark.git

  • setze System-Suchpfade in @.bash_profile@ bzw. @.bashrc@ für Android-SDK/tools und Android-SDK/platform-tools, z.B.:

$ export PATH=~/Library/android-sdk-mac_x86-1.6_r1/tools:$PATH
$ export PATH=~/Library/android-sdk-mac_x86-1.6_r1/platform-tools:$PATH
  • setze Umgebungsvariablen in .bash_profile bzw. .bashrc für ANDROID_NDK, ANDROID_NDK_TOOLCHAIN_ROOT, MOBILE_SPARK. z.B.:
$ export ANDROID_NDK=~/Library/android-ndk-r6b
$ export ANDROID_NDK_TOOLCHAIN_ROOT=$ANDROID_NDK/android-toolchain
$ export MOBILE_SPARK=~/dev/mobile-spark

Windows

  • falls nicht vorhanden, installiere Cygwin
  • setze System-Suchpfade für:
  • msys git
  • cmake
  • ANDROID_NDK
  • ANDROID_SDK/tools
  • ANDROID_SDK/platform-tools
  • ANT_HOME (jakarta ant)
  • setze Umgebungsvariablen für
  • ANDROID_NDK (inkl. /tools und /platform-tools)
  • ANDROID_HOME (für Android SDK)
  • ANT_HOME
  • JAVA_HOME
  • BOOST_HOME
  • Build android ndk toolchain
$ set "MOBILE_SPARK" to your mobile-spark directory (in windows style!!!)
$ export NDK_TMPDIR=$(cygpath "$ANDROID_NDK/")../ndk-tmp
$ call $ANDROID_NDK/build/tools/make-standalone-toolchain.sh \
        --platform=android-9 \
        --install-dir=$ANDROID_NDK/android-toolchain \
        --system=windows
$ export ANDROID_NDK_TOOLCHAIN_ROOT=$ANDROID_NDK/android-toolchain
  • erstelle mobile-spark Ordner

  • checkout Repository im mobile-spark Ordner:

    $ git clone git://github.com/artcom/mobile-spark.git


OS specific builds

Android

$ cd $MOBILE_SPARK/android/
$ ./build.sh

iOS

create and open XCode project:

$ cd $MOBILE_SPARK/iOS/
$ rm -rf _build/
$ mkdir _build
$ ./xcode_ios.sh
$ open mobile-spark.xcodeproj

Einstellungen in XCode IDE:

  • TARGET-Scheme: SparkViewerBase > iOS Device

  • Build Settings: Target Device Family -> iPhone oder iPad

  • Build Settings: iOS Deployment Target -> iOS 4.1

  • Bauen: Product -> Build


Teste Demo

Zum Testen der DemoApp müssen die mobile-spark-Libraries kompiliert sein (siehe Build für Android/iOS).

Android

  • Android-Gerät:
  • aktiviere USB-Debugging
  • erlaube Installation unbekannter Quellen
  • verbinde mittels USB mit Rechner
$ cd $MOBILE_SPARK/projects/DemoApp/
$ rm -rf \_build
$ cd android/
$ ./build.sh
  • copy result to device:
$ ./push.sh
$ ./start.sh

iOS

  • Registrierung als iOS Developer erforderlich:

iOS Developer Center

  • Zur Code-Signierung ist ein Provisioning Profile erforderlich:

Creating and Downloading Development Provisioning Profiles

  • Das Provisioning Profile muss auf iPad/iPhone installiert werden (ausgenommen inHouse provisioning profiles)
  • verbinde Gerät via USB
  • goto to project folder and create XCode project:
$ cd $MOBILE_SPARK/projects/DemoApp/ios/
$ mkdir _build
$ cd _build/
$ rm -rf *
$ ../xcode_ios.sh
$ open DemoApp.xcodeproj

Einstellungen in XCode IDE:

  • TARGET-Scheme: DemoAppApp > yourDevice

  • Build Settings: TARGETS -> DemoAppApp -> Target Device Family -> iPhone oder iPad

  • Build Settings: TARGETS -> DemoAppApp -> iOS Deployment Target -> iOS 4.1

  • Build Settings: TARGETS -> DemoAppApp -> Code Signing Identity -> yourProvisioningProfile

  • Bauen: Product -> Build

  • Deployment und Ausführung: Product -> Run


Neues Project anlegen

  • lege an beliebiger Stelle workspace an

    $ cd anyWhere $ mkdir myWorkspace $ cd myWorkspace

  • rufe createProject-Skript auf (Achtung! Projektnamen dürfen keine Sonderzeichen beinhalten)

    $ $MOBILE_SPARK/createProject.sh MyNewProjectName

  • passe relativen Pfad in MyNewProjectName/android/MyNewProjectName/build.properties an:

  • relativer Pfad muss von MyNewProjectName/android/MyNewProjectName/ nach $MOBILE_SPARK/_build/lib/ zeigen, z.B.:

    native.libs.dir --> ../../../mobile-spark/_build/lib


Tutorials

Erste Schritte

Folgendes Programm zeigt den Umgang mit Spark-Komponenten, EventListenern und einfachen Animationen.

  1. kompiliere mobile-spark für Android bzw. iOS
  • erstelle HelloWorld-Projekt

    $ cd myWorkspace $ $MOBILE_SPARK/createProject.sh HelloWorld

  • passe build.properties an

  • öffne Layout-Datei: HelloWorld/layouts/main.spark

<Window name="ProjectView" fullscreen="true" i18nContext="global-i18n" width="800" height="480" orientation="landscape" clearColor="[0,0,0.5,1]">
    <!-- userinterface is located in 2dworld -->
    <View name="mainView" world="2dworld" pos="[0,0]" size="[1.0,1.0]" cameraName="2dcamera"/>
    <World name="2dworld">    
        <RenderCamera name="2dcamera" frustum="orthonormal[auto]"/>    

        <Transform name="transform">
            <Text name="testtextgreen" y="50" x="10" z="13" text="Hello World" color="[0,1,0,1]" fontsize="32"/>
        </Transform>    
    </World>        
</Window>

ändere Text Komponente und füge Rechteck hinzu

<Transform name="transform" x="50">
    <Text 
        name="blackText" color="[0,0,0,1]" 
        x="20" y="50" z="1" 
        text="push" fontsize="32"/>
    <Rectangle name="whiteRect" color="[1,1,1]"
        x="0" y="0" z="0" width="110" height="2000" />
</Transform>

öffne Header der Hauptklasse: HelloWorld/src/HelloWorld.h
inkludiere spark-Komponenten: Transform, Text, Rectangle und Window

#include <spark/Transform.h>
#include <spark/Text.h>
#include <spark/Rectangle.h>
#include <spark/Window.h>

füge privaten Touch-Handler hinzu:

void onRectTouched(spark::EventPtr theEvent);

deklariere Attribute für Text, Transform, und Displaybreite:

spark::TransformPtr _myTransform;
spark::TextPtr _myText;
int _myWidth;

bearbeite Implementierung der Hauptklasse: HelloWorld/src/HelloWorld.cpp
definiere benötigte Attribute in setup-Methode:
Display-Breite:

_myWidth=_mySparkWindow->getSize()[0];

setze Zeiger auf Layout-Komponenten:

_myTransform = boost::static_pointer_cast<spark::Transform>(
    _mySparkWindow->getChildByName("2dworld", true)->getChildByName(
        "transform",true
    )
);
_myText =  boost::static_pointer_cast<spark::Text>(
    _myTransform->getChildByName("blackText",true)
);
RectanglePtr myRect = boost::static_pointer_cast<Rectangle::Rectangle>(
    _myTransform->getChildByName("whiteRect",true)
);
HelloWorldPtr ptr = boost::static_pointer_cast<HelloWorld>(
    shared_from_this()
);

erzeuge Callback-Methode für Touch-Event, registriere Listener auf Rechteck:

spark::EventCallbackPtr myTransformTouchedCB = EventCallbackPtr(new HelloWorldEventCB(ptr,&HelloWorld::onRectTouched));
myRect->addEventListener(TouchEvent::PICKED, myTransformTouchedCB); 

implementiere Callback-Methode

void HelloWorld::onRectTouched(EventPtr theEvent) {
     float oldX = _myTransform->getX();
     float newX = std::abs(oldX-_myWidth) - 100;
     
     // switch ping and pong
     if(newX < oldX) {
         _myText->setText("ping");
     } else {
         _myText->setText("pong");
     }
}

lasse Bewegung des weißen Rechtecks animieren: inkludiere Animations-Header:

#include <animation/AnimationManager.h>
#include <animation/SequenceAnimation.h>
#include <animation/Easing.h

erweitere Callback-Methode onRectTouched, so dass die x-Position des Transforms animiert wird:

void HelloWorld::onRectTouched(EventPtr _) {
    ...
    // init animation, here for property position x of _myTransform;
    //
    WidgetWeakPtr myWidget = WidgetWeakPtr(WidgetPtr(_myTransform));
    WidgetPropertyAnimationPtr myAnimation = WidgetPropertyAnimationPtr(
        new WidgetPropertyAnimation(
            myWidget, &Widget::setX, oldX, newX, 500,
            animation::EasingFnc(animation::easeInOutElastic)
        )
    );
     
    // add property animation to playable sequence animation (also
    // possible: ParallelAnimation)
    //
    animation::SequenceAnimationPtr mySequence = 
       animation::SequenceAnimationPtr(
           new animation::SequenceAnimation()
       );
    mySequence->add(myAnimation);
    
    // start animation
    //
    animation::AnimationManager::get().play(mySequence);
}

Tips & Tricks

  • das Bauen von Android-Apps kann für Multi-Core-Systeme beschleunigt werden: Parameter -j(Number of Cores) anhängen:

    $ ./build.sh -j3

  • Android-Apps können per Kommandozeile beenden werden

    $ ./kill.sh

  • Debugging und Logging unter Android ist mit adb-tools möglich, z.B.:

    $ adb logcat

  • ändern sich bei Android nur Texturen, Layout-Dateien, Sounds usw. muss nicht neu gebaut werden, es reicht die neuen Daten mittels Push-Skript @./push.sh@ auf die SD-Card zu kopieren

  • bei unerwarteten Fehlern hilft es manchmal, die App manuell vom Gerät zu löschen

  • bei iOS sollte vor jedem Bauen des Projekt ein Cleaning statt finden (cmd+shift+K)

  • Debugging ist in iOS nur mit Developer-Provisioning-Profiles möglich

Architektur

Klassenhierarchie der Widgets

Klassenhierarchie für Animationen

Referenz

to be done