Hello, everyone!
So here is my problem - I need a swapping tiles behavior for my game, like when you touch one tile then move your finger to nearest tile and release then they swap with each other, but without actually dragging the tile itself (I guess it's kinda confusing explanation
).
I accidentally stumbled upon an exact example of what I need (it's for NME framework). Here is the link -
http://www.joshuagranick.com/blog/2012/02/22/nme-game-example-pirate-pig/. There is a source code as well but though it looks rather simple, I'm quite a newbie in programming, so it's not much use for me
.
Comments
When you talked about swapping tiles my first thought was that you were talking about the native tilemap support and I thought ok, I've just worked this out time to post.
However on closer reading (always a good idea, read twice - post once! ), basically what your looking to create is a basic "match3 engine" where by you have a collection of "tiles" (game objects, sprites, whatever) and you can swap their positions by touching and or dragging them around.
First things first (if you haven't completed these steps yet - I suggest you do before progressing).
1. Create your "tiles", you need a list of objects each with an x,y coordinate on the screen, a simple table can be used to hold all of the "tiles".
2. Create a function that responds to a single touch and can then scan the list of "tiles" and based on their x,y positions (and tile width / height), return either the position or a reference to the sprite that was "touched", you can easily recognise this (and ensure you've got the right one) by setting it's alpha, colour modifier or scaling.
Now it get's a little more complex!
3. You need to use a "state machine" so that you know what "state" your game is in - basically this just means creating a simple variable that holds a number, where the number is used to represent the state, it's a way of remembering what your game is supposed to be doing at any given time.
For a simple touch based match 3 you'll be going through (approximately) the following states.
a - waiting for the first tile to be touched (selected)
b - acknowledge the touch and then wait for the second tile - this can either be via a dragging movement or via another press
c - acknowledge the second tile being pressed and then swap their positions - this can either be immediate or via some kind of animation
d - check for matches (more on this later) and then destroy all the appropriate tiles, if no matches then go back to state a, other wise go to state e
e - fill in the gaps, by sliding tiles from above down into position and filling in any gaps at the top - you'll stay in this state until the sliding anim is finished and then go back to state d (this will allow you to check for combo's where one match kicks off another one).
Checking for matches can start to get a little complex, the way I usually do it is by creating a 2D array (ie a table of tables) where each element in the array is either nil or 0 (an empty space) or the index (or reference) to the sprite / tile at this location - note, although you'll have several "tiles" all with the same image, they'll actually have different indexes (or references) as they are actually separate objects - you'll need to store a property with each tile to say which "image" is being used so can see if two "tiles" should be considered the same...
By using some simple logic you can (at stage d) walk through the array fairly easily and see if there are any blocks of three or more tiles that have the same "image" and then you'll be able to mark them as destroyed.
I would suggest starting at step 1. and then posting your code, it might be good learning experience for others as well.
I've deliberately avoided posting code as I think you (and others) would actually learn a LOT more from experimenting and trying to complete the steps yourself, however feel free to ask any more questions if needed.
Jon...
#MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
Edit: Well, maybe I'm not that busy :-) Now I'm confused myself I thought that it can be done with the native tilemap... To make things clear I'll try to explain one more time. I want to make a tile map with two layers - 1st one is a background one and the 2nd is objects layer, so you can swap only objects not the whole layers. What I want to know is how to make an object layer and how can I operate objects to make them swap with each other when you drag one object on another (as I said without actually dragging them, like in the Pirate Pig game example). That's pretty much everything I need to know. And forgive me for being confusing and confused
If I'm understanding what you want correctly, then you will need to do the following:
3.) Add an event listener for MOUSE_DOWN, use your function created in techdojo's step 2 to take the x and y from the click and select your starting tile.
4.) Add an event listener for MOUSE_UP, use your function created in techdojo's step 2 to take the x and y from the event and select your end tile. If the start and end tile are not the same, swap their locations.
If you DO want to use tilemaps, then you need to create a basic tilemap (using Tiled is the easiest way) and then use the code example from here
http://www.giderosmobile.com/forum/discussion/699#Item_15
to create a basic map.
When you build a map you call the setTile function to build up the tile indexes internally - this function is *really* confusing if you look at the documentation but if you think of the "tile sheet" as an 2D array of tiles then your actually specifying the COLUMN (tx) and ROW (ty) of the tile - so if your sheet is 16 tiles wide by 16 tiles high and you want tile 19 then it's on ROW 2, COLUMN 3.
This is not made any easier by the fact if you call getTile then according to the doc's it would actually return the tile index.
However the actual process of "swapping" tiles would involve getting the index of both the source and destination tiles, converting them into row and column values ie. integer divide the index by the number of tiles per row to get the row (not forgetting to +1 as indexes in Lua start at 1 not 0) and modulo the index by the number of tiles per row to get the column (again +1), once you have the two sets of row and column values you just make the appropriate calls to setTile
#MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
Thank you very much, it's working >-
@gorkem When I have some that would be useful to most people definitely will! Really enjoying it so far!