尽管本小结还不算是独立的游戏,甚至还存在几个Bug,但是初期效果是基本达到了。不过觉得自己在很多设计方面经验不足了,比如对碰撞的反应,虽然碰撞检测做得不错,但是反应得不好的话……还有就是对游戏物体(精灵)与窗口关系的设计。于是觉得小时候玩的家机(连接上电视机那种)的坦克1997十分不错!起码在物体大小形状与窗口关系上设计得不错。
(镰刀造成的“塞车”~) (镰刀手与小四“飞拼”) (小四爆炸)
实现了的(新)功能:
旋转碰撞检测,四点碰撞检测(这里没用了,而改为——),Box碰撞检测,小四的血降、血的显示与渐隐,小四的爆炸,镰刀手的能量的升降,镰刀“飞砍”时刀的变形(我对这个效果非常满意),还有Pause键(Enter,虽然简单,也提出来吧~)。
具体实现:
1、动画效果。
这是上次实现的,不过上次忘了讲了,这次补上。动画图是一张长长的合成图,画图时把图分成几块来画,例如要画一个七帧的100*100的动画,在Draw里设置Source Rectangle设为new Rectangle(100 * frame, 0, 100, 100),其中frame是表示播放帧的序号,从0开始。然后再设计一个函数来控制帧就可以了。例如,最简单的可以在Update里输入:
int time = 0;
time++;
if(time==2)
{
frame++;
time=0;
}
其中time是用来控制帧的播放速度的。
2、旋转碰撞检测。
我也看过不少Xna的真正的旋转碰撞检测函数,不过复杂得看不懂,而且粗略估计一下它的效率不会太高。考虑到我要实现的只是子弹与镰刀的碰撞是需要用来旋转碰撞检测而已,而子弹是圆的,所以可以设想成把窗口旋转一定角度,然后子弹和镰刀都可以当作不旋转处理了。这里的代码十分简单,就是在上次的像素检测之前加入:
float ballpx, ballpy;
float tempx = fireballs[i].px - hooker.px;
float tempy = fireballs[i].py - hooker.py;
float myrot = MathHelper.ToRadians(hooker.rot);
ballpx = (int)(hooker.px + tempx * Math.Cos(myrot) + tempy * Math.Sin(myrot));
ballpy = (int)(hooker.py + tempy * Math.Cos(myrot) - tempx * Math.Sin(myrot));
这里是把子弹的位置旋转了,而镰刀仍是当不旋转处理,就达到了“旋转窗口”的效果。
3、四点碰撞检测。
写一个Object类,这个类就是四个点围成的物体。Object类包含点与Object物体的碰撞检测方法,具体思路是把点代入四个点连成的四条边的方程,如果满足在四条边围成的范围内则物体与点有碰撞。而两个Object的碰撞检测刚是把一个物体的四个点代入另一个物体的方程中,再把另一个物体的四点代入这个物体的方程里,如果有一点符合则两物体有碰撞。
public int inside(int x, int y)
{
for (int i = 0; i < 4; i++)
{
Vector2 fac = line(spinpx[i % 4], spinpy[i % 4], spinpx[(i + 1) % 4], spinpy[(i + 1) % 4]);
if ((y - x * fac.X - fac.Y) * (spinpy[(i + 2)%4] - spinpx[(i +2)%4] * fac.X - fac.Y) < 0)
return 0;
}
return 1;
}
这里Object类里的检测函数;
4、Box碰撞检测。
放弃了Object检测的理由是,因为Object的形状不规则,所以对碰撞上的物体的行动有阻碍,造成行动不流畅。所以改为Box(以长方体包围物体),令人沮丧的是,Box也存在同样的问题。为了克服这个问题,我再设计了一个碰撞反弹反应,但是这个反弹只照顾到正在检测中的物体,而对于更多的其它物体都照顾不到,以至于反弹后反而与别的物体碰撞。这是令我最头痛的问题了。一个物体的Box不是固定的,随着物体的旋转,Box会增大或缩小。具体代码就不多介绍了。
5、小四血的显示与渐隐。
在小四内定义一个byte变量fade,然后再为镰刀手设一个attack函数:
public void attack(Badguy a)
{
if (circlehit(a.fourhandbox, attackr) == 1 && newState.IsKeyDown(Keys.Up) &&
newState.IsKeyUp(Keys.Left)&&attackbool ==1)
{
attacktime++;
if (attacktime > 1)
{
a.fade = 200;
a.showblood = 1;
a.showbloodtime = 0;
a.lifevalue -= 1;
attacktime = 0;
}
}
}
其中showblood为1时显示小四的血条,attacktime是用来控制攻击的频率的。
6、Pause效果。
在Update下设一个gamestop,如果它为-1的话Update的内容才运行,如果为1的话就不运行。如果按下Enter键,gamestop*=-1;搞定~
学习心得:
这周的学习相当困难,例如小四的爆炸图,参考了不少的游戏才画出来的,而且由于画工有限……仅是画小四的爆炸图就画了两天。还有镰刀与小四摩擦的火花效果,目前还没研究出来。代码方面,小聪明似乎也用尽了。经验问题渐渐显出来,看来要适当充电一下。由于这次困难重重,花了不少的时间,功课也担阁不少了。而且近两周还有各种测验,就先放松一下Xna学习吧。下周交个机器时代游戏策划好了。嘿嘿……
/Files/sysudm/MachineTime2.rar
浙公网安备 33010602011771号