mattstyles

Moderators
  • Content count

    979
  • Joined

  • Last visited

  • Days Won

    9

mattstyles last won the day on January 29

mattstyles had the most liked content!

6 Followers

About mattstyles

  • Rank
    Advanced Member
  • Birthday

Contact Methods

  • Website URL
    github.com/mattstyles
  • Twitter
    @personalurban

Profile Information

  • Gender
    Not Telling
  • Location
    UK

Recent Profile Visitors

2,121 profile views
  1. I wouldn't worry about inefficiencies until they become a problem, doing a simple check isn't going to harm anything 60 times a second. Knowing when and what might become a problem further down the line takes a lot of experience and even then you might be surprised how far you get by taking the easier route, in any case, the easier route should result in working software faster and you can then iterate based on that working experience (rather than guessing). If you're worried about this particularly inefficiency then its probably because Phaser's update loop isn't suitable for your project (not for this bit anyway). I think I would approach it (using Phaser and its raf update loop) by using pub/sub (event emitter) that switches some variables and the update loop then acts based on those variables, kind of like a switch (infact it could very well be a switch), you might even decide you need a couple of states for this stuff, one for the AI turn, one for the user turn. The event emitter thing might work by: * enter AI game state * set an array of 5 integers all set to 0 (or null) * set a timeout for a random time between 1s and 3s * in the update * for each item in the array grab the corresponding sprite and set it to either the value of the array item, or to a blank face if null/0 * grab the first null/0 entry in the array, lets say its the first one, grab the sprite corresponding to that and update its animation frame * that update logic in the above bullet point keeps going until... * the timeout expires and an event is triggered, this updates the first null slot in our array to a random number between 1-6 * if all elements in the array are > 0 or non-null then we update the game state to the user state for the user turn (or show a button that the user press to initiate their turn, whatever) * if not then the we queue up another timeout and the update keeps on ticking This is attractive in a number of ways because we've separated our view layer from our logic layer i.e. the view layer is pretty dumb, it just queries the array and displays the correct graphics in their places, you could get fancier with what the array holds but simple integers would suffice to get going. As Phaser uses PIxi underneath for graphics we can take the approach that we're going to re-render the entire screen each tick and let the rendering engine (Pixi in this case) work out an efficient way of doing it (it does this with a scene graph and dirty checking, I'd be surprised if most other popular renders didn't work in a very similar fashion). This approach is easy for us as devs to understand and work with, "here's the data, view layer transforms data into pretty graphics, keep doing it", no intermediate state flicking around, just a persistent data set and some process to transform it into a visual representation, no worrying about syncing stuff up, just change the data and on the next loop round the view layer will transform it into the next visual state, pretty simple and simple is good.
  2. Add a line before 76 and log out both `this` and `this.bird`, I'd expect `this` to be an instance of FlappyBoard.Pipe and `this.bird` to be undefined. Now add a new line before line 29 that logs out `this`, I'd expect it to be an instance of FlappyBoard.GameState. I'm hoping that you're guessing where I'm going with this. Looks to me like you've created `bird` on the GameState and you're trying to reference from Pipe, hence explosion.
  3. Absolutely does. If you liked Game Dev Story have you checked out Game Dev Tycoon by Greenheart? It's a node-webkit game too so if anyone says you can't make a successful game using the DOM (or even relying heavily on jQuery!!) then show them that!
  4. It doesn't matter that they are different projects, when you use the constructor it will invoke a new instance of the extended class when you call super, for example, the following works on the pixi examples page: var app = new PIXI.Application(800, 600, {backgroundColor : 0x1099bb}); document.body.appendChild(app.view); // create a new Sprite from an image path //var bunny = PIXI.Sprite.fromImage('required/assets/basics/bunny.png') var tex = PIXI.Texture.fromImage('required/assets/basics/bunny.png') class GameSprite extends PIXI.Sprite { myMethod () { console.log('hello') } } var bunny = new GameSprite(tex) // center the sprite's anchor point bunny.anchor.set(0.5); // move the sprite to the center of the screen bunny.x = app.renderer.width / 2; bunny.y = app.renderer.height / 2; app.stage.addChild(bunny); // Listen for animate update app.ticker.add(function(delta) { // just for fun, let's rotate mr rabbit a little // delta is 1 if running at 100% performance // creates frame-independent tranformation bunny.rotation += 0.1 / delta; }); Whats the stack trace for the error? Does it definitely refer to the 'new GameSprite` line or to something else that game sprite maybe calls?
  5. There's a simple test if you're worried about access issues: import Sprite from '../../path/to/code' console.log(Sprite) But the error simply implies that you're trying to invoke the constructor rather than call new (which can be indicative of an issue using classes, but to each their own), if, for example, you're using: var gs = GameSprite() You'll get that error. There should be a line number on the error, what does your code look like for that line?
  6. This syntax is not es2015, try: class GameSprite extends Sprite { foo () { console.log('hello') } } Although the error message suggests the error is elsewhere, possibly when you try and use GameSprite. Whats the line number on the error? And the corresponding line in your code?
  7. Nope, phonegap/cordova is just a webview, using the exact same engine as the browser app on your phone does (actually, this is not strictly true, iphones still use a slightly older version, although their is a plugin to use wkwebview, don't look at the abomination which is the code that makes that work, hack hack hack! and some slightly older versions of Android also use an older version of Chrome—something like 37 off the top of my head, its old anyways—again, there is a plugin that will use a newer version, crosswalk does it too I believe). If the phone graphic is static then use an image tag for that too and do the whole lot in DOM. Canvas is good for moving around lots and lots of sprites really quickly, although you'd likely be surprised how far just regular old image elements can get you. Keep things as simple as possible, if its image buttons, use the DOM, if its a static image, use the DOM, if its input fields, use the DOM, if its a complex animating tilemap, maybe canvas would be best, if its complex drawing ops you need, use canvas, if its a 2000 element particle emitter you need, use the canvas.
  8. Tried it in Chrome on desktop and Safari on iPhone (latest OS), had a quick butchers through the network tab whilst connected up, all looked fine and dandy, took just over a second I think.
  9. Loading is super speedy for me, both desktop and mobile.
  10. If your game is menu driven then DOM (and its many many many libraries for manipulating it) makes perfect sense in a browser environment and saves you the headache of reimplementing many of its features for a canvas-only env. Use DOM for your UI and a canvas element for your game screen, Phaser would be fine but I'm not sure you'd need all of it, possibly if you want access to its state management functions, quite possibly if you want audio stuff, you'd probably not need its input helpers (but maybe you do, for keyboard shortcuts maybe). Keep your UI dumb, so your UI dispatches actions and you have something listening (basic pub/sub) then somewhere you set up a tick, this is also an action with (at least) 2 listeners, one to perform a render and one to perform logic updates each tick, if you're setup like this you might find you don't want Phaser to manage high-level game states for you (with its own tick and methods) and you might want to create your own. I've done a number of little POC's and demos (similar in requirements to you, a rendering layer and a menu-driven UI) using React for my UI and app state management and Pixi for rendering (I didn't need Phaser for those projects, I just needed a rendering layer, I preferred to write my own state management stuff and I was happy using Howler for audio and my own keyboard entry helper lib for shortcut stuff).
  11. Disney do make a lot of games, if its official it's have a whacking great Disney logo in front. Give us some examples. Many times things just look exactly like Disney (or other) characters, in the toy world this is even worse. I've no idea where the line is but you're ethically on very dodgy ground if you've created a Snow Flight character that looks almost identical to Snow White with the sole purpose of attempting to either deceive or harvest the goodwill or fame of the copied character/thing.
  12. a for loop is synchronous, meaning you've stacked up `level.highlightNum` amount of timeouts that will all fire in roughly 500ms, whereas I think you want them to fire after 500, 1000, 1500 etc ms. var counter = 10 function countdown () { console.log('counter:', counter) if (--counter) { setTimeout(countdown, 500) } } countdown() This way has a downside, that filthy dirty variable out there, yuck, we can solve that in a couple of ways: function countdown (count) { console.log('counter:', count) if (count) { setTimeout(function () { countdown(--count) }, 500) } } countdown(10) Or (with a little bit of es6 sugar) const countdown = (count, time) => () => { console.log(`count: ${count}`) if (!count) { return } setTimeout(countdown(--count, time), time) } const startCount = countdown(10, 500) startCount()
  13. Path finding can get expensive, particularly if you're running it really regularly, you might want to have a play with how regularly you recheck your chase path. If you have a clear LOS to the target you probably don't want to run pathing either, just move straight towards the target rather than calc a specific path.
  14. Yeah, deffo, see how you like the api style, docs and community, those things shouldn't change much (at least in the short-mid term).
  15. Any sort of data transformation and it can be very useful, which helps you keep minimal representations of objects and transform them on the fly when you need to, what you absolutely don't want is two slightly different versions of basically the same object because then you have to maintain synchronicity between those two objects, better to have one object and two transforms of that object that can be applied as and when needed (only scrapping this when/if it becomes too expensive, which is rare). return compose( mapValues(translatePrice(currencyCode)), pick(priceKeys) )(pricing) This is an example from my current project, the compose, pick and mapValues function are all from lodash/fp, what it does is create a composable function that can be passed an object and spits out an array of strings, the pricing object contains more data than I require in this case so I run it through a function that performs the transform I need, in this case I have called the composed function immediately but I have a whole bunch of generic functions (such as translating the currencyCode into a different string) that are then composed together which provides excellent reuse. Here is the translatePrice function: export const translatePrice = code => price => `${getCurrencySymbol(code)}${format(price)}` Very simple but due to the currying lets me tack on a code and then run the resultant function through a mapper to do the actual work. This pattern is highly scalable and results in the wonderful scenario where a huge chunk of your codebase are low level small utility functions that are easily testable and easily composable into more specific functions. Lodash actually has a function that works based on arity allowing you to use either: translatePrice(code, price) translatePrice(code)(price) Most other functional libraries will contain a similar function (i.e. ramda, monet, bacon etc etc).