mycj_demo/mycj/Assets/Game/Scripts/Application/Object/FBMap.cs
2024-12-02 09:37:47 +08:00

377 lines
11 KiB
C#
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Felix-BangMap
//   へ     /|
//  /7    ∠_/
//  / │    
//  Z _,    /`ヽ
// │     ヽ   /  〉
//  Y     `  /  /
// イ● 、 ●  ⊂⊃〈  /
// ()  へ    | \〈
//  >ー 、_  ィ  │
//  / へ   / ノ<|
//  ヽ_ノ  (_  │//
//  7       |
//  ―r ̄ ̄`ー―_
// Describe地图 描述一个关卡地图状态
// Createtime2018/9/10
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace FBApplication
{
//鼠标点击参数类
public class FBGridClickEventArgs : EventArgs
{
public int MouseButton; //0左键1右键
public FBGrid Grid;
public FBGridClickEventArgs(int mouseButton, FBGrid grid)
{
this.MouseButton = mouseButton;
this.Grid = grid;
}
}
public class FBMap : MonoBehaviour
{
#region
public const int RowCount = 8; //行数
public const int ColumnCount = 12; //列数
#endregion
#region
public EventHandler<FBGridClickEventArgs> OnFBGridClick;
#endregion
#region
float f_mapWidth;
float f_mapHeight;
float f_tileWidth;
float f_tileHeight;
List<FBGrid> f_grid = new List<FBGrid>(); //背景网格
List<FBGrid> f_road = new List<FBGrid>(); //道路网个
private FBLevel f_level;
public bool IsDrawGizoms = true; //是否绘制网格
#endregion
#region
public FBLevel Level
{
get { return f_level; }
}
public string BackgroundImage
{
set
{
SpriteRenderer render = transform.Find("Background").GetComponent<SpriteRenderer>();
StartCoroutine(FBTools.LoadImage(value, render));
}
}
public string RoadImage
{
set
{
SpriteRenderer render = transform.Find("Road").GetComponent<SpriteRenderer>();
StartCoroutine(FBTools.LoadImage(value, render));
}
}
public List<FBGrid> Grids
{
get { return f_grid; }
}
public List<FBGrid> Road
{
get { return f_road; }
}
//怪物的寻路路径
public Vector3[] Path
{
get
{
List<Vector3> f_path = new List<Vector3>();
for (int i = 0; i < f_road.Count; i++)
{
FBGrid t = f_road[i];
Vector3 point = GetPosition(t);
f_path.Add(point);
}
return f_path.ToArray();
}
}
public Rect MapRect
{
get { return new Rect(-f_mapWidth / 2,-f_mapHeight / 2, f_mapWidth, f_mapHeight); }
}
#endregion
#region
public void LoadLevel(FBLevel level)
{
//清除当前状态
Clear();
//保存
f_level = level;
//加载图片
BackgroundImage = "file://" + FBConsts.MpsDir + "/" + level.Background;
RoadImage = "file://" + FBConsts.MpsDir + "/" + level.Road;
//寻路点
for (int i = 0; i < level.Path.Count; i++)
{
FBCoords c = level.Path[i];
FBGrid t = GetGrid(c.X, c.Y);
f_road.Add(t);
}
//炮塔点
for (int i = 0; i < level.Holders.Count; i++)
{
FBCoords c = level.Holders[i];
FBGrid t = GetGrid(c.X, c.Y);
t.CanHold = true;
}
}
//清除塔位信息
public void ClearHolder()
{
foreach (FBGrid g in f_grid)
{
if (g.CanHold)
g.CanHold = false;
}
}
//清除寻路格子集合
public void ClearRoad()
{
f_road.Clear();
}
//清除所有信息
public void Clear()
{
f_level = null;
ClearHolder();
ClearRoad();
}
#endregion
#region Unity回调
//只在运行期起作用
void Awake()
{
//计算地图和格子大小
CalculateSize();
//创建所有的格子
for (int i = 0; i < RowCount; i++)
for (int j = 0; j < ColumnCount; j++)
f_grid.Add(new FBGrid(j, i));
//监听鼠标点击事件
OnFBGridClick += MapOnGridClick;
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
FBGrid g = GetTileUnderMouse();
if (g != null)
{
//触发鼠标左键点击事件
FBGridClickEventArgs e = new FBGridClickEventArgs(0,g);
if (OnFBGridClick != null)
OnFBGridClick(this, e);
}
}
if (Input.GetMouseButtonDown(1))
{
FBGrid g = GetTileUnderMouse();
if (g != null)
{
//触发鼠标右键点击事件
FBGridClickEventArgs e = new FBGridClickEventArgs(1, g);
if (OnFBGridClick != null)
OnFBGridClick(this, e);
}
}
}
//只在编辑器里起作用 类似Update不停的执行
void OnDrawGizmos()
{
if (!IsDrawGizoms)
return;
//计算地图和格子大小
CalculateSize();
//绘制格子
Gizmos.color = Color.green;
//绘制行
for (int row = 0; row <= RowCount; row++)
{
Vector2 from = new Vector2(-f_mapWidth / 2, -f_mapHeight / 2 + row * f_tileHeight);
Vector2 to = new Vector2(-f_mapWidth / 2 + f_mapWidth, -f_mapHeight / 2 + row * f_tileHeight);
Gizmos.DrawLine(from, to);
}
//绘制列
for (int col = 0; col <= ColumnCount; col++)
{
Vector2 from = new Vector2(-f_mapWidth / 2 + col * f_tileWidth, f_mapHeight / 2);
Vector2 to = new Vector2(-f_mapWidth / 2 + col * f_tileWidth, -f_mapHeight / 2);
Gizmos.DrawLine(from, to);
}
foreach (FBGrid g in f_grid)
{
if (g.CanHold)
{
Vector3 pos = GetPosition(g);
Gizmos.DrawIcon(pos, "holder.png", true);
}
}
Gizmos.color = Color.red;
for (int i = 0; i < f_road.Count; i++)
{
//起点
if (i == 0)
Gizmos.DrawIcon(GetPosition(f_road[i]), "start.png", true);
//终点
if (f_road.Count > 1 && i == f_road.Count - 1)
Gizmos.DrawIcon(GetPosition(f_road[i]), "end.png", true);
//红色的连线
if (f_road.Count > 1 && i != 0)
{
Vector3 from = GetPosition(f_road[i - 1]);
Vector3 to = GetPosition(f_road[i]);
Gizmos.DrawLine(from, to);
}
}
}
#endregion
#region
private void MapOnGridClick(object sender, FBGridClickEventArgs e)
{
//当前场景不是LevelBuilder 不能编辑
if (gameObject.scene.name != "LevelBuilder")
return;
if (Level == null)
return;
if (e.MouseButton == 0 && !f_road.Contains(e.Grid))
e.Grid.CanHold = !e.Grid.CanHold;
if (e.MouseButton == 1 && !e.Grid.CanHold)
{
if (f_road.Contains(e.Grid))
f_road.Remove(e.Grid);
else
f_road.Add(e.Grid);
}
}
#endregion
#region
//计算地图大小 网格大小
void CalculateSize()
{
Vector3 pos1 = Camera.main.ViewportToWorldPoint(new Vector3(0, 0));
Vector3 pos2 = Camera.main.ViewportToWorldPoint(new Vector3(1, 1));
f_mapWidth = pos2.x - pos1.x;
f_mapHeight = pos2.y - pos1.y;
f_tileWidth = f_mapWidth / ColumnCount;
f_tileHeight = f_mapHeight / RowCount;
}
/// <summary>
/// 根据网格获取网格的世界坐标
/// </summary>
/// <param name="g"> 网格 </param>
/// <returns></returns>
public Vector3 GetPosition(FBGrid g)
{
return new Vector3(
-f_mapWidth / 2 + (g.Index_X + 0.5f) * f_tileWidth,
-f_mapHeight / 2 + (g.Index_Y + 0.5f) * f_tileHeight,
0);
}
/// <summary> 根据索引获取网格 </summary>>
FBGrid GetGrid(int x, int y)
{
int index = x + y * ColumnCount;
if (index < 0 || index >= f_grid.Count)
return null;
return f_grid[index];
}
/// <summary>
/// 根据位置获取网格
/// </summary>
/// <param name="position">坐标</param>
/// <returns></returns>
public FBGrid GetGrid(Vector3 position)
{
int gridX=(int)((position.x + f_mapWidth / 2) / f_tileWidth);
int gridY = (int)((position.y + f_mapHeight / 2) / f_tileHeight);
return GetGrid(gridX, gridY);
}
/// <summary> 获取鼠标下面的格子 <summary>
FBGrid GetTileUnderMouse()
{
Vector2 wordPos = GetWorldPosition();
//int col = (int)((wordPos.x + f_mapWidth / 2) / f_tileWidth);
//int row = (int)((wordPos.y + f_mapHeight / 2) / f_tileHeight);
return GetGrid(wordPos);
}
/// <summary> 获取鼠标所在位置的世界坐标 <summary>
Vector3 GetWorldPosition()
{
Vector3 viewPos = Camera.main.ScreenToViewportPoint(Input.mousePosition);
Vector3 worldPos = Camera.main.ViewportToWorldPoint(viewPos);
return worldPos;
}
#endregion
}
}