基于C#彈幕類射擊游戲的實現(xiàn)——(三)子彈的實現(xiàn)

到這里律歼,我們似乎該讓主角上場了,好就讓我們來顯示一顆子彈吧~
慢著啡专,顯示子彈之前险毁,我們需要小小的抽象一下,把游戲中所有能顯示的物體抽象们童。

/// <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);
大概就是這樣

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市苛坚,隨后出現(xiàn)的幾起案子澈缺,更是在濱河造成了極大的恐慌,老刑警劉巖炕婶,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件姐赡,死亡現(xiàn)場離奇詭異,居然都是意外死亡柠掂,警方通過查閱死者的電腦和手機(jī)项滑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來涯贞,“玉大人枪狂,你說我怎么就攤上這事∷斡妫” “怎么了州疾?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長皇拣。 經(jīng)常有香客問我严蓖,道長,這世上最難降的妖魔是什么氧急? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任颗胡,我火速辦了婚禮,結(jié)果婚禮上吩坝,老公的妹妹穿的比我還像新娘毒姨。我一直安慰自己,他們只是感情好钉寝,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布弧呐。 她就那樣靜靜地躺著,像睡著了一般嵌纲。 火紅的嫁衣襯著肌膚如雪俘枫。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天疹瘦,我揣著相機(jī)與錄音崩哩,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛邓嘹,可吹牛的內(nèi)容都是我干的酣栈。 我是一名探鬼主播,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼汹押,長吁一口氣:“原來是場噩夢啊……” “哼矿筝!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起棚贾,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤窖维,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后妙痹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體铸史,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年怯伊,在試婚紗的時候發(fā)現(xiàn)自己被綠了琳轿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡耿芹,死狀恐怖崭篡,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情吧秕,我是刑警寧澤琉闪,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站砸彬,受9級特大地震影響颠毙,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜拿霉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一吟秩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧绽淘,春花似錦、人聲如沸闹伪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽偏瓤。三九已至杀怠,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間厅克,已是汗流浹背赔退。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人硕旗。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓窗骑,卻偏偏與公主長得像,于是被迫代替她去往敵國和親漆枚。 傳聞我的和親對象是個殘疾皇子创译,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)墙基,斷路器软族,智...
    卡卡羅2017閱讀 134,654評論 18 139
  • 這是今天的成果吧,雖然還是沒有全部完成,但是大致的功能已經(jīng)實現(xiàn),飛機(jī)的移動,限制移動范圍,子彈的發(fā)射,消滅敵人,敵...
    Unity學(xué)習(xí)的路上閱讀 2,839評論 1 2
  • 有了子彈残制,子彈想有個飛機(jī)能發(fā)射子彈了立砸。好,現(xiàn)在我們就實現(xiàn)玩家的戰(zhàn)機(jī) 這是玩家類的定義初茶,當(dāng)然也是繼承自GameObj...
    UnSkyToo閱讀 499評論 0 1
  • 昨天颗祝,4.2班的老師,來到我們教室為我們講一節(jié)作文課纺蛆,老師在講作文的時候也給我們帶來了一個游戲吐葵,叫“擊鼓傳花...
    王楊晨閱讀 305評論 0 1
  • 華為Mate 9試機(jī)照 華為Mate 9試機(jī)照 Mate 9試機(jī)照 華為Mate 9試機(jī)照 華為Mate 9試機(jī)照...
    靈津渡閱讀 221評論 0 1