How to have tiles check neighboring tiles

Hello!!

I’m trying to get certain tiles in my game to check if matching tiles are next to them so they can do a thing!

I’m not sure how to go about doing this and most things I’ve tried haven’t given me the effect I want.

Basically I want matching tiles to notice being adjacent to like tiles then disappear or move somewhere else.

Any ideas?

Thank you!

1 Like

So, first when do you want this to happen? That may have an impact on how you do this.

Secondly, normal "World" tiles cannot have their own logic. You could use Sprite and Item tiles instead, who can have their own logic. I avoid using those for their normal purposes because Sprites must be walls and Items cannot be walls so they are a bit constricting, and their main benefit is that you can call "interact" and "collect" on them which it sounds like you aren't doing here. So I would recommend putting the code in the room itself.

The biggest issue you will come across is how do you programmatically keep track of this information? It is pretty tough to keep track of numbered data in Pulp without doing something like this:

tile_1_1_status = "normal"
tile_1_2_status = "normal"
tile_2_1_status = "normal"
tile_2_2_status = "normal"
tile_1_3_status = "normal"
. . .

that gets really big real fast. I would recommend keeping track of your tile information on the tiles themselves by changing the tile's frame or swapping to a different tile. If you are not intending to have these tiles animated, the frame is a great place to keep some information. Add a second frame that is just a duplicate of the first to each of these tiles that you want to work with and set their framerate to zero. Then in the room, make a function that works like this:

on checkAdjacent do
  x = 0 // set this number to be the left most x value of tiles you want to work with
  while x<=24 do // or change 24 to the right most x value of tiles you want to work with
    y = 0 // top most y
    while y<=14 do // lower most y
      call "individualCheck"
      y++
    end
    x++
  end
  // that will go through each tile and set their frames based on who is next to them
  // next we can remove or move them; removing them is so simpler so we do that
  x = 0 // same as above
  while x<=24 do // ditto
    y = 0
    while y<=14 do
      tell x,y to
        frame_number = frame
        if frame_number == 1 then
          swap "white" // or the name of your empty tile
        end
      end
    y++
    end
  x++
end

on individualCheck do
  this_ones_name = name x,y
  // check the one to the left
  nx = x
  nx--
  ny = y
  call "neighborCheck"
  if this_ones_name==neighbor_name then
    tell x,y to
      frame 1
      done // it has at least one neighbor matching so don't check the others
    end
  end
  // check the one to the right
  nx = x
  nx++
  ny = y
  call "neighborCheck"
  if this_ones_name==neighbor_name then
    tell x,y to
      frame 1
      done // it has at least one neighbor matching so don't check the others
    end
  end
  // check the one above
  nx = x
  ny = y
  ny--
  call "neighborCheck"
  if this_ones_name==neighbor_name then
    tell x,y to
      frame 1
      done // it has at least one neighbor matching so don't check the others
    end
  end
  // check the one below
  nx = x
  ny = y
  ny++
  call "neighborCheck"
  if this_ones_name==neighbor_name then
    tell x,y to
      frame 1
      done // it has at least one neighbor matching so don't check the others
    end
  end
  // if you also want to check diagonals, you'll need to do this four more times for those
  // I'm going to skip them because this is already getting huge
  tell x,y to
    frame 0 // it only gets here if it found no matching neighbors
  end
  // so after this has run, the tile at x,y will be set to frame 0 if it is alone or frame 1 if it has neighbors
end

on neighborCheck do
  // first check if this is off the screen and just set the name to "none" if it is
  if x<0 then
    neighbor_name = "none"
    done
  elseif x>24 then
    neighbor_name = "none"
    done
  elseif y<0 then
    neighbor_name = "none"
    done
  elseif y>14 then
    neighbor_name = "none"
    done
  end
  neighbor_name = name nx,ny
end

if you do need animations, then we'll have to use duplicate tiles instead of frames and I can explain that if you like

this may be really slow on the actual playdate if you leave the numbers the way they are. if you make the x and y bounds tighter, it will check less of the screen but will help performance a lot. you could also just throw up a loading screen if it's too bad

it'd be really nice to use emit and have each tile have a mimic of a function that checks for adjacents, but tiles don't actually know their own location

I hope this helps.

1 Like

Hello!

This is fantastic!

I would like to have animations so duplicate tiles is what I would like to do!

and I think I will restrict the x and y bounds, because I want to give the impression that things are happening on a computer screen within the game.

Thank you for all your help!

Hello!

So i'm having trouble getting duplicate tiles to swap with "white" after matching and i think I'm doing something wrong.

What would be the best way to adapt the code to effect duplicate tiles instead of alternate frames?

Thank you!

Good Morning!

Could you please explain how to do this with duplicate tiles instead of frames?

Thank you!

Okay so basically, you need to duplicate every tile that you're doing this with and give them names like Card0 and Card1 or Apple0 and Apple1

instead of using

tell x,y to
  frame 0 // or frame 1
end

you'll need to do

tell x,y to
  swap "Card0" // or swap "Card1"
end

if you only have the one tile pair (like just Card0 and Card1) that'll do. if it could be one of many different tiles, you'll unfortunately have to use a big if-elseif-else statement
you can get the name of a tile with

a_tiles_name = name x,y

and then proceed to do this sort of thing

if a_tiles_name=="Card0" then
  swap_to = "Card"
elseif a_tiles_name="Apple0" then
  swap_to = "Apple"
. . . // as many of those as you need
end
tell x,y to
  swap "{swap_to}0"
  // swap "{swap_to}1"
end

so just make your tile pairs and then replace the parts that change frame to swap tiles like this instead