예제 #1
0
    private void CreateGrid()
    {
        // calculate pin spacing based on size of board and number of pins
        var space = new Vector2(pinsContainer.rect.width / gridSize.x, pinsContainer.rect.height / gridSize.y);

        // everything is centered around middle of game board so need an offset from that to start placing pins
        var offs = (pinsContainer.rect.size * -0.5f) + (space * 0.5f);

        // define the game board's grid (pins) and place initial tokens
        grid = new GameBoardPin[gridSize.x * gridSize.y];
        var idx = 0;

        for (int x = 0; x < gridSize.x; x++)
        {
            for (int y = 0; y < gridSize.y; y++)
            {
                var gridPos = new Vector2Int(x, y);

                // create and place the pin object
                var pinRt = Instantiate(pinFab, this.pinsContainer).GetComponent <RectTransform>();
                pinRt.anchoredPosition = offs + (space * gridPos);

                // create a token if there is a token in this position at start
                GameTokenDef def   = startTokens.FirstOrDefault(t => t.startPos == gridPos);
                GameToken    token = null;
                if (def != null)
                {
                    if (def.tokenColor >= 0 && def.tokenColor < tokenColours.Length)
                    {
                        token                     = Instantiate(tokenFab, tokensContainer).GetComponent <GameToken>();
                        token.TokenColor          = def.tokenColor;
                        token.image.color         = tokenColours[def.tokenColor];
                        token.Rt.anchoredPosition = pinRt.anchoredPosition;
                        token.PrevAnchorPos       = token.Rt.anchoredPosition;
                    }
                    else
                    {
                        Debug.LogError($"Invalid token colour: {def.tokenColor}. It must be in range 0..{tokenColours.Length-1}");
                    }
                }

                // initialize the grid position
                grid[idx] = new GameBoardPin
                {
                    pinRt = pinRt,
                    token = token,
                };

                idx++;
            }
        }
    }
예제 #2
0
    private void SnapTokenToPin(GameToken token)
    {
        // calculated from (token_size * minSnapFactor) to determine how close a token must be to pin before it will snap
        float minDistToSnap = minSnapFactor * token.Rt.rect.height;

        // find nearest open pin to the token
        float        dist = 0f;
        GameBoardPin pin  = null;

        for (int i = 0; i < gridSize.x * gridSize.y; i++)
        {
            var p = grid[i];
            if (p.token == null || p.token == token)             // open pin or the pin this token came from
            {
                var d = Vector2.Distance(p.pinRt.localPosition, token.Rt.localPosition);
                if (d <= minDistToSnap && (pin == null || d < dist))
                {
                    pin  = p;
                    dist = d;
                }
            }
        }

        // update token with new position in grid
        if (pin != null)
        {
            // remove token from old position in grid
            var p = grid.FirstOrDefault(g => g.token == token);
            if (p != null)
            {
                p.token = null;
            }
            else
            {
                Debug.LogError("This should not happen. There is a bug somewhere with tokens not being linked to pins/grid positions.");
            }

            // place it in new position
            pin.token = token;
            token.Rt.anchoredPosition = pin.pinRt.anchoredPosition;
            token.PrevAnchorPos       = token.Rt.anchoredPosition;
        }
        else
        {
            // snap back to previous position
            token.Rt.anchoredPosition = token.PrevAnchorPos;
        }
    }