Example #1
0
        /// <summary>
        /// Turns items around his position clockwise. Then destroys itself.
        /// 
        /// It takes care of all the changes by itself. So no popping outside.
        /// Only physics needs to get used.
        /// </summary>
        /// <param name="pos">Position in the level</param>
        /// <param name="updateOnly">UpdateOnly always true</param>
        /// <returns>Array of item position to update</returns>
        public override IntVector2[] Activate(IntVector2 pos, out bool updateOnly)
        {
            List<IntVector2> back = new List<IntVector2>();
            updateOnly = true;
            back.Add(pos);

            IntVector2 levelSize = context.GetSize();

            //Test if the position is in bounce. If the turn to near to the left, right top or ground
            //it only pops itself.
            if(
                pos.x != 0 && pos.y != 0 &&
                pos.x != levelSize.x-1 && pos.y != levelSize.y-1

               ){
                //save the first item
                IntVector2 current = pos + items[0];
                Gem temp = context.GetItem(current);

                //swap all items clockwise.
                IntVector2 last = current;
                for(int i = items.Length -1; i > 0; i--){
                    current = pos + items[i];
                    context.SetItem(last, context.GetItem(current));
                    back.Add(last);
                    last = current;
                }
                //set the first item on the position of the last
                context.SetItem(last,temp);
                back.Add(last);
            }
            //remove turn from the level
            context.SetItem(pos,null);
            return back.ToArray();
        }
        /// <summary>
        /// Bring all gems down. 
        /// </summary>
        /// <param name="updateHorizontalArray">Update horizontal array.</param>
        private GemMove[] FallingDown(int[] updateHorizontalArray)
        {
            int width = updateHorizontalArray.Length;
            List<IntVector2> fallingBlocksStart = new List<IntVector2>();
            List<IntVector2> fallingBlocksSEnd = new List<IntVector2>();

            for(int x = 0; x < width; x++){
                bool firstRun = true;
                if(updateHorizontalArray[x] !=-1){
                    // this column needs an update
                    int currentY = updateHorizontalArray[x];
                    bool somethingToMove = true;
                    while(currentY > -1 && somethingToMove){
                        somethingToMove = false;
                        //if there is a item now we can start one item up
                        if(level.GetItem(new IntVector2(x,currentY)) != null){
                            currentY--;
                        }
                        // if there is space bring them all one down
                        for(int y = currentY-1; y >= 0; y--){
                            IntVector2 currentXY = new IntVector2(x,y+1);
                            IntVector2 currentXYTop = new IntVector2(x,y);
                            if(level.GetItem(currentXY) == null){
                                level.SetItem(currentXY, level.GetItem(currentXYTop));
                                if(level.GetItem(currentXYTop) != null){
                                    if(firstRun){
                                        fallingBlocksStart.Add(currentXYTop);
                                        fallingBlocksSEnd.Add(currentXY);
                                    }else{
                                        int pos = fallingBlocksSEnd.IndexOf(currentXYTop);
                                        if(pos != -1){
                                            fallingBlocksSEnd[pos] = currentXY;
                                        }else{
                                            string s = "try to move a not found object?\n";
                                            s += "Look for "+currentXYTop+"\n";
                                            for(int i = 0; i < fallingBlocksSEnd.Count; i++)
                                                s+= fallingBlocksSEnd[i].ToString() + ", ";
                                            Debug.LogWarning(s);
                                        }
                                }
                                }
                                level.SetItem(currentXYTop, null);
                            }
                        }
                        //if there are items over the currentY pos we need to loop more.
                        for(int y = currentY-1; y >= 0 && !somethingToMove; y--){
                            if(level.GetItem(new IntVector2(x,y+1)) != null)
                                somethingToMove = true;
                        }
                        firstRun = false;
                    }
                }
            }
            GemMove[] fallingMoves = new GemMove[fallingBlocksStart.Count];
            for(int i = 0; i < fallingMoves.Length; i++){
                fallingMoves[i].from = fallingBlocksStart[i];
                fallingMoves[i].to = fallingBlocksSEnd[i];
            }
            return fallingMoves;
        }
Example #3
0
        /// <summary>
        /// Returns an array of items to pop in a cross shape.
        /// </summary>
        /// <param name="pos">Position in the level</param>
        /// <param name="updateOnly">UpdateOnly is always false</param>
        /// <returns>Array of item position to pop</returns>
        public override IntVector2[] Activate(IntVector2 pos, out bool updateOnly)
        {
            updateOnly = false;
            IntVector2 leveSize = context.GetSize();
            IntVector2[] back = new IntVector2[leveSize.x + leveSize.y -1];

            back[0] = pos;
            int counter = 1;

            //Insert horizontal, without our own pos.
            for(int y = 0; y < pos.y; y++){
                back[counter++] = new IntVector2(pos.x, y);
            }
            for(int y = pos.y+1; y < leveSize.y; y++){
                back[counter++] = new IntVector2(pos.x, y);
            }

            //Insert vertical, without our own pos.
            for(int x = 0; x < pos.x; x++){
                back[counter++] = new IntVector2(x, pos.y);
            }
            for(int x = pos.x+1; x < leveSize.x; x++){
                back[counter++] = new IntVector2(x, pos.y);
            }

            return back;
        }
Example #4
0
 /// <summary>
 /// Initialize this Class
 /// </summary>
 public override void Awake()
 {
     base.Awake();
     spriteRenderer = GetComponent<SpriteRenderer>();
     startPos = new IntVector2((int)transform.position.x, (int)-transform.position.y);
     targetPos = startPos;
 }
Example #5
0
 /// <summary>
 /// Returns all item positions in the same group. 
 /// </summary>
 /// <param name="pos">Position in the level</param>
 /// <param name="updateOnly">UpdateOnly is always false.</param>
 /// <returns>Array of item position to pop.</returns>
 public override IntVector2[] Activate(IntVector2 pos, out bool updateOnly)
 {
     updateOnly = false;
     IntVector2[] groupEle = context.GetGroup(base.group);
     if(groupEle.Length >= context.GetMinimumPopCount())
         return groupEle;
     else
         return new IntVector2[0];
 }
Example #6
0
 /// <summary>
 /// Returns an area around the Bomb.
 /// </summary>
 /// <param name="pos">Position in the level</param>
 /// <param name="updateOnly">UpdateOnly is always false</param>
 /// <returns>Array of item position to pop.</returns>
 public override IntVector2[] Activate(IntVector2 pos, out bool updateOnly)
 {
     updateOnly = false;
     List<IntVector2> back = new List<IntVector2>();
     back.Add(pos);
     for(int i = 0; i < explosion.Length; i++){
         IntVector2 testPos = pos + explosion[i];
         if(context.IsInLevelBounce(pos + explosion[i]))
            back.Add(testPos);
     }
     return back.ToArray();
 }
        void OnGUI()
        {
            if(debug != DebugType.OFF){
                levelManger.SetPause(true);
                Vector3 topleft = Camera.main.WorldToScreenPoint(- new Vector3(0.5f,0.5f,0f));
                Vector3 buttomRight = Camera.main.WorldToScreenPoint(new Vector3(0.5f,0.5f,0f));
                float itemWidth = buttomRight.x - topleft.x;
                float itemHeight = buttomRight.y - topleft.y;
                topleft.y = Screen.height - topleft.y - itemHeight;
                IntVector2 size = level.GetSize();
                for(int y = 0; y < size.y; y++){
                    for(int x = 0; x < size.x; x++){
                        Gem g = level.GetItem(new IntVector2(x,y));
                        string text = "";
                        switch(debug){
                        case DebugType.ONE_DIM_PLUS_GROUPS:
                            text = new IntVector2(x,y).ToOneDim(size.x) +"\nG:"+ ((g != null)?g.group.ToString():"");
                            break;
                        case DebugType.TOW_DIM_PLUS_GROUPS:
                            text = x+","+y +"\nG:"+ ((g != null)?g.group.ToString():"");
                            break;
                        }

                        if(g != null && selecedGroup == g.group)
                            GUI.backgroundColor = Color.blue;
                        else
                            GUI.backgroundColor = Color.white;
                        if(GUI.Button(new Rect(topleft.x + (x * itemWidth), topleft.y + (y * itemHeight), itemWidth,itemHeight),text)){
                            Debug.Log(new IntVector2(x,y) + " = " + ((g!=null)?g.ToString():"null"));
                            if(g != null){
                                if(selecedGroup == g.group){
                                    selecedGroup = -1;
                                }else{
                                    selecedGroup = g.group;
                                }
                            }
                        }
                    }
                }
            }else{
                levelManger.SetPause(false);
            }
        }
Example #8
0
        /// <summary>
        /// Get the level from source.
        /// </summary>
        /// <param name="level">level</param>
        /// <param name="levelSize">levelSize of the level x = height y = wigth</param>
        public void GetLevel(out Gem[] level, out IntVector2 levelSize)
        {
            levelSize = new IntVector2(source.width, source.maxLinesOnScreen);
            level = new Gem[levelSize.x*levelSize.y];
            currentLines = new int[levelSize.x];

            //calc free lines
            int start = source.maxLinesOnScreen - source.linesOnStart;
            //convert in one dim array pos
            start = start * levelSize.x;

            int i = 0;
            for(; i < source.gems.Length && i < level.Length - start; i++){
                level[i + start] = GemFactory.GetGem(source.gems[i]);
            }

            start = i + 1;
            for(int j = 0; j < currentLines.Length; j++){
                currentLines[j] = source.linesOnStart;
            }
        }
Example #9
0
 /// <summary>
 /// What should happen if the Player click on the item.
 /// 
 /// If updateOnly is true after execution then the item edited
 /// the level by itself. 
 /// Otherwise the context need to pop the positions of the return
 /// array.
 /// In both cases the returned array contains the touched items.
 /// 
 /// For chain reaction types it's important that the first position
 /// in array are the item itself. Otherwise it is likely to create a
 /// endless loop.
 /// </summary>
 /// <param name="pos">Position in the level</param>
 /// <param name="updateOnly">UpdateOnly: false = context has to pop. Otherwise item thaking care by itself</param>
 /// <returns>Array of item position to pop or to update</returns>
 public abstract IntVector2[] Activate(IntVector2 pos, out bool updateOnly);
        /// <summary>
        /// Generate the level to view on start.
        /// </summary>
        /// <param name="level">level</param>
        /// <param name="levelSize">levelSize of the level x = height y = wigth</param>
        public void GetLevel(out Gem[] level, out IntVector2 levelSize)
        {
            levelSize = new IntVector2 (levelWidth, levelHeight);
            lineCache = new Gem[levelWidth];
            level = new Gem[levelWidth * levelHeight];

            for(int y = freeLines; y < levelHeight; y++){
                //read in last line
                Gem[] lastLine = new Gem[levelWidth];
                for(int x = 0; x < levelWidth; x++){
                    lastLine[x] = level[(y-1) * levelWidth + x];
                }
                //refill Cached Line
                FillLineCache(lastLine);
                //Fill in a hippo if needed
                if(y == freeLines && generateTarget){
                    lineCache[random.Next(0, levelWidth)] = new Target();
                }

                //copy the lineCache in the level and clear it
                for(int x = 0; x < levelWidth; x++){
                    level[y * levelWidth + x] = lineCache[x];
                    lineCache[x] = null;
                }
            }
        }
Example #11
0
 /// <summary>
 /// Set a two dimensional level.
 /// </summary>
 /// <param name="level">Level.</param>
 public void SetLevel(Gem[,] level)
 {
     bonus = 0;
     size = new IntVector2(level.GetLength(1), level.GetLength(0));
     items = new Gem[size.x * size.y];
     int i = 0;
     for(int y = 0; y < size.y; y++){
         for(int x = 0; x < size.x; x++){
             items[i++] = level[x,y];
             if(level[x,y] != null)
                 level[x,y].Init(this);
         }
     }
 }
Example #12
0
 /// <summary>
 /// Set a one dimensional level
 /// </summary>
 /// <param name="level">Level</param>
 /// <param name="size">Size of the level</param>
 public void SetLevel(Gem[] level, IntVector2 size)
 {
     bonus = 0;
     this.size = size;
     this.items = level;
     for(int i = 0; i < level.Length; i++){
         if(level[i] != null)
             level[i].Init(this);
     }
 }
Example #13
0
 /// <summary>
 /// Determines if this position is in the borders of this level.
 /// </summary>
 /// <returns>true</returns>
 /// <c>false</c>
 /// <param name="i">The index.</param>
 public bool IsInLevelBounce(IntVector2 i)
 {
     return i.x >= 0 && i.y >= 0 &&
         i.x < size.x && i.y < size.y;
 }
Example #14
0
 public void SetItem(IntVector2 pos, Gem g)
 {
     SetItem(pos.ToOneDim(size.x),g);
 }
Example #15
0
 /// <summary>
 /// Manhattan Distance calculated faster then Euclidean distance. 
 /// Also we expect Gems moving on the grid and not move 
 /// straight through the playing field.
 /// </summary>
 /// <param name="a">start pos</param>
 /// <param name="b">end pos</param>
 /// <returns>distance between them (number of fields to move)</returns>
 private int ManhattanDistance(IntVector2 a, IntVector2 b)
 {
     return Mathf.Abs(a.x-b.x)+ Mathf.Abs(a.y-b.y);
 }
Example #16
0
 /// <summary>
 /// Gets the item on x and y.
 /// </summary>
 /// <returns>The item.</returns>
 /// <param name="pos">Position in x and y.</param>
 public Gem GetItem(IntVector2 pos)
 {
     return GetItem(pos.ToOneDim(size.x));
 }
Example #17
0
 /// <summary>
 /// Play movement animation.
 /// Move Item from "current" to "target" in the time of "duration".
 /// This will simply push the GemVisuals around. It will nor update the element at the target position.
 /// </summary>
 /// <param name="current">position of the Gem that should move</param>
 /// <param name="target">position where is should move to</param>
 /// <param name="duration">The Time it has to execute the move</param>
 public void PlayGemAnimation(IntVector2 current, IntVector2 target, float duration)
 {
     visuals[current.x,current.y].MoveTo(target, duration);
 }
Example #18
0
 /// <summary>
 /// Handle when a player hit a gem to activate it.
 /// </summary>
 /// <returns><c>true</c>, when something has changed, <c>false</c> if not for example Player hits a free space.</returns>
 /// <param name="hitPos">Hit position.</param>
 private bool ExecuteHit(IntVector2 hitPos)
 {
     Gem g = level.GetItem(hitPos);
     if(g != null && g.IsPopabel()){
         bool updateOnly;
         IntVector2[] affected = g.Activate(hitPos, out updateOnly);
         if(affected.Length > 0){
             if(updateOnly){
                 //The item has taken care of the level by themself update only
                 for(int i = 0; i < affected.Length; i++){
                     Gem current = level.GetItem(affected[i]);
                     visuals.SetGem(affected[i], current);
                     if(current == null && updateHorizontalArray[affected[i].x] < affected[i].y){
                         updateHorizontalArray[affected[i].x] = affected[i].y;
                     }
                 }
             }else{
                 //The item returns a list of other items to pop.
                 for(int i = 0; i < affected.Length; i++){
                     Gem toPop = level.GetItem(affected[i]);
                     if(toPop != null){
                         if(toPop.chain){
                             if(hitPos == affected[i]){
                                 level.SetItem(affected[i], null);
                             }else{
                                 //in a chain reaction we recursive call this method.
                                 //this is the reason why the item must be the first in the line.
                                 //so it's consumed before some other item chain back in an endless loop.
                                 ExecuteHit(affected[i]);
                             }
                         }
                         if(toPop.Pop()){
                             level.SetItem(affected[i], null);
                         }
                     }
                     //save the lowest affected y position for the "physic engine"
                     if(updateHorizontalArray[affected[i].x] < affected[i].y){
                         updateHorizontalArray[affected[i].x] = affected[i].y;
                     }
                 }
             }
             return true;
         }
     }
     return false;
 }
Example #19
0
 /// <summary>
 /// Recreate the UI
 /// </summary>
 /// <param name="size">Size.</param>
 public void Recreate(IntVector2 size)
 {
     DestroyLevel();
     CreateLevel(size);
 }
Example #20
0
 /// <summary>
 /// Sets the gem visuals.
 /// </summary>
 /// <param name="pos">Position.</param>
 /// <param name="g">The Gem item.</param>
 public void SetGem(IntVector2 pos, Gem g)
 {
     visuals[pos.x,pos.y].Show(g);
 }
Example #21
0
 /// <summary>
 /// Simulate a movement to target position. In a specific time.
 /// </summary>
 /// <param name="targetPos">target position</param>
 /// <param name="animationDuration">time to complete the movement</param>
 public void MoveTo(IntVector2 targetPos, float animationDuration)
 {
     this.targetPos = targetPos;
     animationEndTime = Time.time + animationDuration;
     this.animationDuration = animationDuration;
 }
Example #22
0
        /// <summary>
        /// Creates the level.
        /// </summary>
        /// <param name="size">Size.</param>
        private void CreateLevel(IntVector2 size)
        {
            visuals = new IGemVisual[size.x,size.y+1];
            for(int y = 0; y < size.y+1; y++){
                for(int x = 0; x < size.x; x++){
                    GameObject c = (GameObject)GameObject.Instantiate(gemVisual,new Vector3(x,-y,0),Quaternion.identity);
                    c.transform.parent = transform;
                    visuals[x,y] = c.GetComponent<IGemVisual>();
                }
            }
            //Create an set the position of the new line switch Visual
            GameObject s = GameObject.Instantiate(switchVisual);
            switchV = (IHitable)s.GetComponent(typeof (IHitable));
            s.transform.position = new Vector3(-2,-size.y+0.5f,0);
            switchV.hitEvent += delegate(int x, int y) { if(newLineEvent != null) newLineEvent.Invoke();};

            //Set the cam on the center of the level
            Vector3 center = new Vector3(size.x / 2, - (size.y / 2), -10);
            gameCam.transform.position = center;

            //Change the size of the camera to fit level
            Vector3 topleft = - new Vector3(0.5f,-0.5f,0f);
            topleft = gameCam.WorldToViewportPoint(topleft);
            float maxV = Mathf.Max (topleft.x, topleft.y);
            gameCam.orthographicSize *= maxV + 0.125f;

            //Change the size of the time bars so they fit over the complite last line.
            timeIndicator.transform.position = new Vector3(-0.5f,-size.y,1);
            timeIndicator.GetChild(0).transform.localScale = new Vector3(size.x / 2 * 100,50,1);
            timeIndicator.GetChild(0).transform.localPosition = new Vector3(size.x / 2f,0,-5);
            timeIndicatorShadow.transform.localScale = new Vector3(size.x / 2 * 100,50,1);
            timeIndicatorShadow.transform.position = new Vector3(size.x / 2f - 0.5f,-size.y,-4);
        }
Example #23
0
 /// <summary>
 /// This method is called every frame.
 /// It's reasonable for the movement animation.
 /// if the target position is not same as the initial position 
 /// we will lerp between initial an target position depending on the animationDuration.
 /// </summary>
 public override void Update()
 {
     base.Update();
     if(targetPos != startPos){
         float lerpPos = animationEndTime - Time.time;
         lerpPos /= animationDuration;
         if(lerpPos >= 0){
             Vector3 pos = Vector3.Lerp(new Vector3(targetPos.x,-targetPos.y,0), new Vector3(startPos.x,-startPos.y,0),lerpPos);
             transform.position = pos;
         }else{
             targetPos = startPos;
         }
     }
 }
Example #24
0
		public GemMove(IntVector2 from, IntVector2 to){
			this.from = from;
			this.to = to;
		}
        /// <summary>
        /// Falling to the right.
        /// </summary>
        GemMove[] FallingRight()
        {
            IntVector2 size = level.GetSize();

            List<int> startXGround = new List<int>();
            List<int> endXGround = new List<int>();
            List<GemMove> moves = new List<GemMove>();

            //find large holes
            for(int x = 0; x < size.x; x++){
                //find the first empty space
                if(level.GetItem(new IntVector2(x,size.y-1)) == null){
                    startXGround.Add(x);
                    //if the next line is also empty we will move over it
                    for(int tx = x; tx < size.x; tx++){
                        if(level.GetItem(new IntVector2(tx,size.y-1)) == null){
                            x++;
                        }else{
                            endXGround.Add(x);
                            break;
                        }
                    }
                }
            }
            if(endXGround.Count < startXGround.Count){
                endXGround.Add(size.x);
            }
            //string s = "list";
            //for(int i = 0; i < startXGround.Count; i++){
            //	s += "("+(startXGround[i]-1) + "," +(endXGround[i]-1)+")";
            //}
            //Debug.Log(s);

            int targetX = size.x-1;
            int distance = 1;
            while(targetX-distance >= 0 && targetX >= 0){
                //if we know we have a hole we add this to move distance
                if(endXGround.Contains(targetX)){
                    int index = endXGround.IndexOf(targetX);
                    distance += (targetX - startXGround[index]) - 1;
                }
                if(level.GetItem(new IntVector2(targetX,size.y-1)) == null){
                    //the target pos could also be empty => then we have to move the item even more.
                    while(targetX-distance >= 0 && level.GetItem(new IntVector2(targetX-distance,size.y-1)) == null){
                        distance += 1;
                    }
                    if(targetX-distance >= 0){
                        for(int y = 0; y < size.y; y++){
                            IntVector2 from = new IntVector2(targetX-distance,y);
                            IntVector2 to = new IntVector2(targetX,y);
                            Gem currentGem = level.GetItem(from);
                            if(currentGem != null){
                                moves.Add(new GemMove(from, to));
                                level.SetItem(to, currentGem);
                                level.SetItem(from, null);
                            }
                        }
                    }
                }

                targetX--;
            }
            return moves.ToArray();
        }