Apache Adobe Flex TutorialTutoriaux Adobe Flex & AIR en Français

27jan/120

[Offre d'emploi] – Consultant expérimenté Flex au Luxembourg

Consultant expérimenté Flex au Luxembourg – Offre d'emploi

  • Titre: Consultant expérimenté Flex
  • L'entreprise: Elan IT pour banque

Profil Recherché

  • Profil recherché:
    • Notre client recherche un consultant expérimenté dans le développement Flex avec une bonne expérience en Java.
    • Au niveau Flex les pré requis sont les suivants :
      • Adobe Flash Builder 4.5 pré-requis pour le développement mobile
      • Utilisation du moteur Adobe Air comme moteur d'exécution
      • JSON comme format d'échange de données via Web services
      • Utilisation obligatoire du framework PureMvc
      • Notre client recherche un consultant capable de coacher des consultants déjà présents sur la technologie Flex
  • Compétences Techniques Requises:
    • Flex 4.5
    • Air
    • Java
    • JSON
    • PureMVC
    • Expérience Requise:  3-5 ans
    • Disponibilité: ASAP

    Conditions d'embauche

    • Lieu : Luxembourg
    • Rémunération: à négocier
    • Contrat: 6 mois renouvelable / freelance

    Pour postuler

    • Contact:
      • Contact : Laurent DOT Marquis AT elanit DOT lu
    26jan/120

    [Offre d'emploi] – Développeur Flex / Adobe AIR (H/F) sur Clémency, Luxembourg

    Développeur Flex / Adobe AIR (H/F) sur Clémency, Luxembourg – Offre d'emploi

    • Titre: Développeur Flex / Adobe AIR (H/F)
    • L'entreprise: Flowfactory (http://www.flowfactory.lu), société luxembourgeoise cherche Développeur d'applications en ligne. Flowfactory S.A. conçoit, développe et commercialise des ERP, outils de gestion et de communication destinés aux TPE et PME. Fondée en 2010, Flowfactory cherche aujourd'hui de nouvelles ressources motivées, compétentes, capables de générer un travail rapide et précis dans un environnement collaboratif.

    Profil Recherché

    • Profil recherché:
      • Description du poste :
        • Analyse technique, élaboration cahier des charges
        • Etude et conception des fonctionnalités à mettre en place, en adéquation avec les besoins des clients cibles
        • Développement applications, nouvelles fonctionnalités et optimisation des produits existants
        • Gestion projet
      • Votre profil :
        • Bac +3/+4/+5 en informatique ou domaine apparenté
        • Expérience significative en développement Flex
        • Maîtrise des technologies Flex 4, Adobe AIR et Flash Builder
        • Sens de l'ergonomie et de la simplicité d'utilisation
        • Facilité d'apprentissage, sens de l'initiative et du défi technique
      • Compétences Techniques Requises:
        • Constitueraient un plus :
          • Connaissance de PHP, MySQL et AMFPHP
          • Connaissance de l'environnement Google Apps
          • Connaissance du Framework Zend Gdata
          • Connaissances en développement d'applications mobiles
      • Expérience Requise:  Expérience significative en développement Flex
      • Disponibilité: à négocier

      Conditions d'embauche

      • Lieu : Clémency, Luxembourg
      • Rémunération: à négocier
      • Contrat: CDI

      Pour postuler

      • Contact:
        • Merci de nous faire parvenir votre lettre de motivation, votre CV, vos références/projets et votre délai de disponibilité à jobs AT flowfactory POINT lu
      24jan/120

      [Offre d'emploi] – Consultant Flex sur Paris

      Consultant Flex sur Paris – Offre d'emploi

      • Titre: Consultant Flex
      • L'entreprise: Matelli Services (http://www.matelli-services.fr/) propose à ses clients de leur créer des applications Web, Mobiles et Windows correspondant à leurs besoins. Nous travaillons avec des clients de toutes tailles et de tous horizons: opérateurs mobiles, banques, sociétés de régie publicitaire, centres de formation. Pour satisfaire une demande toujours plus importante Matelli recherche aujourd’hui plusieurs consultants prêts à être intégrés à son équipe. Ces consultants doivent être spécialistes des technologies Java, Web, .NET, Mobiles, etc.

      Profil Recherché

      • Profil recherché:
        • Le candidat retenu sera chargé d’effectuer des missions de conseil autour des technologies Flex auprès des clients Matelli Services. Il sera en charge de faire évoluer les applications déjà développées et développera les nouvelles applications prévues sur 2012. Ces dernières sont basées sur Flex mais il sera force de proposition s’il faut utiliser d’autres technologies (HTML5, ExtJS, etc.)
        • Le candidat doit avoir un bon sens de la communication et disposer de solides connaissances en Flex.
        • Ce poste donne au candidat l’opportunité de :
          • Travailler dans des contextes clients diversifiés pour des entreprises de dimension internationale
          • Développer ses connaissances et acquérir de nouvelles compétences techniques grâce au temps de montée en compétence et de veille technologique qui lui est accordé
          • Evoluer rapidement au sein d’une structure jeune et dynamique
      • Compétences Techniques Requises:
        • Flex
        • Java et/ou PHP et/ou C# pour le côté serveur
      • Expérience Requise:  Débutant acceptés
      • Disponibilité: dès que possible

      Conditions d'embauche

      • Lieu : Paris
      • Rémunération: 30000-45000 €
      • Contrat: CDI

      Pour postuler

      • Contact:
        • Envoyez-nous votre CV à recrutement AT matelli POINT fr
        • Notre adresse : Matelli Services19 rue Béranger 75003 Paris
      24jan/126

      Starling API – 30 – Fin du fil rouge et pistes d'amélioration

      Après 30 billets, c'est bien la fin du fil rouge Starling! Si vous avez loupé un épisode, vous pouvez retrouver la liste des tutoriaux sur la page qui y est consacré:

      Fil rouge Starling API

      Si vous avez suivi ces billets de bout en bout, vous avez appris:

      • A connaitre les classes de base de l'API Starling
      • De l'animation avec Tween et MovieClip
      • Comment structurer votre code grâce aux Factory présentes dans plusieurs billets
      • Créer un niveau complet à partir d'une description
      • Utiliser Box2D pour gérer les collisions
      • Ecrire quelques règles de gestion pour votre jeu

      Alors bien sûr, il manque beaucoup d'éléments pour créer un jeu digne de ce nom. Voici quelques pistes:

      Rendu final

      This movie requires Flash Player 11

      Télécharger les sources

      Télécharger les sources du tutorial Starling

      Le livre officiel Starling

      Pendant l'écriture de ces billets sur Starling est paru l'ouvrage final sur Starling par Thibault Imbert. Celui-ci est en anglais et aborde certains points que je n'ai pas évoqué:

      http://shop.oreilly.com/product/0636920024217.do

      N'hésitez pas à y jeter un oeil. Si vous avez besoin d'aide, pensez bien à utiliser le forum de Starling qui compte de nombreux utilisateurs actifs:

      http://forum.starling-framework.org/

      Bonus

      Vous l'avez remarqué, les descriptions de niveau sont celles d'Angry Birds et les graphismes ont été légèrement remodelés pour ne pas être identiques. Mais si vous récupérez les SpriteSheet du jeu officiel (avec Firebug ou l'inspecteur de Google Chrome) depuis http://chrome.angrybirds.com/, vous aurez exactement le jeu Angry Birds, avec les vrais blocs ;)

      Merci pour avoir suivi ce travail de longue haleine !

      Fabien

      Remplis sous: Starling 6 Commentaires
      23jan/120

      Starling API – 29 – Réagir à la collision entre 2 body Box2D

      Pour l'instant, on peut avec notre poisson, détruire le décor composé de body Box2D associés à des MovieClip que l'on a créé dans un tutorial précédent:

      Starling API - 17 - Création des éléments du décor avec BlockFactory, TerrainFactory et EnemyFactory

      Nos blocs sont donc des MovieClip contenant plusieurs Texture. Les Textures sont en fait les mêmes mais avec une opacité différente. Si vous avez un graphiste, vous auriez des dessins différents pour chaque état de destruction du bloc. Pour notre test en tout cas, tout bloc qui sera touché va devenir de plus en plus transparent suivant la force qui lui sera appliquée.

      Détecter une collision avec b2World::SetContactListener()

      Il y a une méthode simple pour détecter les collisions qui est de placer un "ContactListener" sur le monde (objet de type b2World). Ce ContactListener est une classe qui étend b2ContactListener. Créons donc la classe BlockContactListener:

      package com.fnicollet {
        import Box2D.Dynamics.b2ContactListener;
      
        public class BlockContactListener extends b2ContactListener {
          public function BlockContactListener() {
            super();
          }
        }
      }
      

      Dans la méthode init() de AquariumScreen, on l'associé à notre monde:

      world.SetContactListener(new BlockContactListener);

      Ensuite, dans BlockContactListener, il faut surcharger la méthode suivante:

      function PostSolve(contact:b2Contact, impulse:b2ContactImpulse):void

      Cette méthode nous donne accès à un objet b2Contact qui a des références vers les 2 objets en contact et à un objet b2ContactImpulse qui contient des informations sur la collision comme sa force. Pour récupérer la force de la collision, on va récupérer la valeur de la normale:

      override public function PostSolve(contact:b2Contact, impulse:b2ContactImpulse):void {
        var firstNormalImpulse:Number = impulse.normalImpulses[0];
      }

      Si cette valeur est supérieure à un certain seul, on va récupérer les 2 objets en contact:

      override public function PostSolve(contact:b2Contact, impulse:b2ContactImpulse):void {
        const MAX_IMPULSE:Number = 10;
        var firstNormalImpulse:Number = impulse.normalImpulses[0];
        if (firstNormalImpulse > MAX_IMPULSE) {
          var userDataA:DisplayObject = contact.GetFixtureA().GetBody().GetUserData();
          var bodyDefinitionA:b2BodyDef = contact.GetFixtureA().GetBody().GetDefinition();
          var userDataB:DisplayObject = contact.GetFixtureB().GetBody().GetUserData();
          var bodyDefinitionB:b2BodyDef = contact.GetFixtureB().GetBody().GetDefinition();
          var nameA:String = userDataA.name;
          var nameB:String = userDataB.name;
        }
      }

      Ensuite, on va détecter la collision entre un fish (dont les noms commencent par "bird_") et un corps Box2D dynamique (nos blocks). En même temps, on va faire pareil pour les collisions avec le sol. Le code n'est pas super mais c'est pour vous expliquer en gros:

      override public function PostSolve(contact:b2Contact, impulse:b2ContactImpulse):void {
        const MAX_IMPULSE:Number = 10;
        var firstNormalImpulse:Number = impulse.normalImpulses[0];
        if (firstNormalImpulse > MAX_IMPULSE) {
          var userDataA:DisplayObject = contact.GetFixtureA().GetBody().GetUserData();
          var bodyDefinitionA:b2BodyDef = contact.GetFixtureA().GetBody().GetDefinition();
          var userDataB:DisplayObject = contact.GetFixtureB().GetBody().GetUserData();
          var bodyDefinitionB:b2BodyDef = contact.GetFixtureB().GetBody().GetDefinition();
          var nameA:String = userDataA.name;
          var nameB:String = userDataB.name;
          var densityA:Number = contact.GetFixtureA().GetDensity();
          var densityB:Number = contact.GetFixtureB().GetDensity();
          var isAFloor:Boolean = densityA == 0;
          var isBFloor:Boolean = densityB == 0;
          var isAFish:Boolean = nameA && nameA.indexOf("GUPPY_") != -1;
          var isBFish:Boolean = nameB && nameB.indexOf("GUPPY_") != -1;
          if ((isAFloor || isAFish) && bodyDefinitionB.type == b2Body.b2_dynamicBody) {
            destroyDisplayObjectBy(userDataB, firstNormalImpulse);
          }
          if ((isBFloor || isBFish) && bodyDefinitionA.type == b2Body.b2_dynamicBody) {
            destroyDisplayObjectBy(userDataA, firstNormalImpulse);
          }
        }
      }
      
      private function destroyDisplayObjectBy(dObj:DisplayObject, damage:Number):void {
        if (damage < 1) {
          return;
        }
        var mc:MovieClip = dObj as MovieClip;
        if (!mc) {
          return;
        }
        if (mc.currentFrame == mc.numFrames - 1) {
          mc.removeFromParent();
          return;
        }
        mc.currentFrame++;
      }

      Faire le ménage avant de partir

      Si vous testez l'application comme cela, vous verrez que lorsque nos blocs ont pris beaucoup de dégâts, ils disparaissent. Mais il sont encore pris en compte dans le calcul des collisions ! En effet,  on a supprimé le MovieClip, donc l'affichage graphique. Le "body" Box2D est lui toujours présent et pris en compte dans la simulation.

      On va donc rajouter le "body" à notre méthode destroyDisplayObjectBy et supprimer l'objet du monde pour de bon:

      private function destroyDisplayObjectBy(dObj:DisplayObject, damage:Number, body:b2Body):void {
        if (damage < 1) {
          return;
        }
        var mc:MovieClip = dObj as MovieClip;
        if (!mc) {
          return;
        }
        if (mc.currentFrame == mc.numFrames - 1) {
          mc.removeFromParent();
          body.GetWorld().DestroyBody(body);
          return;
        }
        mc.currentFrame++;
      }

      Si vous essayez, vous verrez que cela ne fonctionne pas. En cherchant un peu sur le net, on s'aperçoit que la suppression d'un body pendant la simulation n'est pas la bonne solution. Il faut garder une liste des éléments à supprimer et le faire avant le prochain rendu (=Step).

      On rajoute donc une variable static à BlockContactListener pour faire simple:

      public static var toRemove:Array = [];

      puis:

        if (mc.currentFrame == mc.numFrames - 1) {
          mc.removeFromParent();
          if (toRemove.indexOf(body) == -1){
            toRemove.push(body);
          }
          return;
        }

      Et dans notre méthode updateWorld, on supprime les éléments en attente:

      private function updateWorld(event:Event):void {
        var toRemove:Array = BlockContactListener.toRemove;
        for each (var bodyToRemove:b2Body in toRemove) {
          world.DestroyBody(bodyToRemove);
        }
        BlockContactListener.toRemove = [];

      Voilà le rendu final:

      This movie requires Flash Player 11

      Conclusion

      Et voilà, le fil rouge des tutoriaux Starling touche à sa fin. Dans le prochain article (et le dernier), on verra les pistes d'amélioration qu'il vous reste si vous souhaitez continuer :) .

      Télécharger les sources

      Remplis sous: Starling Aucun commentaire