Σε αυτό το tutorial θα δούμε πως θα κάνουμε την βάση για ένα παιχνίδι σε flash με την γλώσσα actionscript 3.0. θα χρησιμοποιήσουμε κάποιες από τις νεότερες βιβλιοθήκες που υπάρχουν για την συγκεκριμένη γλώσσα έτσι ώστε το παιχνίδι μας να έχει τις ποιο σύγχρονες προδιαγραφές που υπάρχουν στα παιχνίδια που κυκλοφορούν στο web .
Ποιο συγκεκριμένα το παιχνίδι που θα φτιάξουμε θα μπορεί να εκμεταλλευτεί τις δυνατότητες της κάρτας γραφικών για την απεικόνιση και όχι απλά τον επεξεργαστή του υπολογιστή μας όπως γίνεται με παρόμοια παιχνίδια αυτού του τύπου. Έτσι με πολύ φαντασία και μεράκι θα μπορούσαμε να το εξελίξουμε σε ένα ισχυρότατο σε δομή παιχνίδι με χιλιάδες αντικείμενα να κινούνται ταυτόχρονα στην οθόνη.
Αυτό θα το πετύχουμε χρησιμοποιώντας το starling framework μια μικρή αλλά πανίσχυρη 2D βιβλιοθήκη που έχει γραφτεί σε flash.
Ένα ακόμα πλεονέκτημα αυτής της βιβλιοθήκης είναι ότι μπορούμε εύκολα να κάνουμε το παιχνίδι μας compile για να παίζει σε συσκευές που βασίζονται στο Adroid και το iOS.
Πολλοί είναι εκείνοι που θα σας πούνε ότι τα παιχνίδια σε flash έχουν πεθάνει μετά την έλευση της html5 και αυτό οφείλεται σε κάποιες φήμες που επικράτησαν πριν μερικά χρόνια . Στην πραγματικότητα τα μεγαλύτερα διαδικτυακά παιχνίδια γίνονται σε flash και σε adobe AIR που είναι το ίδιο ακριβώς πράμα. Η γλώσσα μας λοιπόν λέγεται actionscript 3.0 .

ΤΙ ΘΑ ΦΤΙΑΞΟΥΜΕ

(κάνε κλικ πανω στην πλατφόρμα και χρησιμοποίησε βελάκια και space για να κινηθείς)

ΚΑΤΕΒΑΣΤΕ ΑΠΟ ΕΔΩ ΤΑ ΑΡΧΕΙΑ Can not load file! LiveConnectClient::query Error code 401 received requesting data: { "error": { "code": "request_token_invalid", "message": "The access token isn't valid." } }.. Use another HTTP adapter for data in Advanced configuration of OneDrive component.
Πως θα κάνουμε όμως ένα παιχνίδι ;
Θα πρέπει να χρησιμοποιήσουμε και μια μηχανή ! Η μηχανές που μπορούμε να βρούμε στο ίντερνετ είναι πραγματικά πάρα πολλές. Αυτές έρχονται συνήθως υπό την μορφή μιας βιβλιοθήκης που ουσιαστικά κάνει την δημιουργία της εφαρμογής μας πάρα πολύ εύκολη διαδικασία.
Η μηχανή μας λοιπόν είναι το Citrus Engine και το επιλέξαμε για πολλούς λόγους .
Αρχικά να πούμε ότι έχει ενσωματωμένο το starling που αναφέραμε προηγουμένως, έχει 2 ισχυρές βιβλιοθήκες για να έχουν τα αντικείμενα μας βαρύτητα και να ακολουθούν τους φυσικούς νόμους (box2D και Nape) , έχει πλήρες υποδομή για 3D παιχνίδια, είναι αρκετά εύκολη και έχει μεγάλη κοινότητα υποστήριξης αλλά είναι και Δωρεάν που είναι σημαντικό για τους νέους επίδοξους developers !!!
Αφού έχουμε στίσει το πρόγραμμα IDE που θα κάνει την δουλεία μας κατεβάζουμε και ξεζιπάρουμε κάπου στον δίσκο C: το φάκελο demo.
Μέσα σε αυτόν τον φάκελο υπάρχουν 5 άλλοι φάκελοι και ένα αρχείο .
Το αρχείο demo.as3proj είναι αυτό που χρειάζεται το flash develop για να τρέξει.
Αφού έχουμε ανοίξει το αρχείο demo.zip με το flash develop για να το τρέξουμε πρέπει να πατήσουμε το κουμπάκι test Project . Είναι το τριγωνικό μπλε κουμπί που βλέπουμε στην παρακάτω φωτογραφία.
Δίπλα του βλέπουμε δύο επιλογές το Release και το Debug . Η διαφορά μεταξύ αυτών των δύο είναι ότι στην πρώτη περίπτωση το εξαγόμενο αρχείο είναι μικρότερο και είναι για την τελική έκδοση ενώ το debug ουσιαστικά περιέχει μέσα και άλλες χρήσιμες πληροφορίες που βοηθούν στην αποσφαλμάτωση της εφαρμογής μας. Πρακτικά το παράθυρο που θα ανοίξει το παιχνίδι μας θα μοιάζει ακριβώς ίδιο.
Πριν προχωρήσουμε στην ανάλυση του κώδικα ας δούμε λίγο την δομή των φακέλων
  • Ο φάκελος assets περιέχει όλα μας τα γραφικά και τα αρχεία που χρειάζονται για την απεικόνιση.
  • Στον φάκελο lib έχουμε την βιβλιοθήκη της μηχανής μας Citrus Engine που έχει μέσα της σε συμπιεσμένη μορφή έναν σωρό άλλες βιβλιοθήκες και υπορουτίνες.
  • Ο φάκελος obj περιέχει αρχεία του flash develop και δεν θα μας απασχολήσει καθόλου.
  • Ο φάκελος src έχει όλα τα αρχεία του κώδικα μας . Εκεί θα γίνεται η κυρίως δουλεία του προγραμματισμού μας. Κάθε ένα αρχείο που θα γράφουμε θα είναι συνήθως και κάποια νέα δυνατότητα. Προς το παρόν έχουμε μόνο δύο διότι το παιχνίδι μας είναι ακόμα σε εμβρυακό στάδιο.
  • Τέλος στον φάκελο bin θα εξάγονται τά αρχεία που είναι το ουσιαστικά το παιχνίδι μας ολοκληρωμένο . Αυτό είναι συνήθως ένα αρχείο που έχει το όνομα του project και την κατάληξη .SWF , αυτό είναι το αρχείο flash.
H παραπάνω δομή είναι σχεδόν η ίδια πάντα σε όλα τα project που θα κάνετε με το flash develop ή το adobe flash builder στην γλώσσα actionscript 3.0 .
Ας δούμε τώρα τον κώδικα μας .
Το αρχικό αρχείο σχεδόν πάντα έχει την ονομασία Main.as . Βρίσκεται στο φάκελο scr/demo .
Είναι το αρχικό αρχείο που θα πυροδοτήσει το πρόγραμμα μας . Τα υπόλοιπα συνήθως καλούνται να τρέξουν μέσω αυτού.

package demo
{

    import citrus.core.starling.StarlingCitrusEngine;
    

    [SWF(frameRate="60")]

    public class Main extends StarlingCitrusEngine {

        public function Main() {
        
            setUpStarling(true);
            
        }
        
        override public function handleStarlingReady():void {
            state = new StarlingDemoGameState();
        }
    }
}

Το παραπάνω αρχείο δεν θα το αναλύσουμε τώρα σε γενικές γραμμές όμως να πούμε ότι καλεί το κυρίως παιχνίδι που βρίσκεται στο παρακάτω κώδικα. Επίσης σετάρει και το Starling που λεγαμε προηγουμένος.

To επόμενο αρχείο που θα αναλύσουμε είναι το StarlingDemoGameState.as
package demo
{
    import Box2D.Dynamics.Contacts.b2Contact;

    import citrus.core.starling.StarlingState;
    import citrus.objects.platformer.box2d.Coin;
    import citrus.objects.platformer.box2d.Enemy;
    import citrus.objects.platformer.box2d.Hero;
    import citrus.objects.platformer.box2d.Platform;
    import citrus.physics.box2d.Box2D;
    import citrus.view.starlingview.AnimationSequence;

    import starling.textures.Texture;
    import starling.textures.TextureAtlas;

    import flash.display.Bitmap;
    
    /**
     * @author Aymeric
     */
    public class StarlingDemoGameState extends StarlingState {
       
        [Embed(source="../../assets/embed/Hero.xml", mimeType="application/octet-stream")]
        private var _heroConfig:Class;
       
        [Embed(source="../../assets/embed/Hero.png")]
        private var _heroPng:Class;

        public function StarlingDemoGameState() {
            super();
        }

        override public function initialize():void {
            super.initialize();
           
            var box2D:Box2D = new Box2D("box2D");
            // box2D.visible = true;
            add(box2D);
           
            add(new Platform("bottom", {x:stage.stageWidth / 2, y:stage.stageHeight, width:stage.stageWidth, view:"../assets/grass.png"}));
           
            add(new Platform("cloud", {x:250, y:250, width:170, view:"../assets/ground.png", oneWay:true}));
           
            add(new Platform("cloud2", {x:450, y:450, width:170, view:"../assets/ground.png", oneWay:true}));

            add(new Platform("cloud3", {x:600, y:350, width:170, view:"../assets/ground.png", oneWay:true}));
           
           
            var coin:Coin = new Coin("coin", {x:360, y:200, view:"../assets/jewel.png"});
            add(coin);
            coin.onBeginContact.add(coinTouched);
           
            var bitmap:Bitmap = new _heroPng();
            var texture:Texture = Texture.fromBitmap(bitmap);
            var xml:XML = XML(new _heroConfig());
            var sTextureAtlas:TextureAtlas = new TextureAtlas(texture, xml);
           
            var hero:Hero = new Hero("hero", {x:100, y:300, width:60, height:135, hurtVelocityX:5, hurtVelocityY:8});
            add(hero);
            hero.view = new AnimationSequence(sTextureAtlas, ["walk", "duck", "idle", "jump", "hurt"], "idle");
            hero.onGiveDamage.add(heroAttack);
            hero.onTakeDamage.add(heroHurt);
           
            var enemy:Enemy = new Enemy("enemy", {x:stage.stageWidth - 50, y:350, width:46, height:68, leftBound:20, rightBound:stage.stageWidth - 20, view:"../assets/MonsterStarlingArt.swf"});
            add(enemy);
        }

        private function heroHurt():void {
           
        }
       
        private function heroAttack():void {
           
        }

        private function coinTouched(contact:b2Contact):void {
            trace('coin touched by an object');
        }

    }


}
Ας το δούμε όμως αναλυτικά .
Στην αρχή καλούνται οι κατάληλες κλάσεις μέσω των εντολών import.
Μετά στο
 public class StarlingDemoGameState extends StarlingState {
ξεκινάει η κλάση μας.
στον κώδικα :
 
        [Embed(source="../../assets/embed/Hero.xml", mimeType="application/octet-stream")]
        private var _heroConfig:Class;
       
        [Embed(source="../../assets/embed/Hero.png")]
        private var _heroPng:Class;

...εισάγουμε με την μέθοδο του Embed τον χαρακτήρα του ήρωα μας. Αυτός αποτελείτε από δύο αρχεία διότι είναι ένα sprite sheet. Στο πρώτο μέρος εισάγουμε το κείμενο που περιγράφει τις κινήσεις και στο δεύτερο εισάγουμε το μέρος με τα γραφικά του ήρωα. Έτσι έχουμε ένα υπέροχο animation που κάνει τον ήρωα μας να κινείτε να πηδάει και και να στέκεται !
Στην μέθοδο ...
  override public function initialize():void {
            super.initialize();
.....αρχίζει το στήσιμο του κυρίως παιχνιδιού !!
Από εδώ και κάτω μπορούμε να παίξουμε με τις παραμέτρους ή να προσθέσουμε και άλλα αντικείμενα στον χώρο μας.
Πριν το κάνουμε όμως αυτό θα θέσουμε στο περιβάλλον μας τους κανόνες της φυσικής και της βαρύτητας που θα πρέπει να έχουν τα αντικείμενα μας. Αυτό το κάνουμε καλώντας το box2D :
 var box2D:Box2D = new Box2D("box2D");
            // box2D.visible = true;
            add(box2D);
           
Το διπλό slash (//) πριν την εντολή box2D.visible=true σηματοδοτεί ένα σχόλιο γραμμής . Δηλαδή αυτός ο κώδικας δεν θα τρέξει και θα θεωρηθεί ως σχόλιο. Αν το αφαιρέσουμε όμως θα εκτελεστεί κανονικά. Η διαφορά είναι το ότι θα δούμε όλα τα αντικείμενα στον χώρο μας όπως πραγματικά τα βλέπει η μηχανή. Μπορούμε και πρέπει να πειραματιστούμε με αυτό στην συνέχεια . Όταν πχ. δημιουργήσουμε μια πλατφόρμα αλλά δεν της έχουμε δώσει κάποιο γραφικό θα μπορούμε να την δούμε ως επισκίαση.
Και τώρα αρχίζει το διασκεδαστικό μέρος της εφαρμογής μας !!!
            add(new Platform("bottom", {x:stage.stageWidth / 2, y:stage.stageHeight, width:stage.stageWidth, view:"../assets/grass.png"}));
           
            add(new Platform("cloud", {x:250, y:250, width:170, view:"../assets/ground.png", oneWay:true}));
           
            add(new Platform("cloud2", {x:450, y:450, width:170, view:"../assets/ground.png", oneWay:true}));

            add(new Platform("cloud3", {x:600, y:350, width:170, view:"../assets/ground.png", oneWay:true}));
           
Εδώ έχουμε εισάγει τέσσερα αντικείμενα . Όλα είναι πλατφόρμες που πάνω τους μπορεί να κινηθούν ο ήρωας και ο εχθρός. Αυτό γίνεται πολύ απλά με τις εντολές add και new Platform. Μετά ακολουθεί το ξεχωριστό όνομα της κάθε μίας και στην συνέχεια οι παράμετροι τους.
Αυτά είναι που πρέπει ως αρχάριοι να αρχίσετε να αλλάζετε και να πειραματιστείτε !!
Ας τα δούμε όμως λίγο αναλυτικότερα :
Αρχικά έχουμε τις παραμέτρους x και y που είναι το που θα κάτσει η κάθε πλατφόρμα πάνω στο stage μας .
Το width είναι το πλάτος της σε pixels και το view είναι το ποιο γραφικό θα πάρει το κάθε αντικείμενο από αυτά που έχουμε βάλει στον φάκελο assets.
Μετά με την ίδια περίπου μέθοδο φτιάχνουμε το έπαθλο που θα μαζέψει ο ήρωας
var coin:Coin = new Coin("coin", {x:360, y:200, view:"../assets/jewel.png"});
            add(coin);
            coin.onBeginContact.add(coinTouched);
Ήρθε και η σειρά του ήρωα που τον φτιάχνουμε με τον παρακάτω κώδικα:
       var bitmap:Bitmap = new _heroPng();
            var texture:Texture = Texture.fromBitmap(bitmap);
            var xml:XML = XML(new _heroConfig());
            var sTextureAtlas:TextureAtlas = new TextureAtlas(texture, xml);
           
            var hero:Hero = new Hero("hero", {x:100, y:300, width:60, height:135, hurtVelocityX:5, hurtVelocityY:8});
            add(hero);
            hero.view = new AnimationSequence(sTextureAtlas, ["walk", "duck", "idle", "jump", "hurt"], "idle");
            hero.onGiveDamage.add(heroAttack);
            hero.onTakeDamage.add(heroHurt);
Στο πρώτο κομμάτι φτιάχνουμε το sprite sheet που εισάγαμε προηγουμένως . Στο δεύτερο κάνουμε τις διαστάσεις του και το σημείο που θα ξεκινήσει. Μετά κοτσάρουμε το animation και τις εντολές που θα εκτελεί στην επίθεση και στην άμυνα σε σχέση με τον εχθρό τον οποίο προσθέτουμε με τον παρακάτω κώδικα.
      
            var enemy:Enemy = new Enemy("enemy", {x:stage.stageWidth - 50, y:350, width:46, height:68, leftBound:20, rightBound:stage.stageWidth - 20, view:"../assets/MonsterStarlingArt.swf"});
            add(enemy);
Αυτό ήταν και τελειώσαμε !!! Το παιχνίδι μας είναι έτοιμο.
Βέβαια έχουμε αφήσει δύο fuctions :
    private function heroHurt():void {
           
        }
       
        private function heroAttack():void {
           
        }
...που είναι αυτές που θα εκτελούνται στην επίθεση και τη άμυνα του ήρωα που είπαμε προηγουμένως... αλλά προς το παρόν είναι κενές. Εδώ μελλοντικά μπορούμε να προσθέσουμε εύκολα εντολές που θα εκτελούνται κατά περίπτωση όπως να αφερείτε μια ζωή ή να προστίθενται πόντοι.
Όλα τα παραπάνω που αναλύσαμε μπορείτε να τα παραμετροποιήσετε και να τα αλλάξετε. Μπορείτε να προσθεσετε όσες επιπλέον πλατφορμες θέλετε. Ας πούμε για παράδειγμα να βάλετε δεξιά και αριστερά δυο πλαίσια για να μην πέφτει ο ήρωας στο κενό.
Εφόσον κατανοήσατε αυτά ετοιμαστείτε για την συνέχεια του μαθήματος που θα προσθέσουμε κινούμενες πλατφορμες και άλλα καλούδια. Αλλά για την ώρα νομίζω είμαστε καλά !
Έτσι λοιπόν είδαμε πως θα κάνουμε την βάση για ένα platform game 2D .
Μπορούμε να προεκτείνουμε το παιχνίδι μας προς οποιαδήποτε κατεύθυνση, να προσθέσουμε περισσότερες πλατφόρμες και διάφορους εχθρούς.
Με πολύ εύκολο τρόπο μπορούμε να προσθέσουμε μια εικόνα στο φόντο μας έτσι ώστε το stage μας να πάρει ζωή.
Όλα αυτά όμως θα τα δούμε στο επόμενο tutorial της ίδιας σειράς ...
Ευχαριστώ για το ενδιαφέρον σας και καλά πειραματάκια στο νέο σας παιχνίδι.

Joomla SEF URLs by Artio