接上文.
我们拿到要操作的方块之后,事情就变得简单起来,只要用代码来控制现有的UI即可.
首先来实现方块下落.
我们首先需要定义一些字段来实现下落的功能.
fallspeed来控制方块下落速度,将来可以用来控制游戏的难易度.
runFlag用来表示游戏是否正在进行,可以用来做暂停功能,游戏结束等等.在游戏开始时将这个布尔量为真,暂停和gameover时为假.
fallInterval为下落时间间隔.
timeCount用来计游戏流逝时间,timeCount累积达到fallInterval时,使方块下落一格.
squareMap用来保存已经落地之后的正方形的位置.
[Range(1,10)]
public float fallSpeed;
RectTransform myRectTransform { get { return GetComponent(); } }
dmBlock nowControlBlock;
bool runFlag;
float fallInterval { get { return 1 / fallSpeed; } }
float timeCount;
Vector2 nowBlockPos;
Dictionary squareMap = new Dictionary();
重构StartGame
public void StartGame()
{
if (nowControlBlock != null)
{
blockBuilder.DestroySquares(nowControlBlock);
}
if(squareMap != null)
{
foreach(Vector2 squareCoord in squareMap.Keys)
{
Destroy(squareMap[squareCoord]);
}
}
squareMap.Clear();
blockBuilder.BuildRandomBlock();
NextBlock();
timeCount = 0;
runFlag = true;
}
回收上次游戏的残留正方形,然后初始化一些控制用变量的初始值
写Update函数,Unity每一帧会自动调用Update,我们要把帧转换成固定时间,用timeCount变量的累计来做
void Update () {
if (runFlag)
{
timeCount += Time.deltaTime;
if (timeCount >= fallInterval)
{
timeCount -= fallInterval;
DoFall();
}
}
}
public void DoFall()
{
Vector2 targetPos = nowBlockPos + new Vector2(0, 1);
if(!CheckCollision(nowControlBlock,targetPos))
{
MoveBlockTo(nowControlBlock, targetPos);
}
else
{
FallGround(nowControlBlock);
NextBlock();
}
}
public bool CheckCollision(dmBlock block,Vector2 targetPos)
{
foreach(Vector2 squareCoord in block.bindBase.squareCoordList)
{
Vector2 squarePos = squareCoord + targetPos;
if(squarePos.y >= areaSize.y || squarePos.x<0 || squarePos.x >= areaSize.x)
{
return true;
}
if (squareMap.ContainsKey(squarePos)) return true;
}
return false;
}
public void FallGround(dmBlock block)
{
for(int i = 0; i < block.bindBase.squareCoordList.Count;i++)
{
squareMap.Add(nowBlockPos + block.bindBase.squareCoordList[i], block.squareList[i]);
block.squareList[i].GetComponentInChildren().color = Color.gray;
}
}
本次修改之后,完整的GameArea代码如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class dmGameArea : MonoBehaviour {
public dmBlockBuilder blockBuilder;
public Vector2 areaSize;
public Vector2 initPos;
[Range(1,10)]
public float fallSpeed;
RectTransform myRectTransform { get { return GetComponent(); } }
dmBlock nowControlBlock;
bool runFlag;
float fallInterval { get { return 1 / fallSpeed; } }
float timeCount;
Vector2 nowBlockPos;
Dictionary squareMap = new Dictionary();
void Start () {
myRectTransform.sizeDelta = new Vector2(areaSize.x * blockBuilder.squareSize.x, areaSize.y * blockBuilder.squareSize.y);
runFlag = false;
}
// Update is called once per frame
void Update () {
if (runFlag)
{
timeCount += Time.deltaTime;
if (timeCount >= fallInterval)
{
timeCount -= fallInterval;
DoFall();
}
}
}
public void DoFall()
{
Vector2 targetPos = nowBlockPos + new Vector2(0, 1);
if(!CheckCollision(nowControlBlock,targetPos))
{
MoveBlockTo(nowControlBlock, targetPos);
}
else
{
FallGround(nowControlBlock);
NextBlock();
}
}
public bool CheckCollision(dmBlock block,Vector2 targetPos)
{
foreach(Vector2 squareCoord in block.bindBase.squareCoordList)
{
Vector2 squarePos = squareCoord + targetPos;
if(squarePos.y >= areaSize.y || squarePos.x<0 || squarePos.x >= areaSize.x)
{
return true;
}
if (squareMap.ContainsKey(squarePos)) return true;
}
return false;
}
public void FallGround(dmBlock block)
{
for(int i = 0; i < block.bindBase.squareCoordList.Count;i++)
{
squareMap.Add(nowBlockPos + block.bindBase.squareCoordList[i], block.squareList[i]);
block.squareList[i].GetComponentInChildren().color = Color.gray;
}
}
public void StartGame()
{
if (nowControlBlock != null)
{
blockBuilder.DestroySquares(nowControlBlock);
}
if(squareMap != null)
{
foreach(Vector2 squareCoord in squareMap.Keys)
{
Destroy(squareMap[squareCoord]);
}
}
squareMap.Clear();
blockBuilder.BuildRandomBlock();
NextBlock();
timeCount = 0;
runFlag = true;
}
public void NextBlock()
{
PutInBlock(blockBuilder.nowBlock);
blockBuilder.BuildRandomBlock();
}
public void PutInBlock(dmBlock block)
{
nowControlBlock = block;
blockBuilder.nowBlock = null;
foreach(GameObject square in block.squareList)
{
square.transform.SetParent(transform);
}
MoveBlockTo(block,initPos);
}
public void MoveBlockTo(dmBlock onMoveBlock,Vector2 targetPos)
{
if (CheckCollision(onMoveBlock, targetPos))
{
//GameOver
runFlag = false;
return;
}
for (int i = 0; i < onMoveBlock.bindBase.squareCoordList.Count; i++)
{
Vector2 squareCoord = targetPos + onMoveBlock.bindBase.squareCoordList[i];
onMoveBlock.squareList[i].transform.localPosition = AreaPos2Local(squareCoord);
onMoveBlock.squareList[i].SetActive(squareCoord.y >= 0);
}
nowBlockPos = targetPos;
}
public Vector2 AreaPos2Local(Vector2 areaPos)
{
return new Vector2((areaPos.x + 0.5f) * blockBuilder.squareSize.x, - (0.5f + areaPos.y) * blockBuilder.squareSize.y);
}
}
目录
(一) 定义方块(二) 搭建方块UI和生成方块.
(三) 搭建场地UI和游戏流程控制
(四) 方块下落和落地判定
(五) 方块平移和旋转
(六) 方块消除