Skip to content

Instantly share code, notes, and snippets.

@cacapon
Created September 17, 2021 08:31
Show Gist options
  • Save cacapon/81af7381fb2724a8a7bb6b5be57002ff to your computer and use it in GitHub Desktop.
Save cacapon/81af7381fb2724a8a7bb6b5be57002ff to your computer and use it in GitHub Desktop.
倉庫番ゲーム部分の実装
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