到这里,我们似乎该让主角上场了,好就让我们来显示一颗子弹吧~
慢着,显示子弹之前,我们需要小小的抽象一下,把游戏中所有能显示的物体抽象。
/// <summary>
/// Description of GameObject.
/// </summary>
public class GameObject
{
public Vector2 Position;
public Box BoxCollider;
protected int Width;
protected int Height;
protected int HalfWidth;
protected int HalfHeight;
public GameObject()
{
}
public virtual void Update(float elapsedTime)
{
}
public virtual void Render(Graphics g)
{
}
}
封装了一些基础属性和方法~~特别说明下:HalfWidth和HalfHeight只是用于计算的时候少一个除法,可以不需要的,后面的代码会看到
对了,特别说明下:一般的坐标系是以左上角为(0,0)点,向右为X正方向,向下为Y正方向。
而这个游戏是以屏幕的中间为远点,绘制图片的时候也是,以图片的中间为绘制点。。。至于为什么这样。。我当时脑抽了,忘了为什么了
接下来就是主角
/// <summary>
/// Description of GameBullet.
/// </summary>
public class GameBullet : GameObject
{
public bool IsOwn; // 是否为自己的子弹
public int Type; // 子弹样式
public int Color; // 子弹颜色(0-6)
public float ActiveDelay; // 延迟多久激活
public Vector2 Speed;
public Vector2 Accel;
public bool IsLive; // 是否存活
public GameBullet(bool isOwn, Vector2 position, Vector2 speed, Vector2 accel, int type, int color, float activeDelay)
{
this.IsOwn = isOwn;
this.Type = type;
this.Color = color;
this.ActiveDelay = activeDelay;
this.Position = position;
this.Speed = speed;
this.Accel = accel;
this.IsLive = true;
this.Width = Data.BulletsSize[type].Width;
this.Height = Data.BulletsSize[type].Height;
this.HalfWidth = this.Width / 2;
this.HalfHeight = this.Height / 2;
this.BoxCollider = new Box((int)position.X, (int)position.Y, this.Width, this.Height);
}
public override void Update(float elaspedTime)
{
if ( IsLive == false )
{
return;
}
if (ActiveDelay > 0)
{
ActiveDelay -= elaspedTime;
return;
}
Speed += (Accel * elaspedTime);
Position += (Speed * elaspedTime);
BoxCollider.X = (int)Position.X;
BoxCollider.Y = (int)Position.Y;
if ( Position.X < 0 || Position.Y < 0 || Position.X > Config.ScreenWidth || Position.Y > Config.ScreenHeight )
{
IsLive = false;
}
}
public override void Render(Graphics g)
{
if ( IsLive == false || ActiveDelay > 0)
{
return;
}
g.DrawImage(Data.BulletsSource[this.Type],
new Rectangle((int)Position.X - HalfWidth, (int)Position.Y - HalfHeight, Width, Height),
new Rectangle(this.Color * Width, 0, Width, Height),
GraphicsUnit.Pixel);
if ( Config.IsDebug && Config.IsShowBox )
{
g.DrawRectangle(Pens.Green, BoxCollider.ToRectangle());
}
}
}
唯一要说明的是Update方法的这两句
Speed += (Accel * elaspedTime);
Position += (Speed * elaspedTime);
通过速度和加速度来更新子弹的位置,并且在后面同步更新碰撞盒的位置
这里用简单的物理知识来模拟了一下粒子的运行~其实可以做的更复杂一点,比如线速度角速度。
我们这里学习用,就简单一点。东方系列就比较复杂了
子弹肯定不止一个,而且有自己的和敌人的
所以需要一个管理类,用于管理一堆子弹
public class GameBulletManager
{
private GameScene mScene;
private List<GameBullet> mBullets;
public GameBulletManager(GameScene scene)
{
this.mScene = scene;
this.mBullets = new List<GameBullet>();
}
public void AddBullet(GameBullet bullet)
{
mBullets.Add(bullet);
}
public void Update(float elapsedTime)
{
// 检测子弹的碰撞
for (int i = 0; i < mBullets.Count; i++)
{
mBullets[i].Update(elapsedTime);
if (mBullets[i].IsLive == false)
{
mBullets.RemoveAt(i);
i--;
continue;
}
if ( mBullets[i].IsOwn == false ) // 不是自己的子弹
{
if ( mScene.Player1.Collide(mBullets[i].BoxCollider, 1) == true )
{
GameBombManager.AddBomb(mBullets[i].Position, false, 0.5f);
mBullets.RemoveAt(i);
i--;
continue;
}
}
else
{
if ( mScene.EnemyManager.Collide(mBullets[i].BoxCollider, 1) == true )
{
GameBombManager.AddBomb(mBullets[i].Position, false, 0.5f);
mBullets.RemoveAt(i);
i--;
continue;
}
if ( mScene.BossManager.Collide(mBullets[i].BoxCollider, 1) == true )
{
GameBombManager.AddBomb(mBullets[i].Position, false, 0.5f);
mBullets.RemoveAt(i);
i--;
continue;
}
}
}
}
public void Render(Graphics g)
{
foreach (GameBullet bullet in mBullets)
{
bullet.Render(g);
}
if ( Config.IsDebug )
{
g.DrawString("Bullets:" + mBullets.Count.ToString(), Data.NormalFont, Brushes.Red, 300, 0);
}
}
}
这里面没有遇到的类暂且不管。
大体上就是用一个List来保存所有GameBullet~~更新和绘制也是一个循环
唯一要做的就是检测子弹和其余单位是否碰撞了,碰撞的话要添加爆炸效果,然后移除这个子弹
好,现在你可以添加几个子弹来玩玩了。
比如,创建一个直线上升的子弹
AddBullet(new Bullet(false, new Vector2(0, 0), new Vector2(0, -300), Vector2.Zero, 0, 0, 0);
创建一个斜着飞的子弹
AddBullet(new Bullet(false, new Vector2(0, 0), new Vector2(300, -300), Vector2.Zero, 0, 0, 0);
创建一个越飞越快的子弹
AddBullet(new Bullet(false, new Vector2(0, 0), new Vector2(0, -300), new Vector2(0, -100), 0, 0, 0);
大概就是这样
网友评论