okaybenji Posted February 25, 2017 Share Posted February 25, 2017 (edited) Hi, there! Hope this is the right place to seek Phaser help. If not, I'm happy to move my post. I have three issues I'm trying to troubleshoot: First, the camera LERP system centers my player when I'm walking left or upward, but when I'm walking right or downward, it allows the player to get and stay close to the right/bottom edges of the screen. Second, I can't seem to get my character to collide with the layer I created in Tiled specifically for collisions. The character just walks right over the boundaries as though they are not there. Third, when I load up my game for the first time, the player character (and also any other entities which have sprite-based animations) shows up as his entire spritesheet rather than just one (animated) frame. After refreshing the browser, the character and other entities look normal and their animations work correctly. I would guess it has something to do with loading order/caching of assets? Has anyone seen this issue before? I haven't included the player here, but it's basically just a sprite which gets some custom properties and methods attached to it and then is returned. I'm happy to include more code if it's helpful! Thanks for taking a look! // Play state. const Play = (game) => { let player; let boundary; const factories = { entities: { player: require('../factories/entities/player'), }, keys: require('../factories/keys') }; const play = { create() { const map = game.add.tilemap('dungeon'); map.addTilesetImage('dungeon', 'dungeon'); map.createLayer('Base'); boundary = map.createLayer('Bounds'); map.createLayer('Decorations'); map.createLayer('Foreground'); game.physics.startSystem(Phaser.Physics.ARCADE); map.setCollisionBetween(1, 100000, true, 'Bounds'); const bounds = {x: 0, y: 0, width: 512, height: 512}; player = factories.entities.player({ sprite: game.add.sprite(250, 250), keys: factories.keys(game), game }); game.physics.arcade.enable(player); // camera lerp game.world.setBounds(bounds.x, bounds.y, bounds.width, bounds.height); game.camera.follow(player, Phaser.Camera.FOLLOW_LOCKON, 0.02, 0.02); }, update() { game.physics.arcade.collide(player, boundary); } }; return play; }; module.exports = Play; Edited February 25, 2017 by okaybenji remove potentially distracting code Link to comment Share on other sites More sharing options...
ldd Posted February 26, 2017 Share Posted February 26, 2017 1) I never really completely understood the camera, but play around with the values that you are passing to it. Worst case, take a look at the code ;D 2) you should use: map.setCollisionByExclusion([], true, boundary); 3) It is possible that the assets haven't finished loading, and you are starting the game too soon. At any rate, you should have a menu screen (or at least a button that starts the game.) All games do this, to some extend or another, so you are just playing it safe. If you are using webpack2, you can use a flag to autostart the game inside a setTimeout if(__DEV__){ setTimeout( () => {this.state.start('Play');}, 0); } so that it doesn't feel slow while developing the game. Link to comment Share on other sites More sharing options...
okaybenji Posted February 26, 2017 Author Share Posted February 26, 2017 Thanks so much for taking the time to respond! 1) As obvious as it seems in hindsight, 'take a look at the code' is actually great advice. I will do that. 2) Ah yes, I see setCollisionByExclusion makes a lot more sense, thanks! However, I'm still getting the same result... Can you tell whether I am doing something else wrong?Here's what my code looks like currently: const Play = (game) => { let player; let boundary; const factories = { entities: { player: require('../factories/entities/player'), }, keys: require('../factories/keys') }; const play = { create() { const map = game.add.tilemap('dungeon'); map.addTilesetImage('dungeon', 'dungeon'); map.createLayer('Base'); boundary = map.createLayer('Bounds'); map.createLayer('Decorations'); map.createLayer('Foreground'); game.physics.startSystem(Phaser.Physics.ARCADE); map.setCollisionByExclusion([], true, boundary); const bounds = {x: 0, y: 0, width: 512, height: 512}; player = factories.entities.player({ sprite: game.add.sprite(250, 250), keys: factories.keys(game), gamepad: game.input.gamepad.pad1, game }); game.physics.arcade.enable(player); }, update() { // collide entities game.physics.arcade.collide(player, boundary, () => { console.log('colliding!'); // <- Never gets logged. }); } }; return play; }; module.exports = Play; 3) I actually do have a title screen, though I've tracked the problem to my trying to be clever and calculate the width and height of my animation frames. My filenames include the name of the animation and the number of frames in it, and I create a temporary image to get its width and height in pixels. But on the first load, the width and height come through as 0 for some reason. I wonder if there's any way to make this work without causing the issue... Here's the code if you care to take a look. const spritesheets = [ // TODO: access the filesystem to build this array automatically 'player/walk_e-2.png', 'player/walk_n-2.png', 'player/walk_s-2.png', 'player/walk_w-2.png', ].map((asset, i) => { const slash = asset.indexOf('/'); const underscore = asset.indexOf('_'); const dash = asset.indexOf('-'); const dot = asset.indexOf('.'); const entity = asset.slice(0, slash); const name = entity + '_' + asset.slice(slash + 1, dash); const frameCount = Number(asset.slice(dash + 1, dot)); const path = '../../assets/images/' + asset; const image = (function() { const image = new Image(); image.src = path; return image; }()); return { entity, name, frameCount, image }; }); spritesheets.forEach(({ name, image, frameCount }) => { const path = image.src; const width = image.width / frameCount; const height = image.height; game.load.spritesheet(name, path, width, height); }); Link to comment Share on other sites More sharing options...
samme Posted February 26, 2017 Share Posted February 26, 2017 19 hours ago, okaybenji said: when I'm walking right or downward, it allows the player to get and stay close to the right/bottom edges of the screen. That actually sounds like the camera has reached the right or bottom boundary. Link to comment Share on other sites More sharing options...
Recommended Posts