Jump to content

Collision Detection with Sprite and Text Object not working. Please Help


yesh0907
 Share

Recommended Posts

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 advance

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;//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

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.

Link to comment
Share on other sites

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 :D

Link to comment
Share on other sites

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.

B) 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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...