Tagged in: mac

Mix xcode+quartz

On souhaite réaliser un diaporama avec effets graphiques. L’effet de base est illustré dans la vidéo suivante : exemple. La réalisation est en deux parties :

  1. réaliser une composition Quartz permettant d’animer l’affichage d’un ensemble d’images
  2. intégrer et piloter cette composition depuis une application MacOSX

Première partie : Quartz

Revenir sur votre composition Quartz d’animation (si vous n’en avez pas une fonctionelle, fabriquez en une simple).

  1. Modifiez votre composition de sorte à exporter certains paramètres comme des paramètres d’entrée, c’est-à-dire des paramètres dont les valeurs pourront être injectées depuis l’extérieur de la composition. Commencer par le paramètre contrôlant la vitesse de rotation. Sélectionner par clic doirt l’entrée du patch Quartz et choisir Publish Inputs. Choisir un nom adéquat pour l’export.
  2. Tester que ce paramètre est effectivement utilisable en sélectionnant l’onglet Parameters dans la barre d’outils. Modifiez la valeur directement dans le formulaire présenté et vérifier que cela fonctionne comme attendu.

Seconde partie : XCode

  1. Créer ou modifier une application xcode intégrant la composition Quartz précédente. Ajouter deux boutons, l’un de libellé +vite l’autre -vite.
  2. Ajouter une classe Cocoa descendante de NSObject contenant un attribut entier correspondant à la valeur vitesse et un Outlet de type QCView.
  3. Instancier via le constructeur d’interface un objet de la classe précédente. Établir le lien Outlet entre l’objet et la QCView.
  4. Établir un lien réactionnel (une Action) entre les boutons +vite et -vite et la classe de l’objet métier. Une action s’appellera plusVite et l’autre moinsVite.
  5. Modifier le code de ces méthodes de sorte à modifier en conséquence la valeur de l’attribut stocké par l’objet (afficher cette valeur via un appel à NSLog. Tester. Question : comment est initialisé l’attribut ? Est-ce la bonne valeur de départ ?
  6. Rechercher dans la document de la QCView comment modifier la valeur d’un paramètre exporté d’une composition Quartz jouée dans une QCView. Faire en sorte que les deux actions modifient le paramètre. Tester.

Troisième partie : XCode

  1. Rechercher dans la documentation comment une QCView peut en retour appeler du code contenu dans l’application (piste: cet appel est effectué sur une base temporelle). Implanter du code de sorte qu’une méthode de l’objet métier soit appelée sur une base temporelle (y placer un appel à NSLog).
  2. Rechercher dans la documentation comment les valeurs de paramètres de sortie de composition Quartz peuvent être consultées dans un code applicatif. Modifier la composition Quartz pour produire une valeur indiquant qu’il est temps de changer d’image. Rajouter une entrée publique à la composition permettant d’injeter une image NSImage.
  3. Modifier le code de sorte que lorsque cet indicateur est positionné, l’application change d’image tournante (on s’autorisera à basculer entre deux images pour commencer). Consulter la documentation de NSImage pour retrouver comment des images peuvent être lues depuis le système de fichiers.
  4. Modifier le code de sorte à ajouter un NSOpenPanel lorsqu’on choisit l’option Ouvrir du menu de l’application. Ce Panel devra permettre de choisir dans le système de fichiers un répertoire contenant des images (on pourra supposer que le répertoire contient effectivement des images et uniquement des images). Les images du répertoire seront utilisées dans l’ordre comme suite d’image à afficher par la composition animée.

Quatrième partie : cosmétique + extension…

  • Fournir une application au standard attendu : icône, etc
  • Définir une extension de fichier .dpr (.diaporama) reconnue par l’application dont le contenu pourra être une liste d’URL désignant des images qui seront utilisées lors de la projection

XCode (découverte)

Après avoir réalisé une composition Quartz dans le TP1, on souhaite l’intégrer à une application MacOSX.

Les objectifs de ce TP :

  • Découvrir XCode
  • Ajouter des composants graphiques
  • Créer des actions et les lier aux composants
  • Intégrer une composition Quartz et la déclencher par un bouton

La liaison des paramètres de la composition avec des variables de l’application se fera dans un prochain TP (suspense…)

Partie préliminaire : les supports de cours

Pour ce TP, on utilisera Objective-C et le framework Foundation.

  1. Télécharger les deux supports de cours pdf et les enregistrer
  2. Ouvrir chacun de ces pdf et les mettre en affichage « Planche contact » (Alt-Cmd-4) puis grossir au maximum le zoom (Cmd-+).
  3. Conserver ces documents ouverts et y chercher des informations ou des exemples chaque fois que nécessaire.

Première partie : prise en main

  1. Lancer xcode (qui se trouve normalement dans le répertoire /Applications) et créer une application de type Cocoa Application (attention à sélectionner le template dans la rubrique OS X et non la rubrique iOS).
  2. Compiler et tester l’application (vide) afin de vérifier que l’environnement de développement est correctement installé et configuré. Une fois lancée (avec Cmd-R), l’application se comporte comme n’importe quelle application MacOSX : lorsqu’elle est sélectionnée, son menu s’affiche tout en haut de l’écran. Pour la retrouver lorsqu’on a sélectionné une autre application active, on peut utiliser Cmd-Tab, et pour la quitter, on utilise son menu ou Cmd-Q.
  3. De retour dans XCode, sélectionner le fichier MainMenu.xib. La feuille quadrillée qui s’affiche est destinée à contenir les fenêtres de l’application. C’est l’éditeur d’interface. Le volet vertical situé entre cette feuille quadrillée et le volet de navigation permet de voir les objets que l’on manipulera. Si ce n’est pas fait par défaut, développer ce volet, soit en cliquant sur l’icône en bas à gauche de la feuille quadrillée, soit par le menu Editor > Show Document Outline.
  4. Dans le volet Document outline, sélectionner l’objet représentant la fenêtre, et si ce n’est pas fait par défaut, déployer son contenu. La fenêtre contient une vue. Toujours dans le volet Document outline, sélectionner la vue, puis à nouveau la fenêtre qui la contient, et observer la différence d’affichage sur la fenêtre de l’application (sur la feuille quadrillée).
  5. S’il ne l’est pas par défaut, afficher le volet des utilitaires, soit par Cmd-Alt-0 (idem pour le cacher), soit par le menu View > Utilities > Show Utilities. Notez à ce propos, que si par suite d’une mauvaise manipulation, vous perdez le volet de navigation (celui de gauche), vous pouvez le retrouver par Cmd-0 ou par View > Navigators > Show Navigator
  6. Sélectionner la vue, puis chercher, dans la bibliothèque d’objets (panneau en bas à droite), un objet de type Label, et le glisser sur la fenêtre de l’application. Remarquer les modifications sur le volet Document outline : deux objets encapsulés ont été ajoutée. Observer les différences d’affichage lorsqu’on sélectionne successivement ces deux nouveaux objets (remarquer en particulier la barre d’adresse, tout en haut de l’éditeur, affichant le chemin complet vers l’objet sélectionné. Chaque noeud de ce chemin est cliquable…)
  7. Modifier le texte de la cellule de texte, enregistrer, compiler puis exécuter l’application.
  8. Ajouter un bouton à la fenêtre de l’application, enregistrer, compiler, tester.
  9. Modifier diverses propriétés d’affichage des objets ajoutés, au moyen des inspecteurs de taille et d’attributs, dans le volet des inspecteurs, en haut à droite.
  10. L’éditeur d’interface comporte également le menu de l’application. Déplacer le menu Format juste avant le menu Help, supprimer le menu Window, enregister, compiler, tester.
  11. Observer dans le Document Outline le type des objets constituant le menu, et ajouter un élément dans le menu View. Renommer cet élément « Message in Console ». Enregistrer, compiler, tester.

Deuxième partie : un peu de code (ou pas)

  1. Ajouter une nouvelle classe au projet à l’aide du menu File > New… (Cmd-N), en sélectionnant une Objective-C class, et en prenant bien soin de la définir commoe sous-classe de NSObject. Deux fichier, .h et .m s’affichent alors dans le navigateur du projet. Laisser pour le moment ces fichiers intacts, mais observer que lorsqu’on édite l’un des deux, il est possible de basculer de l’un à l’autre par les touches Ctrl-Cmd-↑ et ↓.
  2. Pour faire de la place, cacher (momentanément) le volet des utilitaires (Cmd-Alt-0, idem pour le faire réapparaître).
  3. Faire apparaître l’éditeur assistant (Alt-Cmd-Enter ; ou View > Assistant Editor > Show ; ou l’icône du milieu dans le groupe d’icônes Editor tout en haut à droite !)
  4. Dans l’éditeur principal, sélectionner le fichier .m nouvellement créé et dans la barre d’adresse de l’éditeur assistant, si le fichier .h ne s’est pas affiché automatiquement, cliquer sur le premier mot pour sélectionner Counterparts > .h
  5. Sélectionner à nouveau MainMenu.xib, fermer (momentanément) l’assistant éditeur (petite croix tout à droite de sa barre d’adresse) et faire revenir le volet des utilitaires. Ajouter aux objets de l’interface (mais en dehors de la fenêtre de l’application) un NSObject.
  6. Au moyen de l’inspecteur d’identité, modifier le type de l’objet, pour que ce soit la nouvelle classe créée.
  7. Faire à nouveau apparaître l’éditeur assistant (et éventuellement cacher le volet des utilitaires), et sur sa barre d’adresse, cliquer sur le premier mot pour faire apparaître, dans le menu Automatic, le fichier .h de la nouvelle classe. (Il est aussi possible d’y revenir directement avec la flèche qui reprend le fichier précédent, puisque c’est lui qui avait été affiché dans le cas présent).
  8. Dans l’éditeur d’interface, faire apparaître l’élément ajouté précédemment dans le menu View de l’application (Message in Console). Attention, magie, cliquer avec le bouton droit sur ce menu (ou Ctrl-clic si pas de bouton droit) et maintenir appuyé pour tirer un fil bleu depuis le menu vers le contenu du fichier .h dans l’éditeur assistant. Relâcher juste en dessous de la ligne @interface. Dans la boîte qui apparaît, sélectionner Action comme type de connexion, et taper message comme nom d’action, puis valider. La déclaration d’une nouvelle action a dû s’ajouter au code du fichier.
  9. Basculer sur le .m et écrire, comme première ligne de code de ce TP, une instruction qui fait afficher un message quelconque sur la console au moyen de la méthode NSLog (consulter la documentation, et prendre bien garde à la syntaxe des constantes de type NSString, voir le cours Foundation à partir de la page 6).
  10. Enregistrer, compiler, exécuter l’application et tester l’effet du nouveau menu.

Troisième partie : la même chose, à la main

  1. Fermer l’éditeur assistant
  2. Ajouter à la main (!) une action de nom click dans le .h et le .m de la classe. L’effet de cette action sera d’afficher un autre message que précédemment sur la console. Enregistrer.
  3. Dans l’éditeur d’interface, sélectionner le bouton ajouté initialement à la fenêtre de l’application et tirer un fil bleu vers l’instance de la nouvelle classe. Le menu qui s’affiche permet de choisir l’action qui vient d’être créée.
  4. Dans l’inspecteur des connexions, vérifier que la connexion est bien présente. Enregistrer, compiler, tester.
  5. Pour bien prendre le pli, supprimer la connexion dans l’inspecteur, et constater qu’il est là aussi possible de la reformer, en cliquant sur le petit rond pour tirer un fil bleu à nouveau vers l’instance de la classe. De même, la connexion pouvait s’établir de l’instance de la classe via l’inspecteur des connexions de celle-ci, vers le bouton.

Quatrième partie : Quartz is back

  1. Ajouter à la fenêtre de l’application un objet de type QCView.
  2. À l’aide de l’inspecteur des propriétés, éditer l’objet QCView pour qu’il charge la composition Quartz créée au TP précédent, penser à paramétrer cet objet.
  3. Par une des deux méthodes vues précédemment (par l’éditeur assistant ou à la main), ajouter une connexion du QCView vers AppDelegate.h, mais cette fois la connexion sera un outlet (et non une action), de nom renderer, et sa méthode de stockage sera weak.
    (Un Outlet est une propriété visible de l’éditeur d’interface à laquelle on peut associer un objet, c’est une propriété représentant une association au sens UML. Désormais l’objet App Delegate connaît la QCView de l’interface via la propriété renderer). 
    Penser à enregistrer les deux fichiers : l’interface et AppDelegate.h.
  4. Pour que l’objet QCView soit connu du compilateur, il faut ajouter au projet le framework Quartz, et importer Quartz/Quartz.h.
  5. Dans l’interface, associer le bouton au déclenchement de l’action play: de la QCView. Enregistrer, compiler, tester.

Pour aller plus loin

AppDelegateObserver les connexions de l’objet App Delegate et constater que cet objet est connu d’un autre de nom File's Owner via un Outlet à l’intérieur de celui-ci. Observer l’objet File's Owner et constater que sa classe est NSApplication. Utiliser la documentation pour comprendre à quoi ces objets sont utiles.Les projets XCodeDans le navigateur, sélectionner la toute première ligne, qui représente l’intégralité du projet, et observer les différentes options de configuration du projet et de la cible (métadonnées, options de compilation, etc). Attention à ne rien changer que vous ne sauriez remettre en l’état…

SuperDestructor

On souhaite réaliser un jeu à l’aide du framework SpriteKit.

Le principe général du jeu

Le jeu se situe dans l’espace que tout le monde sait être hostile. Le joueur doit pouvoir contrôler à l’aide des flèches de clavier le déplacement d’un vaisseau spatial. Ce vaisseau spatial est équipé d’un système de défense très perfectionné permettant d’envoyer des missiles vers l’avant.

L’hostilité rencontrée par le vaisseau durant ce jeu est constituée d’un autre vaisseau mais ennemi. Celui-ci se déplace aléatoirement dans l’espace et a pour activité principale de lancer des obus vers le vaisseau du joueur.

Description précise

Le vaisseau du joueur peut se déplacer dans les 4 directions : gauche, droit, haut, bas à l’aide des flèches du clavier. Mais son déplacement est limité à une partie précise de l’espace, uniquement la moitié gauche de la fenêtre de jeu; impossible de sortir de cette zone. Le lancement de missile s’effectue à l’aide de la touche d’espacement. La fréquence de tir est limitée, mais cette limitation doit s’alléger au cours du temps afin d’améliorer les possibilités de défense du joueur. La vitesse du missile peut aussi être variable au cours du temps.

Le vaisseau ennemi se déplace aléatoirement (mais pas trop tout de même) sur une ligne verticale située à droite de l’écran, mais il ne sort jamais de l’écran. À intervalles réguliers il lance un obus à l’horizontale de sa position. La vitesse de déplacement du vaisseau ennemi, la fréquence de tir et la vitesse des missiles doivent augmenter au cours du jeu pour augmenter la difficulté de jeu.

Le joueur gagne un point lorsqu’il arrive à toucher le vaisseau spatial ennemi mais perd 10% de sa force vitale à chaque fois qu’un obus l’atteind. Le joueur possède deux vies au départ. Lorsqu’il n’a plus de vie le joueur a perdu et son score doit être enregistré.

Réalisation

Il est impératif d’employer SpriteKit pour gérer l’ensemble des aspects du jeu.

Il est possible de modifier légèrement le jeu mais il est impératif d’en respecter l’esprit.

Il est possible de rajouter des difficultés, des décors, des animations, des effets sonores en tout genre; mais ce n’est pas le but principal! Le jeu prime!

VisuImage

Première partie : une prise en main (pas de code à écrire, enfin!?)

  1. Lancer xcode (qui se trouve normalement dans le répertoire /Applications) et créer une application de type Cocoa Application (langage Swift de préférence, sans StoryBoard, ni tests unitaires, ni Core Data). Compiler et tester le modèle par défaut afin de vérifier que l’environnement de développement est correctement installé et configuré.
  2. Explorer le projet afin d’en anaylser la structure (fichiers sources, ressources, frameworks, etc).
  3. Revenir à la sélection du premier élément représentant le projet et observer les différentes options de configuration du projet et de la cible (métadonnées, options de compilation, etc). Attention à ne rien changer que vous ne sauriez remettre en l’état…
  4. Sélectionner le fichier MainMenu.xib et éditer l’interface de sorte que lui soit rajoutée un objet permettant de visualiser une image (piste : NSImageView).
  5. Configurer ce visualiseur d’image de sorte qu’une image de votre choix y soit présente au lancement de l’application. Attention, cela nécessitera sans doute d’ajouter cette image dans le projet lui-même… Tester.
  6. Modifier les caractéristiques de cet objet visualiseur d’image de sorte qu’il soit autorisé de déposer une image quelconque depuis l’extérieur de l’application (piste : propriété Editable). Tester.

Seconde partie : un peu de code… (ah… Enfin!)

  1. Créer un nouveau projet vierge de type Cocoa Application (langage Swift de préférence). Le configurer.
  2. Y ajouter une nouvelle classe à l’aide du menu File > New > File.... Observer l’instanciation d’un modèle de source de classe Swift.
  3. Ajouter, dans la classe une action de nom click:. La signature devra en être @IBAction func click(sender: AnyObject?). Faire en sorte qu’un message soit affiché (via Swift.print) lorsque cette méthode est appelée.
  4. Éditer MainMenu.xib afin d’ajouter à l’interface un simple bouton.
  5. Dans la partie Objects de l’interface, rajouter une instance d’objet (NSObject). Modifier la classe de cet objet en choisissant la classe précédemment créée.
  6. En tenant le bouton droit de la souris, tirer un trait du bouton vers l’objet instancié. Dans le menu contextuel qui apparaît choisir l’action adéquate… Observer le lien créé via l’inspecteur du bouton et/ou de l’objet : onglet Connections inspector en partie droite de la fenêtre principale.
  7. Compiler et tester votre première application Mac.

Troisième partie : le monde est vaste… (internationalisation)

  1. Reprendre l’application précédente et modifier le projet de sorte qu’il soit localisable (aller sur le projet et modifier sa configuration générale pour obtenir des localisations)
  2. Ajouter un fichier de ressources de type Strings File de nom Localizable.
  3. Revenir sur le fichier de localisation créé précédemment et le rendre localisable (via l’inspecteur) en choisissant une langue parmi celles offertes.
  4. Une entrée d’un tel fichier est toujour au format "clé" = "valeur";. Modifier les fichiers de localisation de sorte qu’à la clé "clic" soit associé un texte particulier pour chaque langue.
  5. Modifier le source de la classe de sorte que Swift.print affiche un message localisée selon l’environnement. Pour cela, on peut utiliser la méthode NSLocalizedString (consulter la documentation pour en connaître les détails).
  6. Compiler et tester que le message s’affiche correctement.
  7. Modifier la langue de l’environnement (via les Préférences Systèmes…) et relancer l’application pour constater que la localisation fonctionne.

Quatrième partie : une image vaut mieux que cent discours…

Si ce n’est pas déjà récupéré depuis la première question:

  1. Ajouter dans le projet une image
  2. Dans l’interface, ajouter une ImageView
  3. Modifier les propriétés de l’Image View pour qu’elle affiche l’image contenue dans le projet.
  4. Compiler, tester.

Cinquième partie : qu’est-ce qu’il y a au menu aujourd’hui ?

  1. Vérifier qu’à l’exécution l’option Open du menu est désactivée.
  2. Observer les liaisons du FirstResponder et de l’option de menu Open
  3. Créer une sous-classe Swift de NSImageView
  4. Modifier la classe de l’instance précédente de l’Image View de votre interface
  5. Ajouter à cette classe une méthode de signature @IBAction func openDocument:(sender: AnyObject?) qui affiche un message simple sur la console (Swift.print you know?)
  6. Faire une liaison de l’option de menu vers l’instance de la classe
  7. Compiler et vérifier que l’option du menu est active!
  8. Implanter de quoi sélectionner un fichier image (NSOpenPanel) et qu’il s’affiche dans l’Image View
  9. Compiler, tester

Sixième partie :

  1. Livrer le code à l’enseignant. Code expurgé de tout exécutable, etc. Vérifier que votre livraison est correcte (par exemple en testant sur une autre machine et avec le compte d’un camarade, celui-ci devrait pouvoir compiler et tester sans erreur aucune!). Pour les détails de la livraison, s’adresser à l’enseignant.

Foody

Il est demandé d’utiliser SpriteKit pour réaliser un jeu. La vidéo suivante en serait une version primitive :

Le scénario est qu’une petite bestiole se déplace dans un labyrinthe (celui-ci n’est pas illustré dans la vidéo) et doit aller chercher de quoi manger (ceci augmente son score comme dans la vidéo) mais qu’en chemin il y a des pièges de différentes sortes. Lorsque le joueur n’a plus de points de vie, la partie est finie.

Les pièges peuvent être :

  • des trappes qui le font passer dans un autre labyrinthe (pour aller chercher d’autres choses à manger). Les trappes se rendent visibles pour un temps assez court mais sont normalement invisibles. Elles peuvent aussi changer de place au cours du temps
  • des pièges qui amputent la vie du joueur (lorsque la vie s’épuise la partie est terminée)

La nourriture peut être de différentes sortes :

  • de la nourriture simple qui ne fait qu’augmenter le score
  • de la nourriture magique qui fait apparaître les trappes
  • de la nourriture régénérante qui permet de récupérer quelques points de vie

On prendra soin d’essayer d’animer si possible agréablement le jeu par différents effets :

  • sonores
  • graphiques