Created
September 17, 2021 08:31
-
-
Save cacapon/81af7381fb2724a8a7bb6b5be57002ff to your computer and use it in GitHub Desktop.
倉庫番ゲーム部分の実装
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
using UnityEngine.Tilemaps; | |
public class Game : MonoBehaviour | |
{ | |
[SerializeField] private List<TileBase> tileBases; | |
[SerializeField] Tilemap Stage; | |
[SerializeField] AudioSource BGM; | |
[SerializeField] GameObject GameObj; | |
[SerializeField] GameObject MenuObj; | |
[SerializeField] GameObject ClearObject; | |
[SerializeField] GameObject Howto; | |
private static string gStageData; | |
private int gStageWidth; | |
private int gStageHeight; | |
public string StageName; | |
enum eStageData | |
{ | |
Wall, | |
Goal, | |
Object, | |
Player, | |
ObjectOnGoal, | |
PlayerOnGoal, | |
Space, | |
NewLine, | |
Unknown, | |
} | |
private eStageData[] state; | |
void Awake() | |
{ | |
Howto.SetActive(true); | |
} | |
public static int CountChar(string s, char c) | |
{ | |
return s.Length - s.Replace(c.ToString(), "").Length; | |
} | |
void OnEnable() | |
{ | |
BGM.Play(); | |
Initialize(); | |
} | |
private void Initialize() | |
{ | |
TextAsset textasset = new TextAsset(); //テキストファイルのデータを取得するインスタンスを作成 | |
textasset = Resources.Load(StageName, typeof(TextAsset)) as TextAsset; //Resourcesフォルダから対象テキストを取得 | |
gStageData = textasset.text; | |
gStageHeight = CountChar(gStageData, '\n') + 1; | |
gStageWidth = gStageData.IndexOf("\n") - 1; | |
Debug.Log($"gStageWidth = {gStageWidth}"); | |
state = new eStageData[gStageWidth * gStageHeight]; | |
ClearObject.SetActive(false); | |
int x = 0; | |
int y = 0; | |
foreach (char ch in gStageData) | |
{ | |
eStageData t = ConvertStageData(ch); | |
if (t == eStageData.NewLine) | |
{ | |
x = 0; | |
y++; | |
t = eStageData.Unknown; | |
} | |
if (t != eStageData.Unknown) | |
{ | |
state[y * gStageWidth + x] = t; | |
x++; | |
} | |
} | |
} | |
void Update() | |
{ | |
Draw(); | |
if (checkClear()) | |
{ | |
BGM.Stop(); | |
ClearObject.SetActive(true); | |
Debug.Log("Game Clear"); | |
} | |
GameUpdate(GameInput()); | |
} | |
private void Draw() | |
{ | |
Stage.ClearAllTiles(); | |
//TODO:画像を読み込みたい | |
char[] font = new char[] { '#', '.', 'o', 'p', 'O', 'P', ' ' }; | |
string s = ""; | |
for (int y = 0; y < gStageHeight; y++) | |
{ | |
for (int x = 0; x < gStageWidth; x++) | |
{ | |
Debug.Log((int)state[y * gStageWidth + x]); | |
Stage.SetTile(new Vector3Int(x, -y, 0), tileBases[(int)state[y * gStageWidth + x]]); | |
s += font[(int)state[y * gStageWidth + x]]; | |
} | |
s += "\n"; | |
} | |
Debug.Log(s); | |
} | |
private Vector2Int GameInput() | |
{ | |
if (Input.GetKeyDown(KeyCode.UpArrow)) | |
{ | |
return Vector2Int.down; // (0,-1) | |
} | |
if (Input.GetKeyDown(KeyCode.DownArrow)) | |
{ | |
return Vector2Int.up; // (0,1) | |
} | |
if (Input.GetKeyDown(KeyCode.LeftArrow)) | |
{ | |
return Vector2Int.left; | |
} | |
if (Input.GetKeyDown(KeyCode.RightArrow)) | |
{ | |
return Vector2Int.right; | |
} | |
if (Input.GetKeyDown(KeyCode.Space)) | |
{ | |
if (checkClear()) { Next(); } | |
else { Initialize(); } | |
} | |
if (Input.GetKeyDown(KeyCode.M)) | |
{ | |
MoveMenu(); | |
} | |
if (Input.GetKeyDown(KeyCode.Q)) | |
{ | |
Howto.SetActive(!Howto.activeSelf); | |
} | |
return Vector2Int.zero; | |
} | |
private void GameUpdate(Vector2Int move) | |
{ | |
if (notMove(move)) { return; } | |
Vector2Int playerpos = new Vector2Int(-1, -1); | |
int count = 0; | |
//playerの位置を検索 | |
foreach (var obj in state) | |
{ | |
if (isPlayer(obj)) | |
{ | |
playerpos.y = count / gStageWidth; | |
playerpos.x = count % gStageWidth; | |
} | |
count++; | |
} | |
//player位置変更 | |
Vector2Int tmp_pos = playerpos + move; | |
//範囲外チェック | |
if (isOver(tmp_pos)) { return; } | |
switch (state[tmp_pos.y * gStageWidth + tmp_pos.x]) | |
{ | |
case eStageData.Wall: | |
//移動しない | |
break; | |
case eStageData.Object: | |
if (push(tmp_pos, move)) | |
{ | |
state[playerpos.y * gStageWidth + playerpos.x] = GetMovedStageData(playerpos); | |
state[tmp_pos.y * gStageWidth + tmp_pos.x] = eStageData.Player; | |
}; | |
break; | |
case eStageData.ObjectOnGoal: | |
if (push(tmp_pos, move)) | |
{ | |
state[playerpos.y * gStageWidth + playerpos.x] = GetMovedStageData(playerpos); | |
state[tmp_pos.y * gStageWidth + tmp_pos.x] = eStageData.PlayerOnGoal; | |
}; | |
break; | |
case eStageData.Goal: | |
state[playerpos.y * gStageWidth + playerpos.x] = GetMovedStageData(playerpos); | |
state[tmp_pos.y * gStageWidth + tmp_pos.x] = eStageData.PlayerOnGoal; | |
break; | |
default: | |
state[playerpos.y * gStageWidth + playerpos.x] = GetMovedStageData(playerpos); | |
state[tmp_pos.y * gStageWidth + tmp_pos.x] = eStageData.Player; | |
break; | |
} | |
} | |
private bool notMove(Vector2Int move) | |
{ | |
return move == Vector2Int.zero; | |
} | |
private eStageData GetMovedStageData(Vector2Int pos) | |
{ | |
if (state[pos.y * gStageWidth + pos.x] == eStageData.PlayerOnGoal || | |
state[pos.y * gStageWidth + pos.x] == eStageData.ObjectOnGoal) | |
{ | |
return eStageData.Goal; | |
} | |
else | |
{ | |
return eStageData.Space; | |
} | |
} | |
private bool push(Vector2Int obj_pos, Vector2Int move) | |
{ | |
Vector2Int tmp_pos = new Vector2Int(obj_pos.x + move.x, obj_pos.y + move.y); | |
switch (state[tmp_pos.y * gStageWidth + tmp_pos.x]) | |
{ | |
case eStageData.Wall: | |
case eStageData.Object: | |
case eStageData.ObjectOnGoal: | |
return false; | |
case eStageData.Goal: | |
state[obj_pos.y * gStageWidth + obj_pos.x] = GetMovedStageData(obj_pos); | |
state[tmp_pos.y * gStageWidth + tmp_pos.x] = eStageData.ObjectOnGoal; | |
return true; | |
default: | |
state[obj_pos.y * gStageWidth + obj_pos.x] = GetMovedStageData(obj_pos); | |
state[tmp_pos.y * gStageWidth + tmp_pos.x] = eStageData.Object; | |
return true; | |
} | |
} | |
private bool isOver(Vector2Int tmp_pos) | |
{ | |
return tmp_pos.x < 0 || tmp_pos.y < 0 || tmp_pos.x >= gStageWidth || tmp_pos.y >= gStageHeight; | |
} | |
private bool isPlayer(eStageData obj) | |
{ | |
return obj == eStageData.Player || obj == eStageData.PlayerOnGoal; | |
} | |
private bool checkClear() | |
{ | |
for (int i = 0; i < state.Length; i++) | |
{ | |
if (state[i] == eStageData.Object) | |
{ | |
return false; | |
} | |
} | |
return true; | |
} | |
private eStageData ConvertStageData(char stagechar) | |
{ | |
switch (stagechar) | |
{ | |
case '#': return eStageData.Wall; | |
case '.': return eStageData.Goal; | |
case 'o': return eStageData.Object; | |
case 'p': return eStageData.Player; | |
case 'O': return eStageData.ObjectOnGoal; | |
case 'P': return eStageData.PlayerOnGoal; | |
case ' ': return eStageData.Space; | |
case '\n': return eStageData.NewLine; | |
default: return eStageData.Unknown; | |
} | |
} | |
public void Next() | |
{ | |
int nextStageNo = Convert.ToInt32(StageName.Substring(StageName.Length - 1)) + 1; | |
if (nextStageNo >= 10) | |
{ | |
MoveMenu(); | |
} | |
else | |
{ | |
StageName = "Stage" + nextStageNo.ToString(); | |
BGM.Play(); | |
Initialize(); | |
} | |
} | |
public void MoveMenu() | |
{ | |
MenuObj.SetActive(true); | |
GameObj.SetActive(false); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment