看注释吧,写的很清楚了

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace ZoneTest
{
public class Zone
{
public int mId;
public float Width;
public float Height;
public List<Zone> VisibleZoneList = new List<Zone>(); public Zone(int id, float width, float height)
{
mId = id;
Width = width;
Height = height;
} public void AddVisibleZone(Zone zone)
{
VisibleZoneList.Add(zone);
}
}
public class Scene
{
private List<Zone> mZoneList = new List<Zone>(); public Scene(float w,float h)
{
mSceneWidth = w;
mSceneHeight = h;
}
public const float ZONE_SIDE = 1.0f;
//场景宽高
private float mSceneWidth;
private float mSceneHeight; //格子列数和行数
private int mZoneColumnCount;
private int mZoneLineCount; public Zone GetZone(int id)
{
if (id < 0 || id > mZoneList.Count)
{
return null;
}
return mZoneList[id];
} //Zone示意图
/*
| mSceneWidth |
----------------- --
| | | | |ZONE_SIDE
-----------------
| | | | |
----------------- mSceneHeight
| | | | |
----------------- -- ----------------- line 0 ----------------- line 1 ----------------- line 2 ----------------- line 3 column0 column1 column2 column3
| | | | | | | | | | | | | | | | *
*/ public bool InitZone()
{
//计算场景内zone行和列
mZoneLineCount = (int)Math.Ceiling((double)mSceneHeight / (double)ZONE_SIDE);
mZoneColumnCount = (int)Math.Ceiling((double)mSceneWidth / (double)ZONE_SIDE); //创建zone
for (int i = 0; i < mZoneLineCount; i++)
{
for (int j = 0; j < mZoneColumnCount; j++)
{
int id = i * mZoneColumnCount + j;
Zone zone = new Zone(id, ZONE_SIDE, ZONE_SIDE);
mZoneList.Add(zone);
}
} //最大周围多少个格子被可见 MaxNearByZoneNumber*MaxNearByZoneNumber 个
const int MaxNearByZoneNumber = 3;
//可见格子的起始偏移
const int Offset = MaxNearByZoneNumber / 2; //把周围可见格子加入列表
/*
*    -------------
* |0 |1 |2 |
* -------------
* |3 |4 |5 |
* -------------
* |6 |7 |8 |
* -------------
*/ //0的可见格子为 0134
//4的可见格子为 0123456789
//7的可见格子为 345678 //遍历所有格子行
for (int i = 0; i < mZoneLineCount; i++)
{
//遍历所有格子列
for (int j = 0; j < mZoneColumnCount; j++)
{
//当前要判断可见性的格子id
int id = i * mZoneColumnCount + j;
Zone zone = mZoneList[id]; //遍历周围 MaxNearByZoneNumber*MaxNearByZoneNumber个格子
//判断[x,y]这个格子是否出界 //行
for (int n = 0; n < MaxNearByZoneNumber; n++)
{
int y = i - Offset + n;
if (y < 0 || y >= mZoneLineCount) continue;//y出界 //列
for (int m = 0; m < MaxNearByZoneNumber; m++)
{ int x = j - Offset + m;
if (x < 0 || x >= mZoneColumnCount) continue;//x出界 //算当前格子id
int visibleZoneId = y * mZoneColumnCount + x; //if (visibleZoneId == id) continue;//是自己格子也要加入,自己属于自己可见格子 zone.AddVisibleZone(mZoneList[visibleZoneId]);
}
} }
} return true;
} public void Print()
{
for (int i = 0; i < mZoneLineCount; i++)
{
string str = "";
//遍历所有格子列
for (int j = 0; j < mZoneColumnCount; j++)
{
str += (i * mZoneColumnCount + j).ToString()+"\t";
}
Debug.Print(str);
}
} public void PrintZone(int i)
{
Debug.Print("[{0}]---------------------",i);
var zone = mZoneList[i];
string str = "";
foreach(var z in zone.VisibleZoneList)
{ str+=z.mId.ToString()+"\t";
}
Debug.Print(str);
Debug.Print("[{0}]---------------------",i);
}
}
class Program
{
static void Main(string[] args)
{ Scene scene = new Scene(5,7);
scene.InitZone(); scene.Print(); int oldId = 5;
int newId = 10; Zone oldZone = scene.GetZone(oldId);
Zone newZone = scene.GetZone(newId); /*
//比较计算应该删除我的zone
List<Zone> deleteMeZone = new List<Zone>();
foreach (var zone in oldZone.VisibleZoneList)
{
if (!newZone.VisibleZoneList.Contains(zone))
{
deleteMeZone.Add(zone);
Debug.Print(zone.mId.ToString());
}
}
Debug.Print("-----------");
//比较计算应该创建我的
List<Zone> createMeZone = new List<Zone>();
foreach (var zone in newZone.VisibleZoneList)
{
if (!oldZone.VisibleZoneList.Contains(zone))
{
createMeZone.Add(zone);
Debug.Print(zone.mId.ToString());
}
}
*/ scene.PrintZone(4); scene.PrintZone(16); scene.PrintZone(28); scene.PrintZone(30); }
}
}

  

//当角色位置发生改变

protected void UpdateZone()
{
//安全检查
if (null == Scene || null == Zone)
return; //获得我的zone id
int zoneId = Scene.Pos2ZoneId(mPosition.X, mPosition.Y); Zone newZone = Scene.GetZone(zoneId);
if (null==newZone)
{
Logger.Fatal("[{0}] move out of scene[{1},{2}]", GetName(), GetPosition().X, GetPosition().Y);
}
//如果我的zone没变化
if (zoneId == Zone.Id) return; //比较计算应该删除我的zone
List<Zone> deleteMeZone = new List<Zone>();
foreach (var zone in Zone.VisibleZoneList)
{
if (!newZone.VisibleZoneList.Contains(zone))
{
deleteMeZone.Add(zone);
}
} //比较计算应该创建我的
List<Zone> createMeZone = new List<Zone>();
foreach (var zone in newZone.VisibleZoneList)
{
if (!Zone.VisibleZoneList.Contains(zone))
{
createMeZone.Add(zone);
}
} //发包删除我
foreach(var zone in deleteMeZone)
{
zone.PushAction2AllPlayer((player)=>{
player.Proxy.DeleteObj(ObjId, (int)ReasonType.VisibilityChanged);
},ObjId);
} //把该删除的通知我
if (GetObjType() == ObjType.PLAYER)
{
ObjPlayer player = this as ObjPlayer;
foreach (var zone in deleteMeZone)
{
zone.PushAction((obj) =>
{
if(obj!=this)
{
player.Proxy.DeleteObj(obj.ObjId, (int)ReasonType.VisibilityChanged);
}
});
} } //发包创建我
CreateObjMsg msg2Other = new CreateObjMsg();
ObjData data = DumpObjData(ReasonType.VisibilityChanged);
msg2Other.Data.Add(data);
foreach (var zone in createMeZone)
{
zone.PushAction2AllPlayer((player) =>
{
if (IsVisibleTo(player))
{
player.Proxy.CreateObj(msg2Other);
}
}, ObjId);
} //把周围所有人通知给我
if(GetObjType()==ObjType.PLAYER)
{
ObjPlayer player = this as ObjPlayer; CreateObjMsg msg2Me = new CreateObjMsg();
foreach (var zone in createMeZone)
{
zone.PushAction((obj) =>
{
if(obj!=this)
{
if (obj.IsVisibleTo(this))
{
msg2Me.Data.Add(obj.DumpObjData(ReasonType.VisibilityChanged));
}
}
});
}
player.Proxy.CreateObj(msg2Me);
}
Zone.RemoveObj(this);
newZone.AddObj(this);
SetZone(newZone); }

  

MMO可见格子算法的更多相关文章

  1. java算法 蓝桥杯 格子位置

    问题描述 输入三个自然数N,i,j (1<=i<=N,1<=j<=N),输出在一个N*N格的棋盘中,与格子(i,j)同行.同列.同一对角线的所有格子的位置. 输入格式 输入共三 ...

  2. 算法笔记_135:格子取数问题(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 有n*n个格子,每个格子里有正数或者0,从最左上角往最右下角走,只能向下和向右走,一共走两次(即从左上角往右下角走两趟),把所有经过的格子里的数加起 ...

  3. Java实现 蓝桥杯VIP 算法提高 格子位置

    算法提高 格子位置 时间限制:1.0s 内存限制:512.0MB 问题描述 输入三个自然数N,i,j (1<=i<=N,1<=j<=N),输出在一个N*N格的棋盘中,与格子(i ...

  4. 蓝桥杯-算法训练--ALGO-8 操作格子

    问题描述 有n个格子,从左到右放成一排,编号为1-n. 共有m次操作,有3种操作类型: 1.修改一个格子的权值, 2.求连续一段格子权值和, 3.求连续一段格子的最大值. 对于每个2.3操作输出你所求 ...

  5. [蓝桥杯]ALGO-8.算法训练_操作格子

    题目描述: 问题描述 有n个格子,从左到右放成一排,编号为1-n. 共有m次操作,有3种操作类型: .修改一个格子的权值, .求连续一段格子权值和, .求连续一段格子的最大值. 对于每个2.3操作输出 ...

  6. 算法笔记_196:历届试题 剪格子(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 如下图所示,3 x 3 的格子中填写了一些整数. +--*--+--+|10* 1|52|+--****--+|20|30* 1|**** ...

  7. 算法笔记_185:历届试题 格子刷油漆(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 X国的一段古城墙的顶端可以看成 2*N个格子组成的矩形(如下图所示),现需要把这些格子刷上保护漆. 你可以从任意一个格子刷起,刷完一格,可 ...

  8. 算法笔记_064:蓝桥杯练习 操作格子(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 有n个格子,从左到右放成一排,编号为1-n. 共有m次操作,有3种操作类型: 1.修改一个格子的权值, 2.求连续一段格子权值和, 3.求 ...

  9. SLG, 菱形格子的算法.(递归版

    class GeoPoint{ public: int x; int y; public: bool operator == (const GeoPoint& p){ return p.x = ...

随机推荐

  1. ps切图设置

    1. 新建设置 文件->新建->预设->自定义 1920 像素 2000 像素 72 像素/英寸 背景内容 透明 存储预设 2.视图设置 视图->显示->智能参考线选中视 ...

  2. zabbix安装全过程

    在了解<zabbix硬件.软件需求>之后,在你心里应该有备选的机器.今天开始安装zabbix.zabbix需要LNMP或者LAMP环境.环境的搭建不在本章范围内. LNMP环境配置Linu ...

  3. vi和vim区别及命令详解

    vi和vim都是Linux中的编辑器,不同的是vim比较高级,可以视为vi的升级版本.vi使用于文本编辑,但是vim更适用于coding.     现将vim的命令行收集于下: vi有3个模式:插入模 ...

  4. C语言strdup函数

    static RD_INLINE RD_UNUSED char *rd_strdup(const char *s) { #ifndef _MSC_VER char *n = strdup(s); #e ...

  5. ubuntu系统下使用锐捷上网的方法——特快

    1.点击右上方的有线连接: 2.点击编辑连接: 3.选择802.x的安全性分页: 4.勾选下面的单选框: 5.输入登陆账号(通常就是学号),密码(通常是身份证后六位),如果出现了一个“解锁密码环”的对 ...

  6. some experience duing wrting myweb in php

    书写风格:一切以 最高效, 最简单为 标准!! 不必管格式的规范了! 在html中, 的属性是用双引号, 在php, tp中, 没有特殊情况, 都是用单引号. vim 下how to format c ...

  7. Javaee----重新回顾servlet

    最近面临找工作,不得不回顾一下java servelt . 发现lz的基本功还是很差 1. 每一个servlet都必须实现servlet接口,GenericServlet是个通用的.不特定于任何协议的 ...

  8. Excel 使用CHIINV函数和GAMMA.DIST函数绘制卡方分布

    1.使用CHIINV(概率,自由度),在Excel中绘制卡方分布. 若n个独立的随机变量均服从标准正态分布,则这n个随机变量的平方和构成一新的随机变量,其分布规律称为服从自由度为ν 的χ2分布. 2. ...

  9. jquery 使用textarea

    问题: 若在textarea标签中键入一个回车时,将插入2个字符\n\r ,将在datagrid不能正确显示. \n: 回车符 \r: 换行符  解决方案: txt = txt.Replace(&qu ...

  10. OC第一节 —— 类和对象

    一.类和对象的概念 1.1类 自己的定义: 具有相同或相似性质对象的抽象. 1.2 对象 自己的定义: 对象是人们要进行研究的任何物体,从最简单的整数到复杂的飞机 等均可以看做是对象. 举例说明: 类 ...