PDA

View Full Version : find adjecent balls in grid (arrays) for bubble game



Wocker
April 22nd, 2009, 03:29 PM
Hi everyone,
I am creating a bubble shooter game in AS3, and now I am at the phase where I want to detect the bubbles arround the bubble I hit.

I have an array called levelBalls
it contains 10 arrays, and each of those 10 arrays can contain balls.

levelBalls[0][0] for example returns a reference to a ball object( BallClip class -this is basically a movieClip with extra properties for storing color info etc.)

The first 5 rows are filled with a ball object.
The remaining 5 rows are filled with 0 (zero), to indicate nothing is there.

Every other row onscreen has a offset on x. This is to create a brick layer effect, instead of just having straight rows of balls.

QUESTION:
Taking into account limits on the array length, how do I return the six positions surrounding the ball that got hit.



//h = horizontal pos
//v = vertical pos of ball
//the balls are distributed bij 32px
//registration point of balls is in the center, not top left
function getSix(h,v){
var ballRadius = 32;
var centerBall = levelBalls[v][h];
var indentVal = ballRadius/2;

var hasIndent:Boolean = false;
if (h == 0){
//this is the left most ball in this row.
if (centerBall.x >indentVal ) {
//this row has an indent
hasIndent = true;
}
} else {

if (centerBall.x > (h*spacingX)+indentVal){
hasIndent = true;
}
}
//.....and then???? I know if the row has an indent or not
// but how do I get the surrounding balls?

}

DrRobot
April 22nd, 2009, 04:04 PM
maybe this will help:
http://www.emanueleferonato.com/2008/04/23/finding-adjacent-cells-in-an-hex-map/

Wocker
April 23rd, 2009, 02:36 AM
I didn't think the hexmap would work for me.
Now I came up with the following....



function getSix(mBall:BallClip) {
var gridObj = coordToGrid(mBall.x,mBall.y);
var h = gridObj.h;
var v = gridObj.v;
//check if this is a indent row
var centerBal = levelBalls[v][h];
var indentVal = startX+(spacingX/2);
var centerBall = levelBalls[v][h];
trace("centerBall:"+v+","+h);
var hasIndent:Boolean = false;
if (h == 0) {
//this is the left most ball in this row.
if (centerBall.x > indentVal) {
//this row has an indent
hasIndent = true;
}
} else {
if (centerBall.x > (h*spacingX)+indentVal) {
hasIndent = true;
}
}
trace("has indent:"+hasIndent);
var connectedBalls = new Array();
var cBalls = new Array();

if (h > 0) {
connectedBalls.push(levelBalls[v][h-1]);
cBalls.push(v+","+(h-1));
}
if (h < 9) {
connectedBalls.push(levelBalls[v][h+1]);
cBalls.push(v+","+(h+1));
}
if (v > 0) {
connectedBalls.push(levelBalls[v-1][h]);
cBalls.push((v-1)+","+(h));
if (h > 0 && h < 9) {
if (hasIndent == false) {
connectedBalls.push(levelBalls[v-1][h-1]);
cBalls.push((v-1)+","+(h-1));
} else {
connectedBalls.push(levelBalls[v-1][h+1]);
cBalls.push((v-1)+","+(h+1));
}
}
}
if (v < 9) {
connectedBalls.push(levelBalls[v+1][h]);
cBalls.push((v+1)+","+(h));
if (h > 0 && h < 9) {
if (hasIndent == false) {
connectedBalls.push(levelBalls[v+1][h-1]);
cBalls.push((v+1)+","+(h-1));
} else {
connectedBalls.push(levelBalls[v+1][h+1]);
cBalls.push((v-1)+","+(h+1));
}
}
}

//Filter the array, so it only contains filled spaces (which would return a BallClip object) on the grid, and not the empty places (which would return 0)
trace("connectedBals before"+connectedBalls);
for (var i = connectedBalls.length-1; i>0; i--) {
if (connectedBalls[i] == 0) {
connectedBalls[i].splice(i,1);
}
}

trace("connectedBals after"+connectedBalls);
trace("cBals"+cBalls);
}
Everything seems to work, except for the last bit. It gives me the error: TypeError: Error #1006: value is not a function

UPDATE: found the error: stupid copy paste error. connectedBalls[i].splice(i,1); should of course be connectedBalls.splice(i,1);

Valaran
April 23rd, 2009, 04:52 AM
You seem to have found your own solution, but I'm gonna throw you a bone anyway! When working with games, or actually when programming, its better to seperate code from display, in your case, you shouldnt really bother with the x position of the ball and such, just look it up in the array! Sorry if i misunderstood you in any way, anyway here is the bone:


// 2d array with 3x3 grid of balls
var arr:Array = [
["ball-00", "ball-01", "ball-02"],
["ball-10", "ball-11", "ball-12"],
["ball-20", "ball-21", "ball-22"]
];

// If you want to exclude any direction, just comment it out in this array
var directions:Array = [
{ x:-1, y:0 }, // Left
{ x:-1, y:-1 }, // Top Left
{ x:0, y:-1 }, // Top
{ x:1, y:-1 }, // Top Right
{ x:1, y:0 }, // Right
{ x:1, y:1 }, // Bottom Right
{ x:0, y:1 }, // Bottom
{ x:-1, y:1 } // Bottom Left
];

function returnAdjacent(x:uint, y:uint):Array
{
if(arr[x][y])
{
var rArr:Array = [];
for(var i:int = 0; i < directions.length; i++)
{
var currX:int = x + directions[i].x;
var currY:int = y + directions[i].y;

if(arr[currX])
if(arr[currX][currY])
rArr.push(arr[currX][currY]);
}
return rArr;
}
return null;
}

var test:Array = returnAdjacent(2, 2); // Looks for adjacent balls to the bottom right one

trace(test);


Edit: I forgot to mention it, but from there, you could just get the positions of the balls returned by the function by accessing the balls x and y properties (incase that wasnt clear..)

rrh
April 23rd, 2009, 10:36 AM
Something like:


var surroundingBalls:Array = [];
surroundingBalls.push(levelBalls[v-1][h]);
if (hasIndent) {
surroundingBalls.push(levelBalls[v-1][h+1]);
} else {
surroundingBalls.push(levelBalls[v-1][h-1]);
}
... etc ...

Wocker
April 28th, 2009, 09:23 AM
Thanks for the tip Valaran.
I have implemented your code example.

Now how would I go about checking for isolated balls?
Because what I want to do, is check if the balls arent connected (directly or inderectly) to the top row. The top row is fixed to the 'ceiling'. And when they are isolated I want them to dissapear.

I come up with different kinds of recursive functions, but they seem to be overkill.
Checking each and everyball, to see if it's connected to any of the top balls through a connection with the other balls.

I have seen a post about it on this forum for the bubble shooter, but it didn't give an example or answer.

DfKimera
April 28th, 2009, 02:51 PM
Assuming that it is code who generates each of the bubbles, you can have so for each adjacent bubble found when the bubble is created, both bubble and adjacent bubble have a counter incremented. This counter will be the amount of adjacent bubbles, and if the bubble has no adjacent bubbles when it is created, its counter will remain zero.

rrh
April 28th, 2009, 03:41 PM
But you want groups to fall off, not just individuals.

I think you still need to do it recursively. But try approaching it from the other direction. Don't test each ball to see if it's connected to the top. Start at the top row of balls and find every ball connected to them. Anything left over when you're finished the top row will fall.