portaldacalheta.pt
  • Κύριος
  • Επενδυτές & Χρηματοδότηση
  • Σχεδιασμός Διεπαφής Χρήστη
  • Τεχνολογία
  • Διαχείριση Έργου
Διεπαφή Ιστού

Δημιουργία παιχνιδιού με βάση τον καμβά HTML5: Ένα πρόγραμμα εκμάθησης που χρησιμοποιεί το AngularJS και το CreateJS



Η ανάπτυξη παιχνιδιών είναι μια από τις πιο ενδιαφέρουσες, προηγμένες τεχνικές προγραμματισμού που προκαλούν συνεχώς τη βιομηχανία ανάπτυξης λογισμικού.

Υπάρχουν πολλές πλατφόρμες προγραμματισμού που χρησιμοποιούνται για την ανάπτυξη παιχνιδιών και υπάρχει μια πληθώρα συσκευών για να τα παίξετε, αλλά όταν πρόκειται για παιχνίδια σε ένα πρόγραμμα περιήγησης στο Web, η ανάπτυξη με βάση το Flash εξακολουθεί να οδηγεί στο δρόμο.



Επανεγγραφή παιχνιδιών που βασίζονται σε Flash σε HTML5 Η τεχνολογία Canvas θα μας επέτρεπε να τα παίξουμε και σε προγράμματα περιήγησης για κινητά. Και, με την Apache Cordova, ειδικευμένοι προγραμματιστές ιστού θα μπορούσε εύκολα να τα τυλίξει σε εφαρμογές παιχνιδιών για κινητές συσκευές πολλαπλών πλατφορμών.



Οι άνθρωποι στο Δημιουργία JS ξεκίνησε να κάνει αυτό και πολλά άλλα.



EaselJS , μέρος της σουίτας του CreateJS, απλοποιεί το σχέδιο σε καμβά HTML5. Φανταστείτε να δημιουργήσετε προσαρμοσμένη οπτικοποίηση δεδομένων με υψηλή απόδοση και χιλιάδες στοιχεία. Το Scalable Vector Graphic (SVG) δεν είναι η σωστή επιλογή, επειδή χρησιμοποιεί στοιχεία DOM. Τα προγράμματα περιήγησης κατακλύζονται όταν, σε περίπου 600 στοιχεία DOM, οι αρχικές αποδόσεις, οι επαναλήψεις και οι κινούμενες εικόνες γίνονται ακριβές. Με το HTML5 Canvas, μπορούμε εύκολα να αντιμετωπίσουμε αυτά τα προβλήματα. Τα σχέδια καμβά είναι σαν μελάνι σε χαρτί, χωρίς στοιχεία DOM και το σχετικό κόστος.

Αυτό σημαίνει ότι η ανάπτυξη που βασίζεται σε καμβά χρειάζεται περισσότερη προσοχή όσον αφορά το διαχωρισμό στοιχείων και την προσάρτηση συμβάντων και συμπεριφορών σε αυτά. Το EaselJS έρχεται στη διάσωση. μπορούμε να κωδικοποιήσουμε σαν να ασχολούμαστε με μεμονωμένα στοιχεία, επιτρέποντας στη βιβλιοθήκη EaselJS να χειρίζεται τα ποντίκια, τα κλικ και τις συγκρούσεις σας.



Η κωδικοποίηση με βάση το SVG έχει ένα μεγάλο πλεονέκτημα: Το SVG έχει μια παλιά προδιαγραφή και υπάρχουν πολλά εργαλεία σχεδίασης που εξάγουν στοιχεία SVG για χρήση στην ανάπτυξη, έτσι ώστε η συνεργασία μεταξύ σχεδιαστών και προγραμματιστών να λειτουργεί καλά. Δημοφιλείς βιβλιοθήκες, όπως D3.JS και νεότερες, πιο ισχυρές βιβλιοθήκες SnapSVG , φέρτε πολλά στο τραπέζι.

Εάν η ροή εργασίας σχεδιαστής-προς-προγραμματιστή είναι ο μόνος λόγος που θα χρησιμοποιούσατε SVG, σκεφτείτε τις επεκτάσεις για Adobe Illustrator (AI) που δημιουργούν κώδικα από σχήματα που δημιουργούνται στο AI. Στο πλαίσιο μας, τέτοιες επεκτάσεις δημιουργούν κώδικα EaselJS ή κώδικα ProcessingJS, και οι δύο είναι βιβλιοθήκες που βασίζονται σε καμβά HTML5



Κατώτατη γραμμή, εάν ξεκινάτε ένα νέο έργο, δεν υπάρχει κανένας λόγος να χρησιμοποιήσετε πια SVG!

SoundJS είναι μέρος της σουίτας CreateJS. Παρέχει ένα απλό API για προδιαγραφές ήχου HTML5.



δωρεάν χακαρισμένοι αριθμοί πιστωτικών καρτών με cvv

PreloadJS χρησιμοποιείται για την προφόρτωση στοιχείων όπως bitmap, αρχεία ήχου και τα παρόμοια. Λειτουργεί καλά σε συνδυασμό με άλλες βιβλιοθήκες CreateJS.

Τα EaselJS, SoundJS και PreloadJS κάνουν την ανάπτυξη παιχνιδιών εξαιρετικά εύκολη για κάθε ninja JavaScript. Οι μέθοδοι API του είναι γνωστές σε οποιονδήποτε χρησιμοποίησε την ανάπτυξη παιχνιδιών με βάση το Flash.



«Όλα αυτά είναι υπέροχα. Τι γίνεται όμως αν έχουμε μια ομάδα προγραμματιστών που μετατρέπουν μια σειρά παιχνιδιών από το Flash σε HTML5; Είναι δυνατόν να το κάνετε αυτό με αυτή τη σουίτα; '

Η απάντηση: 'Ναι, αλλά μόνο εάν όλοι οι προγραμματιστές σας είναι σε επίπεδο Jedi!'.



Εάν έχετε μια ομάδα διαφορετικών προγραμματιστών σετ δεξιοτήτων, κάτι που συμβαίνει συχνά, μπορεί να είναι λίγο τρομακτικό να χρησιμοποιήσετε το CreateJS και να περιμένετε έναν επεκτάσιμο και αρθρωτό κώδικα. Τι γίνεται αν φέρουμε μαζί τη σουίτα CreateJS με Γωνιακό JS ; Μπορούμε να μετριάσουμε αυτόν τον κίνδυνο φέρνοντας το καλύτερο και πιο υιοθετημένο πλαίσιο JS front-end;

Ναί , και αυτό το σεμινάριο παιχνιδιών HTML5 Canvas θα σας διδάξει πώς να δημιουργήσετε ένα βασικό παιχνίδι με το CreateJS και το AngularJS!

Σεμινάριο παιχνιδιών HTML5 Canvas με το CreateJS και το AngularJS

από την πλευρά του πελάτη έναντι της απόδοσης από την πλευρά του διακομιστή

Φύτευση του σπόρου

Το AngularJS μειώνει σημαντικά την πολυπλοκότητα επιτρέποντας στην ομάδα ανάπτυξής σας τα εξής:

  1. Προσθέτοντας modularity κώδικα, έτσι ώστε τα μέλη της ομάδας να μπορούν να επικεντρωθούν σε διαφορετικές πτυχές του παιχνιδιού.
  2. Διάσπαση του κώδικα σε ξεχωριστά δοκιμή και συντηρήσιμα κομμάτια.
  3. Ενεργοποίηση επαναχρησιμοποίησης κώδικα, έτσι ώστε μια κλάση εργοστασίων να μπορεί να δημιουργηθεί πολλές φορές και να χρησιμοποιηθεί ξανά για τη φόρτωση διαφορετικών αλλά παρόμοιων στοιχείων και συμπεριφορών.
  4. Επιτάχυνση της ανάπτυξης επειδή πολλά μέλη της ομάδας μπορούν να εργαστούν παράλληλα, χωρίς να πατήσουν τα δάχτυλα του άλλου.
  5. Προστασία των προγραμματιστών από τη χρήση κακών μοτίβων (το Javascript φέρνει φημισμένα κακά μέρη μαζί του και το JSLint μπορεί να μας βοηθήσει μόνο πολύ).
  6. Προσθήκη ενός σταθερού πλαισίου δοκιμών.

Εάν, όπως εγώ, είστε «μάθημα» ή μαθητής αφής, θα πρέπει να λάβετε τον κωδικό από GitHub και αρχίστε να μαθαίνετε. Η πρότασή μου είναι να κοιτάξω τα check-in μου και να κατανοήσω τα βήματα που έκανα για να κερδίσω οφέλη από την προσθήκη του AngularJS καλοσύνη στον κώδικα CreateJS.

Εκτέλεση του έργου σας AngularJS Seed

Εάν δεν το έχετε κάνει ήδη, πρέπει να το εγκαταστήσετε nodeJS πριν μπορέσετε να εκτελέσετε αυτό το demo.

Αφού δημιουργήσετε ένα έργο AngularJS seed ή κατεβάστε το από GitHub , τρέξτε npm install για λήψη όλων των εξαρτήσεων στο φάκελο της εφαρμογής σας.

Για να εκτελέσετε την εφαρμογή σας, εκτελέστε npm start από τον ίδιο φάκελο και μεταβείτε στο http://localhost:8000/app/#/view1 στο πρόγραμμα περιήγησής σας. Η σελίδα σας θα πρέπει να μοιάζει με την παρακάτω εικόνα.

παράδειγμα σελίδας

Το EaselJS συναντά το AngularJS

Προσθέστε αναφορά βιβλιοθήκης CreateJS στο έργο σας AngularJS seed. Βεβαιωθείτε ότι το σενάριο CreateJS περιλαμβάνεται μετά το AngularJS.

Στη συνέχεια, καθαρίστε την εφαρμογή:

  • Διαγράψτε το φάκελο view2 από το φάκελο της εφαρμογής σας
  • Καταργήστε τις πληροφορίες του μενού και της έκδοσης AngularJS από το index.html, διαγράφοντας τον παρακάτω κώδικα:
  • view1
  • view2
… Angular seed app: v …

Κατάργηση view2 ενότητα από app.js, διαγράφοντας την ακόλουθη γραμμή

myApp.view2,

Εάν δεν έχετε χρησιμοποιήσει το AngularJS στο παρελθόν και δεν είστε εξοικειωμένοι με τις οδηγίες του AngularJS, ελέγξτε αυτό το σεμινάριο . Οι οδηγίες στο AngularJS είναι ένας τρόπος για να διδάξετε HTML μερικά νέα κόλπα. Είναι το πιο καλά μελετημένο χαρακτηριστικό στο πλαίσιο και καθιστούν το AngularJS ισχυρό και επεκτάσιμο.

Όποτε χρειάζεστε μια εξειδικευμένη λειτουργικότητα DOM ή ένα στοιχείο, αναζητήστε το στο διαδίκτυο. υπάρχει μια καλή πιθανότητα να είναι ήδη διαθέσιμο σε μέρη όπως Γωνιακές ενότητες .

Το επόμενο πράγμα που πρέπει να κάνουμε είναι να δημιουργήσουμε μια νέα οδηγία AngularJS που θα εφαρμόσει το παράδειγμα από το EaselJS. Δημιουργήστε μια νέα οδηγία που ονομάζεται spriteSheetRunner σε ένα νέο αρχείο που βρίσκεται στο /app/view1/directives/spriteSheetRunner.js.

angular.module('myApp.directives', []) .directive('spriteSheetRunner', function () { 'use strict'; return { restrict : 'EAC', replace : true, scope :{ }, template: '', link: function (scope, element, attribute) { var w, h, loader, manifest, sky, grant, ground, hill, hill2; drawGame(); function drawGame() { //drawing the game canvas from scratch here //In future we can pass stages as param and load indexes from arrays of background elements etc if (scope.stage) { scope.stage.autoClear = true; scope.stage.removeAllChildren(); scope.stage.update(); } else { scope.stage = new createjs.Stage(element[0]); } w = scope.stage.canvas.width; h = scope.stage.canvas.height; manifest = [ {src: 'spritesheet_grant.png', id: 'grant'}, {src: 'sky.png', id: 'sky'}, {src: 'ground.png', id: 'ground'}, {src: 'hill1.png', id: 'hill'}, {src: 'hill2.png', id: 'hill2'} ]; loader = new createjs.LoadQueue(false); loader.addEventListener('complete', handleComplete); loader.loadManifest(manifest, true, '/app/assets/'); } function handleComplete() { sky = new createjs.Shape(); sky.graphics.beginBitmapFill(loader.getResult('sky')).drawRect(0, 0, w, h); var groundImg = loader.getResult('ground'); ground = new createjs.Shape(); ground.graphics.beginBitmapFill(groundImg).drawRect(0, 0, w groundImg.width, groundImg.height); ground.tileW = groundImg.width; ground.y = h - groundImg.height; hill = new createjs.Bitmap(loader.getResult('hill')); hill.setTransform(Math.random() * w, h - hill.image.height * 4 - groundImg.height, 4, 4); hill.alpha = 0.5; hill2 = new createjs.Bitmap(loader.getResult('hill2')); hill2.setTransform(Math.random() * w, h - hill2.image.height * 3 - groundImg.height, 3, 3); var spriteSheet = new createjs.SpriteSheet({ framerate: 30, 'images': [loader.getResult('grant')], 'frames': {'regX': 82, 'height': 292, 'count': 64, 'regY': 0, 'width': 165}, // define two animations, run (loops, 1.5x speed) and jump (returns to run): 'animations': { 'run': [0, 25, 'run', 1.5], 'jump': [26, 63, 'run'] } }); grant = new createjs.Sprite(spriteSheet, 'run'); grant.y = 35; scope.stage.addChild(sky, hill, hill2, ground, grant); scope.stage.addEventListener('stagemousedown', handleJumpStart); createjs.Ticker.timingMode = createjs.Ticker.RAF; createjs.Ticker.addEventListener('tick', tick); } function handleJumpStart() { grant.gotoAndPlay('jump'); } function tick(event) { var deltaS = event.delta / 1000; var position = grant.x 150 * deltaS; var grantW = grant.getBounds().width * grant.scaleX; grant.x = (position >= w grantW) ? -grantW : position; ground.x = (ground.x - deltaS * 150) % ground.tileW; hill.x = (hill.x - deltaS * 30); if (hill.x hill.image.width * hill.scaleX <= 0) { hill.x = w; } hill2.x = (hill2.x - deltaS * 45); if (hill2.x hill2.image.width * hill2.scaleX <= 0) { hill2.x = w; } scope.stage.update(event); } } } });

Μόλις δημιουργηθεί η οδηγία σας, προσθέστε μια εξάρτηση στην εφαρμογή ενημερώνοντας /app/app.js ως κατωτέρω:

'use strict'; // Declare app level module which depends on views, and components angular.module('myApp',[ 'ngRoute', 'myApp.view1', 'myApp.version', 'myApp.services', 'myApp.uiClasses', 'myApp.directives']) .config(['$routeProvider', function($routeProvider) { $routeProvider.otherwise({redirectTo: '/view1'}); }]);

Συμπεριλάβετε τον κωδικό οδηγίας στο index.html προσθέτοντας μια αναφορά στο spriteSheetRunner.js.

app/view/view1.html

Είμαστε σχεδόν έτοιμοι! Αντιγράψτε τα στοιχεία παιχνιδιού στο φάκελο της εφαρμογής σας. Έχω ετοιμάσει τις εικόνες, οπότε μη διστάσετε να τις κατεβάσετε και να τις αποθηκεύσετε στο φάκελο της εφαρμογής / στοιχείων σας.

ερωτήματα πολυμέσων για τυπικές συσκευές
  • app / asset / spritesheet_grant.png
  • app / asset / ground.png
  • app / asset / hill1.png
  • app / asset / hill2.png
  • app / asset / sky.png

Ως τελικό βήμα, προσθέστε τη νέα μας οδηγία στη σελίδα. Για να το αλλάξετε, αλλάξτε το loaderSvc.js αρχείο, και να το κάνουμε με ένα επένδυση:

/app/view1/services

Ξεκινήστε την αίτησή σας και θα ξεκινήσετε τον δρομέα σας :)

δρομέας σε κίνηση

Εάν αυτή είναι η πρώτη σας εφαρμογή AngularJS ή CreateJS, γιορτάστε, κάνατε κάτι πολύ ωραίο!

Προφόρτωση περιουσιακών στοιχείων σε μια υπηρεσία

Οι υπηρεσίες στο AngularJS είναι απλές που χρησιμοποιούνται κυρίως για την κοινή χρήση του κώδικα και των δεδομένων. Θα χρησιμοποιήσουμε μια υπηρεσία για να μοιραστούμε τα «στοιχεία παιχνιδιού» σε ολόκληρη την εφαρμογή. Για να μάθετε περισσότερα σχετικά με τις υπηρεσίες AngularJS, ελέγξτε το Τεκμηρίωση AngularJS .

Υπηρεσίες ανάπτυξης AngularJS παρέχει έναν αποτελεσματικό μηχανισμό φόρτωσης και διαχείρισης όλων των περιουσιακών στοιχείων σε ένα μέρος. Οι αλλαγές στοιχείων μεταδίδονται σε κάθε μεμονωμένη παρουσία μιας υπηρεσίας, κάνοντας τον κώδικά μας πολύ πιο εύκολο να διατηρηθεί.

Δημιουργήστε νέο αρχείο JS με όνομα //app/view1/services/loaderSvc.js myServices.service('loaderSvc', function () { var manifest = [ {src: 'spritesheet_grant.png', id: 'grant'}, {src: 'sky.png', id: 'sky'}, {src: 'ground.png', id: 'ground'}, {src: 'hill1.png', id: 'hill'}, {src: 'hill2.png', id: 'hill2'} ], loader = new createjs.LoadQueue(true); this.getResult = function (asset) { return loader.getResult(asset); }; this.getLoader = function () { return loader; }; this.loadAssets = function () { loader.loadManifest(manifest, true, '/app/assets/'); }; }); στο app.js ντοσιέ.

myApp.services

Το AngularJS απαιτεί από εμάς να καταχωρήσουμε οποιαδήποτε υπηρεσία χρησιμοποιούμε. Για να το κάνετε αυτό, ενημερώστε το 'use strict'; // Declare app level module which depends on views, and components angular.module('myApp',[ 'ngRoute', 'myApp.view1', 'myApp.version', 'myApp.services', 'myApp.directives']) .config(['$routeProvider', function($routeProvider) { $routeProvider.otherwise({redirectTo: '/view1'}); }]); var myServices = angular.module('myApp.services', []); αρχείο για να συμπεριληφθεί αναφορά στο app/view1/directives/spriteSheetRunner.js.

angular.module('myApp.directives', []) .directive('spriteSheetRunner', ['loaderSvc', function (loaderSvc) { 'use strict'; return { restrict : 'EAC', replace : true, scope :{ }, template: '', link: function (scope, element, attribute) { var w, h, manifest, sky, grant, ground, hill, hill2; drawGame(); function drawGame() { //drawing the game canvas from scratch here //In future we can pass stages as param and load indexes from arrays of background elements etc if (scope.stage) { scope.stage.autoClear = true; scope.stage.removeAllChildren(); scope.stage.update(); } else { scope.stage = new createjs.Stage(element[0]); } w = scope.stage.canvas.width; h = scope.stage.canvas.height; loaderSvc.getLoader().addEventListener('complete', handleComplete); loaderSvc.loadAssets(); } function handleComplete() { sky = new createjs.Shape(); sky.graphics.beginBitmapFill(loaderSvc.getResult('sky')).drawRect(0, 0, w, h); var groundImg = loaderSvc.getResult('ground'); ground = new createjs.Shape(); ground.graphics.beginBitmapFill(groundImg).drawRect(0, 0, w + groundImg.width, groundImg.height); ground.tileW = groundImg.width; ground.y = h - groundImg.height; hill = new createjs.Bitmap(loaderSvc.getResult('hill')); hill.setTransform(Math.random() * w, h - hill.image.height * 4 - groundImg.height, 4, 4); hill.alpha = 0.5; hill2 = new createjs.Bitmap(loaderSvc.getResult('hill2')); hill2.setTransform(Math.random() * w, h - hill2.image.height * 3 - groundImg.height, 3, 3); var spriteSheet = new createjs.SpriteSheet({ framerate: 30, 'images': [loaderSvc.getResult('grant')], 'frames': {'regX': 82, 'height': 292, 'count': 64, 'regY': 0, 'width': 165}, // define two animations, run (loops, 1.5x speed) and jump (returns to run): 'animations': { 'run': [0, 25, 'run', 1.5], 'jump': [26, 63, 'run'] } }); grant = new createjs.Sprite(spriteSheet, 'run'); grant.y = 35; scope.stage.addChild(sky, hill, hill2, ground, grant); scope.stage.addEventListener('stagemousedown', handleJumpStart); createjs.Ticker.timingMode = createjs.Ticker.RAF; createjs.Ticker.addEventListener('tick', tick); } function handleJumpStart() { grant.gotoAndPlay('jump'); } function tick(event) { var deltaS = event.delta / 1000; var position = grant.x + 150 * deltaS; var grantW = grant.getBounds().width * grant.scaleX; grant.x = (position >= w + grantW) ? -grantW : position; ground.x = (ground.x - deltaS * 150) % ground.tileW; hill.x = (hill.x - deltaS * 30); if (hill.x + hill.image.width * hill.scaleX <= 0) { hill.x = w; } hill2.x = (hill2.x - deltaS * 45); if (hill2.x + hill2.image.width * hill2.scaleX <= 0) { hill2.x = w; } scope.stage.update(event); } } } }]);

Ενημερώστε τον κωδικό της οδηγίας σας, σε 'use strict'; // Declare app level module which depends on views, and components angular.module('myApp',[ 'ngRoute', 'myApp.view1', 'myApp.version', 'myApp.services', 'myApp.uiClasses', 'myApp.directives']) .config(['$routeProvider', function($routeProvider) { $routeProvider.otherwise({redirectTo: '/view1'}); }]); var uiClasses = angular.module('myApp.uiClasses', []); var myServices = angular.module('myApp.services', []); αρχείο, για να καταργήσετε τον κωδικό προφόρτωσης και να χρησιμοποιήσετε την υπηρεσία αντ 'αυτού.

uiClasses.factory('Sky', [ 'loaderSvc', function (loaderSvc) { function Sky(obj) { this.sky = new createjs.Shape(); this.sky.graphics.beginBitmapFill(loaderSvc.getResult('sky')).drawRect(0, 0, obj.width, obj.height); } Sky.prototype = { addToStage: function (stage) { stage.addChild(this.sky); }, removeFromStage: function (stage) { stage.removeChild(this.sky); } }; return (Sky); }]);

Δημιουργία εργοστασίου στοιχείων διεπαφής χρήστη

Η επαναχρησιμοποίηση και η επανάληψη των sprite στην ανάπτυξη παιχνιδιών είναι πολύ σημαντική. Προκειμένου να ενεργοποιήσουμε το instantiation των κατηγοριών UI (που είναι sprites στην περίπτωσή μας) θα χρησιμοποιήσουμε το AngularJS Factories.

Το εργοστάσιο είναι εγγεγραμμένο στην εφαρμογή όπως και κάθε άλλη μονάδα AngularJS. Για να δημιουργήσετε το εργοστάσιο uiClasses, τροποποιήστε το αρχείο app.js για να μοιάζει με αυτό:

uiClasses.factory('Hill', [ 'loaderSvc', function (loaderSvc) { function Hill(obj) { this.hill = new createjs.Bitmap(loaderSvc.getResult(obj.assetName)); this.hill.setTransform(Math.random() * obj.width, obj.height - this.hill.image.height * obj.scaleFactor - obj.groundHeight, obj.scaleFactor, obj.scaleFactor); } Hill.prototype = { addToStage: function (stage) { stage.addChild(this.hill); }, removeFromStage: function (stage) { stage.removeChild(this.hill); }, setAlpha: function (val) { this.hill.alpha = val; }, getImageWidth: function () { return this.hill.image.width; }, getScaleX: function () { return this.hill.scaleX; }, getX: function () { return this.hill.x; }, getY: function () { return this.hill.y; }, setX: function (val) { this.hill.x = val; }, move: function (x, y) { this.hill.x = this.hill.x + x; this.hill.y = this.hill.y + y; } }; return (Hill); }]);

Ας χρησιμοποιήσουμε το νέο εργοστάσιο για να δημιουργήσουμε ουρανό, λόφο, έδαφος και τον δρομέα μας. Για να το κάνετε αυτό, δημιουργήστε αρχεία JavaScript όπως αναφέρονται παρακάτω.

  • app / view1 / uiClasses / sky.js
uiClasses.factory('Ground', [ 'loaderSvc', function (loaderSvc) { function Ground(obj) { var groundImg = loaderSvc.getResult('ground'); this.ground = new createjs.Shape(); this.ground.graphics.beginBitmapFill(groundImg).drawRect(0, 0, obj.width + groundImg.width, groundImg.height); this.ground.tileW = groundImg.width; this.ground.y = obj.height - groundImg.height; this.height = groundImg.height; } Ground.prototype = { addToStage: function (stage) { stage.addChild(this.ground); }, removeFromStage: function (stage) { stage.removeChild(this.ground); }, getHeight: function () { return this.height; }, getX: function () { return this.ground.x; }, setX: function (val) { this.ground.x = val; }, getTileWidth: function () { return this.ground.tileW; }, move: function (x, y) { this.ground.x = this.ground.x + x; this.ground.y = this.ground.y + y; } }; return (Ground); }]);
  • app / view1 / uiClasses / hill.js
uiClasses.factory('Character', [ 'loaderSvc', function (loaderSvc) { function Character(obj) { var spriteSheet = new createjs.SpriteSheet({ framerate: 30, 'images': [loaderSvc.getResult(obj.characterAssetName)], 'frames': {'regX': 82, 'height': 292, 'count': 64, 'regY': 0, 'width': 165}, // define two animations, run (loops, 1.5x speed) and jump (returns to run): 'animations': { 'run': [0, 25, 'run', 1.5], 'jump': [26, 63, 'run'] } }); this.grant = new createjs.Sprite(spriteSheet, 'run'); this.grant.y = obj.y; } Character.prototype = { addToStage: function (stage) { stage.addChild(this.grant); }, removeFromStage: function (stage) { stage.removeChild(this.grant); }, getWidth: function () { return this.grant.getBounds().width * this.grant.scaleX; }, getX: function () { return this.grant.x; }, setX: function (val) { this.grant.x = val; }, playAnimation: function (animation) { this.grant.gotoAndPlay(animation); } }; return (Character); }]);
  • app / view1 / ground.js
index.html
  • app / view1 / uiClasses / character.js
myDirectives.directive('spriteSheetRunner', ['loaderSvc','Sky', 'Ground', 'Hill', 'Character', function (loaderSvc, Sky, Ground, Hill, Character) { 'use strict'; return { restrict : 'EAC', replace : true, scope :{ }, template: '', link: function (scope, element, attribute) { var w, h, sky, grant, ground, hill, hill2; drawGame(); function drawGame() { //drawing the game canvas from scratch here if (scope.stage) { scope.stage.autoClear = true; scope.stage.removeAllChildren(); scope.stage.update(); } else { scope.stage = new createjs.Stage(element[0]); } w = scope.stage.canvas.width; h = scope.stage.canvas.height; loaderSvc.getLoader().addEventListener('complete', handleComplete); loaderSvc.loadAssets(); } function handleComplete() { sky = new Sky({width:w, height:h}); sky.addToStage(scope.stage); ground = new Ground({width:w, height:h}); hill = new Hill({width:w, height:h, scaleFactor: 4, assetName: 'hill', groundHeight: ground.getHeight()}); hill.setAlpha(0.5); hill.addToStage(scope.stage); hill2 = new Hill({width:w, height:h, scaleFactor: 3, assetName: 'hill2', groundHeight: ground.getHeight()}); hill2.addToStage(scope.stage); ground.addToStage(scope.stage); grant = new Character({characterAssetName: 'grant', y: 34}) grant.addToStage(scope.stage); scope.stage.addEventListener('stagemousedown', handleJumpStart); createjs.Ticker.timingMode = createjs.Ticker.RAF; createjs.Ticker.addEventListener('tick', tick); } function handleJumpStart() { grant.playAnimation('jump'); } function tick(event) { var deltaS = event.delta / 1000; var position = grant.getX() + 150 * deltaS; grant.setX((position >= w + grant.getWidth()) ? -grant.getWidth() : position); ground.setX((ground.getX() - deltaS * 150) % ground.getTileWidth()); hill.move(deltaS * -30, 0); if (hill.getX() + hill.getImageWidth() * hill.getScaleX() <= 0) { hill.setX(w); } hill2.move(deltaS * -45, 0); if (hill2.getX() + hill2.getImageWidth() * hill2.getScaleX() <= 0) { hill2.setX(w); } scope.stage.update(event); } } } }]);

Μην ξεχάσετε να προσθέσετε όλα αυτά τα νέα αρχεία JS στο uiClasses.

Τώρα, πρέπει να ενημερώσουμε την οδηγία για τα παιχνίδια.

keyDown

Σημειώστε ότι η μετακίνηση handleComplete() από την οδηγία μείωσε το μέγεθος της οδηγίας κατά 20%, από 91 σε 65 γραμμές.

Επιπλέον, μπορούμε να γράψουμε ανεξάρτητα δοκιμές για κάθε κατηγορία εργοστασίων για να απλοποιήσουμε τη συντήρησή του.

πώς να ερμηνεύσετε τα αποτελέσματα της προσομοίωσης Monte Carlo

Σημείωση: Η δοκιμή είναι ένα θέμα που δεν καλύπτεται σε αυτήν την ανάρτηση αλλά εδώ είναι ένα καλό μέρος για να ξεκινήσετε.

Αλληλεπίδραση με τα βέλη

Σε αυτό το σημείο στο σεμινάριο παιχνιδιών HTML5 Canvas, το κλικ ή το πάτημα του ποντικιού σε ένα κινητό θα κάνει τον άντρα μας να πηδήξει και δεν μπορούμε να τον σταματήσουμε. Ας προσθέσουμε τα πλήκτρα βέλους:

  • Αριστερό βέλος (παύση του παιχνιδιού)
  • Πάνω βέλος (άλμα)
  • Δεξί βέλος (έναρξη λειτουργίας)

Για να το κάνετε αυτό, δημιουργήστε το function keydown(event) { if (event.keyCode === 38) {//if keyCode is 'Up' handleJumpStart(); } if (event.keyCode === 39) {//if keyCode is 'Right' if (scope.status === 'paused') { createjs.Ticker.addEventListener('tick', tick); scope.status = 'running'; } } if (event.keyCode === 37) {//if keyCode is 'Left' createjs.Ticker.removeEventListener('tick', tick); scope.status = 'paused'; } } window.onkeydown = keydown; λειτουργία και προσθέστε ένα πρόγραμμα ακρόασης ως τελευταία γραμμή loadQueue λειτουργία.

PreloaderJS

Δοκιμάστε να εκτελέσετε ξανά το παιχνίδι σας και ελέγξτε τα στοιχεία ελέγχου πληκτρολογίου.

Αφησε τη μουσική να παίζει

Τα παιχνίδια δεν είναι διασκεδαστικά χωρίς μουσική, οπότε ας παίξουμε κάποια μουσική.

Πρώτα θα πρέπει να προσθέσουμε αρχεία MP3 στο φάκελο της εφαρμογής / στοιχείων. Μπορείτε να τα κατεβάσετε από τις διευθύνσεις URL που παρέχονται παρακάτω.

  • app / asset / jump.mp3
  • app / asset / runningTrack.mp3

Τώρα, πρέπει να προφορτώσουμε αυτά τα αρχεία ήχου χρησιμοποιώντας την υπηρεσία φόρτωσης. Θα χρησιμοποιήσουμε app/view1/services/loaderSvc.js από myServices.service('loaderSvc', function () { var manifest = [ {src: 'spritesheet_grant.png', id: 'grant'}, {src: 'sky.png', id: 'sky'}, {src: 'ground.png', id: 'ground'}, {src: 'hill1.png', id: 'hill'}, {src: 'hill2.png', id: 'hill2'}, {src: 'runningTrack.mp3', id: 'runningSound'}, {src: 'jump.mp3', id: 'jumpingSound'} ], loader = new createjs.LoadQueue(true); // need this so it doesn't default to Web Audio createjs.Sound.registerPlugins([createjs.HTMLAudioPlugin]); loader.installPlugin(createjs.Sound); this.getResult = function (asset) { return loader.getResult(asset); }; this.getLoader = function () { return loader; }; this.loadAssets = function () { loader.loadManifest(manifest, true, '/app/assets/'); }; }); βιβλιοθήκη. Ενημερώστε το myDirectives.directive('spriteSheetRunner', [ 'loaderSvc', 'Sky', 'Ground', 'Hill', 'Character', function (loaderSvc, Sky, Ground, Hill, Character) { 'use strict'; return { restrict : 'EAC', replace : true, scope :{ }, template: '', link: function (scope, element, attribute) { var w, h, sky, grant, ground, hill, hill2, runningSoundInstance, status; drawGame(); function drawGame() { //drawing the game canvas from scratch here if (scope.stage) { scope.stage.autoClear = true; scope.stage.removeAllChildren(); scope.stage.update(); } else { scope.stage = new createjs.Stage(element[0]); } w = scope.stage.canvas.width; h = scope.stage.canvas.height; loaderSvc.getLoader().addEventListener('complete', handleComplete); loaderSvc.loadAssets(); } function handleComplete() { sky = new Sky({width:w, height:h}); sky.addToStage(scope.stage); ground = new Ground({width:w, height:h}); hill = new Hill({width:w, height:h, scaleFactor: 4, assetName: 'hill', groundHeight: ground.getHeight()}); hill.setAlpha(0.5); hill.addToStage(scope.stage); hill2 = new Hill({width:w, height:h, scaleFactor: 3, assetName: 'hill2', groundHeight: ground.getHeight()}); hill2.addToStage(scope.stage); ground.addToStage(scope.stage); grant = new Character({characterAssetName: 'grant', y: 34}); grant.addToStage(scope.stage); scope.stage.addEventListener('stagemousedown', handleJumpStart); createjs.Ticker.timingMode = createjs.Ticker.RAF; createjs.Ticker.addEventListener('tick', tick); // start playing the running sound looping indefinitely runningSoundInstance = createjs.Sound.play('runningSound', {loop: -1}); scope.status = 'running'; window.onkeydown = keydown; } function keydown(event) { if (event.keyCode === 38) {//if keyCode is 'Up' handleJumpStart(); } if (event.keyCode === 39) {//if keyCode is 'Right' if (scope.status === 'paused') { createjs.Ticker.addEventListener('tick', tick); runningSoundInstance = createjs.Sound.play('runningSound', {loop: -1}); scope.status = 'running'; } } if (event.keyCode === 37) {//if keyCode is 'Left' createjs.Ticker.removeEventListener('tick', tick); createjs.Sound.stop(); scope.status = 'paused'; } } function handleJumpStart() { if (scope.status === 'running') { createjs.Sound.play('jumpingSound'); grant.playAnimation('jump'); } } function tick(event) { var deltaS = event.delta / 1000; var position = grant.getX() + 150 * deltaS; grant.setX((position >= w + grant.getWidth()) ? -grant.getWidth() : position); ground.setX((ground.getX() - deltaS * 150) % ground.getTileWidth()); hill.move(deltaS * -30, 0); if (hill.getX() + hill.getImageWidth() * hill.getScaleX() <= 0) { hill.setX(w); } hill2.move(deltaS * -45, 0); if (hill2.getX() + hill2.getImageWidth() * hill2.getScaleX() <= 0) { hill2.setX(w); } scope.stage.update(event); } } } }]); για να προφορτώσετε αυτά τα αρχεία.

index.html

Τροποποιήστε την οδηγία παιχνιδιού σας για να παίξετε ήχους σε εκδηλώσεις παιχνιδιών.

app/view1/view1.html Σχετίζεται με: Βέλτιστες πρακτικές και συμβουλές του AngularJS από τους ApeeScape Developers

Προσθήκη δεικτών βαθμολογίας και ζωής

Ας προσθέσουμε τους δείκτες σκορ και ζωής (καρδιά) στο παιχνίδι HTML5 Canvas. Το σκορ θα εμφανίζεται ως αριθμός στην επάνω αριστερή γωνία και τα σύμβολα καρδιάς, στην επάνω δεξιά γωνία, θα υποδεικνύουν τον αριθμό ζωής.

Θα χρησιμοποιήσουμε μια εξωτερική βιβλιοθήκη γραμματοσειρών για να αποδώσουμε καρδιές, οπότε προσθέστε την ακόλουθη γραμμή στο

Score: {{score}}

Life: 1' class='fa fa-heart'> 2' class='fa fa-heart'> .top-left { position: absolute; left: 30px; top: 10px; } .top-right { position: absolute; right: 100px; top: 10px; float: right; } αρχείο:

lifesCount

Για να τοποθετήσουμε σωστά τους δείκτες μας, πρέπει να προσθέσουμε τάξεις CSS για πάνω-αριστερά και πάνω-δεξιά στο app/view1/view1.js αρχείο.

'use strict'; angular.module('myApp.view1', ['ngRoute']) .config(['$routeProvider', function($routeProvider) { $routeProvider.when('/view1', { templateUrl: 'view1/view1.html', controller: 'View1Ctrl' }); }]) .controller('View1Ctrl', ['$scope', function($scope) { $scope.score = 0; $scope.lifesCount = 3; }]);

Αρχικοποιήστε το σκορ και ... replace : true, scope :{ score: '=score', lifesCount: '=lifesCount' }, template: ... μεταβλητές σε handleComplete() ελεγκτής.

scope.score = 10; scope.lifesCount = 2; scope.$apply();

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

app/view1/view1.js

Για να δοκιμάσετε τη δέσμευση πεδίου, προσθέστε αυτές τις τρεις γραμμές στο τέλος του $window μέθοδος.

'use strict'; angular.module('myApp.view1', ['ngRoute']) .config(['$routeProvider', function($routeProvider) { $routeProvider.when('/view1', { templateUrl: 'view1/view1.html', controller: 'View1Ctrl' }); }]) .controller('View1Ctrl', ['$scope', '$window', function($scope, $window) { $scope.windowWidth = $window.innerWidth; $scope.gameHeight = 400; $scope.score = 0; $scope.lifesCount = 3; }]);

Όταν εκτελείτε την εφαρμογή θα πρέπει να δείτε τους δείκτες βαθμολογίας και ζωής.

δείκτες βαθμολογίας και ζωής

Πρόσθετος λευκός χώρος, στα δεξιά της σελίδας, θα συνεχίσει να υπάρχει επειδή εξακολουθούμε να κωδικοποιούμε το πλάτος και το ύψος του παιχνιδιού σε αυτό το σημείο στο σεμινάριο προγραμματισμού παιχνιδιών HTML5.

Προσαρμογή του πλάτους του παιχνιδιού

Το AngularJS είναι γεμάτο με χρήσιμες μεθόδους και υπηρεσίες. Ένα από αυτά είναι $ window, το οποίο παρέχει μια ιδιότητα innerWidth που θα χρησιμοποιήσουμε για τον υπολογισμό της θέσης των στοιχείων μας.

Τροποποιήστε το ... scope :{ width: '=width', height: '=height', score: '=score', lifesCount: '=lifesCount' }, ... drawGame(); element[0].width = scope.width; element[0].height = scope.height; w = scope.width; h = scope.height; function drawGame() { ... για ένεση

|_+_|
υπηρεσία.

|_+_|

Επεκτείνετε την κύρια οδηγία παιχνιδιού με ιδιότητες πλάτους και ύψους και αυτό είναι!

|_+_|

Τώρα έχετε το παιχνίδι να προσαρμόζεται στο πλάτος του παραθύρου του προγράμματος περιήγησης.

Εάν θέλετε να το μεταφέρετε σε μια εφαρμογή για κινητά, προτείνω να διαβάσετε το άλλο εκπαιδευτικό πρόγραμμα για την εφαρμογή για κινητά χρησιμοποιώντας το Ionic framework για τη δημιουργία εφαρμογών για κινητά . Θα πρέπει να μπορείτε να δημιουργήσετε μια εφαρμογή ιονικού σπόρου, να αντιγράψετε όλο τον κώδικα από αυτό το έργο και να ξεκινήσετε να παίζετε το παιχνίδι στην κινητή συσκευή σας σε λιγότερο από μία ώρα.

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

Τύλιξε

Πιστεύω ότι κατά τη διάρκεια αυτού του σεμιναρίου ανάπτυξης παιχνιδιών το καταλάβατε Γωνιακό JS και το CreateJS είναι ένα νικηφόρο δίδυμο για ανάπτυξη παιχνιδιών με βάση το HTML5. Έχετε όλα τα βασικά και είμαι βέβαιος ότι αναγνωρίσατε τα οφέλη από το συνδυασμό αυτών των δύο πλατφορμών.

αναφέρετε τρεις από τις πιο κοινές επιθέσεις διαδικτυακών εφαρμογών

Μπορείτε να κατεβάσετε τον κωδικό για αυτό το άρθρο από GitHub , μη διστάσετε να χρησιμοποιήσετε, να μοιραστείτε και να το κάνετε δικό σας.

Σχετίζεται με: Κορυφαία 18 πιο κοινά λάθη AngularJS που κάνουν οι προγραμματιστές

Βελτιστοποίηση της απόδοσης του ιστότοπου και της κρίσιμης διαδρομής απόδοσης

Διεπαφή Ιστού

Βελτιστοποίηση της απόδοσης του ιστότοπου και της κρίσιμης διαδρομής απόδοσης
Ένα πρόγραμμα εκμάθησης ροής εργασίας για προγραμματιστές: Παρέχετε καλύτερα UI / UX εγκαίρως

Ένα πρόγραμμα εκμάθησης ροής εργασίας για προγραμματιστές: Παρέχετε καλύτερα UI / UX εγκαίρως

Τροποσ Ζωησ

Δημοφιλείς Αναρτήσεις
Scaling Scala: Τρόπος Dockerize χρησιμοποιώντας Kubernetes
Scaling Scala: Τρόπος Dockerize χρησιμοποιώντας Kubernetes
Μείωση του κόστους σε ένα ψηφιακό μέλλον πετρελαίου και φυσικού αερίου
Μείωση του κόστους σε ένα ψηφιακό μέλλον πετρελαίου και φυσικού αερίου
Το GWT Toolkit: Δημιουργήστε ισχυρές διεπαφές JavaScript χρησιμοποιώντας Java
Το GWT Toolkit: Δημιουργήστε ισχυρές διεπαφές JavaScript χρησιμοποιώντας Java
Επισκόπηση των δημοφιλών δημιουργών στατικών ιστότοπων
Επισκόπηση των δημοφιλών δημιουργών στατικών ιστότοπων
Γνωρίστε το Volt, ένα πολλά υποσχόμενο Ruby Framework για δυναμικές εφαρμογές
Γνωρίστε το Volt, ένα πολλά υποσχόμενο Ruby Framework για δυναμικές εφαρμογές
 
Οι μεγάλες ερωτήσεις οδηγούν σε εξαιρετικό σχεδιασμό - Ένας οδηγός για τη διαδικασία σκέψης σχεδιασμού
Οι μεγάλες ερωτήσεις οδηγούν σε εξαιρετικό σχεδιασμό - Ένας οδηγός για τη διαδικασία σκέψης σχεδιασμού
Η Ψυχολογία του Σχεδιασμού και η Νευροεπιστήμη του Amazing UX
Η Ψυχολογία του Σχεδιασμού και η Νευροεπιστήμη του Amazing UX
APIs στα κοινωνικά δίκτυα: Η διαδικτυακή πύλη στον πραγματικό κόσμο
APIs στα κοινωνικά δίκτυα: Η διαδικτυακή πύλη στον πραγματικό κόσμο
Οδηγός επένδυσης Family Office: Μια εναλλακτική λύση στο επιχειρηματικό κεφάλαιο
Οδηγός επένδυσης Family Office: Μια εναλλακτική λύση στο επιχειρηματικό κεφάλαιο
Αρχές Σχεδιασμού - Εισαγωγή στην Οπτική Ιεραρχία
Αρχές Σχεδιασμού - Εισαγωγή στην Οπτική Ιεραρχία
Δημοφιλείς Αναρτήσεις
  • οδήγηση για το uber vs lyft 2017
  • cross platform mobile ανάπτυξη xamarin
  • Η δοκιμή πρωτοτύπων εφαρμογών για κινητά μπορεί να γίνει χειροκίνητα ή τι;
  • ποια γλώσσα προγραμματισμού χρησιμοποιούν τα ρομπότ
  • διαφορά μεταξύ s corp και corp
  • Οι μέθοδοι προεξόφλησης ταμειακών ροών για τον προϋπολογισμό κεφαλαίου επικεντρώνονται σε
  • πλεονεκτήματα εταιρικής σχέσης έναντι εταιρικού φόρου
Κατηγορίες
  • Επενδυτές & Χρηματοδότηση
  • Σχεδιασμός Διεπαφής Χρήστη
  • Τεχνολογία
  • Διαχείριση Έργου
  • © 2022 | Ολα Τα Δικαιώματα Διατηρούνται

    portaldacalheta.pt