Ejemplo n.º 1
0
    //-----------------------------------------------------------------------------------------------------
    // Try to find and clamp all pieces/groups
    public void TryToClampAllGroups()
    {
        if (enablePiecesGroups)
        {
            overlappedPieces.Clear();
            for (int i = 0; i < movedPieces.Count; i++)
            {
                currentObjectTransform = pieces[movedPieces[i]].transform;

                foreach (int movedPieceId in movedPieces)
                {
                    if (movedPieces[i] != movedPieceId)
                    {
                        if (currentObjectTransform.parent == thisTransform || (currentObjectTransform.parent != thisTransform && currentObjectTransform.parent != pieces[movedPieceId].transform.parent))
                        {
                            if (pieces[movedPieces[i]].renderer.bounds.Intersects(pieces[movedPieceId].renderer.bounds))
                            {
                                overlappedPieces.Add(pieces[movedPieceId]);
                            }
                        }
                    }
                }


                for (int j = 0; j < overlappedPieces.Count; j++)
                {
                    PuzzlePieceGroup.MergeGroupsOrPieces(pieces[movedPieces[i]], overlappedPieces[j], this);
                }
                overlappedPieces.Clear();
            }


            CreateUngroupedPiecesList();
        }
    }
Ejemplo n.º 2
0
    public void transferPieceTo(PuzzlePieceGroup target)
    {
        var pieces = GetComponentsInChildren <PuzzlePiece>();

        //轉移Child
        var targetTransform = target.transform;
        var transforms      = GetComponentsInChildren <Transform>();

        for (var i = 0; i < transforms.Length; i++)
        {
            var t = transforms[i];

            //排除自己
            if (t != transform)
            {
                t.parent = targetTransform;
            }
        }

        //記下Scale(因為進Pocket會改變Scale)

        foreach (var p in pieces)
        {
            p.memoryScale();
        }

        Destroy(gameObject);
    }
Ejemplo n.º 3
0
    //---------------------------------------------------------------------------------------------------------------------------------------------------
    // Return Group object if object or its paren is group
    public static GameObject GetGroupObjectIfPossible(GameObject _pieceOrGroupObject)
    {
        // Is it a Group
        PuzzlePieceGroup pieceGroup = _pieceOrGroupObject.GetComponent <PuzzlePieceGroup>();

        // Is it part of a Group
        if (pieceGroup == null)
        {
            if (_pieceOrGroupObject.transform.parent.GetComponent <PuzzlePieceGroup>() != null)
            {
                _pieceOrGroupObject = _pieceOrGroupObject.transform.parent.gameObject;
            }
        }

        return(_pieceOrGroupObject);
    }
Ejemplo n.º 4
0
    //-----------------------------------------------------------------------------------------------------
    // Process puzzle during gameplay (including user input)
    public PuzzleState ProcessPuzzle(Vector3 _pointerPosition, bool _dragInput, float _rotationDirection)
    {
        if (IsAssembled())
        {
            return(PuzzleState.PuzzleAssembled);
        }
        else
        {
            state = PuzzleState.None;
        }


        // Check is any piece clicked and get it Id
        if (_dragInput && currentPiece < 0)
        {
            _pointerPosition.z = 0;
            currentPiece       = GetPointedPieceId(_pointerPosition, true);

            if (currentPiece >= 0)
            {
                pieceCenterOffset = pieces[currentPiece].GetPieceCenterOffset();

                if (enablePiecesGroups)
                {
                    currentObject          = PuzzlePieceGroup.GetGroupObjectIfPossible(pieces[currentPiece].transform.gameObject);
                    currentObjectTransform = currentObject.transform;
                    currentGroup           = currentObject.GetComponent <PuzzlePieceGroup>();
                }
                else
                {
                    currentObject          = pieces[currentPiece].transform.gameObject;
                    currentObjectTransform = pieces[currentPiece].transform;
                }
                Debug.Log(currentObject.name);
                SpriteRenderer render = currentObject.GetComponent <SpriteRenderer>() as SpriteRenderer;

                render.drawMode = SpriteDrawMode.Sliced;
                render.size     = pieces[currentPiece].oldSize;
                pieces[currentPiece].transform.localScale = pieces[currentPiece].oldScale;
                if (!changeOnlyRotation)
                {
                    if (fullyIn3D)
                    {
                        currentObjectTransform.position = new Vector3(_pointerPosition.x - pieceCenterOffset.x, _pointerPosition.y - pieceCenterOffset.y, currentObjectTransform.position.z - dragOffsetZ);
                    }
                    else
                    {
                        currentObjectTransform.position = new Vector3(_pointerPosition.x - pieceCenterOffset.x, _pointerPosition.y - pieceCenterOffset.y, -dragOffsetZ);
                    }
                }

                state = PuzzleState.DragPiece;
            }
        }


        // If no piece is grabbed - RETURN
        if (currentObject == null)
        {
            return(PuzzleState.None);
        }


        // Pointer position offset for mobile
#if !UNITY_EDITOR && !UNITY_STANDALONE && !UNITY_WEBPLAYER && !UNITY_WEBGL
        _pointerPosition.y += maxPieceSize.y * mobileDragOffsetY;
#else // for desktop
        if (changeOnlyRotation)
        {
            _rotationDirection = 1;
        }
#endif


        // Set currentObject center position  to pointerPosition
        if (!changeOnlyRotation)
        {
            currentObjectTransform.position = new Vector3(_pointerPosition.x - pieceCenterOffset.x, _pointerPosition.y - pieceCenterOffset.y, currentObjectTransform.position.z);
        }


        // If piece rotation requested(by RMB or 2 touched) and possible - rotate piece around Z-axis
        if (_rotationDirection != 0 && randomizeRotation)
        {
            pieceCenterOffset = pieces[currentPiece].GetPieceCenterOffset();
            currentObjectTransform.RotateAround(pieces[currentPiece].renderer.bounds.center, Vector3.forward, _rotationDirection * rotationSpeed * Time.deltaTime);

            state = PuzzleState.RotatePiece;
        }


        // Tilt piece according to movement direction if needed
        if (dragTiltSpeed > 0)
        {
            currentObjectTransform.localRotation = new Quaternion(
                Mathf.Lerp(currentObjectTransform.localRotation.x, (oldPointerPosition.y - _pointerPosition.y) * dragTiltSpeed, Time.deltaTime),
                Mathf.Lerp(currentObjectTransform.localRotation.y, (oldPointerPosition.x - _pointerPosition.x) * dragTiltSpeed, Time.deltaTime),
                currentObjectTransform.localRotation.z,
                currentObjectTransform.localRotation.w
                );
            oldPointerPosition = _pointerPosition;
        }



        // Drop piece and assemble it to puzzle (if it close enough to it initial position/rotation)
        if (!_dragInput)
        {
            currentObjectTransform.localRotation = new Quaternion(0, 0, currentObjectTransform.localRotation.z, currentObjectTransform.localRotation.w); //Removes the tilt effect
            if (!changeOnlyRotation)
            {
                currentObjectTransform.position = new Vector3(currentObjectTransform.position.x, currentObjectTransform.position.y, currentObjectTransform.position.z + dragOffsetZ);
            }

            // Process groups if needed
            //if (enablePiecesGroups)
            //{
            //    bool grouping = false;

            //    // Get list of all pieces overlapped by currentPiece
            //    foreach (int movedPieceId in movedPieces)
            //        if (movedPieceId != currentPiece)
            //            if (currentGroup != null) // if dropped a group
            //            {
            //                if (pieces[movedPieceId].transform.parent != currentGroup.transform)
            //                    foreach (PuzzlePiece groupPiece in currentGroup.puzzlePieces)
            //                        if (groupPiece.renderer.bounds.Intersects(pieces[movedPieceId].renderer.bounds))
            //                            overlappedPieces.Add(pieces[movedPieceId]);
            //            }
            //            else  // if dropped a piece
            //                if (pieces[currentPiece].renderer.bounds.Intersects(pieces[movedPieceId].renderer.bounds))
            //                overlappedPieces.Add(pieces[movedPieceId]);

            //    // Try to merge overlapped pieces to groups
            //    for (int i = 0; i < overlappedPieces.Count; i++)
            //        grouping |= PuzzlePieceGroup.MergeGroupsOrPieces(pieces[currentPiece], overlappedPieces[i], this);
            //    overlappedPieces.Clear();

            //    if (grouping)
            //    {
            //        UpdateUngroupedPiecesList();
            //        state = PuzzleState.DropPiece;
            //    }


            //    // Assemble grouped pieces to puzzle
            //    if (currentGroup != null)
            //    {
            //        if (IsPieceInPlace(currentGroup.puzzlePieces[0], allowedDistance, allowedRotation) || (invertedRules && !IsPieceInPlace(currentGroup.puzzlePieces[0], allowedDistance, allowedRotation)))
            //        {
            //            int groupPieceId;

            //            foreach (PuzzlePiece groupPiece in currentGroup.puzzlePieces)
            //            {
            //                groupPiece.transform.parent = thisTransform;
            //                groupPieceId = GetPieceId(groupPiece);

            //                if (invertedRules)
            //                    movedPieces.Remove(groupPieceId);
            //                else
            //                    ReturnPiece(groupPieceId, movementTime);

            //            }
            //            Destroy(currentGroup.gameObject);

            //            state = PuzzleState.ReturnPiece;
            //        }
            //        else // Just drop it
            //            state = PuzzleState.DropPiece;
            //    }

            //}

            //Assemble ungrouped piece to puzzle
            if (currentGroup == null)
            {
                if (IsPieceInPlace(currentPiece, allowedDistance, allowedRotation) || (invertedRules && !IsPieceInPlace(currentPiece, allowedDistance, allowedRotation)))
                {
                    if (invertedRules)
                    {
                        movedPieces.Remove(currentPiece);
                    }
                    else
                    {
                        ReturnPiece(currentPiece, movementTime);
                    }

                    pieces[currentPiece].spriteRenderer.drawMode = SpriteDrawMode.Tiled;
                    pieces[currentPiece].spriteRenderer.size     = pieces[currentPiece].oldSize;
                    pieces[currentPiece].spriteRenderer.drawMode = SpriteDrawMode.Simple;

                    pieces[currentPiece].transform.localScale = pieces[currentPiece].oldScale;
                    GameManager.Instance.numberPiece         -= 1;
                    // khi gắn xong mảnh thì trừ biến đếm đi 1, nếu hết 4 mảnh thì active các mảnh còn lại
                    if (GameManager.Instance.numberPiece <= 0)
                    {
                        ActivePiece();
                    }
                    state = PuzzleState.ReturnPiece;
                }
                else // Just drop it
                {// tra ve vi tri ban dau
                    currentObjectTransform.position = pieces[currentPiece].targetPosition;
                    pieces[currentPiece].spriteRenderer.drawMode = SpriteDrawMode.Tiled;
                    pieces[currentPiece].spriteRenderer.size     = new Vector3(1, 1, 1);
                    pieces[currentPiece].spriteRenderer.drawMode = SpriteDrawMode.Simple;
                    pieces[currentPiece].transform.localScale    = GameManager.Instance.getSizePieceFake();

                    state = PuzzleState.DropPiece;
                }
            }



            currentObject = null;
            currentPiece  = -1;
        }


        return(state);
    }
Ejemplo n.º 5
0
    public void merge(HashSet <IPuzzleLayer> set, PuzzlePieceGroup group)
    {
        var layerManager = LayerMananger.GetInstance();
        var layers       = new List <IPuzzleLayer>(set);

        // print("before sort");
        // foreach (var e in layers)
        //     print(e.GetLayerIndex());

        // 從depth小排到大
        layers.Sort((a, b) =>
        {
            return(a.GetLayerIndex() - b.GetLayerIndex());
        });

        // print("after sort");
        // foreach (var e in layers)
        //     print(e.GetLayerIndex());

        // 取出含有最多piece的Layer,把所有piece都給它
        var theChosenOne = layers[0];

        // 全部set都只有1塊piece
        if (theChosenOne.GetPiecesCount() == 1)
        {
            var p = theChosenOne as PuzzlePiece;

            // 建立connectedSet,全部piece都加進來
            var cs = group.createConnectedSet(p);
            for (var i = layers.Count - 1; i >= 0; --i) //從最上層開始
            {
                var L = layers[i];
                cs.add(L as PuzzlePiece);
                layerManager.remove(L);
            }

            layerManager.add(cs);
            return;
        }

        var nowCS = theChosenOne as ConnectedSet;

        // 把其他piece都加進來
        for (var i = layers.Count - 1; i >= 1; --i) //從最上層開始
        {
            var L = layers[i];

            if (L.GetPiecesCount() == 1)
            {
                nowCS.add(L as PuzzlePiece);
                layerManager.remove(L);
            }
            else
            {
                var cs = L as ConnectedSet;
                nowCS.add(cs);
                layerManager.remove(L);
                Object.Destroy(cs.gameObject);//刪除connectedSet
            }
        }
        layerManager.update(theChosenOne);
    }
Ejemplo n.º 6
0
    //---------------------------------------------------------------------------------------------------------------------------------------------------
    // Main function to process grouping pieces and clamping groups
    public static bool MergeGroupsOrPieces(PuzzlePiece _puzzlePiece1, PuzzlePiece _puzzlePiece2, PuzzleController _puzzleController)
    {
        GameObject object1 = _puzzlePiece1.transform.gameObject;
        GameObject object2 = _puzzlePiece2.transform.gameObject;


        //Convert to group if it's not a single piece
        object1 = GetGroupObjectIfPossible(object1);
        object2 = GetGroupObjectIfPossible(object2);

        if (object1 == object2)
        {
            return(false);
        }

        // Get groups
        PuzzlePieceGroup pieceGroup1 = object1.GetComponent <PuzzlePieceGroup>();
        PuzzlePieceGroup pieceGroup2 = object2.GetComponent <PuzzlePieceGroup>();


        //// If both objects non-grouped
        if (pieceGroup1 == null && pieceGroup2 == null)
        {
            bool clamped = TryClampPieces(_puzzlePiece1, _puzzlePiece2, _puzzleController);

            // Create new group
            if (clamped)
            {
                GameObject pieceGroupObject = new GameObject("_PieceGroup".ToString());
                pieceGroupObject.transform.parent = _puzzleController.transform;
                PuzzlePieceGroup pieceGroup = pieceGroupObject.AddComponent <PuzzlePieceGroup>();

                // Include pieces in the group
                pieceGroup.AddNewPiece(_puzzlePiece1);
                pieceGroup.AddNewPiece(_puzzlePiece2);

                pieceGroup.RecalculateCenterAndTransformGroup();
            }

            return(clamped);
        }
        else          //// If both objects are groups
        if (pieceGroup1 != null && pieceGroup2 != null)
        {
            foreach (PuzzlePiece puzzlePiece1 in pieceGroup1.puzzlePieces)
            {
                foreach (PuzzlePiece puzzlePiece2 in pieceGroup2.puzzlePieces)
                {
                    if (TryClampPieces(puzzlePiece1, puzzlePiece2, _puzzleController))
                    {
                        // Move pieces to one group
                        foreach (PuzzlePiece puzzlePiece in pieceGroup2.puzzlePieces)
                        {
                            pieceGroup1.AddNewPiece(puzzlePiece);
                        }

                        pieceGroup1.RecalculateCenterAndTransformGroup();
                        Destroy(pieceGroup2.gameObject);

                        return(true);
                    }
                }
            }
        }
        else                  //// One object is a group and another is non-grouped piece
        {
            PuzzlePieceGroup pieceGroup;
            PuzzlePiece      puzzlePiece;

            // Figure out which object is group/single piece
            if (pieceGroup1 == null)
            {
                pieceGroup  = pieceGroup2;
                puzzlePiece = _puzzlePiece1;
            }
            else
            {
                pieceGroup  = pieceGroup1;
                puzzlePiece = _puzzlePiece2;
            }

            // Try to clamp each piece in group with the single piece
            for (int i = 0; i < pieceGroup.puzzlePieces.Count; ++i)
            {
                if (TryClampPieces(puzzlePiece, pieceGroup.puzzlePieces[i], _puzzleController))
                {
                    pieceGroup.AddNewPiece(puzzlePiece);
                    pieceGroup.RecalculateCenterAndTransformGroup();

                    return(true);
                }
            }
        }


        return(false);
    }
Ejemplo n.º 7
0
    // Process puzzle during gameplay (including user input)
    public PuzzleState ProcessPuzzle(Vector3 _pointerPosition, bool _dragInput, float _rotationDirection)
    {
        if (IsAssembled())
        {
            return(PuzzleState.PuzzleAssembled);
        }
        else
        {
            state = PuzzleState.None;
        }

        // Check is any piece clicked and get it Id
        if (_dragInput && currentPiece < 0)
        {
            _pointerPosition.z = 0;
            currentPiece       = GetPointedPieceId(_pointerPosition, true);

            if (currentPiece >= 0)
            {
                pieceCenterOffset = pieces[currentPiece].GetPieceCenterOffset();

                if (EnablePiecesGroups)
                {
                    currentObject          = PuzzlePieceGroup.GetGroupObjectIfPossible(pieces[currentPiece].Transform.gameObject);
                    currentObjectTransform = currentObject.transform;
                    currentGroup           = currentObject.GetComponent <PuzzlePieceGroup>();
                }
                else
                {
                    currentObject          = pieces[currentPiece].Transform.gameObject;
                    currentObjectTransform = pieces[currentPiece].Transform;
                }

                if (!ChangeOnlyRotation)
                {
                    if (FullyIn3D)
                    {
                        currentObjectTransform.position = new Vector3(_pointerPosition.x - pieceCenterOffset.x, _pointerPosition.y - pieceCenterOffset.y, currentObjectTransform.position.z - dragOffsetZ);
                    }
                    else
                    {
                        currentObjectTransform.position = new Vector3(_pointerPosition.x - pieceCenterOffset.x, _pointerPosition.y - pieceCenterOffset.y, -dragOffsetZ);
                    }
                }

                state = PuzzleState.DragPiece;
            }
        }

        // If no piece is grabbed - RETURN
        if (currentObject == null)
        {
            return(PuzzleState.None);
        }

        // Pointer position offset for mobile
#if !UNITY_EDITOR && !UNITY_STANDALONE && !UNITY_WEBPLAYER && !UNITY_WEBGL
        _pointerPosition.y += maxPieceSize.y * mobileDragOffsetY;
#else // for desktop
        if (ChangeOnlyRotation)
        {
            _rotationDirection = 1;
        }
#endif


        // Set currentObject center position  to pointerPosition
        if (!ChangeOnlyRotation)
        {
            currentObjectTransform.position = new Vector3(_pointerPosition.x - pieceCenterOffset.x, _pointerPosition.y - pieceCenterOffset.y, currentObjectTransform.position.z);
        }


        // If piece rotation requested(by RMB or 2 touched) and possible - rotate piece around Z-axis
        if (_rotationDirection != 0 && RandomizeRotation)
        {
            pieceCenterOffset = pieces[currentPiece].GetPieceCenterOffset();
            currentObjectTransform.RotateAround(pieces[currentPiece].Renderer.bounds.center, Vector3.forward, _rotationDirection * rotationSpeed * Time.deltaTime);

            state = PuzzleState.RotatePiece;
        }


        // Tilt piece according to movement direction if needed
        if (dragTiltSpeed > 0)
        {
            currentObjectTransform.localRotation = new Quaternion(
                Mathf.Lerp(currentObjectTransform.localRotation.x, (oldPointerPosition.y - _pointerPosition.y) * dragTiltSpeed, Time.deltaTime),
                Mathf.Lerp(currentObjectTransform.localRotation.y, (oldPointerPosition.x - _pointerPosition.x) * dragTiltSpeed, Time.deltaTime),
                currentObjectTransform.localRotation.z,
                currentObjectTransform.localRotation.w
                );
            oldPointerPosition = _pointerPosition;
        }



        // Drop piece and assemble it to puzzle (if it close enough to it initial position/rotation)
        if (!_dragInput)
        {
            currentObjectTransform.localRotation = new Quaternion(0, 0, currentObjectTransform.localRotation.z, currentObjectTransform.localRotation.w); //Removes the tilt effect
            if (!ChangeOnlyRotation)
            {
                currentObjectTransform.position = new Vector3(currentObjectTransform.position.x, currentObjectTransform.position.y, currentObjectTransform.position.z + dragOffsetZ);
            }

            // Process groups if needed
            if (EnablePiecesGroups)
            {
                bool grouping = false;

                // Get list of all pieces overlapped by currentPiece
                foreach (int movedPieceId in movedPieces)
                {
                    if (movedPieceId != currentPiece)
                    {
                        if (currentGroup != null) // if dropped a group
                        {
                            if (pieces[movedPieceId].Transform.parent != currentGroup.transform)
                            {
                                foreach (PuzzlePiece groupPiece in currentGroup.puzzlePieces)
                                {
                                    if (groupPiece.Renderer.bounds.Intersects(pieces[movedPieceId].Renderer.bounds))
                                    {
                                        overlappedPieces.Add(pieces[movedPieceId]);
                                    }
                                }
                            }
                        }
                        else  // if dropped a piece
                        if (pieces[currentPiece].Renderer.bounds.Intersects(pieces[movedPieceId].Renderer.bounds))
                        {
                            overlappedPieces.Add(pieces[movedPieceId]);
                        }
                    }
                }

                // Try to merge overlapped pieces to groups
                for (int i = 0; i < overlappedPieces.Count; i++)
                {
                    grouping |= PuzzlePieceGroup.MergeGroupsOrPieces(pieces[currentPiece], overlappedPieces[i], this);
                }
                overlappedPieces.Clear();

                if (grouping)
                {
                    UpdateUngroupedPiecesList();
                    state = PuzzleState.DropPiece;
                }


                // Assemble grouped pieces to puzzle
                if (currentGroup != null)
                {
                    if (IsPieceInPlace(currentGroup.puzzlePieces[0], allowedDistance, allowedRotation) || (invertedRules && !IsPieceInPlace(currentGroup.puzzlePieces[0], allowedDistance, allowedRotation)))
                    {
                        int groupPieceId;

                        foreach (PuzzlePiece groupPiece in currentGroup.puzzlePieces)
                        {
                            groupPiece.Transform.parent = thisTransform;
                            groupPieceId = GetPieceId(groupPiece);

                            if (invertedRules)
                            {
                                movedPieces.Remove(groupPieceId);
                            }
                            else
                            {
                                ReturnPiece(groupPieceId, movementTime);
                            }
                        }
                        Destroy(currentGroup.gameObject);

                        state = PuzzleState.ReturnPiece;
                    }
                    else // Just drop it
                    {
                        state = PuzzleState.DropPiece;
                    }
                }
            }

            //Assemble ungrouped piece to puzzle
            if (currentGroup == null)
            {
                if (IsPieceInPlace(currentPiece, allowedDistance, allowedRotation) || (invertedRules && !IsPieceInPlace(currentPiece, allowedDistance, allowedRotation)))
                {
                    if (invertedRules)
                    {
                        movedPieces.Remove(currentPiece);
                    }
                    else
                    {
                        ReturnPiece(currentPiece, movementTime);
                    }

                    state = PuzzleState.ReturnPiece;
                }
                else // Just drop it
                {
                    state = PuzzleState.DropPiece;
                }
            }



            currentObject = null;
            currentPiece  = -1;
        }


        return(state);
    }
Ejemplo n.º 8
0
    void GeneratePieceGroupAndTransferPiece(Vector3 pos, Vector3 scale, Vector2 uvScaleFactor, Vector2 uvOffsetFactor, PuzzlePieceGroup target)
    {
        var group = GameObject.Instantiate <PuzzlePieceGroup>(puzzlePieceGroup, pos, rot);

        group.transform.localScale = scale;
        group.setPieceTexture(Bootstrap.getInstance().GetMaterial().mainTexture);
        group.resetPieceUV(uvScaleFactor, uvOffsetFactor);
        group.transferPieceTo(target);
    }