satanas Posted February 15, 2015 Share Posted February 15, 2015 Hello everyone, I'm working in a sokoban-like game and in this kind of game you need to reduce the player mobility to single tiles. I implemented this restriction using tween to change the x and y coordinates of the sprite along the time. When I did this I realized that the player didn't collide with the tiles, so I read the forum and someone said that the arcade physics engine doesn't detect collisions unless the velocity of the player is distinct than 0. I tried moving the sprite through velocity then but for some weird reason I still can not make the arcade engine detects collisions between the tiles and the hero. What could I be doing wrong? Did I miss something else? Here you can see the play.js code:var playState = { create: function() { this.map = null; this.player = null; this.map = game.add.tilemap(game.global.level.toString()); this.map.addTilesetImage('walls', 'walls'); this.map.addTilesetImage('grounds', 'grounds'); groups.walls = this.map.createLayer('Walls'); this.map.createLayer('Grounds'); this.map.setCollisionBetween(1, 18, true, 'Walls'); var e = this.map.objects['Hero'][0]; var y = e.y - this.map.tileHeight; var color = e.properties.color; this.player = new Hero(e.x, y); groups.walls.debug = true;}; And here is the player's code:var Hero = function(x, y, color) { Phaser.Sprite.call(this, game, x, y, 'hero', 0); game.physics.arcade.enable(this); this.body.allowGravity = false; this.cursors = game.input.keyboard.createCursorKeys(); this.animations.add('down-' + capsuleType.RED, [0, 1, 2], 12, true); this.animations.add('left-' + capsuleType.RED, [3, 4, 5], 12, true); this.animations.add('right-' + capsuleType.RED, [6, 7, 8], 12, true); this.animations.add('up-' + capsuleType.RED, [9, 10, 11], 12, true); this.color = 'red'; this.walking = false; this.nextX = null; this.nextY = null; game.add.existing(this);};Hero.prototype = Object.create(Phaser.Sprite.prototype);Hero.prototype.constructor = Hero;Hero.prototype.update = function() { game.physics.arcade.collide(this, groups.walls); this.body.velocity.x = 0; if (!this.walking) { var xDir = (this.cursors.left.isDown ? -1 : (this.cursors.right.isDown ? 1: 0)); var yDir = (this.cursors.up.isDown ? -1 : (this.cursors.down.isDown ? 1: 0)); if (yDir !== 0) { this.move(null, yDir); } else if (xDir !== 0) { this.move(xDir, null); } }};Hero.prototype.move = function(xDir, yDir) { var newX, newY, frame, direction; if (yDir) { direction = (yDir > 0) ? 'down' : 'up'; frame = (yDir > 0) ? 0 : 9; newX = this.x; newY = this.y + Math.floor(tileSize * yDir) } else if (xDir) { direction = (xDir > 0) ? 'right' : 'left'; frame = (xDir > 0) ? 6 : 3; newX = this.x + Math.floor(tileSize * xDir); newY = this.y; }};Thanks in advance for your help Link to comment Share on other sites More sharing options...
Triplanetary Posted February 15, 2015 Share Posted February 15, 2015 Instead of using physics collisions, you could check whether the tile the player is about to move into is a wall, and not execute the movie if it is. In your Hero.move function, you could take the newX,newY coordinate and use getTiles to check it - if the length of the array returned by getTiles is greater than 0, there's a wall there and the Hero shouldn't be moved. Hope this helps. Link to comment Share on other sites More sharing options...
satanas Posted February 16, 2015 Author Share Posted February 16, 2015 Hey Triplanetary, I've tried what you say, I pass the (newX, newY) coordinate to groups.walls.getTiles() method but it always returns an array with four elements no matter where I move. I've tried with hasTile too but it doesn't work, it doesn't find information for that coordinate and throws a:Uncaught TypeError: Cannot read property 'index' of undefinedI'm thinking in create a walkable table when I load the map and compare against it because any method from Phaser seems to work Link to comment Share on other sites More sharing options...
satanas Posted February 17, 2015 Author Share Posted February 17, 2015 Just for the record: the hasTile() method works properly. The problem was that I passed float numbers as coordinate params (while the player moved from one tile to another) and that was breaking the method. I used Math.floor before and now everything works like a charm Link to comment Share on other sites More sharing options...
Recommended Posts