Search the Community

Showing results for tags 'tilemap'.



More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • HTML5 Game Coding
    • News
    • Game Showcase
    • Coding and Game Design
  • Frameworks
    • Phaser
    • Pixi.js
    • Babylon.js
    • Panda.js
    • melonJS
    • Haxe JS
    • Kiwi.js
  • General
    • General Talk
  • Business
    • Collaborations (un-paid)
    • Jobs (Hiring and Freelance)
    • Services Offered

Found 294 results

  1. Phaser Plugin: NavMesh Generation

    Update 19 Sept: v0.0.9 Released: I've published the plugin and is available on NPM: https://www.npmjs.com/package/phaser-navmesh-generation The SRC can be viewed on the GitHub repo: https://github.com/amaccann/phaser-navmesh-generation Summary (apologies for the long post) I've been working on this for a few weeks now, and thought I'd share the Work in Progress so far: I'm still working on various edge cases, bugs and performance R&D, but it's in a state worth demoing IMO & thought I'd share the progress with the forum, see if there's any interest in that sort of thing. It's a relatively simple plugin to use, where you give it the ref. of a Phaser.Tilemaplayer, a couple of options & it generates a Navigation Mesh for use later by your Sprites & Game Objects. This plugin for now has a very simple set of options; all that's passed to it includes: The Phaser.Tilemap (required) The Phaser.TilemapLayer that's acting as your 'collision' layer (required) Any collision indices that determine the impassable tiles (required) Any debug options you want so you can see the calculations How much you want to offset your Sprites from the calculated path What I call a 'midpoint' threshold - more on that in a minute Demo Videos: (NB: the 'pause' between the drawing of new tiles & the NavMesh update was intentional, so it didn't get run until onMouseUp - it's not performance lag - the NavMeshs are generating / updating in about 15 - 20ms ) This demos basic movement; the test Sprite is a little hard to make out, sorry! I draw some extra impassable tiles to show the NavMesh re-calculating new triangles: https://youtu.be/7v4wIn7mrNY This shows how with narrow spaces, the NavMesh uses the 'midpoint' of the the polygon line segment, instead of trying to turn around corners https://youtu.be/AYUKLRmVzUQ Why do this? This all started with a larger project I'm working on: it's going to (hopefully!) involve large tilemaps, a large number of sprites and procedural generation. A messy combination. As a result, I've been looking into ways I could perform pathfinding around Tilemaps in Phaser, and the most popular choice seems to be the grid-based a*star plugins; while in the main it probably does the job for smaller tilemaps, I don't think they scale very well. One standard method of pathfinding used by other engines is something called Navigation (Nav) Meshes: basically, you calculate all the passable areas on your map and reduce it all to a small array of connected polygons, then figure out how to travel across those polygons. In my R&D, I did come across Mike Westhad's great Phaser NavMesh plugin that does this, but one limitation of it is that it expects the Developer to have manually drawn the NavMesh in the Tiled Editor. IMO, this didn't go far enough as it'd be great if a plugin could 'just' take any Phaser.TilemapLayer, inspect its passable areas and calculate a NavMesh on the fly. Assuming your game uses a larger, more complicated map, then in theory a NavMesh could be much more performance friendly than a giant A*Star grid. Because we're reducing all passable tiles into a smaller number of triangle space, there are fewer computations needed to get from point A to point B, as rather than (for instance) iterating across dozens, or even hundreds of grid tiles to find the shortest path, you're only iterating across a handful of polygons instead. Equally, if you do this at the load of your game level it should be a relatively small footprint of memory in your game. The Science Bit: How does this work? Well, the principle is actually quite 'simple' really. To give a rough breakdown of the process of calculation: Iterate across the tileLayer and merge all the impassable tiles into a series of unified polygons; this is done using what's known as 'Marching Squares Algorithm' - often used for finding the outlines of graphics objects. Recursively do this until we're confident we've found all possible impassable tile groups, and any groups within each other Extract all the corner points for these polygons, and perform 'Constrained Delaunay Triangulation' on these points. Basically, fill the area with connected triangles with these corner points. Loop over all these triangles, and find each others' neighbours. When we actually want to trace a path from A to B, find the triangle underneath the two points, then use A*Star to discover the shortest sequence of triangles to get to that destination. Use Funnel Algorithm to draw a path through those triangles, finding the corners around which to move. - This is where the 'midpoint threshold' comes into play, as some polygons might be too small to properly corner around: so instead we just take the midpoint of the funnel edge instead. Performance / Bugs: I'm still working on performance, and I'd like this to be as fast as humanely possible. IMO the biggest bottleneck is the Marching Squares phase, when it searches the map for impassable outlines. It's inherently a brute force iteration, so it could take a long time - depending on the map size One solution I'm investigating is using Web Workers to perform this calculation in another thread, but I'm not yet convinced this is the way to go here. One major bug I have ATM is while the corner offsetting works fine in most cases, if the edges of the polygons are parallel, it gives weird results: see an example here: https://youtu.be/nApp17njzkg
  2. Can a tile from a tilemap be moved?

    So I am trying to make a platformer game using Phaser. The game contains a lot of blocks (tiles) which are loaded from the tilemap. Now what I want is that these blocks can be moved dynamically during the game (for ex. if the player bangs their head against it). The thing is, I don't know how? My first question is, is this possible? Because I tried changing the position, it didn't work (but I successfully changed its alpha). Moreover, I tried using Physics P2, but it has a null sprite value, so all the changes done are done to the body and the sprite still remains there. I can use any physics system, I am open to all. All I need is a way to work this out.
  3. Hello! I'm not well versed in game development but I write a lot of JS for my classes and my job, so I'd like to think I have some semblance of knowing what I'm doing, but the issue I'm having with Phaser right now is completely beyond me. It's hard to accurately describe my problem in words, so I've left the entire project as an attachment for you to see for yourself. (Cursor keys to control.) Essentially, I'm trying to write a simple platformer using a tilemap larger than the screen. However, when the camera is set to follow an object, and that object crosses the center of the window in a given direction on either axis, the camera slides in that direction at high speed - it seems to depend on how far you've crossed the threshold - until it reaches the stage boundary. The most difficult part is that the object seems to move properly relative to the camera - meaning it moves across the stage itself at very high speeds, confusing the arcade physics system and causing clips and zips galore if you're in the wrong places (try jumping under the spawn platform, for instance - you'll zip to the left or right) The problem doesn't happen at all when the stage size is equal to the game window size, nor does it happen if the camera is not following an object. Here are some things I've tried to resolve the issue: Removing game window scaling code Rewriting of Tilemap import code & use of different maps and tilesets Refactoring/simplification of the Player object (as well as forgoing the use of a class and extending Phaser.Sprite) Applying "layer.fixedToCamera = false" and "layer.fixedToCamera = true" Restarting the project and rewriting all code (this happened on a prior test project as well) Rolling back to some prior versions of Phaser I'm not certain whether the issue is with my Tilemap setup, my use of the camera, the general jankiness of the arcade physics system, or maybe something else I haven't taken into account, but given half of my Google searches lead here, I'm sure someone's got some kind of answer for me. For convenience, here's the important bits of my code, in case anything looks off at first glance: (game.js, the main game code) 'use strict' /* global Phaser, Player */ var game = new Phaser.Game( 161, // width 145, // height Phaser.AUTO, // idek 'game', // game name { create: create, update: update, preload: preload, render: render } // functions ) game.antialias = false function preload () { game.load.tilemap('mapTest', 'assets/map/testmap.json', null, Phaser.Tilemap.TILED_JSON) game.load.image('tileGrass', 'assets/img/grass.png') game.load.image('bgClouds', 'assets/img/bg.png') game.load.spritesheet('spritePlayer', 'assets/img/player.png', 9, 9) } let bg, player, map, layer function create () { // display background bg = game.add.image(1, 1, 'bgClouds') bg.fixedToCamera = true // instantiate the map map = game.add.tilemap('mapTest') map.addTilesetImage('tileGrass', 'tileGrass') layer = map.createLayer('terrain') map.setCollisionBetween(1, 10, 'terrain') layer.resizeWorld() layer.debug = true // initialize physics and set gravity game.physics.startSystem(Phaser.Physics.ARCADE) game.physics.arcade.gravity.y = 257 // set up the player player = new Player(game, 33, 49) game.physics.arcade.enable(player) // set game scale game.scale.scaleMode = Phaser.ScaleManager.USER_SCALE game.scale.setUserScale(6, 6) game.renderer.renderSession.roundPixels = true Phaser.Canvas.setImageRenderingCrisp(game.canvas) // camera: follow the player game.camera.follow(player) } function update () { game.physics.arcade.collide(player, layer) } function render () { game.debug.body(player) game.debug.body(layer) game.debug.text(Math.round(player.body.position.x), 9, 17) } game.antialias = false (player.js, the Player object file) /* global Phaser */ class Player extends Phaser.Sprite { constructor (game, x, y) { // set up the player super(game, x, y, 'spritePlayer') // physics game.physics.enable(this, Phaser.Physics.ARCADE) this.velCap = {x: 64, y: 150} this.jumpVel = -100 this.acceleration = 500 // units per second // animations this.anims = { 'idle': this.animations.add('idle', [0, 1, 2, 3], 6, true), 'walk': this.animations.add('walk', [8, 9, 10, 11, 12, 13, 14, 15], 15, true), 'down': this.animations.add('down', [21, 22], 15, false), 'jump': this.animations.add('jump', [16, 17, 18, 19], 15, false), 'fall': this.animations.add('fall', [19], 20, true), 'land': this.animations.add('land', [20, 21, 22, 23], 10, false) } this.animations.play('idle') this._facing = true this.anchor.setTo(0.5, 1) this.body.setSize(6,8,1,0) this.body.tilePadding.x = 12 this.body.tilePadding.y = 12 // input this.keys = game.input.keyboard.createCursorKeys() // add the player to the stage game.stage.addChild(this) } // facing code set face (bool) { if (bool) { this.scale.x = 1 } else { this.scale.x = -1 } this._facing = bool } get face () { return this._facing } update () { let airborne = !(this.body.blocked.down || this.body.touching.down) let dt = game.time.physicsElapsed if(this.keys.right.isDown) { this._move(dt, true, airborne) } else if(this.keys.left.isDown) { this._move(dt, false, airborne) } else{ this._decelerate(airborne) } if(this.keys.up.isDown && !airborne) { this._jump() } else if(this.keys.down.isDown && !airborne) { this._crouch() } this._capMovement() } _move (dt, right, airborne) { if(this.face != right){ this.face = right if(!airborne){ this.body.velocity.x = -this.body.velocity.x } } else { this.body.velocity.x += Math.floor(this.acceleration * (right ? 1 : -1) * dt) if (airborne) { this.animations.play('fall') } else { this.animations.play('walk') } } } _jump () { this.body.velocity.y = this.jumpVel this.animations.play('jump') } _crouch() { // stop all movement and crouch the player this.body.velocity.x = 0 if(this.animations.currentAnim.name != 'down'){ this.animations.play('down') } } _decelerate(airborne) { this.body.velocity.x = this.body.velocity.x / 2 if(airborne){ this.animations.play('fall') } else { this.animations.play('idle') } } _capMovement () { if(this.body.velocity.y > this.velCap.y){ this.body.velocity.y = this.velCap.y } else if (this.body.velocity.y < -this.velCap.y) { this.body.velocity.y = -this.velCap.y } if(this.body.velocity.x > this.velCap.x){ this.body.velocity.x = this.velCap.x } else if (this.body.velocity.x < -this.velCap.x) { this.body.velocity.x = -this.velCap.x } } } Thanks in advance! phaser_wtf.zip
  4. Tilemap gets clipped

    Hello all, if i display a tilemap and then move the camera the tilemap gets clipped. When i first load the tilemap everything is rendered properly (red border is the canvas size) but then when i move the camera a bit it looks like this The tilemap is still in the canvas but it doesn't get fully rendered. Here is also a modified example from Phaser.io to demonstrate that problem: http://phaser.io/sandbox/sKmpqFwf just draw some tiles and then move the camera with the arrow keys Any help would be appreciated.
  5. Ladder

    510/5000 Good night people! I'm developing a game where the character needs to climb a ladder. The problem I am facing is when he needs to enter a tile that is down the ladder, as I try to illustrate in the image below. When hitting the tile the pesonagem stops to move because the tile needs to be solid so the character can walk on it, but when he is on the stairs he must pass over this tile. Could someone show an example of how I can do this? Since then, thank you very much.
  6. Hey guys, I'm having trouble swapping tiles in a Tilemap. In all the examples it seems like to get a tile object (to pass into map.putTile) it has be selected from an already instantiated tile that's part of the map. What I'd like to do is create a new tile from the map's tileset. Is this possible?
  7. I am trying to use this lib: https://github.com/pixijs/pixi-tilemap and it seems using shader rather than sprites to render tilemap? is it more efficiency? why? the memory usage is the same, right? thanks.
  8. Hi, I'm using a tileset for my maps. Not all tiles fill their whole square though, like the top and bottom blocks there, for example. The player character is a simple square guy. Here's my problem : for example in this part of one of the map, as long as there's one tiny bit of rock in a tile, Arcade will consider the whole tile should detect collisions. Meaning the player will effectively bounce back against thin air. To have more precise collisions, I'd like to have the character using Arcade physics as it's a simple square and I don't need anything fancy for its physics, and I'd like to use P2 to add detailed physics for collision with the "not entirely filled" map tiles. Is that even possible ? How would you go about doing it ? For now, I've made a json file with physics applied to the whole tileset (using PhysicsEditor) and imported it in the preload method of the Preload state like that : //Preload.js InteractiveResume.Preload.prototype = { preload: function() { //... //load Tiled map this.load.tilemap('grottoMap', 'assets/tilemaps/testGrotto.json', null, Phaser.Tilemap.TILED_JSON); //the terrain tileset and its physics this.load.image('mainTileset', 'assets/png/mainTileset.png'); this.game.load.physics("mainTileset-physics", "assets/json/mainTileset-physics.json"); } } I setup my game maps with an external method located in a "global namespace", the method looks like this : //gameFunctions.js var funcs = { mapSetup: function(map) { config.currentState.map = config.currentState.game.add.tilemap(map); //the first parameter is the tileset name as specified in Tiled, the second is the key to the asset config.currentState.map.addTilesetImage('mainTileset', 'mainTileset', 16, 16); //create layers config.currentState.firstBackgroundLayer = config.currentState.map.createLayer('firstBackgroundLayer'); config.currentState.secondBackgroundLayer = config.currentState.map.createLayer('secondBackgroundLayer'); config.currentState.blockedLayer = config.currentState.map.createLayer('blockedLayer'); //resizes the game world to match the layer dimensions config.currentState.firstBackgroundLayer.resizeWorld(); config.currentState.secondBackgroundLayer.resizeWorld(); config.currentState.blockedLayer.resizeWorld(); //collision on blockedLayer config.currentState.map.setCollisionBetween(1, 100000, true, 'blockedLayer'); config.currentState.game.physics.p2.convertTilemap(config.currentState.map, config.currentState.blockedLayer); } } (I had to define a global variable 'config.currentState' to access the 'this' keyword representing the current state outside of it, if anyone knows a better solution I'd be very thankful as its quite heavy to use) And then in my Grotto state : // Grotto.js InteractiveResume.Grotto.prototype = { create: function() { //Creating the map, player sprite and everything... //setup Arcade physics for the player character this.game.physics.arcade.enable(this.player); }, update: function() { //collisions this.game.physics.arcade.collide(this.player, this.blockedLayer); //... } } Could anyone point me to the correct direction here ? I must admit I'm totally lost
  9. I'm trying to make game resize appropriately to size of the window/screen. Everything's working out great, except for the tilemap. It seems like the rendering bounds are not updated. (typescript) onResize() { this.game.scale.refresh(); var newWidth = window.innerWidth / 3; var newHeight = window.innerHeight / 3; this.game.scale.setGameSize(newWidth, newHeight); this.game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL; //need to call this to apply new size? this.game.camera.setSize(newWidth, newHeight); for (var i = 0; i < this.tilemap.layer.length; i++) { this.tilemap.layer[i].width = newWidth; this.tilemap.layer[i].resizeFrame(this.tilemap, newWidth, newHeight); this.tilemap.layer[i].crop(new Phaser.Rectangle(0, 0, newWidth, newHeight), false); this.tilemap.layer[i].updateCrop(); } this.game.camera.follow(this.player.sprite, Phaser.Camera.FOLLOW_TOPDOWN, 0.8, 0.8); } As you can see I've tried everything, I would've expected resizeFrame or crop to do something, but unfortunately they don't. Do note that the rest of the game updates the size correctly, as the fish get rendered in the widened area just fine. Any ideas how to update the tilemap to the new size? Thanks!
  10. Need help scaling TilemapLayer

    I'm trying to scale a tilemap using TilemapLayer.setScale but it blurs tiles, is there any way to scale tilemap with full quality? Phaser's scaling: https://prnt.sc/fsgcfz Tiled zoom: https://prnt.sc/fsgcp3
  11. I'm trying to get my tilemap to scale and I'm basically following the example here: https://github.com/pixijs/pixi-tilemap/blob/master/demo/main.js#L17 However, what ends up happening is the tilemap itself will scale but the frames won't. I can't record a GIF because for some reason the screen randomly flashes white when running the PIXI app, but here are some screenshots which may be helpful:
  12. Making looped tilemap

    I am using a tilemap that is draggable and the world bounds are currently equal to the tilemap size. My goal to achieve is converting this simple tilemap to one that is looped by its eastern and western edges so if you scroll over the bounds to east or west you would see the map repeated with all the tiles and sprite objects on it. To describe it more technically I would like the user to feel that all tiles and objects showing up at any ((x % mapWidth), y) position. To fake this effect in case of tilemaps bigger than the screen, I suppose that I require at least two copies of the tilemap and all objects on it side by side. With that and the tricky repositioning of the camera over the two clones I could fake the seamless looping effect. But unfortunately I have no idea how to double the whole map content and make the other one show p when the bounds are crossed. Any hint on how to do that would be a great help.
  13. Collision with Tilemap not working

    H, I'm just beginning a Boulder Dash type of game to teach myself phaser...so far seems to be a fun and easy library but I've found myself unable to make the player sprite collide with the tilemap representing the level. Perhaps the answer is pretty obvious, but I can't manage to see it. I will share my code: /** * Super fun gamez */ // Main namespaces and definitions var Engine; var Game = Game || {}; Game.name = "_lepdash"; Game.version = "0.1"; Game.width = 800; Game.height = 600; /*User*/ Game.tileSize = 32; // Load assets state Game.loadState = { preload: function() { console.info(Game.name + " loading assets"); // Put your assets loader logic here... /*User*/ Engine.add.text(10, 10, "Loading...", { font: "20px Arial", fill: "#ffffff" }); //Engine.load.image('bg', 'img/bg0.png'); Engine.load.spritesheet("player", "img/player.png", Game.tileSize, Game.tileSize); Engine.load.spritesheet("terrain", "img/terrain.png", Game.tileSize, Game.tileSize); Engine.load.tilemap("map", "maps/map1.json", null, Phaser.Tilemap.TILED_JSON); }, create: function() { Engine.state.start("main"); } }; // Main menu state Game.mainState = { preload: function() { console.info(Game.name + " main menu"); }, create: function() { // Create your main menu logic here... /*User*/ // Draw main menu Engine.add.text(10, 10, Game.name, { font: "20px Arial", fill: "#ffffff" }); Engine.add.text(10, 50, "press space to start", { font: "12px Arial", fill: "#ffffff" }); // Set game parameters Game.level = 1; Game.score = 0; Game.lives = 3; // Wait for user input var key = Engine.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR); key.onDown.addOnce(function() { Engine.state.start("play"); }, this); } }; // Play loop state Game.playState = { cursors: null, //player: null, preload: function() { console.info(Game.name + " play loop"); }, // Create your play logic here /*User*/ create: function() { console.info("Game params", Game); Engine.physics.startSystem(Phaser.Physics.ARCADE); // build map Game.map = Engine.add.tilemap("map"); Game.map.addTilesetImage("tiles", "terrain"); //"tiles name in JSON", "tileset" defined in preload state Game.map.setCollision(1, "map" + Game.level); /*Game.map.setTileIndexCallback(2, function(a, b, c) { console.info("callback", this, a, b, c) }, this);*/ Game.layer = Game.map.createLayer("map" + Game.level); Game.layer.resizeWorld(); Game.layer.debug = true; // add player Game.player = this._createPlayer(); Game.player.animations.play("tap"); Engine.physics.enable(Game.player); //Game.player.body.setSize(10, 14, 2, 1); this.cursors = Engine.input.keyboard.createCursorKeys(); // add HUD Game.HUD = Engine.add.text(10, Game.height - 15, "", { font: "15px Arial", fill: "#ffffff" }); }, update: function() { Engine.physics.arcade.collide(Game.player, Game.layer); this._checkInput(); this._updateHUD(); }, render: function() { Engine.debug.body(Game.player); }, _updateHUD: function() { Game.HUD.text = "Map:" + Game.level + " Score: " + Game.score + " Lives: " + Game.lives; }, _checkInput: function() { Game.player.body.velocity.set(0); if (this.cursors.left.isDown) { Game.player.body.velocity.x = -100; Game.player.play("left"); } else if (this.cursors.right.isDown) { Game.player.body.velocity.x = +100; Game.player.play("right"); } else if (this.cursors.up.isDown) { Game.player.body.velocity.y = -100; Game.player.play("up"); } else if (this.cursors.down.isDown) { Game.player.body.velocity.y = 100; Game.player.play("down"); } else { Game.player.play("still"); } }, _createPlayer: function() { var player = Engine.add.sprite(Game.tileSize, Game.tileSize, "player"); player.animations.add("left", [ 7, 8, 9, 10, 11, 12, 13 ], 20, false); player.animations.add("right", [ 14, 15, 16, 17, 18, 19, 20 ], 20, false); player.animations.add("up", [ 7, 8, 9, 10, 11, 12, 13 ], 20, false); player.animations.add("down", [ 14, 15, 16, 17, 18, 19, 20 ], 20, false); player.animations.add("still", [ 0 ], 10, false); player.animations.add("blink", [ 0, 1, 2, 1 ], 10, false).onComplete.add(function() { player.animations.play("still"); }); player.animations.add("tap", [ 3, 4, 3, 4, 5, 6, 5, 4, 3, 4, 3, 4, 5, 6, 5, 4 ], 10, false).onComplete.add(function() { player.animations.play("still"); }); return player; } }; // Setting up main states Engine = new Phaser.Game({ //enableDebug: false, width: Game.width, height: Game.height, renderer: Phaser.AUTO, antialias: false, //transparent: true, parent: "game" }); //Engine = new Phaser.Game(Game.width, Game.height, Phaser.AUTO, "game"); Engine.state.add("load", Game.loadState); Engine.state.add("main", Game.mainState); Engine.state.add("play", Game.playState); // Let's roll window.onload = function() { console.info(Game.name + " init"); Engine.state.start("load"); }; Attached are the assets I'm using for this project. Thanks in advance map.tmx map1.json
  14. tilemap not displaying properly

    So I'm having an issue trying to get a tilemap working properly. I made my tilemap in Tiled. JSON: http://intheexpanse.com/rpg/levels/level4.json Image: http://intheexpanse.com/rpg/images//base_out_atlas.png Code: http://intheexpanse.com/rpg/js/main.js Any ideas what I'm doing wrong? I've used multiple tilemaps from different sources and they all have similar display errors. Thank you.
  15. TileMap doesn't show correctly

    Hi!, i use tiled for create a map, but when i try show the map in the game, this doesn't show correctly (the map in tiled) And the map in the game: The main file: class Main extends Phaser.State { create() { this.game.physics.startSystem(Phaser.Physics.ARCADE); this.game.add.sprite(0, 0, 'Sky'); this.map = this.game.add.tilemap('Tilemap'); this.map.addTilesetImage('Tiles', 'Tileset'); this.layer = this.map.createLayer('Platforms'); this.layer.resizeWorld(); this.wrap = true; this.cursors = this.game.input.keyboard.createCursorKeys(); } update() { if (this.cursors.left.isDown) { this.game.camera.x -= 8; } else if (this.cursors.right.isDown) { this.game.camera.x += 8; } if (this.cursors.up.isDown) { this.game.camera.y -= 8; } else if (this.cursors.down.isDown) { this.game.camera.y += 8; } } } export default Main; Any idea or solution?(sorry for my bad english)
  16. Tilemap collision

    Hello! I am working with Phaser and having some problem to collide sprite with tiles, the sprite can walk through everything. on create: map = game.add.tilemap('ninomap'); map.addTilesetImage('tilesheet', 'tilesheet'); ground = map.createLayer('background'); ground.resizeWorld(); wcollide = map.createLayer('walls'); map.setCollision(1624, true, wcollide); Where 1624 is the index of tile to collide. I've been looking the posts on this forums, but couldn't get it to work yet, so i'm asking for help to understand the collide system on Phaser and how can i get my sprite to collide with certain tile indexes or layers.
  17. Tilemap Copy/Pasted tiles not rendering

    I'm working on an endless runner than uses multiple tilemaps as segments in order to achieve a procedurally generated effect. I'm copying tile data from a buffered tilemap (not being rendered) and pasting that data to another tilemap (currently being rendered) but not all the tiles show up. I copy and paste the tiles in three separate batches. The first batch works fine. The second and third batch of tiles don't render at all, but the collision tiles still work. All the tiles are copied from the same tilemap. Attached is the relevant file. Runner.js
  18. CSV Tilemap Collisions not Working

    I am really struggling with collision on CSV tilemaps. I am creating the CSV string in the create function before doing the Phaser tilemap stuff. The map is rendering as expected along with the player sprite but collisions are not happening. The CSV map consists currently of 1s and 0s but I'll add more later. 0 should be impassable. Here is what I've got in the create function. this.game.cache.addTilemap('map', null, csvContent, Phaser.Tilemap.CSV); this.map = this.game.add.tilemap('map', 16, 16); this.map.addTilesetImage('dungeontile'); this.map.setCollision(0); //I don't think this is doing what I think it does. this.layer = this.map.createLayer(0); this.layer.resizeWorld(); In the update function, I have this: this.game.physics.arcade.collide(this.player, this.layer); I think that is the important code. I also have arcade physics enabled for the game and player. Sorry if I'm missing something. Any thoughts on why this isn't working?
  19. Use tilemap as spritesheet

    I am building a platformer game Mario Style, and I have a tiled tilemap. I know how to set collisions and place it in the game statically, but I don't understand if it is possible to reuse the same tilemap to, for example, move platforms up/down left/right or load the character spritesheet that is inside the tilemap and animate it. So, basically...do I need a separate spritesheet for dynamic sprites (for example bundled with texturepacker)? Or should I use the same tilemap but load it again as a spritesheet so I reuse the same PNG? Would that improve performance?
  20. Hi, I'm trying to build a top-down 2d game. You can find the code for it here: https://github.com/JimTheMan/Room-Walkers Here is a screenshot of the game using "this.scale.scaleMode = Phaser.ScaleManager.NO_SCALE ;" The game works, but there are a few issues I'm having: 1) The "viewport" always shows an area of 10 x 10 tiles. As the player moves the camera follows him and he appears to be moving around the map. However, the viewport is always 10 x x10. Is there a way to change this, for example, to where the viewport always showed an area of 20x20 tiles? 2) When I use "NO_SCALE" mode everything looks super tiny, but when I use any scale mode (such as SHOW_ALL) the text looks blurry and is completely unreadable... How can I have graphics that are large enough to see while still keeping nice, crisp fonts? thanks.
  21. Loading tilemap error

    Hi, in my platform game I want to load map from Tiled. Everything was working fine, with this example: function preload() { game.load.tilemap('level1', 'assets/level8.json', null, Phaser.Tilemap.TILED_JSON); game.load.image('tiles-1', 'assets/tiles-1.png'); } function create() { //MAP SETTINGS map = game.add.tilemap('level1'); map.addTilesetImage('tiles-1'); map.setCollisionByExclusion([ 13, 14, 15, 16, 46, 47, 48, 49, 50, 51 ]); layer = map.createLayer('Tile Layer 1'); layer.resizeWorld(); } It worked perfectly, but when I just edited tilesheet and used them in Tiled (identical tiles but grey instead brown), the game cannot load. The error from the console: Failed to load resource: the server responded with a status of 404 (Not Found) and Uncaught TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(CSSImageValue or HTMLImageElement or HTMLVideoElement or HTMLCanvasElement or ImageBitmap or OffscreenCanvas)' at c.Tileset.draw (phaser.min.js:27) at c.TilemapLayer.renderRegion (phaser.min.js:26) at c.TilemapLayer.renderFull (phaser.min.js:26) at c.TilemapLayer.render (phaser.min.js:26) at c.TilemapLayer._renderCanvas (phaser.min.js:26) at c.World.d.DisplayObjectContainer._renderCanvas (phaser.min.js:7) at c.Stage.d.DisplayObjectContainer._renderCanvas (phaser.min.js:7) at d.CanvasRenderer.renderDisplayObject (phaser.min.js:9) at d.CanvasRenderer.render (phaser.min.js:9) at c.Game.updateRender (phaser.min.js:11)
  22. Generate Dungeon CSV

    Hi everyone, I'm generating a random dungeon that I convert to CSV ( with Array.join ) but I can't find how to make it works with the Game.load.tilemap because the file doesn't need to be download as it's just a string in the program. How can I do to make my CSV string work with the pahser loader ? Thanks !
  23. map.setCollision doesn't work

    Hi. I want to make a collision between character and tiles so that character couldn't go through the tiles, but nothing works. <script> var game = new Phaser.Game(800, 600, Phaser.AUTO); var player; var cursor; var map; var layer; var GameState = { preload: function() { this.load.image('character', 'assets/character.png'); this.load.tilemap('map', 'assets/tile_csv.csv', null, Phaser.Tilemap.CVS); this.load.image('tiles', 'assets/tile.png'); }, create: function() { game.physics.startSystem(Phaser.Physics.ARCADE); game.stage.backgroundColor = "#0000ff"; map = game.add.tilemap('map', 32, 32); map.addTilesetImage('tiles'); layer1 = map.createLayer(0); layer1.resizeWorld(); map.setCollision(2); player = game.add.sprite(50, game.world.height - 110, 'block'); game.physics.arcade.enable(player); player.anchor.setTo(0.5); player.scale.setTo(0.4); player.body.collideWorldBounds = true; cursors = game.input.keyboard.createCursorKeys(); game.camera.follow(player); }, update: function() { game.physics.arcade.collide(player, layer1); player.body.velocity.x = 0; player.body.velocity.y = 0; if (cursors.left.isDown) { player.body.velocity.x = -1500; } else if (cursors.right.isDown) { player.body.velocity.x = 1500; } if (cursors.up.isDown) { player.body.velocity.y = -1500; } else if (cursors.down.isDown) { player.body.velocity.y = 1500; } } }; game.state.add('GameState', GameState); game.state.start('GameState'); </script>
  24. TilemapLayer to Sprites

    Hello, In my game, I created my tilemap with Tiled (like most of us). But my sprite were always in front of my scenery. and i have place some element like cars who were supposed to hide sprites (see example.png). The solution was to extract sprites from the layer containing these sprites and add them to sprite group, then sort this group using this.gamegroup.sort('y', Phaser.Group.SORT_ASCENDING); Here is the class that I made to achieve this goal. Note that I have to get the json file describing Tilemap. It's written in Typescript anf i use lodash, but it's easy to transpile it to plain javascript. import * as _ from 'lodash'; export class LayerToSprites { public placeMapSprite(layer: Phaser.TilemapLayer, map: Phaser.Tilemap, tilemapJson: any, group: Phaser.Group, game: Phaser.Game) { let layerJson = this.findLayerJson('sprites', tilemapJson), layerData: Array<any>, collectedSprites: collectedSpriteFromLayer; if (!layerJson) { return; // no data found } collectedSprites = this.collectSpriteFromLayer(layerJson.data, map); this.updateTextureAtlasCache(collectedSprites, game); this.addSpritesToGroup(collectedSprites, map, game, group); layer.renderable = false; } private addSpritesToGroup(collectedSprites: collectedSpriteFromLayer, map: Phaser.Tilemap, game: Phaser.Game, group: Phaser.Group) { _(collectedSprites.tileSprites).each(tileSprite => { let width = map.tileWidth, height = map.tileHeight, spriteInfo = tileSprite[0], row = Math.floor(spriteInfo.index / 100), column = spriteInfo.index % 100, x = Math.min(column * width, 100 * width), y = Math.min(row * height, 100 * height), tileset = _(map.tilesets).find(t => t.containsTileIndex(spriteInfo.id)); game.add.sprite(x, y, tileset.name, spriteInfo.id.toString(), group); }); } private updateTextureAtlasCache(collectedSprites: collectedSpriteFromLayer, game: Phaser.Game) { collectedSprites.tileSpriteFramesData.forEach((spriteFrameData, key) => { game.cache.addTextureAtlas(key, '', spriteFrameData.image, spriteFrameData, Phaser.Loader.TEXTURE_ATLAS_JSON_HASH); }); } private collectSpriteFromLayer(layerData: Array<any>, map: Phaser.Tilemap): collectedSpriteFromLayer { let processedTiles = new Map<number, boolean>(), tilewidth = map.tileWidth, tileheight = map.tileHeight, tileSprites = new Array<Array<tileInfo>>(), tileSpriteFramesData = new Map<string, tileAtlas>(); _(layerData) .each((id, index) => { let spriteInfo: tileInfo, currentSpriteInfo: tileInfo, tileset: Phaser.Tileset, collectedLayerSprite: collectedSprite; if (id == 0 || processedTiles.get(index)) { return; } spriteInfo = { index: index, id: id }; tileset = _(map.tilesets).find(t => t.containsTileIndex(spriteInfo.id)); currentSpriteInfo = spriteInfo; collectedLayerSprite = this.collectSprite(currentSpriteInfo, layerData, tileset, processedTiles); this.addSpriteToLayerAtlas(collectedLayerSprite, tileSpriteFramesData, tileSprites, tileset, map); }); return { tileSpriteFramesData: tileSpriteFramesData, tileSprites: tileSprites } } private findLayerJson(name: string, json: any) { return _(json.layers).find((l) => l.name == 'sprites'); } private rightTileIsSameGroup = (tileset: Phaser.Tileset, spriteInfo: tileInfo, layerData: any) => { return layerData[spriteInfo.index + 1] == spriteInfo.id + 1 } private bottomTileIsSameGroup = (tileset: Phaser.Tileset, spriteInfo: tileInfo, layerData: any) => { return layerData[spriteInfo.index + 100] == spriteInfo.id + tileset.columns } private collectSprite(spriteInfo: tileInfo, layerData: any, tileset: Phaser.Tileset, processedTiles: Map<number, boolean>): collectedSprite { let currentSpriteInfo = spriteInfo, currentLayerSprite = new Array<{ index: number, id: number }>(), continueReadingRight = true, continueReadingBottom = true, spritewidth = 0, spriteheight = 0; while (continueReadingRight) { spritewidth++; let bottomSpriteInfo: tileInfo = { index: currentSpriteInfo.index, id: layerData[currentSpriteInfo.index] }; continueReadingBottom = this.bottomTileIsSameGroup(tileset, bottomSpriteInfo, layerData); let currentspriteheight = 0 while (continueReadingBottom) { currentspriteheight++; currentLayerSprite.push(bottomSpriteInfo); processedTiles.set(bottomSpriteInfo.index, true); continueReadingBottom = this.bottomTileIsSameGroup(tileset, bottomSpriteInfo, layerData); bottomSpriteInfo = { index: bottomSpriteInfo.index + 100, id: layerData[bottomSpriteInfo.index + 100] } } if (currentspriteheight > spriteheight) { spriteheight = currentspriteheight } continueReadingRight = this.rightTileIsSameGroup(tileset, currentSpriteInfo, layerData); currentSpriteInfo = { index: currentSpriteInfo.index + 1, id: layerData[currentSpriteInfo.index + 1] }; } return { layerSprite: currentLayerSprite, spriteheight: spriteheight, spritewidth: spritewidth }; } private addSpriteToLayerAtlas(collectedLayerSprite: collectedSprite, tileSpriteFramesData: Map<string, tileAtlas>, tileSprites: Array<Array<tileInfo>>, tileset: Phaser.Tileset, map: Phaser.Tilemap) { let currentLayerSprite = collectedLayerSprite.layerSprite, tilewidth = map.tileWidth, tileheight = map.tileHeight; if (currentLayerSprite.length) { let tilesetRaw: any = tileset, currentgid = currentLayerSprite[0].id - tileset.firstgid, tilex = tilesetRaw.drawCoords[currentgid * 2], tiley = tilesetRaw.drawCoords[1 + (currentgid * 2)], spritewidthPixel = collectedLayerSprite.spritewidth * tilewidth, spriteHeightPixel = collectedLayerSprite.spriteheight * tileheight, spriteFrameAtlas: frameAtlas = { filename: currentLayerSprite[0].id.toString(), frame: { x: tilex, y: tiley, w: spritewidthPixel, h: spriteHeightPixel }, rotated: false, trimmed: false, spriteSourceSize: { x: tilex, y: tiley, w: spritewidthPixel, h: spriteHeightPixel }, sourceSize: { w: spritewidthPixel, h: spriteHeightPixel } } if (!tileSpriteFramesData.has(tileset.name)) { let newFrameAtlas = { frames: new Array<frameAtlas>(), image: tileset.image }; tileSpriteFramesData.set(tileset.name, newFrameAtlas); } tileSpriteFramesData .get(tileset.name) .frames.push(spriteFrameAtlas); tileSprites.push(currentLayerSprite); } } } interface tileInfo { index: number, id: number } interface frameAtlas { filename: string, frame: { x: number, y: number, w: number, h: number }, rotated: false, trimmed: false, spriteSourceSize: { x: number, y: number, w: number, h: number }, sourceSize: { w: number, h: number } } interface tileAtlas { frames: Array<frameAtlas>, image: any } interface collectedSprite { layerSprite: Array<tileInfo>, spritewidth: number, spriteheight: number } interface collectedSpriteFromLayer { tileSprites: Array<Array<tileInfo>>, tileSpriteFramesData: Map<string, tileAtlas> }