yesh0907 Posted January 14, 2015 Share Posted January 14, 2015 Hi, I am working on an RPG like game. I am using an ASCII Map drawn by an algorithm that I found online. So right now my objective is getting collision detection working with the player. However, when I try to add the text to a group it works, but when the player hits against any part of the map the hit detection does not work. So i am kind of stuck. Please help me! Thanks in advanceHere is my code:// font sizevar FONT = 22;//var Height and Width for the Map's COLS and ROWSvar HEIGHT = 550;var WIDTH = 800;//Key variable set upvar cursors;var spaceKey;//offset for map's positionvar MAP_OFFSET = 2.38;//Game's height and widthvar gameHeight = 600, gameWidth = 800;//text for the mapvar text;//Style of textvar style = { font: FONT + "px monospace", fill:"#fff"};// map dimensionsvar ROWS = HEIGHT/FONT;var COLS = WIDTH/FONT/0.61;// number of actors per level, including playervar ACTORS = 10;// the structure of the mapvar map;//group the map objectsvar mapGroup; // the ascii display, as a 2d array of charactersvar asciidisplay;// initialize phaser, call create() once donevar game = new Phaser.Game(gameWidth, gameHeight, Phaser.CANVAS, '', { preload: preload, create: create, update: update});var graphics;function preload() { /* Using a square instead for now don't like the charcter */ //game.load.spritesheet('dude', 'assets/dude.png', 32, 48); graphics = game.add.graphics(0,0); graphics.beginFill("0xFF700B", 1); graphics.lineStyle(2, 0x0000FF, 1); graphics.drawRect(20, game.height - 550, 25, 25); graphics.endFill();}function create() { //Start game physics game.physics.startSystem(Phaser.Physics.ARCADE); // initialize map initMap(maze(ROWS, COLS)); // initialize ascii display asciidisplay = []; for (var y=0; y<ROWS; y++) { var newRow = []; asciidisplay.push(newRow); for (var x=0;x<COLS;x++) newRow.push(initCell('', x, y + MAP_OFFSET)); } drawMap(); // the map group mapGroup = game.add.group(); mapGroup.add(text); console.log(mapGroup); game.physics.arcade.enable(mapGroup); player = game.add.sprite(0, 0); player.addChild(graphics); game.physics.arcade.enable(player); cursors = game.input.keyboard.createCursorKeys();}function update() { player.body.velocity.x = 0; player.body.velocity.y = 0; if (cursors.left.isDown) { player.body.velocity.x = -150; //player.animations.play('left'); } else if (cursors.right.isDown) { player.body.velocity.x = 150; //player.animations.play('right'); } else if (cursors.up.isDown) { //Move up the screen player.body.velocity.y = -150; } else if (cursors.down.isDown) { //Move down the screen player.body.velocity.y = 150; } game.physics.arcade.collide(player.body, mapGroup.child, stopPlayer);}function initCell(chr, x, y) { // add a single cell in a given position to the ascii display text = game.add.text(FONT*0.6*x, FONT*y, chr, style); return text;}//creating the mapfunction initMap(m) { // create a new random map map = []; for (var j= 0; j<m.x*2+1; j++) { var line= []; if (0 == j%2) for (var k=0; k<m.y*4+1; k++) if (0 == k%4) line[k]= '+'; else if (j>0 && m.verti[j/2-1][Math.floor(k/4)]) line[k]= ' '; else line[k]= '-'; else for (var k=0; k<m.y*4+1; k++) if (0 == k%4) if (k>0 && m.horiz[(j-1)/2][k/4-1]) line[k]= ' '; else line[k]= '|'; else line[k]= ' '; if (0 == j) line[1]= line[2]= line[3]= ' '; if (m.x*2-1 == j) line[4*m.y]= ' '; map.push(line.join('')+'\r\n'); } return map.join('');}function drawMap() { for (var y = 0; y < ROWS; y++) for (var x = 0; x < COLS; x++) asciidisplay[y][x].text = map[y][x];}function maze(x,y) { var n=x*y-1; if (n<0) {alert("illegal maze dimensions");return;} var horiz =[]; for (var j= 0; j<x+1; j++) horiz[j]= [], verti =[]; for (var j= 0; j<y+1; j++) verti[j]= [], here = [Math.floor(Math.random()*x), Math.floor(Math.random()*y)], path = [here], unvisited = []; for (var j = 0; j<x+2; j++) { unvisited[j] = []; for (var k= 0; k<y+1; k++) unvisited[j].push(j>0 && j<x+1 && k>0 && (j != here[0]+1 || k != here[1]+1)); } while (0<n) { var potential = [[here[0]+1, here[1]], [here[0],here[1]+1], [here[0]-1, here[1]], [here[0],here[1]-1]]; var neighbors = []; for (var j = 0; j < 4; j++) if (unvisited[potential[j][0]+1][potential[j][1]+1]) neighbors.push(potential[j]); if (neighbors.length) { n = n-1; next= neighbors[Math.floor(Math.random()*neighbors.length)]; unvisited[next[0]+1][next[1]+1]= false; if (next[0] == here[0]) horiz[next[0]][(next[1]+here[1]-1)/2]= true; else verti[(next[0]+here[0]-1)/2][next[1]]= true; path.push(here = next); } else here = path.pop(); } return {x: x, y: y, horiz: horiz, verti: verti};}function stopPlayer() { player.body.velocity = 0; console.log("stopped");}Thank You for your help in advance! Link to comment Share on other sites More sharing options...
ultimatematchthree Posted January 15, 2015 Share Posted January 15, 2015 Your mapGroup contains only a single text object, which is the last one generated by initCell. This isn't probably what you intended. First of all, there's no need for your text variable to be in the global scope. Remove that variable declaration at the beginning of your code and let the text variable inside your initCell function be local instead, this will help you avoid bugs like this. Second, initialize your mapGroup before you populate your asciiDisplay array. Third, modify your initCell call so that after creating the text object, you immediately add it to your mapGroup before you return it. Finally, check for collisions between the player and the entire mapGroup, not just mapGroup.child. Then see what happens. Not sure if these will help you solve your problem but hopefully these will help you get closer to a solution. yesh0907 1 Link to comment Share on other sites More sharing options...
yesh0907 Posted January 15, 2015 Author Share Posted January 15, 2015 Hi, thanks for the reply. I tried all your suggestions and thanks for them. However, there is still the problem of them not being detected. I don't know why. Logically, it makes sense to me. Does it to you?Here is my code:// font sizevar FONT = 22;//var Height and Width for the Map's COLS and ROWSvar HEIGHT = 550;var WIDTH = 800;//Key variable set upvar cursors;var spaceKey;//offset for map's positionvar MAP_OFFSET = 2.38;//Game's height and widthvar gameHeight = 600, gameWidth = 800;//Style of textvar style = { font: FONT + "px monospace", fill:"#fff"};// map dimensionsvar ROWS = HEIGHT/FONT;var COLS = WIDTH/FONT/0.61;// number of actors per level, including playervar ACTORS = 10;// the structure of the mapvar map;//group the map objectsvar mapGroup; // the ascii display, as a 2d array of charactersvar asciidisplay;// initialize phaser, call create() once donevar game = new Phaser.Game(gameWidth, gameHeight, Phaser.CANVAS, '', { preload: preload, create: create, update: update});var graphics;function preload() { /* Using a square instead for now don't like the charcter */ //game.load.spritesheet('dude', 'assets/dude.png', 32, 48); graphics = game.add.graphics(0,0); graphics.beginFill("0xFF700B", 1); graphics.lineStyle(2, 0x0000FF, 1); graphics.drawRect(20, game.height - 550, 25, 25); graphics.endFill();}function create() { //Start game physics game.physics.startSystem(Phaser.Physics.ARCADE); // the map group mapGroup = game.add.group(); console.log(mapGroup); game.physics.arcade.enable(mapGroup); //Player player = game.add.sprite(0, 0); player.addChild(graphics); game.physics.arcade.enable(player); // initialize map initMap(maze(ROWS, COLS)); // initialize ascii display asciidisplay = []; for (var y=0; y<ROWS; y++) { var newRow = []; asciidisplay.push(newRow); for (var x=0;x<COLS;x++) newRow.push(initCell('', x, y + MAP_OFFSET)); } drawMap(); cursors = game.input.keyboard.createCursorKeys();}function update() { player.body.velocity.x = 0; player.body.velocity.y = 0; if (cursors.left.isDown) { player.body.velocity.x = -150; //player.animations.play('left'); } else if (cursors.right.isDown) { player.body.velocity.x = 150; //player.animations.play('right'); } else if (cursors.up.isDown) { //Move up the screen player.body.velocity.y = -150; } else if (cursors.down.isDown) { //Move down the screen player.body.velocity.y = 150; } game.physics.arcade.collide(player.body, mapGroup.child, stopPlayer);}function initCell(chr, x, y) { // add a single cell in a given position to the ascii display var text = game.add.text(FONT*0.6*x, FONT*y, chr, style); mapGroup.add(text); return text;}//creating the mapfunction initMap(m) { // create a new random map map = []; for (var j= 0; j<m.x*2+1; j++) { var line= []; if (0 == j%2) for (var k=0; k<m.y*4+1; k++) if (0 == k%4) line[k]= '+'; else if (j>0 && m.verti[j/2-1][Math.floor(k/4)]) line[k]= ' '; else line[k]= '-'; else for (var k=0; k<m.y*4+1; k++) if (0 == k%4) if (k>0 && m.horiz[(j-1)/2][k/4-1]) line[k]= ' '; else line[k]= '|'; else line[k]= ' '; if (0 == j) line[1]= line[2]= line[3]= ' '; if (m.x*2-1 == j) line[4*m.y]= ' '; map.push(line.join('')+'\r\n'); } return map.join('');}function drawMap() { for (var y = 0; y < ROWS; y++) for (var x = 0; x < COLS; x++) asciidisplay[y][x].text = map[y][x];}function maze(x,y) { var n=x*y-1; if (n<0) {alert("illegal maze dimensions");return;} var horiz =[]; for (var j= 0; j<x+1; j++) horiz[j]= [], verti =[]; for (var j= 0; j<y+1; j++) verti[j]= [], here = [Math.floor(Math.random()*x), Math.floor(Math.random()*y)], path = [here], unvisited = []; for (var j = 0; j<x+2; j++) { unvisited[j] = []; for (var k= 0; k<y+1; k++) unvisited[j].push(j>0 && j<x+1 && k>0 && (j != here[0]+1 || k != here[1]+1)); } while (0<n) { var potential = [[here[0]+1, here[1]], [here[0],here[1]+1], [here[0]-1, here[1]], [here[0],here[1]-1]]; var neighbors = []; for (var j = 0; j < 4; j++) if (unvisited[potential[j][0]+1][potential[j][1]+1]) neighbors.push(potential[j]); if (neighbors.length) { n = n-1; next= neighbors[Math.floor(Math.random()*neighbors.length)]; unvisited[next[0]+1][next[1]+1]= false; if (next[0] == here[0]) horiz[next[0]][(next[1]+here[1]-1)/2]= true; else verti[(next[0]+here[0]-1)/2][next[1]]= true; path.push(here = next); } else here = path.pop(); } return {x: x, y: y, horiz: horiz, verti: verti};}function stopPlayer() { player.body.velocity = 0; console.log("stopped");}Thanks for replying in advanced Link to comment Share on other sites More sharing options...
ultimatematchthree Posted January 15, 2015 Share Posted January 15, 2015 I think you missed the last suggestion. Change this line:game.physics.arcade.collide(player.body, mapGroup.child, stopPlayer);to:game.physics.arcade.collide(player.body, mapGroup, stopPlayer);Then see what happens... Link to comment Share on other sites More sharing options...
yesh0907 Posted January 15, 2015 Author Share Posted January 15, 2015 Ohh sorry, totally forgot to do that . However, the collision detection still does not work. Any more ideas?Thanks Link to comment Share on other sites More sharing options...
ultimatematchthree Posted January 15, 2015 Share Posted January 15, 2015 Hmmm according to the documentation for the collide method of Phaser.Physics.Arcade, you shouldn't pass it body objects. Try changing your line to the following and see what happens:game.physics.arcade.collide(player, mapGroup, stopPlayer); Link to comment Share on other sites More sharing options...
ultimatematchthree Posted January 16, 2015 Share Posted January 16, 2015 One more thing, this line:game.physics.arcade.enable(mapGroup);To be sure, place it at the very end of your create function (after your mapGroup has been populated with text objects). Link to comment Share on other sites More sharing options...
yesh0907 Posted January 16, 2015 Author Share Posted January 16, 2015 Hi, it is still not colliding. But thanks for your help. I think I am going to have to try another colliding method or change up the map...If you still have any ideas please write it down. Thanks for your help. Link to comment Share on other sites More sharing options...
ultimatematchthree Posted January 16, 2015 Share Posted January 16, 2015 Okay so I've gone ahead and read through the code for the collide method, and it looks like the current approach wouldn't work after all. At least two options for you in the meantime: 1) Add a texture that is completely transparent (all pixels with alpha 0) to your player sprite, then change your initCell function so that instead of creating a text object and returning that directly, you create a sprite first, assign a transparent texture to it, then add your text object to that sprite as a child, then return that sprite. Then collide should work as expected, using the dimensions of the transparent textures to compute collisions, or... 2) ...skip using the collide method of Arcade Physics altogether and roll your own. Just a few reasons why the current approach is failing: a) The Text class doesn't define a body property, so you can't call enable on it. The type property of Text isn't Phaser.SPRITE, Phaser.TILESPRITE, Phaser.GROUP, Phaser.EMITTER, or Phaser.TILEMAPLAYER.c) In your code, even though your player is a Phaser.Sprite, it won't factor in the Phaser.Graphics object that you add to it when computing collisions because...d) ...the body's dimensions are used to compute the collisions...e) ...but when the body's dimensions are assigned, the values are taken from the dimensions of the host sprite's corresponding texture. So to summarize, if you still want to continue with your current approach, then you need to use sprites with textures assigned to them, even if the textures are transparent, and when collisions are computed, the sizes of the textures that you assign will be used in the computations. If you don't want to use textures, then don't use Arcade Physics to manage your collisions. yesh0907 1 Link to comment Share on other sites More sharing options...
ultimatematchthree Posted January 16, 2015 Share Posted January 16, 2015 Okay so the forum software turned item b above into a smiley, just wanted to clarify that that wasn't what I intended to post Link to comment Share on other sites More sharing options...
yesh0907 Posted January 16, 2015 Author Share Posted January 16, 2015 Hi thanks for the post, is it possible for you to give me an example on how i would be able to add a texture onto the sprite and map. Mostly the map because the sprite i can do it try by myself. Thanks ! Link to comment Share on other sites More sharing options...
ultimatematchthree Posted January 16, 2015 Share Posted January 16, 2015 You won't be associating a single texture with the whole map. Instead, every text object will have its own texture associated to it. In your preload function, you can have something like:game.load.image('transparent_texture_for_text', 'assets/transparent_texture_for_text.png');Then you replace your initCell function with the following:function initCell(chr, x, y) { var text = game.add.sprite(FONT*0.6*x, FONT*y, "transparent_texture_for_text"); text.addChild(game.add.text(FONT*0.6*x, FONT*y, chr, style)); mapGroup.add(text); return text;}I didn't test the above code so you might have to fix it after copy-pasting. You'll be doing something similar for your player sprite, too. Then see what happens. yesh0907 1 Link to comment Share on other sites More sharing options...
Recommended Posts