1.坦克相关信息
这里的各种类型,使用struct而不是enum,避免后面强制转换。
//子弹信息
public struct t_bulletinfo
{
public int idx;//链表中的顺序号
public int dir;//当前方向
public t_bulletinfo(int i, int d)
{
this.idx = i;
this.dir = d;
}
}
//坦克类型
public struct t_type
{
public const int PLAYER = 0; //玩家车
public const int COMMOM = 1; //普通车
public const int FAST = 2; //快车
public const int SLOW = 3; //慢车
public const int ARMORED = 4; //装甲车
}
//坦克行动方向
public struct t_dir
{
public const int DIR_UP = 0;
public const int DIR_DOWN = 1;
public const int DIR_LEFT = 2;
public const int DIR_RIGHT = 3;
public const int DIR_STAY = 4;//不动
}
//公共参数
public struct t_commpar
{
public const int TANKALIVECNTMAX = 3; //爆炸时间
public const int TANKNUMMAX = 20; //坦克最大数目
public const int BULLETNUMMAX = 20; //单量坦克的最大子弹显示子弹数
public const int PIXMIN = 2; //最小行动距离
public const int TANKSIZEX = 64;//坦克长度
public const int TANKSIZEY = 64;//坦克宽度
public const int BULLETSIZEX = 32;//子弹长度
public const int BULLETSIZEY = 32;//子弹宽度
public static int MAPSIZEX = 896; //默认地图大小
public static int MAPSIZEY = 896; //默认地图大小
public static Point playerStartLocation ;//玩家坦克的开始位置
}
2.坦克类
设计框架是,很纠结一点:碰撞检测函数,应该写在主程序类,还是写在坦克类,作为坦克的成员函数?后来“方便”打败其他一切,毕竟生成一个坦克实例,也就生成对应成员函数,然后直接加到委托里面,一次调用,太省事了,避免主程序一个个轮询。
车体:4个方向使用不同 的检测函数
/// <summary>
/// 检测是否顺通[分别4个方向]
/// </summary>
/// <returns>false:阻碍;true:顺通</returns>
bool carDetectUP()
{
this.tankSpeed = this.tankSpeedbk;//恢复速度
//检测与别的车是否碰撞
foreach (var i in map.tkinfos)
{
if (i.uid != uuid)
{
if (location.Y <= (i.Y + t_commpar.TANKSIZEY) && location.Y >= i.Y && location.X + t_commpar.TANKSIZEX > i.X && location.X < i.X + t_commpar.TANKSIZEX)
{
return false;
}
}
}
//检测与地图元素是否碰撞
int x1 = location.X + (t_commpar.PIXMIN * tankSpeed) / 2 + c_map.OFFET;
int y1 = location.Y - (t_commpar.PIXMIN * tankSpeed) / 2 + c_map.OFFET;
int x2 = location.X + t_commpar.TANKSIZEX - (t_commpar.PIXMIN * tankSpeed) / 2 + c_map.OFFET;
int y2 = location.Y - (t_commpar.PIXMIN * tankSpeed) / 2 + c_map.OFFET;
if (x1 < 0 + c_map.OFFET || x1 >= t_commpar.MAPSIZEX + c_map.OFFET || x2 < 0 + c_map.OFFET || x2 >= t_commpar.MAPSIZEX + c_map.OFFET || y1 < 0 + c_map.OFFET || y1 >= t_commpar.MAPSIZEY + c_map.OFFET || y2 < 0 + c_map.OFFET || y2 >= t_commpar.MAPSIZEY + c_map.OFFET)
{
return false;
}
else
{
byte t1 = map.mask[x1, y1];
byte t2 = map.mask[x2, y2];
//根据地图元素处理
return docarForMap(t1, t2);
}
}
子弹:4个方向使用不同 的检测函数
/// <summary>
/// 子弹检测
/// </summary>
/// <param name="pt">子弹位置</param>
/// <param name="xrt">需要消灭的位置</param>
/// <param name="fill">消灭方式(弃用)</param>
/// <returns>本子弹是否需要销毁</returns>
bool bulletDetectUP(Point pt, ref Rectangle xrt, ref byte fill)
{
this.bulletSpeed = this.bulletSpeedbk;//恢复子弹速度
//检测是否击中坦克车子
foreach (var i in map.tkinfos)
{
if (i.uid != uuid)
if (new Rectangle(pt, new Size(t_commpar.BULLETSIZEX, t_commpar.BULLETSIZEY)).IntersectsWith(new Rectangle(i.X, i.Y, t_commpar.TANKSIZEX, t_commpar.TANKSIZEY)))
{
bingo = i.uid; //记录击中的目标
return false;
}
}
//检测地图元素
{
int x1 = pt.X + c_map.OFFET;
int y1 = pt.Y + c_map.OFFET;
int x2 = pt.X + t_commpar.BULLETSIZEX + c_map.OFFET;
int y2 = pt.Y + c_map.OFFET;
if (x1 < 0 + c_map.OFFET || x1 >= t_commpar.MAPSIZEX + c_map.OFFET || x2 < 0 + c_map.OFFET || x2 >= t_commpar.MAPSIZEX + c_map.OFFET || y1 < 0 + c_map.OFFET || y1 >= t_commpar.MAPSIZEY + c_map.OFFET || y2 < 0 + c_map.OFFET || y2 >= t_commpar.MAPSIZEY + c_map.OFFET)
{
return false;
}
//获取地图元素号
byte t1 = map.mask[x1, y1];
byte t2 = map.mask[x2, y2];
if (t1 == 0 && t2 == 0) return true;
//获取地图元素生命值
int hp1 = map.mapHps[pt.X / t_commpar.TANKSIZEX, pt.Y / t_commpar.TANKSIZEY];
int hp2 = map.mapHps[(pt.X + t_commpar.BULLETSIZEX) / t_commpar.TANKSIZEX, pt.Y / t_commpar.TANKSIZEY];
//获取地图元素类型
tlandformType lft1 = map.tlandforms[t1];
tlandformType lft2 = map.tlandforms[t2];
//处理不同地图元素
if (lft1.bulletpass && lft2.bulletpass)
{
this.bulletSpeed = this.bulletSpeedbk + (int)(this.bulletSpeedbk * (lft1.bulletspeed + lft2.bulletspeed) / 200.0);
if (this.bulletSpeed < 4) this.bulletSpeed = 4;
}
else
{
if (!lft1.bulletpass && lft1.hp > 0)
{
if (hp1 > 1) { map.mapHps[pt.X / t_commpar.TANKSIZEX, pt.Y / t_commpar.TANKSIZEY]--; }
else
{
xrt = new Rectangle(pt.X - pt.X % t_commpar.TANKSIZEX, pt.Y - pt.Y % t_commpar.TANKSIZEY, t_commpar.TANKSIZEX, t_commpar.TANKSIZEY);
clearmask(xrt);
fill = 1;
}
}
else
if (!lft2.bulletpass && lft2.hp > 0)
{
if (hp2 > 1) { map.mapHps[(pt.X + t_commpar.BULLETSIZEX) / t_commpar.TANKSIZEX, pt.Y / t_commpar.TANKSIZEY]--; }
else
{
xrt = new Rectangle(pt.X - pt.X % t_commpar.TANKSIZEX + t_commpar.TANKSIZEX, pt.Y - pt.Y % t_commpar.TANKSIZEY, t_commpar.TANKSIZEX, t_commpar.TANKSIZEY);
clearmask(xrt); //
fill = 1;
}
}
return false;
}
}
return true;
}
代码太长,需要的朋友可以下载。
4.效果