c#控件弹幕效果_基于C#弹幕类射击游戏的实现——(十)整合
先看實現(xiàn)的效果
剩下部分代碼,首先是入口,MainForm
public partial class MainForm : Form
{
public MainForm()
{
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
//
// TODO: Add constructor code after the InitializeComponent() call.
//
this.ClientSize = new Size(Config.ScreenWidth, Config.ScreenHeight);
this.StartPosition = FormStartPosition.CenterScreen;
this.pictureBox1.Location = new Point(0, 0);
this.pictureBox1.ClientSize = new Size(Config.ScreenWidth, Config.ScreenHeight);
this.DoubleBuffered = true;
}
private Game.GameScene scene;
private void RenderOver(object sender)
{
this.pictureBox1.Image = scene.Surface;
this.Text = "FPS:" + scene.FPS.ToString();
}
void MainFormLoad(object sender, EventArgs e)
{
Resources.Load("Bullets.png");
Resources.Load("Background.bmp");
Resources.Load("Res.bmp");
Resources.Load("BulletsAll.png");
Resources.Load("Player.png");
Resources.Load("Bomb.png");
Resources.Load("Enemy.png");
Resources.Load("Boss1.png");
Resources.Load("PlayerPoint.png");
Resources.Load("Hp.png");
for ( int i = 0; i < Config.BulletTypeCount; i++ )
{
Resources.Load("Bullet" + i.ToString() + ".png");
}
Data.BulletSource = Resources.Get("Bullets");
Data.BackgroundSource = Resources.Get("Background");
Data.BulletAllSource = Resources.Get("BulletsAll");
Data.PlayerSource = Resources.Get("Player");
Data.PlayerPointSource =Resources.Get("PlayerPoint");
Data.BombSource = Resources.Get("Bomb");
Data.EnemySource = Resources.Get("Enemy");
Data.Boss1Source = Resources.Get("Boss1");
Data.HpSource = Resources.Get("Hp");
Data.BulletsSource = new Bitmap[Config.BulletTypeCount];
for ( int i = 0; i < Config.BulletTypeCount; i++ )
{
Data.BulletsSource[i] = Resources.Get("Bullet" + i.ToString());
}
Data.BulletAllSource.MakeTransparent(Color.FromArgb(255, 0, 255));
Data.PlayerSource.MakeTransparent(Color.FromArgb(255, 0, 255));
Data.BombSource.MakeTransparent(Color.FromArgb(255, 0, 255));
Data.EnemySource.MakeTransparent(Color.FromArgb(255, 0, 255));
Data.Boss1Source.MakeTransparent(Color.FromArgb(255, 0, 255));
scene = new STG.Game.GameScene();
scene.RenderOver += RenderOver;
}
void MainFormKeyDown(object sender, KeyEventArgs e)
{
Input.KeyDown(e.KeyCode);
}
void MainFormKeyUp(object sender, KeyEventArgs e)
{
Input.KeyUp(e.KeyCode);
}
}
這里面用到了Resource和Data。
Resource用來管理資源,其實最開始打算是這樣的,后來。。。沒寫,就成下面這樣了
public static class Resources
{
private static Hashtable mRes;
static Resources()
{
mRes = new Hashtable();
}
public static void Load(string path)
{
Bitmap res = new Bitmap(System.Windows.Forms.Application.StartupPath + @"\Resources\" + path);
if ( res == null )
{
Log.Error("Can't load : " + System.Windows.Forms.Application.StartupPath + @"\Resources\" + path);
return;
}
string name = string.Empty;
int start = path.LastIndexOf('\\');
int end = path.LastIndexOf('.');
if ( start == -1 )
{
start = 0;
}
name = path.Substring(start, end);
mRes.Add(name, res);
}
public static Bitmap Get(string name)
{
return mRes[name] as Bitmap;
}
}
完全是多此一舉的感覺啊。。哈哈
然后是Data,保存一些大家共用的圖片啊,數(shù)據(jù)啊
public static class Data
{
public static Bitmap BulletSource = null;
public static Bitmap BackgroundSource = null;
public static Bitmap BulletAllSource = null;
public static Bitmap PlayerSource = null;
public static Bitmap PlayerPointSource = null;
public static Bitmap HpSource = null;
public static Bitmap BombSource = null;
public static Bitmap EnemySource = null;
public static Bitmap Boss1Source = null;
public static Bitmap [] BulletsSource = null;
public static Font NormalFont = new Font("Arial", 12);
public static Random Rnd = new Random(DateTime.Now.Millisecond);
///
/// 2 * PI
///
public static float TwoPI = (float)Math.PI * 2.0f;
///
/// 弧度單位
///
public static float Radian = (float)Math.PI / 180.0f;
///
/// 不同類型的敵人位圖在圖庫中的位置
///
public static Rectangle[] EnemySourceRectangle = new Rectangle[]
{
new Rectangle(0, 0, 34, 31), // (1, 1) Enemy 第1排 第1個
new Rectangle(35, 0, 31, 33), // (1, 2)
new Rectangle(0, 33, 33, 27), // (2, 1)
new Rectangle(67, 0, 36, 32), // (1, 3)
new Rectangle(104, 0, 30, 36), // (1, 4)
new Rectangle(133, 54, 38, 22), // (2, 4)
new Rectangle(39, 34, 42, 39), // (2, 2)
new Rectangle(82, 39, 48, 34), // (2, 3)
new Rectangle(135, 0, 64, 53) // (1, 5)
};
///
/// 不同類型的敵人的碰撞盒子(X,Y相對于位圖中心點的便宜,W,H大小)
///
public static Rectangle[] EnemyBoxColliderRectangle = new Rectangle[]
{
new Rectangle(0, 0, 34, 31), // (1, 1) Enemy 第1排 第1個
new Rectangle(0, 0, 31, 33), // (1, 2)
new Rectangle(0, 0, 33, 27), // (2, 1)
new Rectangle(0, 0, 36, 32), // (1, 3)
new Rectangle(0, 0, 30, 36), // (1, 4)
new Rectangle(0, 0, 38, 22), // (2, 4)
new Rectangle(0, 0, 23, 39), // (2, 2)
new Rectangle(0, -5, 48, 24), // (2, 3)
new Rectangle(0, -10, 64, 37) // (1, 5)
};
///
/// 不同子彈類型的大小
///
public static Size[] BulletsSize = new Size[]
{
new Size(10, 10),
new Size(16, 14),
new Size(18, 18),
new Size(18, 18),
new Size(9, 17),
new Size(9, 17),
new Size(7, 44)
};
public enum MouseButton
{
Left,
Right,
Middle
}
///
/// 方向
///
public enum Direction
{
None,
Up,
Down,
Left,
Right,
LeftUp,
LeftDown,
RightUp,
RightDown
}
}
///
/// Bottom : 0
/// Background : 10
/// Floor : 20
/// Map : 30
/// Object : 40
/// Effect : 50
/// Sky : 80
/// UI : 90
/// Top : 100
///
public static class DepthLayer
{
public const int Bottom = 0;
public const int Background = 10; // 背景層
public const int Map = 20; // 地表層
public const int Bullet = 30; // 子彈層
public const int Object = 40; // 單位層
public const int Effect = 50; // 特效層
public const int UI = 90; // UI層
public const int Top = 100;
}
然后是播放聲音,網(wǎng)上找的一個類
public class GameSound
{
protected const int SND_SYNC = 0x0;
protected const int SND_ASYNC = 0x1;
protected const int SND_NODEFAULT = 0x2;
protected const int SND_MEMORY = 0x4;
protected const int SND_LOOP = 0x8;
protected const int SND_NOSTOP = 0x10;
protected const int SND_NOWAIT = 0x2000;
protected const int SND_ALIAS = 0x10000;
protected const int SND_ALIAS_ID = 0x110000;
protected const int SND_FILENAME = 0x20000;
protected const int SND_RESOURCE = 0x40004;
protected const int SND_PURGE = 0x40;
protected const int SND_APPLICATION = 0x80;
[DllImport("Winmm.dll", CharSet=CharSet.Auto)]
protected extern static bool PlaySound(string strFile, IntPtr hMod, int flag );
//播放聲音函數(shù)
//strSoundFile --- 聲音文件
//bSynch --- 是否同步,如果為True,則播放聲音完畢再執(zhí)行后面的操作,為False,則播放聲音的同時繼續(xù)執(zhí)行后面的操作
public static bool PlaySoundFile(string strSoundFile, bool bSynch)
{
if(!System.IO.File.Exists(strSoundFile))
return false;
int Flags;
if(bSynch)
Flags = SND_FILENAME | SND_SYNC;
else
Flags = SND_FILENAME | SND_ASYNC;
return PlaySound(strSoundFile, IntPtr.Zero, Flags);
}
剩下的一些Log啊,GPoint啊~~都是無關(guān)緊要的,自己實現(xiàn)或者不要都行
整個游戲就這么完成了。勉強算是半成品
對了,差點忘了,載入地圖資源的函數(shù)沒給出
private void LoadMapInfo(string path)
{
try
{
StreamReader fp = new StreamReader(path, Encoding.Default);
int timeIndex = 0;
while ( fp.EndOfStream == false )
{
string line = fp.ReadLine();
if ( line.StartsWith("[") && line.EndsWith("]") )
{
timeIndex = int.Parse(line.Substring(1, line.Length - 2));
continue;
}
if ( timeIndex >= Config.OneMapTime )
{
Log.Error("索引超出地圖最大限制");
fp.Close();
return;
}
mMapInfo[timeIndex].Add(line);
}
fp.Close();
}
catch(Exception ce)
{
Log.Error(ce.Message);
}
}
private void DealMapInfo(int index)
{
if ( index < 0 || index >= Config.OneMapTime )
{
return;
}
if ( mMapInfo[index].Count == 0 )
{
return;
}
foreach ( string line in mMapInfo[index] )
{
string [] param = line.Split(',');
Vector2 pos = new Vector2(int.Parse(param[1]), int.Parse(param[2]));
if ( pos.X == -1 )
{
pos.X = Config.ScreenWidth / 2;
}
if ( pos.Y == -1 )
{
pos.Y = Config.ScreenHeight / 2;
}
switch ( param[0] )
{
case "Enemy1":
AddEnemy(new Enemy1(pos));
break;
case "Enemy2":
AddEnemy(new Enemy2(pos));
break;
case "Enemy3":
AddEnemy(new Enemy3(pos));
break;
case "Enemy4":
AddEnemy(new Enemy4(pos));
break;
case "Enemy5":
AddEnemy(new Enemy5(pos));
break;
case "Enemy6":
AddEnemy(new Enemy6(pos));
break;
case "Enemy7":
AddEnemy(new Enemy7(pos));
break;
case "Enemy8":
AddEnemy(new Enemy8(pos));
break;
case "Enemy9":
AddEnemy(new Enemy9(pos));
break;
case "Boss1":
AddBoss(new Boss1(mBarrage, pos));
break;
default:
break;
}
}
}
public bool InScreen(Box box)
{
if ( box.Left > Config.ScreenWidth )
{
return false;
}
if ( box.Right < 0 )
{
return false;
}
if ( box.Top > Config.ScreenHeight )
{
return false;
}
if ( box.Bottom < 0 )
{
return false;
}
return true;
}
這一部分用于從文件中載入配置,動態(tài)的生成敵人
好了,半成品完成了~~貌似我沒講什么啊。。。哎,不太會寫博客啊,下面一個游戲?qū)W著多講一些吧
總結(jié)
以上是生活随笔為你收集整理的c#控件弹幕效果_基于C#弹幕类射击游戏的实现——(十)整合的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 机械臂运动空间的计算_机器人学导论---
- 下一篇: Java后端真实面试题大全(有详细答案)