到這里律歼,我們似乎該讓主角上場了,好就讓我們來顯示一顆子彈吧~
慢著啡专,顯示子彈之前险毁,我們需要小小的抽象一下,把游戲中所有能顯示的物體抽象们童。
/// <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)
{
}
}
封裝了一些基礎(chǔ)屬性和方法~~特別說明下:HalfWidth和HalfHeight只是用于計算的時候少一個除法畔况,可以不需要的,后面的代碼會看到
對了病附,特別說明下:一般的坐標(biāo)系是以左上角為(0问窃,0)點(diǎn),向右為X正方向完沪,向下為Y正方向。
而這個游戲是以屏幕的中間為遠(yuǎn)點(diǎn)嵌戈,繪制圖片的時候也是覆积,以圖片的中間為繪制點(diǎn)。熟呛。宽档。至于為什么這樣。庵朝。我當(dāng)時腦抽了吗冤,忘了為什么了
接下來就是主角
/// <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);
通過速度和加速度來更新子彈的位置,并且在后面同步更新碰撞盒的位置
這里用簡單的物理知識來模擬了一下粒子的運(yùn)行~其實可以做的更復(fù)雜一點(diǎn)九府,比如線速度角速度椎瘟。
我們這里學(xué)習(xí)用,就簡單一點(diǎn)侄旬。東方系列就比較復(fù)雜了
子彈肯定不止一個肺蔚,而且有自己的和敵人的
所以需要一個管理類,用于管理一堆子彈
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~~更新和繪制也是一個循環(huán)
唯一要做的就是檢測子彈和其余單位是否碰撞了宣羊,碰撞的話要添加爆炸效果璧诵,然后移除這個子彈
好,現(xiàn)在你可以添加幾個子彈來玩玩了仇冯。
比如之宿,創(chuàng)建一個直線上升的子彈
AddBullet(new Bullet(false, new Vector2(0, 0), new Vector2(0, -300), Vector2.Zero, 0, 0, 0);
創(chuàng)建一個斜著飛的子彈
AddBullet(new Bullet(false, new Vector2(0, 0), new Vector2(300, -300), Vector2.Zero, 0, 0, 0);
創(chuàng)建一個越飛越快的子彈
AddBullet(new Bullet(false, new Vector2(0, 0), new Vector2(0, -300), new Vector2(0, -100), 0, 0, 0);
大概就是這樣