8.方块左右移动
8.1 知识点
主要操作
- 在搬砖工人类里编写一些方法,以使方块能够左右移动。
- 创建左右移动的函数,根据传入的类型决定向左移动还是向右移动。
- 在进行移动之前,获取原来的坐标,进行擦除,然后遍历所有搬砖工人手上的方块,逐个绘制。
- 在游戏场景类测试时发现可能会和墙壁重合。
- 移动之前要判断是否可以进行左右移动,因此创建判断能否移动的函数。函数内模拟移动一次,判断是否会和地图边界或者动态墙壁重合。
- 在移动前再次进行能否移动的判断。
8.2 知识点代码
BlockWorker
using System;
using System.Collections.Generic;
using System.Text;
namespace CSharp实践教学
{
/// <summary>
/// 变形左右枚举 决定顺时针还是逆时针
/// </summary>
enum E_Change_Type
{
Left,
Right,
}
### BlockWorker
class BlockWorker : IDraw
{
//方块们
private List<DrawObject> blocks;
//心中要默默的知道 各个形状的方块信息是什么
//选择一个容器来纪录各个方块的形态信息
//用list和Dictionary都可以用来存储方块的几种信息
//我们选择Dictionary的主要目的是好找 并且起到练习的作用
private Dictionary<E_DrawType, BlockInfo> blockInfoDic;
//记录随机创建出来的方块的 具体形态信息
private BlockInfo nowBlockInfo;
//当前的形态索引
private int nowInfoIndex;
public BlockWorker()
{
//初始化 装块信息
blockInfoDic = new Dictionary<E_DrawType, BlockInfo>()
{
{ E_DrawType.Cube, new BlockInfo(E_DrawType.Cube) },
{ E_DrawType.Line, new BlockInfo(E_DrawType.Line) },
{ E_DrawType.Tank, new BlockInfo(E_DrawType.Tank) },
{ E_DrawType.Left_Ladder, new BlockInfo(E_DrawType.Left_Ladder) },
{ E_DrawType.Right_Ladder, new BlockInfo(E_DrawType.Right_Ladder) },
{ E_DrawType.Left_Long_Ladder, new BlockInfo(E_DrawType.Left_Long_Ladder) },
{ E_DrawType.Right_Long_Ladder, new BlockInfo(E_DrawType.Right_Long_Ladder) },
};
//随机方块
RandomCreateBlock();
}
public void Draw()
{
for (int i = 0; i < blocks.Count; i++)
{
blocks[i].Draw();
}
}
/// <summary>
/// 随机创建一个方块
/// </summary>
public void RandomCreateBlock()
{
//随机方块类型
Random r = new Random();
E_DrawType type = (E_DrawType)r.Next(1, 8);
//每次新建一个 砖块 其实就是创建4个小方形
blocks = new List<DrawObject>()
{
new DrawObject(type),
new DrawObject(type),
new DrawObject(type),
new DrawObject(type),
};
//需要初始化方块位置
//原点位置 我们随机 自己定义 方块List中第0个就是我们的原点方块
blocks[0].pos = new Position(24, 5);
//其它三个方块的位置
//取出方块的形态信息 来进行具体的随机
//应该把取出来的 方块具体的形态信息 存起来 用于之后变形
nowBlockInfo = blockInfoDic[type];
//随机几种形态中的一种来设置方块的信息吧
nowInfoIndex = r.Next(0, nowBlockInfo.Count);
//取出其中一种形态的坐标信息
Position[] pos = nowBlockInfo[nowInfoIndex];
//讲另外的三个小方块进行设置 计算
for (int i = 0; i < pos.Length; i++)
{
//取出来的pos是相对原点方块的坐标 所以需要进行计算
blocks[i + 1].pos = blocks[0].pos + pos[i];
}
}
### Lesson6 变形相关方法
//擦除的方法
public void ClearDraw()
{
for (int i = 0; i < blocks.Count; i++)
{
blocks[i].ClearDraw();
}
}
/// <summary>
/// 变形
/// </summary>
/// <param name="type">左边还是右边</param>
public void Change(E_Change_Type type)
{
//变之前把之前的位置擦除
ClearDraw();
switch (type)
{
case E_Change_Type.Left:
--nowInfoIndex;
if (nowInfoIndex < 0)
nowInfoIndex = nowBlockInfo.Count - 1;
break;
case E_Change_Type.Right:
++nowInfoIndex;
if (nowInfoIndex >= nowBlockInfo.Count)
nowInfoIndex = 0;
break;
}
//得到索引目的 是得到对应形态的 位置偏移信息
//用于设置另外的三个小方块
Position[] pos = nowBlockInfo[nowInfoIndex];
//将另外的三个小方块进行设置 计算
for (int i = 0; i < pos.Length; i++)
{
//取出来的pos是相对原点方块的坐标 所以需要进行计算
blocks[i + 1].pos = blocks[0].pos + pos[i];
}
//变之后再来绘制
Draw();
}
/// <summary>
/// 判断是否可以进行变形
/// </summary>
/// <param name="type">变形方向</param>
/// <param name="map">地图信息</param>
/// <returns></returns>
public bool CanChange(E_Change_Type type, Map map)
{
//用一个临时变量记录 当前索引 不变化当前索引
//变化这个临时变量
int nowIndex = nowInfoIndex;
switch (type)
{
case E_Change_Type.Left:
--nowIndex;
if (nowIndex < 0)
nowIndex = nowBlockInfo.Count - 1;
break;
case E_Change_Type.Right:
++nowIndex;
if (nowIndex >= nowBlockInfo.Count)
nowIndex = 0;
break;
}
//通过临时索引 取出形态信息 用于重合判断
Position[] nowPos = nowBlockInfo[nowIndex];
//判断是否超出地图边界
Position tempPos;
for (int i = 0; i < nowPos.Length; i++)
{
tempPos = blocks[0].pos + nowPos[i];
//判断左右边界 和 下边界
if( tempPos.x < 2 ||
tempPos.x >= Game.w - 2 ||
tempPos.y >= map.h)
{
return false;
}
}
//判断是否和地图上的动态方块重合
for (int i = 0; i < nowPos.Length; i++)
{
tempPos = blocks[0].pos + nowPos[i];
for (int j = 0; j < map.dynamicWalls.Count; j++)
{
if( tempPos == map.dynamicWalls[j].pos )
{
return false;
}
}
}
return true;
}
### Lesson7 方块左右移动
/// <summary>
/// 左右移动的函数
/// </summary>
/// <param name="type">左或者右</param>
public void MoveRL(E_Change_Type type)
{
//在动之前 要得到原来的坐标 进行擦除
ClearDraw();
//根据传入的类型 决定左动还是右动
//左动 x-2,y0 右动x 2 y 0
//得到我们的便宜位置
Position movePos = new Position(type == E_Change_Type.Left ? -2 : 2, 0);
//遍历我的所有小方块
for (int i = 0; i < blocks.Count; i++)
{
blocks[i].pos += movePos;
}
//动之后 再画上去
Draw();
}
/// <summary>
/// 移动之前判断 判断是否可以进行左右移动
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public bool CanMoveRL(E_Change_Type type, Map map)
{
//根据传入的类型 决定左动还是右动
//左动 x-2,y0 右动x 2 y 0
//得到我们的便宜位置
Position movePos = new Position(type == E_Change_Type.Left ? -2 : 2, 0);
//要不和左右边界重合
//动过后的结果 不能直接改小方块的位置 改了就覆水难收
//这只是想预判断 所以 得一个临时变量用于判断即可
Position pos;
for (int i = 0; i < blocks.Count; i++)
{
pos = blocks[i].pos + movePos;
if (pos.x < 2 || pos.x >= Game.w - 2)
return false;
}
//要不和动态方块重合了
for (int i = 0; i < blocks.Count; i++)
{
pos = blocks[i].pos + movePos;
for (int j = 0; j < map.dynamicWalls.Count; j++)
{
if (pos == map.dynamicWalls[j].pos)
return false;
}
}
return true;
}
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com