stvrbbns

Members
  • Content Count

    16
  • Joined

  • Last visited

About stvrbbns

  • Rank
    Member

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. I have some moderately complex text-centric interface to build in addition to a rendered+physics portion. I need to use Phaser for the latter, but would like to use overlaid DOM elements for the former, especially since it sounds like updates from the reactive data sources would be easier. Am I risking not being able to build the app for mobile using CocoonJS if I use both Phaser and the DOM instead of rendering everything onto the canvas?
  2. Looks interesting. If you're looking for some design inspiration, consider comparing your creation to Ikariam and Global Triumph. Some questions to consider: Does any game feature (e.g. research) ever get finished? (i.e. is there a finite number of colonies one can have or a finite number of technologies to research) Can a game / map / server ever be finished / won? (and, if so, what forewarning is there for new players that a match/map is about to end) What prevents a single player or alliance from dominating an entire game/server? (there doesn't have to be anything, but if a player or group becomes too dominating then it can lead to boredom and burnout as the playerbase becomes bifurcated into those who never win and those who never lose - if there is no mechanism to maintain hope for the losers and risk for the winners) Good luck with your game (and with filtering spam bots out of the forum).
  3. Happily, you're welcome. I don't know without seeing all of your code, but the main problem I found out I was having (and is resolved in my example) is the necessary order of function calls: map.createLayer() layer.resizeWorld() game.physics.p2.setBoundsToWorld() game.physics.p2.createCollisionGroup()
  4. Is there a way to suggest new examples? I've created collision groups using P2 physics such that the Tilemap and the player's ship collide, the player's ship and the panda collide, and the Tilemap and the panda do not collide. However, I had trouble getting either the player's ship or the panda to collide with the world boundary. My understanding was that: Since I called "layer.resizeWorld()", I must call "game.physics.p2.setBoundsToWorld(true, true, true, true, ???)" to reset the P2 physics' world bounds. [reason: example lines 48-54] Since I called "this.physics.p2.createCollisionGroup()", I must call "game.physics.p2.setBoundsToWorld(true, true, true, true, true)" to reset the P2 physics' world bounds *with/as a collision group*, -or- call "game.physics.p2.updateBoundsCollisionGroup()" to update the world bounds to be their own collision group, so that other collision groups can collide with the world bounds. [reason: example lines 30-32]. Setting the 5th parameter to setBoundsToWorld() to "true", for "If true the Bounds will be set to use its own Collision Group." (source in documentation) makes calling "updateBoundsCollisionGroup()" extraneous. It seemed like I should be able to call "ship.body.collideWorldBounds = true" somewhere and have it work (or maybe not? ...), but it didn't, and leaving it out entirely didn't work either. Finally I found [this comment] which clarified the order which functions had to be called in. I now have the below example working with: tilemap and ship collide tilemap and panda do not collide world boundary and ship do not collide world boundary and panda collide ship and panda collide CODE: var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update, render: render }); function preload() { game.load.tilemap('map', 'assets/tilemaps/maps/collision_test.json', null, Phaser.Tilemap.TILED_JSON); game.load.image('ground_1x1', 'assets/tilemaps/tiles/ground_1x1.png'); game.load.image('walls_1x2', 'assets/tilemaps/tiles/walls_1x2.png'); game.load.image('tiles2', 'assets/tilemaps/tiles/tiles2.png'); game.load.image('ship', 'assets/sprites/thrust_ship2.png'); game.load.image('panda', 'assets/sprites/spinObj_01.png'); } var ship; var map; var layer; var cursors; var panda; var tilesCollisionGroup; var shipCollisionGroup; var pandaCollisionGroup; function create() { game.stage.backgroundColor = '#2d2d2d'; game.physics.startSystem(Phaser.Physics.P2JS); map = game.add.tilemap('map'); map.addTilesetImage('ground_1x1'); map.addTilesetImage('walls_1x2'); map.addTilesetImage('tiles2'); layer = map.createLayer('Tile Layer 1'); layer.resizeWorld(); // Set the tiles for collision. // Do this BEFORE generating the p2 bodies below. map.setCollisionBetween(1, 12); // Convert the tilemap layer into bodies. Only tiles that collide (see above) are created. // This call returns an array of body objects which you can perform addition actions on if // required. There is also a parameter to control optimising the map build. game.physics.p2.convertTilemap(map, layer); // By default the ship will collide with the World bounds, // however because you have changed the size of the world (via layer.resizeWorld) to match the tilemap // you need to rebuild the physics world boundary as well. The following // line does that. The first 4 parameters control if you need a boundary on the left, right, top and bottom of your world. // The final parameter controls if the boundary should use its own collision group or not. In this case we do require // that because custom collision groups have been set up for the ship and panda. game.physics.p2.setBoundsToWorld(true, true, true, true, true); // collision groups must be created after world boundaries have been finalized/fixed for the groups to collide with the boundaries tilesCollisionGroup = this.physics.p2.createCollisionGroup(); shipCollisionGroup = this.physics.p2.createCollisionGroup(); pandaCollisionGroup = this.physics.p2.createCollisionGroup(); for (var bodyIndex = 0; bodyIndex < map.layer.bodies.length; bodyIndex++) { var tileBody = map.layer.bodies[bodyIndex]; tileBody.setCollisionGroup(tilesCollisionGroup); tileBody.collides([shipCollisionGroup]); } ship = game.add.sprite(400, 200, 'ship'); game.physics.p2.enable(ship); ship.body.setCollisionGroup(shipCollisionGroup); ship.body.collides([tilesCollisionGroup, pandaCollisionGroup]); // Even after the world boundary is set-up you can still toggle if the ship collides or not with this: ship.body.collideWorldBounds = false; panda = game.add.sprite(200, 200, 'panda'); game.physics.p2.enable(panda); panda.body.setRectangle(40, 40); panda.body.setCollisionGroup(pandaCollisionGroup); panda.body.collides([pandaCollisionGroup, shipCollisionGroup]); game.camera.follow(ship); cursors = game.input.keyboard.createCursorKeys(); } function update() { if (cursors.left.isDown) { ship.body.rotateLeft(100); } else if (cursors.right.isDown) { ship.body.rotateRight(100); } else { ship.body.setZeroRotation(); } if (cursors.up.isDown) { ship.body.thrust(400); } else if (cursors.down.isDown) { ship.body.reverse(400); } } function render() { } Lesson: These functions MUST be called in order: map.createLayer() layer.resizeWorld() game.physics.p2.setBoundsToWorld() game.physics.p2.createCollisionGroup()
  5. rtileBody = map.layer.bodies;;s In your for-loop, you didn't actually use the increment. Also, you're never using explosionsCollisionGroup.
  6. What is the smart way to do top-down tile terrain borders in Phaser? You can't see hard-line tile edges if you look at basically any top-down game with tiles (Sid Meier's Colonization, Rimworld, Civilization 2, Heroes of Might & Magic); there are a few pixels between the tiles that get merged which makes the image as a whole look more or less seamless. Using Phaser, it looks to me like manipulating and rendering a large tile-based game map/board should probably make use of Tilemaps. However, the examples all look like the tilemap tiles do not overlap at all. I can see how you could make a complete set of intermediate/edge/border tiles if your tileset only had a couple types of terrain on a single tilemap. Assuming that you rotate tiles when needed then such a tileset requires you needing something like a straight edge, an inner corner, an outer corner, and a pocket (bordered on 1, 2, 3, or 4 sides) for every terrain combination. For 2 terrains, that is only 4 border tiles. For 3 terrains, that is 12 border tiles. For 4 terrains, that is 24 border tiles. ... For 16 terrains, that is 480 border tiles! This is clearly unsustainable. So what is the solution? Is it possible to use a negative margin and positive spacing in the Tileset? Do you use a second TilemapLayer with partially transparent border tiles (so you only need some border tiles per terrain instead of per terrain combination)? Do you manually load images instead of using the Tilemap objects/functionality?
  7. See http://phaser.io/examples/v2/tilemaps/csv-map-with-p2 Run "map.replace(57,25)" either in the console, or in the code box at the end of the create() function just after the help text. map.replace() is definitely not updating collision information *on it's own*. Running "map.removeTile(1,2); map.removeTile(1,3); map.removeTile(1,4);" or "map.putTile(25,1,2); map.putTile(25,1,3); map.putTile(25,1,4);" shows that map.removeTile() and map.putTile() also do not update collision information on their own. However, calling "game.physics.p2.convertTilemap(map, layer)" again after running map.removeTile() and map.putTile() does update P2 collision - although it still does not update P2 collision after map.replace(). What gives? === convertTilemap() only updates P2 physics based on the collision information about each individual Tile object. removeTile() and putTile() literally remove/replace Tile objects whereas map.replace() only updates Tile index values. === In order to mass-update physics as well as graphics utilizing map.replace(), we must update Tile collision information as well as index values. Running "map.setCollision(25, false);" after map.replace(), and then also calling "game.physics.p2.convertTilemap(map, layer)" again will properly update P2 physics collision.
  8. There is definitely no easy way using JSON.stringify() because of the Phaser objects' inherent circular structure (e.g. reference properties such as TileMap.game, or TileMapLayer.map).
  9. I am writing a 2D, top-down persistent game with land and multi-character ships, using Phaser. Players will be able to modify the game world. It looks to me like using Phaser TileMaps is probably the most sensible way to display the ships and the land - composing each out of tiles as opposed to groups of sprites. However, in any case, I must be able to persist/save tilemap information to a store/database (currently using MongoDB). How would you, the reader, solve this? The Phaser TileMap data could be exported to a format it natively imports, but that requires looping over every tile in every layer to get each tile's index. And either deciding what else to save if creating JSON, or being sure to not use features other than tiles if writing CSV (because the CSV won't contain information like rotation). ("export tilemap as json" thread) A separate "tilemap" (2D matrix of information) could be implemented which save and reload itself, and can return itself as a Phaser TileMap. ?? ... Is there an easy way to save and reload an entire Phaser.TileMap object using something like JSON.stringify() + _.extend()? (I'll try this next)
  10. I've gotten this far: tileMapLayer_to_CSV = function (layer) { var csv = ''; for (var y = 0; y < layer.data.length; y++) { if (y > 0) { csv += '\n'; } for (var x = 0; x < layer.data[y].length; x++) { if (x > 0) { csv += ','; } csv += layer.data[y][x].index; } } return csv; }; // end tileMapLayer_to_CSV()
  11. Is there a real answer to this question? What is the best way to save/export a Phaser.TileMap as JSON to be reloaded/reinstantiated later? As of 2.4.6 - Baerlon, the public methods do not appear to contain built-in functionality for this. Phaser's accepted tile map formats (Phaser.Tilemap.CSV or Phaser.Tilemap.TILED_JSON) aren't particularly well documented themselves. I assume that the latter is "the Tiled JSON format" (based on the TMX format), but I have not figured out what the CSV format actually is. Looking at the examples (e.g. catastrophi_level1.csv), "CSV" looks to be nothing more than a map of tile integer IDs - no objects, collision data, layers, etc. That pretty much necessitates any *useful* Phaser TileMap save/export to result in the TILED_JSON format.
  12. I am trying to make a menu screen with a centered title, some centered column headers, some right-aligned row labels, and some left-aligned row notes. relevant examples: Basics 06 Render Text Text Bounds relevant documentation: Phaser.Text This seems like it ought to be trivial, but none of my text alignment is working - it's all "left" all the time. I've tried declaring a non-left alignment (e.g. align:'center') on a style object before creating the text and I've tried assigning alignment to the text object immediately after creating it. Both of these methods appear to work trivially in the "Basics 06 Render Text" example. If I instead use anchor (e.g. .anchor.setTo(0.5,0.5) ), then that works. ----- My problem was that I hadn't understood the text.align vs. boundsAlign and had missed a crucial comment in the documentation about text.align: "Does not affect single lines of text.". text.align only aligns the text within the area that the text is actually rendered in. A single line of text is already taking up 100% of the width and height of the rendered text area, so it is already "aligned" in all possible ways (i.e. it can't be moved left, right, up, or down without changing which area it is being rendered in). boundsAlign aligns a rendering of text within a set of bounds - but these bounds must be set.
  13. My guess is that the correct call is "game.load" not "game.add" to make images available in the first place.
  14. 1) Is it strongly preferred to *not* go "back" to previous Phaser game States? For example, if dying on a level is supposed to send the player back to level selection, should the level selection and the levels themselves be coded into the same State, or is it fine to flip between game States? Thank you very much!