- Home /
[Re-Edited] Clone Of Bejeweled for Android
Hi Guys any one could point me out how to make Bejeweled type game........all i want to know is how to check for the three or more objects are in line either vertical or Horizontal axis?? all the part is in 2d Only...... Any kind of help will be much appreciated.....Can't afford plugins.....For learning purpose only......If providing Scripts Then Go for C# only.......Thanks a Lot in Advance....
Ask specific questions! You basically ask how to create the whole game. It's almost impossible to answer the question except with the ready made game...
@Bunny83 Thanks for the Comment....i should be Specific from next time....could you please help with above mentioned part of the Game??? Thanks again for your kind Reply
@Bunny83 as per your $$anonymous$$gestion The Question is edited.....
Answer by CodeMasterMike · Jan 04, 2013 at 06:44 AM
On way to do it is to first create a list, and then create a loop-function that checks the neighbours of a object.
If object has a neighbour (horizontally and vertically) that is the same type, then save that object to your list.
When you have checked all the neighbours for the first object, take your list and you do the same to all the objects in the list, until all objects have checked if they have a neighbour of the same type.
Remember to have some kind of check that you either ignore a neighbour if its already in the list or that you ignore the last object you checked so you won't get duplicates in the list
Now you have a list of objects which are connected both vertically and horizontally and are connected as neighbours.
If the list has enough objects (more than 3 objects for instance), loop through your finished list and destroy the objects and when done clear the list, and you are done.
A very simple pseudo example code:
private List<GameObject>m_listOfObjectsToRemove = new List<GameObject>();
private int m_minimumNoOfObjects = 3;
private void StartCheck(GameObject startObject)
{
m_listOfObjectsToRemove.Add(startObject);
CheckNeighbours(startObject, null, true, true);
GameObject previousStartObject = startObject;
for(int i = 1; i < m_listOfObjectsToRemove.Count; ++i)
{
CheckNeighbours(m_listOfObjectsToRemove[i], previousStartObject, true, true);
previousStartObject = m_listOfObjectsToRemove[i];
}
if(m_listOfObjectsToRemove.Count > m_minimumNoOfObjects)
{
for(int i = 1; i < m_listOfObjectsToRemove.Count; ++i)
{
Destroy(m_listOfObjectsToRemove[i]);
}
m_listOfObjectsToRemove.Clear();
}
}
private void CheckNeighbours(GameObject startObject, GameObject previousStartObject, bool check horizontally, bool check vertically)
{
// Check all four neighbours (vertically and horizontally)
// and make sure the previous start object is ignored if found...
if(horizontally == true)
{
if(leftNeighbourObject != null)
{
if(leftNeighbourObject.typeOfObject == startObject.typeOfObject && leftNeighbourObject != previousStartObject)
{
m_listOfObjectsToRemove.Add(leftNeighbourObject);
}
}
if(rightNeighbourObject != null)
{
if(rightNeighbourObject.typeOfObject == startObject.typeOfObject && rightNeighbourObject != previousStartObject)
{
m_listOfObjectsToRemove.Add(rightNeighbourObject);
}
}
}
if(vertically == true)
{
if(aboveNeighbourObject != null)
{
if(aboveNeighbourObject.typeOfObject == startObject.typeOfObject && aboveNeighbourObject != previousStartObject)
{
m_listOfObjectsToRemove.Add(aboveNeighbourObject);
}
}
if(belowNeighbourObject != null)
{
if(belowNeighbourObject.typeOfObject == startObject.typeOfObject && belowNeighbourObject != previousStartObject)
{
m_listOfObjectsToRemove.Add(belowNeighbourObject);
}
}
}
}
It's not a very nice looking code, but it should give you an idea of one way you can do it.
Good luck!
hi, i uses your code but not able to make a perfect grid ...as its overlapping with each other when object get instantiated.
Answer by Maulik2208 · Jan 04, 2013 at 10:23 AM
int gameSize = 6;
public GameObject [] MyGems = new GameObject [6];
public Material [] MyMaterial = new Material [6];
void Start ()
{
for(int x = 0;x < 6 ; x++)
{
for(int y = 0;y < 6 ; y++)
{
int RandomNumber = Random.Range (0,6);
if(RandomNumber == 0)
{
Instantiate (MyGems[RandomNumber],new Vector3(x,y,0),MyGems[RandomNumber].transform.rotation);
MyGems[RandomNumber].renderer.material = MyMaterial[RandomNumber];
}
if(RandomNumber == 1)
{
Instantiate (MyGems[RandomNumber],new Vector3(x+0.35f,y-0.0f,0f),MyGems[RandomNumber].transform.rotation);
MyGems[RandomNumber].renderer.material = MyMaterial[RandomNumber];
}
if(RandomNumber == 2)
{
Instantiate (MyGems[RandomNumber],new Vector3(x+0.05f,y+0f,0.0f),MyGems[RandomNumber].transform.rotation);
MyGems[RandomNumber].renderer.material = MyMaterial[RandomNumber];
}
if(RandomNumber == 3)
{
Instantiate (MyGems[RandomNumber],new Vector3(x+0.0f,y-0.2f,0),MyGems[RandomNumber].transform.rotation);
MyGems[RandomNumber].renderer.material = MyMaterial[RandomNumber];
}
if(RandomNumber == 4)
{
Instantiate (MyGems[RandomNumber],new Vector3(x+0.0f,y+0.94f,0.0f),MyGems[RandomNumber].transform.rotation);
MyGems[RandomNumber].renderer.material = MyMaterial[RandomNumber];
}
if(RandomNumber == 5)
{
Instantiate (MyGems[RandomNumber],new Vector3(x,y,0),MyGems[RandomNumber].transform.rotation);
MyGems[RandomNumber].renderer.material = MyMaterial[RandomNumber];
}
Was unable to Edit the question and Post this So posted as a answer so sorry about this
Till now i am having this Simple Script to Create the Grid.......
1) How to swap objects (only next either Horizontally or Vertically)
2)After Swapping Check if there are 3 Or more same are there or not(either Horizontally or Vertically Only) if there then destroy the matching objects......
Currently Grid of Object Look like this------>
Oddly enough I've just been working on a bejeweled clone :) Not as easy as it looks I know.
I abstracted the gems from their visual representation by making a function that would return the gem at a given grid X/Y coordinate. Then the for/next loops are easier to write - the grids are small enough that you can just write one function that scans the whole grid after every move.
First scan horizontally - > add exploding gems to a list.
Next scan vertically -> add any gems to destroy that aren't already in the list to the list.
You might have to do special cases if you want to detect 4/5 gems and corners (I did this as part of the previous passes with the horizontal case checking for corners).
Blow up the gems.
Either get all gems to scan beneath them to see if the space is now empty - if it is, tell that gem and all the ones above it to move downwards (may need to be repeated). Or give all gems "gravity" by having them continually scan below to see if the gem below is missing or moving and in which case move it downwards.
I did all my gem positioning by lerping between multiplied out grid coordinates (so setting a gem to move from 1,1 to 1,2 caused it to move downwards by it's actual screen height).
Heh, are you asking for my noob perspective, or is it knowing how much I like to explain things far beyond my skill level =]
You missed a few other good names on that callout list, and even though I made the second cut, I am no authority compared to the other excellent talented clever programmers you have mentioned. If karma was actually a reflection of knowledge and experience, I wouldn't be past 1k. (and that is being nice to myself!)
AS I am here, where to start? Well there are 2 excellent methods described on this page by Code$$anonymous$$aster$$anonymous$$ike and whydoidoit, so which one to adopt? AS your code seems to indicate that you are thinking in a 2-dimensional method, I would go with $$anonymous$$i...whydoidoit.
Now this is not the easiest project to start with, so break it break it down (sometimes I think of the Bill $$anonymous$$urray movie "What About Bob?" ... baby steps ... ). You have alot of things to consider and get comfortable with to get to the end. Here is how I would summize :
Game Rules : how is the game played? (movement, combos, scoring, win/lose conditions). Now would be a good time to state I have never played Bejewelled, but have an idea from one of the Plants Vs Zombies $$anonymous$$igames.
Player Inputs : how is the game controlled by the player.
Visual representation : how does the game work, not just what it looks like. Stunning graphics are fine, but how to implement them? This leads to ....
Game $$anonymous$$anagement : the big script. The idea behind both of these methods is that everything is stored as data, so not using physics or graphics, but checking through an 'imaginary' grid, doing all the calculations, then setting the graphics last to visually represent the state of the game.
For you to even take step one, you'll have to learn how to use a 2-dimensional array, so that is where I suggest you start. This is not far from what you have currently written. SO start there, with a Start function (groan). Create a 2-dimensional array, and populate it with integers to represent each gem. Remember consideration 1? Some of those rules have to be set now!
number of rows = 6;
number of columns = 6;
types of gem ( 6 + 1 for empty ) = 7;
Quickly consider how the gem objects are going to work. I suggest just use a primitive cube, and change the material for each gem type (I won't go into swapping UVs here).
Oh, heck, I just noticed you are coding in C#, not my native tongue, so to a very useful link on arrays : http://wiki.unity3d.com/index.php?title=Which_$$anonymous$$ind_Of_Array_Or_Collection_Should_I_Use?
so without knowing C#, here's some pseudocode for you to convert to C# :
for a comment so verbose, I need 2 comment boxes =]
int[,] playGrid; // 2-dimensional array
void Startup()
{
// assign size to array
playGrid = new int[6,6];
for (int y = 0; y < 6; y ++)
{
for (int x = 0; x < 6; x ++)
{
playGrid[x,y] = Random.Range(0,8); // remember Random.Range max int is **exclusive**
}
}
}
void BuildPlayGrid()
{
for (int y = 0; y < 6; y ++)
{
for (int x = 0; x < 6; x ++)
{
// place gameObject in position of grid
GameObject clone = Instantiate( cube, new Vector3(x,y,0), Quaternion.identity );
clone.name = "pos_" + x.ToString() + "_" + y.ToString(); // the na$$anonymous$$g can be very useful later, especially if your objects are not to a scale of 1 unit per gem
// show gem as correct type by assigning material
switch( playGrid[x,y] )
{
case 0 :
// no gem :(
clone.renderer.material = mtlBlank;
break;
case 1 :
clone.renderer.material = mtlGem1;
break;
case 2 :
clone.renderer.material = mtlGem2;
break;
// you get the idea, make a case for each and all gem types, Do IT !
// at this point my fellow Unites are saying "Use an array of materials!",
// but I think one 2-dimensional array is enough to keep track of and explain at this level =]
// unless you can do this yourself (which at some stage I strongly encourage you do, then this whole switch-case becomes one line!)
}
}
}
}
See, the first step is done, and was relatively painless! Now by yourself you should be able to generate a grid, populate it, then instantiate gameObjects to represent the values in the grid. Nice job =]
for your homework : learn how to use raycast, and write a method that raycasts to one of the cubes (from now to be called gems), and return the x and y playGrid position of that gem. If that is too easy, then also work out a way for the raycast to also return what type of gem was RaycastHit.
When you are done, EDIT YOUR QUESTION to include the code you have written for these first 3 steps (yes, 3 already! Declare and assign values to a 2-dimensiional array, instantiate cubes with materials for that array, and then raycast to return the gem information).
Then post a comment saying "lookie here" when you have done it. See you then =]
I hope the other users don't $$anonymous$$d my comments. I saw someone specifically write that they wanted to learn, so I couldn't go past without offering a step (or enough rope ....). If and I hope it is the former, perhaps this should be a http://forum.unity3d.com/ topic for you to run, and who knows how many other people jump in, help or chat about it. And it can be an ongoing post in the forums =]
Answer by 10 cent pistol · Oct 01, 2013 at 10:34 PM
I am trying to develop this kind of game for Android, and i am stuck with swapping grid cells (cubes in my case). I successfully initialized grid (9x9) and filled it with cubes with different textures. I am using Mouse Button Down, Up for catching movement of cubes. On Down i just get selected cube using RayCast and then while moving I detect direction, and move one cube till it goes for example 0,1 on x axis and then try to swap with next cube (in this case right of current cube, so i am moving just by x). For now swapping is my main problem, i know it is probably simple but since I am amateur in Unity world, this is really annoying for me now.
Chaos of my code: //////////////////////////////////
if(Input.GetMouseButtonDown (0)) {
RaycastHit hitInfo;
target = GetClickedObject(out hitInfo);
if (target != null) {
_mouseState = true;
screenSpace = Camera.main.WorldToScreenPoint (target.transform.position);
offset = target.transform.position - Camera.main.ScreenToWorldPoint (new Vector3 (Input.mousePosition.x, Input.mousePosition.y, screenSpace.z));
startScreenSpace = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, screenSpace.z);
//convert the screen mouse position to world point and adjust with offset -> temp position of touched cell!
startScreenPosition = Camera.main.ScreenToWorldPoint(startScreenSpace) + offset;
Debug.Log("Kliknuto X= " + startScreenPosition.x + " Kliknuto Y= " + startScreenPosition.y);
//referece to selected obj from array of Gams
currentSelectedObj = arrayOfGames[GRID_SIZE * (int)startScreenPosition.y + (int)startScreenPosition.x];
Debug.Log("currentSelectedObj cor: " + currentSelectedObj.positionInGrid);
//currentSelectedObj.gObject.transform.position = currentSelectedObj.positionInGrid;
Debug.Log("World cor:" + currentSelectedObj.gObject.transform.position);
setCurrentDirection = false;
}
}
if (Input.GetMouseButtonUp (0)) {
_mouseState = false;
}
if (_mouseState) {
//keep track of the mouse position
curScreenSpace = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, screenSpace.z);
//convert the screen mouse position to world point and adjust with offset
curPosition = Camera.main.ScreenToWorldPoint(curScreenSpace) + offset;
//Debug.Log("Curr pos: " + curPosition);
//najpre odredjujemo pravac kretanja
if(!setCurrentDirection)
{
if(curPosition.x != startScreenPosition.x)
{//promena po x -> horizontalno kretanje
setCurrentDirection = true;
//Debug.Log("Move Drirection " + "promena po x -> horizontalno kretanje");
if(curPosition.x > startScreenPosition.x)
currDirection = MovingDirection.Right;
else
currDirection = MovingDirection.Left;
}
else if(curPosition.y != startScreenPosition.y)
{ //promena po y -> vertikalno kretanje
setCurrentDirection = true;
if(curPosition.y > startScreenPosition.y)
currDirection = MovingDirection.Top;
else
currDirection = MovingDirection.Bottom;
}
}
if(setCurrentDirection && isNeighbrouExist(currDirection))
{
if(currDirection == MovingDirection.Right && (currentSelectedObj.gObject.transform.position.x >= startScreenPosition.x + 0.1))
{
//Debug.Log("Pozicija targeta: " + target.transform.position);
_mouseState = false;
SwapCubes(currentSelectedObj);
}
else
{
switch(currDirection)
{
case MovingDirection.Bottom:
target.transform.position = new Vector3(target.transform.position.x, curPosition.y, target.transform.position.z);
break;
case MovingDirection.Top:
target.transform.position = new Vector3(target.transform.position.x, curPosition.y, target.transform.position.z);
break;
case MovingDirection.Left:
target.transform.position = new Vector3(curPosition.x, target.transform.position.y, target.transform.position.z);
break;
case MovingDirection.Right:
target.transform.position = new Vector3(curPosition.x, target.transform.position.y, target.transform.position.z);
break;
}
}
}
}
}
void SwapCubes(Gam sourceCube)
{
Vector3 tempVect = arrayOfGames[sourceCube.indexInGrid].getPositionInGrid();
arrayOfGames[sourceCube.indexInGrid].gObject.transform.position = new Vector3(arrayOfGames[sourceCube.indexInGrid + 1].gObject.transform.position.x,
arrayOfGames[sourceCube.indexInGrid + 1].gObject.transform.position.y,
arrayOfGames[sourceCube.indexInGrid + 1].gObject.transform.position.z);
arrayOfGames[sourceCube.indexInGrid + 1].gObject.transform.position = tempVect;
//change position in grid
int temp = sourceCube.indexInGrid;
sourceCube.indexInGrid = arrayOfGames[sourceCube.indexInGrid + 1].indexInGrid;
arrayOfGames[sourceCube.indexInGrid + 1].indexInGrid = temp;
Vector3 tempPosition = sourceCube.positionInGrid;
sourceCube.positionInGrid = arrayOfGames[sourceCube.indexInGrid - 1].positionInGrid;
arrayOfGames[sourceCube.indexInGrid - 1].positionInGrid = tempPosition;
}
///////////////////////////////////////////
So, this is BIG chunk of my code, a apologize because I am so detailed, but I am stuck, and don't know if my logic is good for now. Any advice or help is more then welcome.
@Maulik2208 & rest of you -> if someone has some kind of tutorial or detailed explanation for this game in Unity, please feel free to share with a group.
Thank you in advance!
Your answer
Follow this Question
Related Questions
IOS Swipe Gesture 0 Answers
How to control a 2d character in an top-down android game with the standard joystick? 1 Answer
Trouble with Screen Glitch with Android Build 1 Answer
2D Platformer Mouse aiming! 0 Answers
Is there anything wrong with this script? It used to work but now it doesn't. 2 Answers