using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.U2D;
public class AtlasManager : MonoBehaviour
{
public static AtlasManager instance;
public SpriteAtlas blockAtlas;
//싱글톤
private void Awake()
{
//AtlasManager 클래스의 인스턴스를 instance에 할당
instance = this;
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.U2D;
using Random = UnityEngine.Random;
public class Test : MonoBehaviour
{
public Board board;
private void Start()
{
board.CreateBoard();
}
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
Debug.DrawRay(ray.origin, ray.direction * 100f, Color.red, 1);
RaycastHit2D raycastHit2D = Physics2D.Raycast(ray.origin, ray.direction);
if (raycastHit2D.collider != null)
{
Block block = raycastHit2D.collider.GetComponent<Block>();
Debug.Log($"[{block.row}, {block.col}] ({block.transform.position.x}, {block.transform.position.y}), {block.blockType}");
}
}
}
}
using Codice.Client.BaseCommands.Filters;
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEditor;
using UnityEngine;
public class BlockSwapWindow : EditorWindow
{
private int row1;
private int col1;
private int row2;
private int col2;
[MenuItem("Window/Block Swap Window")]
public static void ShowWindow()
{
GetWindow<BlockSwapWindow>("Block Swap Window");
}
private void OnGUI()
{
GUILayout.Label("Swap Blocks", EditorStyles.boldLabel);
row1 = EditorGUILayout.IntField("Row 1", row1);
col1 = EditorGUILayout.IntField("Column 1", col1);
row2 = EditorGUILayout.IntField("Row 2", row2);
col2 = EditorGUILayout.IntField("Column 2", col2);
//버튼 UI추가
if (GUILayout.Button("Swap"))
{
Board.instance.SwapBlocks(row1, col1, row2, col2);
Debug.Log($"Swapped blocks at [{row1}, {col1} ane [{row2}, {col2}]");
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(Block))]
public class BlockEditor : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
Block block = target as Block;
if (GUILayout.Button("제거"))
{
Debug.Log($"[{block.row},{block.col}]을 제거 합니다.");
Board.instance.RemoveBlock(block.row, block.col);
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using Random = UnityEngine.Random;
public class Board : MonoBehaviour
{
public static Board instance;// 싱글톤
private Block[,] board; //2차원 배열이 Block들을 관리
public GameObject blockPrefab;
private int[] arrEmptySpaceCol;
public int totalHeight = 10;
public int height = 5;
public int width = 9;
private void Awake()
{
instance = this;
}
public void CreateBoard()
{
//크기가 9인 BlockType의 2차원 배열 만들기
board = new Block[totalHeight, width]; // 2차원 배열로 변경
//5행 9열의 Block타입의 2차원 배열 만들기
for (int i = 0; i < height; i++) //board.GetLength(0)
{
for (int j = 0; j < width; j++) //board.GetLength(1)
{
CreateBlock(i, j);
}
}
PrintBoard();
}
public void CreateBlock(int row, int col)
{
Vector2 pos = new Vector2(col, row);
Block.BlockType blockType = (Block.BlockType)Random.Range(0, 5);
GameObject blockGo = Instantiate(blockPrefab);
Block block = blockGo.GetComponent<Block>();
block.Init(blockType);
block.SetPosition(pos);
//배열의 요소에 블록 넣기
board[row, col] = block;
}
public void RemoveBlock(int row, int col)
{
Block block = board[row, col];
Destroy(block.gameObject); //게임 오브젝트 파괴
//배열의 요소를 비워줌
board[row, col] = null;
}
public void PrintBoard()
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < height; i++) //행
{
for (int j = 0; j < width; j++) //열
{
Block block = board[i, j];
string strElement = (block == null) ? "null" : block.blockType.ToString();
// 각 엘리먼트를 고정된 너비로 출력
sb.AppendFormat("[{0},{1}] = {2,-11}", i, j, strElement);
}
sb.AppendLine();
}
Debug.Log(sb.ToString());
}
public void FindEmptySpaceFromColumn()
{
arrEmptySpaceCol = new int[width]; //배열 초기화
for (int i = 0; i < width; i++) //열
{
int existBlockCnt = 0;
for (int j = 0; j < totalHeight; j++) //행
{
Block block = board[j, i];
if (block != null)
{
existBlockCnt++;
}
}
int emptySpace = height - existBlockCnt;
arrEmptySpaceCol[i] = emptySpace; // 배열의 인덱스(열)에 emptySpace(카운트)값 할당 => 각 열마다 빈공간의 개수
Debug.Log($"{i}열의 빈공간은 {emptySpace}개 입니다.");
}
}
public void CreateNewBlocks()
{
if (arrEmptySpaceCol == null || arrEmptySpaceCol.All(x => x == 0))
{
Debug.Log("빈 공간이 없습니다.");
}
else
{
for (int i = 0; i < arrEmptySpaceCol.Length; i++)
{
int cnt = arrEmptySpaceCol[i];
if (cnt > 0)
{
Debug.Log($"{i}열에 {cnt}만큼 블록 생성 필요");
CreateBlockFromColumn(i, cnt);
}
}
}
arrEmptySpaceCol = null;
}
private void CreateBlockFromColumn(int col, int cnt)
{
int startRow = height; //행
for (int i = 0; i < cnt; i++)
{
//[7, col] -> [8, col] -> [9, col]
CreateBlock(startRow, col);
startRow++;
}
}
public void MoveAllBlocksInRow(int row)
{
if (row == 0)
{
Debug.Log("가장 아래 있는 행 입니다. (이동불가)");
return;
}
int numberOfBlocksToMove = 0;
for (int col = 0; col < width; col++)
{
int targetRow = row - 1;
Block fromBlock = board[row, col];
Block toBlock = board[targetRow, col];
string strFromBlock = (fromBlock == null) ? "비어있음" : fromBlock.ToString();
string strToBlock = (toBlock == null) ? "비어있음" : toBlock.ToString();
if (fromBlock != null && toBlock == null)
{
//이동가능
Debug.Log($"[{row},{col}] {strFromBlock} -> [{targetRow}, {col} {strToBlock}]으로 이동합니다");
numberOfBlocksToMove++;
}
else
{
//이동 불가능
}
}
if (numberOfBlocksToMove == 0)
{
Debug.Log($"{row} 행의 이동 블록이 업습니다.");
}
else
{
Debug.Log($"{row}행의 이동해야 할 블록이 {numberOfBlocksToMove}개 있습니다.");
}
}
public void SwapBlocks(int row1, int col1, int row2, int col2)
{
if (board[row1, col1] == null && board[row2, col2] == null)
{
Debug.LogError($"[{row1}, {col1}]와 [{row2}, {col2}]가 모두 비어 있습니다. (스왑 실패)");
return;
}
//위치 가져오기
Vector2 fromPos = Block.Index2Position(row1, col1);
Vector2 toPos = Block.Index2Position(row2, col2);
//데이터 변경
Block temp = board[row1, col1];
board[row1, col1] = board[row2, col2];
board[row2, col2] = temp;
//비주얼 이동
if (board[row1, col1] != null)
board[row1, col1].SetPosition(fromPos);
if (board[row2, col2] != null)
board[row2, col2].SetPosition(toPos);
Debug.Log($"Swapped blocks at [{row1}, {col1}] and [{row2}, {col2}]");
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using Random = UnityEngine.Random;
public class Board : MonoBehaviour
{
public static Board instance;// 싱글톤
private Block[,] board; //2차원 배열이 Block들을 관리
public GameObject blockPrefab;
private int[] arrEmptySpaceCol;
public int totalHeight = 10;
public int height = 5;
public int width = 9;
private void Awake()
{
instance = this;
}
public void CreateBoard()
{
//크기가 9인 BlockType의 2차원 배열 만들기
board = new Block[totalHeight, width]; // 2차원 배열로 변경
//5행 9열의 Block타입의 2차원 배열 만들기
for (int i = 0; i < height; i++) //board.GetLength(0)
{
for (int j = 0; j < width; j++) //board.GetLength(1)
{
CreateBlock(i, j);
}
}
PrintBoard();
}
public void CreateBlock(int row, int col)
{
Vector2 pos = new Vector2(col, row);
Block.BlockType blockType = (Block.BlockType)Random.Range(0, 5);
GameObject blockGo = Instantiate(blockPrefab);
Block block = blockGo.GetComponent<Block>();
block.Init(blockType);
block.SetPosition(pos);
//배열의 요소에 블록 넣기
board[row, col] = block;
}
public void RemoveBlock(int row, int col)
{
Block block = board[row, col];
Destroy(block.gameObject); //게임 오브젝트 파괴
//배열의 요소를 비워줌
board[row, col] = null;
}
public void PrintBoard()
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < height; i++) //행
{
for (int j = 0; j < width; j++) //열
{
Block block = board[i, j];
string strElement = (block == null) ? "null" : block.blockType.ToString();
// 각 엘리먼트를 고정된 너비로 출력
sb.AppendFormat("[{0},{1}] = {2,-11}", i, j, strElement);
}
sb.AppendLine();
}
Debug.Log(sb.ToString());
}
public void FindEmptySpaceFromColumn()
{
arrEmptySpaceCol = new int[width]; //배열 초기화
for (int i = 0; i < width; i++) //열
{
int existBlockCnt = 0;
for (int j = 0; j < totalHeight; j++) //행
{
Block block = board[j, i];
if (block != null)
{
existBlockCnt++;
}
}
int emptySpace = height - existBlockCnt;
arrEmptySpaceCol[i] = emptySpace; // 배열의 인덱스(열)에 emptySpace(카운트)값 할당 => 각 열마다 빈공간의 개수
Debug.Log($"{i}열의 빈공간은 {emptySpace}개 입니다.");
}
}
public void CreateNewBlocks()
{
if (arrEmptySpaceCol == null || arrEmptySpaceCol.All(x => x == 0))
{
Debug.Log("빈 공간이 없습니다.");
}
else
{
for (int i = 0; i < arrEmptySpaceCol.Length; i++)
{
int cnt = arrEmptySpaceCol[i];
if (cnt > 0)
{
Debug.Log($"{i}열에 {cnt}만큼 블록 생성 필요");
CreateBlockFromColumn(i, cnt);
}
}
}
arrEmptySpaceCol = null;
}
private void CreateBlockFromColumn(int col, int cnt)
{
int startRow = height; //행
for (int i = 0; i < cnt; i++)
{
//[7, col] -> [8, col] -> [9, col]
CreateBlock(startRow, col);
startRow++;
}
}
public void MoveAllBlocksInRow(int row)
{
if (row == 0)
{
Debug.Log("가장 아래 있는 행 입니다. (이동불가)");
return;
}
int numberOfBlocksToMove = 0;
for (int col = 0; col < width; col++)
{
int targetRow = row - 1;
Block fromBlock = board[row, col];
Block toBlock = board[targetRow, col];
string strFromBlock = (fromBlock == null) ? "비어있음" : fromBlock.ToString();
string strToBlock = (toBlock == null) ? "비어있음" : toBlock.ToString();
if (fromBlock != null && toBlock == null)
{
//이동가능
Debug.Log($"[{row},{col}] {strFromBlock} -> [{targetRow}, {col} {strToBlock}]으로 이동합니다");
numberOfBlocksToMove++;
}
else
{
//이동 불가능
}
}
if (numberOfBlocksToMove == 0)
{
Debug.Log($"{row} 행의 이동 블록이 업습니다.");
}
else
{
Debug.Log($"{row}행의 이동해야 할 블록이 {numberOfBlocksToMove}개 있습니다.");
}
}
public void SwapBlocks(int row1, int col1, int row2, int col2)
{
if (board[row1, col1] == null && board[row2, col2] == null)
{
Debug.LogError($"[{row1}, {col1}]와 [{row2}, {col2}]가 모두 비어 있습니다. (스왑 실패)");
return;
}
//위치 가져오기
Vector2 fromPos = Block.Index2Position(row1, col1);
Vector2 toPos = Block.Index2Position(row2, col2);
//데이터 변경
Block temp = board[row1, col1];
board[row1, col1] = board[row2, col2];
board[row2, col2] = temp;
//비주얼 이동
if (board[row1, col1] != null)
board[row1, col1].SetPosition(fromPos);
if (board[row2, col2] != null)
board[row2, col2].SetPosition(toPos);
Debug.Log($"Swapped blocks at [{row1}, {col1}] and [{row2}, {col2}]");
}
}
using System.Collections;
using System.Collections.Generic;
using TMPro;
using Unity.Mathematics;
using UnityEngine;
public class Block : MonoBehaviour
{
public enum BlockType
{
Blue, Gray, Green, Pink, Yellow
}
public BlockType blockType;
public SpriteRenderer spriteRenderer;
public TMP_Text debugText;
public int row;
public int col;
public void Init(BlockType blockType)
{
this.blockType = blockType;
//이미지 변경
ChangeSprite(blockType);
}
public void ChangeSprite(BlockType blockType)
{
//블록의 이름을 넣어서 아틀라스에서 같은 이름인 sprite를 찾고 할당
Sprite sp =
AtlasManager.instance.blockAtlas.GetSprite(blockType.ToString());
spriteRenderer.sprite = sp;
}
public void SetPosition(Vector2 pos)
{
transform.position = pos;
var index = Position2Index(pos);
row = index.row;
col = index.col;
debugText.text = $"[{index.row}, {index.col}]";
}
// 위치와 벡터 좌표가 다르기에 서로 교환가능하게 만들어주는 메소드
public static (int row, int col) Position2Index(Vector2 pos)
{
return ((int)pos.y, (int)pos.x);
}
public static (int x, int y) Index2Position(Vector2 index)
{
return ((int)index.x, (int)index.y);
}
public static Vector2 Position2Index(int posX, int posY)
{
return new Vector2((int)posY, (int)posX);
}
public static Vector2 Index2Position(int row, int col)
{
return new Vector2((int)col, (int)row);
}
}
'Solo > Puzzle' 카테고리의 다른 글
[3Match Puzzle] 스왑 메서드 만들기 (0) | 2024.06.20 |
---|---|
[3Match Puzzle] 스왑 Tool UI (0) | 2024.06.19 |
[3Match Puzzle] 각 행에 있는 모든 블록 내려보내기 버튼 생성 (0) | 2024.06.19 |
[3Match Puzzle] 각 열에 빈공간 찾기 로직 수 (0) | 2024.06.19 |
[3Match Puzzle] 빈공간에 해당하는 위치에 블록 생성하기 (0) | 2024.06.18 |