点我查看《混战》源码

目录

第1章 任务描述

第二章 总体设计

第三章 详细设计

第四章 介面设计

第5章 代码设计

第六章 总结

第七章 参考文献


摘  要

Microsoft给开发人员一个选择-一专门用于. NET、具有新起点的语言,即Visual C# .NET。Microsoft 在正式场合把C#描述成一种简单、现代、面向对象、类型非常安全、派生于C和C++的编程语言。大多独立的评论员对其说法是“继承于C、C++和Java”。这种描述在技术上是非常精准的,但没有涉及到该种语言的真正优点。从语法上看,C#非常类同于C++和Java, 许多关键字都是相同的,C#也使用类似于C++和Java的块状结构,并用括号( {} )来标识代码块,用分号分隔各行语句。对C#代码的第一个印象是它非常类似于C++或Java代码。但在这些表面级的类似性后面,C#学习起来要比C++轻松得多,但比Java难一些。 其设计与现代开发工具的可适应性要比其他语言更高,它同时具有Visual Basic 的易用性、高性能以及C++的低级内存访问性。

在游戏开发领域,C#已经逐渐变成了使用人数最多的语言。不仅是Unity,还有一些新兴的游戏引擎也采用了C#语言(比如godot引擎)。

在游戏行业从业多年的开发者,大都掌握多门开发语言,可以对比评测。总体来看,C#在游戏开发领域口碑非常不错,具体在学习上手、招聘人才、编程规范、运行性能方面都做的十分平衡,没有明显的缺陷。

除游戏前端,C#和.net技术在游戏后端(游戏服务器)也获得了越来越广泛的应用,以前C#在linux上运行有一些问题,现在有了.net core,问题基本解决。

现在市面上大部分游戏都能盈利,相对比影视来讲,影视开发周期长,上线后能不能盈利还不好说。 现在是市场经济,都追求能快熟盈利的产品无论你在哪里,只要有手机,电脑,iPad,估计您都能看到玩游戏的人,VR虚拟游戏体验也非常受大众喜爱,特别是90后,00后,对游戏的接受喜爱程度都很高

这已经足以支撑游戏产业的蓬勃发展,所以,游戏在未来将会越来越火,这一行的薪资待遇自然是非常不错的。

关键词:c#;游戏;.net技术;

1 任务描述

在Visual Studio平台下基于C# 利用Form.NET编程独立游戏,塔防卡牌游戏《混战》,并完成以下的总体目标:

  1. 体现出面向对象思想的三大特性:封装,继承,多态。
  2. 自主设计,体现出卡牌,对战,角色扮演的游戏要素。
  3. 在游戏中加载基本的图片和音效资源,实现基础打击反馈。
  4. 至少有一个开始界面和游戏界面。
  5. 利用拖动和手动编程俩种方法来生成和显示控件。
  6. 利用属性事件填写和自定义委托俩种方法来完成事件绑定。
  7. 游戏完成后,录制视频,进行简单的游戏介绍和编程思想解释。

第二章 总体设计

2.1 框架结构

表2.1 框架结构

平台

Window10

软件

Visual Studio 2019

编程语言

C#

编程框架

WinForm.NET窗体应用程序

2.2 目录结构

图2.1目录结构图

2.3 下载资源

2.3.1 图片资源

图2.2 图片资源

2.3.2 音效资源

图2.3 音效资源

第三章 详细设计

列出了主要类和主要方法名,以及类和方法的用途,方法体内容省略,进行大概理解整体框架结构。主要有Manager类,People类,role类组,Player类和俩个辅助类MCI类和PanelEnhanced类。

3.1 Manager类

用于统筹管理,进行显示和数据管理,对整个系统进行整合,关联所有类

class Manager{Form cform = new Form();public int mouse_int = 0;//鼠标编号public static List<People> roles = new List<People>();//角色图签,只是可读public Player I_Player = new Player(1);//自己玩家public Player E_Player = new Player(2);//敌人玩家public List<People> road1 = new List<People>();//1路自己public List<People> eroad1 = new List<People>();//1路敌人public List<People> road2 = new List<People>();//2路自己public List<People> eroad2 = new List<People>();//2路敌人public List<People> road3 = new List<People>();//3路自己public List<People> eroad3 = new List<People>();//3路敌人int E_MaxValue = 0;Button PB = new Button();//头像框Button I_HPB = new Button();//血条框Button E_HPB = new Button();//敌人血条框public Manager(){...}//初始化-无参构造函数public void Ini_Eintlist(){...}//敌人卡牌集初始化public void AddRoles(){...}//图签初始化public  void GenerateRole(int sum,int team,int road){...}//生成角色,sun编号,team队伍,road生成道路public void addform(Form _cform){...}//绑定当前窗口 初始化窗口控件位置 卡牌框组样式既位置
public void Move_or_Atk(){...}//检测移动攻击//以下私有成员函数,用于简化前面公有函数所提取
private void random(int[] a,int n){...}//不重复随机整数数组生成,用于初始化敌人卡牌图签
private void change_mouse(object sender,EventArgs e){...}//点击角色卡牌,鼠标数值变化private void Place_people(Object sender,EventArgs e){...}//放置角色卡牌
private void cards_down(){...} //点击其他地方 卡牌下移private void Addroad(People p, int road){...}//把某人加到某路
private void Fram_rate(){...}//帧率:敌我血条变化 金币显示 敌人AI出兵 敌我增长钱
private void one_MA(List<People> road1, List<People> eroad1){...}//一路检测移动攻击
private void ATK_one(List<People> road1, List<People> eroad1){...}
private void check_state(List<People> road1){...}//状态检测
private void check_die(){...} //检测死亡和兵走到路尽头扣血}

3.3 Player类

玩家类,继承People,用于判断游戏输赢,拥有自己卡牌组和金币

 class Player:People{public int[] intList= new int[6];//自己的卡牌号码组public int gold=13;//玩家金币public int gold_getspeed=10;//玩家得到金币速度public int gold_time = 0;//满百得1public int grade=1;//玩家等级public Player(){...}//无参构造,初始化玩家血量public Player(int _team) : this(){...}//生成有位置,有队伍的图片,且调用无参构造public void addgold()//自动增长金币//以下为无用的空函数,为了满足抽象类People重写public override void atk_sound(){}public override void PassiveSkill(List<People> road1, List<People> eroad1, People ep){}public override void Skill(List<People> road1, List<People> eroad1, People ep)public override void skill_sound(){}public override void Skill_time_change(){}
}

3.4 role类组举例

卡牌角色类,继承People,游戏中基本单位,拥有各自的特征(生命,攻击,移速,攻速,图片,技能等等....)可实现扩展,用其中之一类SwordMan剑士类作为举例:

图3.1  role类组包含的角色类

【举例】SwordMan类:

class SwordMan : People{   public SwordMan()//角色初始化{NAME = "剑士";//名称num = 1;//编号VALUE = 14;//购买价格MHP = 100;//最大血量HP = 100;//血量ATK = 10;//攻击力DEF = 10;//防御力 减伤百分比=防御力/(防御力+X)ATK_mothod = 1;//攻击方法ATK_range = 10;//攻击范围ATK_speed = 10;//攻击速度SPEED = 10;//移动速度PBox.Image = System.Drawing.Image.FromFile(@"..//..//Resources//剑.png");//队伍team//显示框PBox//当前位置_P}
public SwordMan(int _team):this(){...}//生成有位置,有队伍的图片,调用无参构造
public override void Skill_time_change(){...}//损失血量增加技能释放概率
public override void Skill(List<People> road1,List<People> eroad1,People ep){...}//主动技能 激励:攻速加快
public override void PassiveSkill(List<People> road1, List<People> eroad1, People ep){}//被动技能:无
public override void atk_sound(){...}//攻击音效
public override void skill_sound(){...}//技能音效
}

3.5 MCI类

自带的音乐播放函数System.Meida.SoundPlayer(),会造成播放阻塞,不能同时播放俩首音乐。为了使得游戏音效重叠播放需要自定义音乐播放类.用线程来解决在播放的时候指定wait时产生线程阻塞,从而导致界面假死的现象。

public class MCI{[DllImport("winmm.dll")]private static extern long mciSendString(string command,      //MCI命令字符串string returnString, //存放反馈信息的缓冲区int returnSize,      //缓冲区的长度IntPtr hwndCallback  //回调窗口的句柄,一般为NULL);     private Thread thread;private void PlayWait(string file){...}// 按指定次数播放
private void PlayRepeat(string file){...}  // 循环播放public void Play(string file, int times){...}//播放音频文件public void Exit(){...}// 结束播放的线程
}

3.6自定义控件PanelEnhanced类

由于背景图的存在,当角色移动时,由于窗口频繁刷新会产生角色白光闪烁,为解决这一问题,需要自定义Panel控件重写里面的函数,来放置背景,利用双缓冲区解决问题

class PanelEnhanced : Panel{
protected override void OnPaintBackground(PaintEventArgs e){...}// 重载基类的背景擦除函数, 解决窗口刷新,放大,图像闪烁
protected override void OnPaint(PaintEventArgs e){...}// 使用双缓冲 背景重绘移动到此
}

 第四章 介面设计

为适应游戏的可扩展性,只有少部分不动的控件利用拖动和属性修改器进行生成控件,但为了随着游戏的随机性和角色图签的扩展性,是通过代码来根据数据自动生成界面。

4.1 开始界面

图4.1 开始界面

其中只有“请选择六名角色卡牌”是拖动Label控件完成,其他都是代码书写样式并显示,下面展示样式及其按钮事件代码

 public partial class Start : Form{int selectCount = 0;public static int[] intlist=new int[6];public Start(){InitializeComponent();}private void Start_Load(object sender, EventArgs e){  int x = this.Width;//获得屏幕宽度
// 卡牌样式for (int i = 0; i < Manager.roles.Count; i++){Button B_I_role = new Button();B_I_role.Size = new Size(150,150);this.Controls.Add(B_I_role);B_I_role.Location = new Point(i*160%(Width-150), (i*160/(Width-150))*160+100);B_I_role.Name = "button" + Convert.ToString(i);B_I_role.Text = Convert.ToString(i + 1)+Manager.roles[i].NAME;B_I_role.TextAlign = ContentAlignment.TopCenter;B_I_role.Image = Manager.roles[i].PBox.Image;B_I_role.Click += new EventHandler(select);//绑定按钮事件B_I_role.Tag ="0";}//开始按钮及其样式Button Run = new Button();Run.Size = new Size(300, 50);this.Controls.Add(Run);Run.Location = new Point(600,700);Run.Text = "开始";Run.TextAlign = ContentAlignment.MiddleCenter;Run.Click += new EventHandler(run);//绑定按钮事件Run.Tag = "0";}
//开始按钮点击事件private void select(object sender, EventArgs e){Button button = (Button)sender;//获取调用事件的主体for (int i = 0; i < Manager.roles.Count; i++){if (button.Name == "button" + Convert.ToString(i))//找到所点击的按钮{  if ((string)button.Tag == "0"&&selectCount<6) { button.Tag ="1";selectCount++; button.BackColor = Color.Red;for (int j = 0; j < 6; j++){if (intlist[j] == 0){ intlist[j]= i+1;break;}                      }break; };if ((string)button.Tag == "1") { button.Tag ="0"; selectCount--; button.BackColor = Color.White;for (int j = 0; j < 6; j++){if (intlist[j] == i+1){intlist[j] =0;break;}}break; };}}}private void run(object sender,EventArgs e){   //检测选满后创建新窗口Button b = (Button)sender;for(int i=0;i<6; i++){if (intlist[i] != 0){ }else { b.Text = "未满6名角色无法开始游戏"; return; }}Form1 form1 = new Form1(intlist);form1.ShowDialog();this.Close();}}

4.2 游戏界面

图4.2 游戏界面

本页面全通过手动代码完成,通过Manager类根据数据进行自动显示,然后在窗体的Load函数中调用该函数完成页面初始化,只挑选出有关此游戏页面样式的代码进行展示:

class Manager
{......
//绑定当前窗口 初始化窗口控件 卡牌框组样式既位置public void addform(Form _cform){   cform = _cform;cform.Text = "《混战》";cform.MouseDown += new MouseEventHandler(Place_people);//给窗体添加点击事件/*      AI_first();//AI初始化*///初始化窗口控件//敌人金币初始化(难度)E_Player.gold += 5;E_Player.gold_getspeed +=1;//头像界面PB.Size = new Size(130, 130);I_HPB.Size = new Size(970, 20);E_HPB.Size = new Size(970, 20);cform.Controls.Add(PB);cform.Controls.Add(I_HPB);cform.Controls.Add(E_HPB);PB.Location = new Point(260, 515);I_HPB.Location = new Point(260, 480);E_HPB.Location = new Point(260, 460);PB.Name = "头像";PB.BackColor =Color.White;I_HPB.BackColor = Color.Green;E_HPB.BackColor = Color.Red;PB.Enabled = false;I_HPB.Enabled = false;E_HPB.Enabled = false;PB.TextAlign =ContentAlignment.BottomCenter;for (int i = 0; i < 6; i++){//卡牌组样式既位置Button B_I_role = new Button();B_I_role.Size = new Size(130, 130);cform.Controls.Add(B_I_role);B_I_role.Location = new Point(400+i*140,515);B_I_role.Name = "button"+Convert.ToString(i + 1);B_I_role.Text =Convert.ToString(i+1);for (int j=0; j < roles.Count; j++){ if (I_Player.intList[i] == roles[j].num){B_I_role.Text +=roles[j].NAME;B_I_role.Text += "\n";B_I_role.Text +="价格:"+ roles[j].VALUE+"金币";break;}}B_I_role.TextAlign = ContentAlignment.TopLeft;B_I_role.Image = roles[I_Player.intList[i]-1].PBox.Image;B_I_role.Click += new EventHandler(change_mouse);//绑定自定义按钮事件}}
.....
}

第5章 代码设计

此部分主要用来介绍一些主要功能代码,详细到方法体内容。

5.1 焦点点击屏幕放置功能

public void addform(Form _cform){
......  cform.MouseDown += new MouseEventHandler(Place_people);//给窗体添加点击事件
......
}
private void Place_people(Object sender,EventArgs e)//放置角色卡牌{  if (mouse_int > 0&&I_Player.gold>= roles[mouse_int - 1].VALUE){I_Player.gold -= roles[mouse_int-1].VALUE;Point MouP = cform.PointToClient(Control.MousePosition);//焦点点击if (MouP.Y > 85 && MouP.Y <= 115 + People.SIDE)//焦点点击在第一路{GenerateRole(mouse_int,1,1);}else if (MouP.Y > 115 + People.SIDE && MouP.Y <= 145 + 2 * People.SIDE)//第二路{GenerateRole(mouse_int, 1, 2);}else if (MouP.Y > 145 + 2 * People.SIDE && MouP.Y <= 175 + 3 * People.SIDE)//第三路{GenerateRole(mouse_int, 1, 3);}else{//点击其他地方 卡牌下移cards_down();I_Player.gold += roles[mouse_int - 1].VALUE;mouse_int = 0;}}}public  void GenerateRole(int sum,int team,int road)//生成角色,sun编号,team队伍,road生成道路{People p;switch (sum)//编号{case 0: return;case 1:  p = new SwordMan(team); p.addform(cform); Addroad(p, road); break;case 2:  p = new StoneMan(team); p.addform(cform); Addroad(p, road); break;case 3: p = new vampire(team); p.addform(cform); Addroad(p, road); break;case 4: p = new FireMage(team); p.addform(cform); Addroad(p, road); break;case 5: p = new Archer(team); p.addform(cform); Addroad(p, road); break;case 6: p = new Dog(team); p.addform(cform); Addroad(p, road); break;case 7: p = new Minister(team); p.addform(cform); Addroad(p, road); break;case 8: p = new ThornBeast(team); p.addform(cform); Addroad(p, road); break;case 9: p = new Orcs(team); p.addform(cform); Addroad(p, road); break;case 10: p = new SKeleton(team); p.addform(cform); Addroad(p, road); break;          case 11: p = new SKeletonMage(team); p.addform(cform); Addroad(p, road); break;case 12: p = new Boom(team); p.addform(cform); Addroad(p, road); break;case 13: p = new Shrem(team); p.addform(cform); Addroad(p, road); break;}}private void Addroad(People p, int road)//把某人加到某路{        switch (road){case 1:if (p.team == 1){ road1.Add(p);p.road1 = road1;p.eroad1 = eroad1;p._P = new Point(People.SIDE, 100);}else{ eroad1.Add(p);p.road1 = eroad1;p.eroad1 = road1;p._P = new Point(1552-People.SIDE*2, 100);} break;case 2:if (p.team == 1){ road2.Add(p);p.road1 = road2;p.eroad1 = eroad2;p._P = new Point(People.SIDE, 100 + (People.SIDE + 30));}else{ eroad2.Add(p);p.road1 = eroad2;p.eroad1 = road2;p._P = new Point(1552 - People.SIDE * 2, 100 + (People.SIDE + 30));} break;case 3:if (p.team == 1){ road3.Add(p);p.road1 = road3;p.eroad1 = eroad3;p._P = new Point(People.SIDE, 100 + (People.SIDE + 30) * 2);}else{   eroad3.Add(p);p.road1 = eroad3;p.eroad1 = road3;p._P = new Point(1552 - People.SIDE * 2, 100 + (People.SIDE + 30) * 2);} break;}//显示p.PBox.Location = p._P;p.HpBox.Location = p._P;cform.Controls.Add(p.HpBox);cform.Controls.Add(p.PBox);}

5.2 随机化敌人卡牌功能

 public void Ini_Eintlist()//敌人卡牌集初始化{   //敌人初始化 Array.Clear(E_Player.intList, 0, E_Player.intList.Length);random(E_Player.intList, 6);E_MaxValue = roles[E_Player.intList[0] - 1].VALUE; //敌人最大价格foreach (int sum in E_Player.intList){if (roles[sum - 1].VALUE > E_MaxValue){E_MaxValue = roles[sum - 1].VALUE;}}}//不重复随机整数数组生成,用于初始化敌人卡牌图签private void random(int[] a,int n){long tick = DateTime.Now.Ticks;Random ran = new Random((int)(tick & 0xffffffffL) | (int)(tick >> 32));for (int i = 0; i < n; i++){a[i] = ran.Next(1, roles.Count+1);}Boolean bol = true;while (bol){Array.Sort(a);int num = 0;for (int i = 0; i < 5; i++){if (a[i] != a[i + 1]){num++;}else{a[i + 1] = ran.Next(1, roles.Count+1);}if (num == 5){bol = false;}}}}

5.3 卡牌移动与攻击功能

  class Manager
{
.....public void Move_or_Atk()//检测移动攻击{   // 帧率变化Fram_rate();//检测移动攻击one_MA(road1, eroad1);one_MA(road2, eroad2);one_MA(road3, eroad3);check_die();//检测死亡}private void one_MA(List<People> road1, List<People> eroad1)//一路检测移动攻击{   //状态检测check_state(road1);check_state(eroad1);//如果两边都有人if (road1.Count != 0 && eroad1.Count != 0){   //攻击或移动ATK_one(road1, eroad1);ATK_one(eroad1, road1);        //交换检测}else{//如果只有一边有人foreach (People p1 in road1){ p1.Move(); };foreach (People p2 in eroad1){ p2.Move(); };}}//攻击或移动private void ATK_one(List<People> road1, List<People> eroad1){try//避免空集暂停程序{foreach (People p1 in road1){bool IsMove = true;bool IsAtk = true;foreach (People p2 in eroad1){int range = Math.Abs(p2._P.X - p1._P.X);IsAtk = ((p1.ATK_range + People.SIDE) >= range);if (IsAtk){p1.Atk(p2);if (p1.ATK_mothod == 1) break;//单体攻击找到后退出循环IsMove = false; //(解决后方问题?会移动后方,由于判断移动了)}}if (IsAtk == false && IsMove == true){p1.Move();}}}catch { };}
.....
}abstract class People
{
......public  void Move()//公共方法-移动{//移动上下跳动_P.Y = (int)(_P.Y - SPEED * Math.Cos(time++)+0.45); //移动switch (team){    case 1: _P.X += (int)(SPEED / 1.2 + 1); break;case 2: _P.X -= (int)(SPEED / 1.2 + 1); break;}PBox.Location = _P;HpBox.Location = _P;HpBox.BringToFront();  }public virtual void Atk(People p)//虚方法-攻击/特殊的重写{Skill_time_change();//技能概率变化//技能随机释放int a = 1+Convert.ToInt32(Guid.NewGuid().GetHashCode() % 100);int random=0;if (a < 0) random = a + 100;else { random = 100; }this.ATK_time += this.ATK_speed;//攻速满一百一次攻击if (this.ATK_time >= 100){this.ATK_time -= 100;if (random >= Skill_time){p.PassiveSkill(eroad1, road1, this);//被动技能atk_sound();//攻击音效p.HP -= (int)(this.ATK * (1 - (p.DEF / (p.DEF + 30))));}else { Skill(road1, eroad1, p); }}}
public abstract void Skill_time_change();//多态方法-技能概率变换public abstract void Skill(List<People> road1,List<People> eroad1,People ep);//多态方法-技能public abstract void PassiveSkill(List<People> road1, List<People> eroad1, People ep);//多态方法-被动技能public abstract void atk_sound();//攻击音效public abstract void skill_sound();//技能音效
}

5.4动态化频率显示功能

 private void Fram_rate(){  //敌我血条变化I_HPB.Size =new Size(970*I_Player.HP/2000,20);E_HPB.Size = new Size(970 * E_Player.HP / 2000, 20);//金币显示PB.Text ="生命:"+I_Player.HP+"\n"+ "金币:" + I_Player.gold;//敌人AI出兵if (E_MaxValue <= E_Player.gold){int MaxX = 0;int road = 2;foreach (People p1 in road1){if (p1._P.X > MaxX){MaxX = p1._P.X; road = 1;}}foreach (People p1 in road2){if (p1._P.X > MaxX){MaxX = p1._P.X; road = 2;}}foreach (People p1 in road3){if (p1._P.X > MaxX){MaxX = p1._P.X; road = 3;}}int r2 =100* (MaxX-People.SIDE) /( 1552 - People.SIDE);int r3 = (UInt16)DateTime.Now.Ticks % 101;int r = (UInt16)DateTime.Now.Ticks % 6;if (roles[E_Player.intList[r]-1].VALUE <= E_Player.gold){if (r3 <= r2 + 30){ GenerateRole(E_Player.intList[r], 2, road); }else{int road2 = 1 + r3 % 3;GenerateRole(E_Player.intList[r], 2, road2);}E_Player.gold -= roles[E_Player.intList[r]-1].VALUE;}}//敌我增长钱I_Player.addgold();E_Player.addgold();for (int i = 0; i < 6; i++){Control[] c = cform.Controls.Find("button" + Convert.ToString(i + 1), false);if (roles[I_Player.intList[i]-1].VALUE > I_Player.gold)c[0].BackColor = Color.Red;else { c[0].BackColor = Color.White; }}}

第六章 总结

刚开始作为游戏编程小白的我,听别人建议,这一学期专门学习了c#来进行编程,为了使得游戏好玩,我零零散散学了许多东西,例如像素画,音效合成,打击反馈等等。刚开始是这个c#WinForm窗口提起了我的兴趣(作为一个被控制台文字毒害的我,终于发现了一个可视化程序编程宝藏),于是我马不停蹄的俩周学完了c#基础,然后因为拥有c++编程的原因,以及做过几个小系统,立马完成了我的第一款自己做的《飞机大战》小游戏,但是这个游戏的编程思想纯粹是顺序编程,没有体现面向对象,于是在接下来的一周时间,我好好计划了一下项目,既不能太大让我束手无策,也不能太小没有可玩性。于是《混战》便诞生了,刚开始的版本非常简陋,只有几个角色,而且也有许多BUG,可能一天查BUG到最后才发现不小心写错了单词。但我还是坚持下来了,总的来说,编程是最重要的,但是查找各种图片音效资源,以及手动画了一张像素背景画却也花费了我的大量时间,所以说游戏编程并不容易。

虽然说这个版本还有许多遗憾没有完成,像开始界面的设置按钮(调音量,调背景,调上传头像),关卡界面(增强可玩性),存档功能(IO流记录的比较多,不想搞了),以及比较难搞的攻击和移动动画等都是一些遗憾,但就此结束吧!

最主要原因,还是这个WinForm的框架编游戏太困难了,不仅出现背景闪烁(加入新控件,已解决),音频互相阻塞(加入新类,已解决),,帧移动不流畅(未解决),用过的垃圾不能手动回收(未解决,死亡的人物占内存,没有垃圾池机制)等等许多毛病,而且需要手动编写碰撞箱,基础表格,以及运行起来缓慢,让我放弃了WinForm窗体应用程序框架。

幸运的是,在我学习过程中,我了解了Unity软件,它对3D游戏编程最为方便也可进行2D游戏编程,且内置了许多功能,方便一众独立游戏编程,我已经大概了解了软件使用基本过程,准备在假期期间继续对C#的深入学习和Unity的熟练掌握。

第七章 参考文献

  1. 知乎,皮皮关,《c#目前在游戏领域应用》
  2. CSDN,kucoffee12,《解决C#Winform应用程序中窗体背景闪烁问题》
  3. CSDN,Zhy,《调用API函数mciSendString播放音频文件》

基于C#.NET对战卡牌游戏-《混战》游戏开发相关推荐

  1. 哈利波特魔法觉醒Mac端(卡牌角色扮演游戏)

    每个人都有一个魔法梦,近日沉寂多年的霍格沃茨魔法学院,已经恢复招生了!哈利波特:魔法觉醒 for Mac是由<哈利·波特>官方授权的一款卡牌类角色扮演演戏!哈利波特魔法觉醒mac游戏共分为 ...

  2. 怎么修改artifact_《Artifact》怎么修改卡牌描述 修改卡牌描述与游戏UI文字方法分享...

    <Artifact>中有着许多的卡牌,由于<Artifact>采用了<DOTA2>的背景故事,这使得我们可以在这款卡牌游戏中看到许多熟悉的身影.下面小编带来了< ...

  3. 怎么修改artifact_《Artifact》卡牌描述与游戏UI文字修改教程

    第1页: 展开 <Artifact>中有着许多的卡牌,由于<Artifact>采用了<DOTA2>的背景故事,这使得我们可以在这款卡牌游戏中看到许多熟悉的身影.下面 ...

  4. IOS对战卡牌《梦回水浒》抢先体验

    <梦回水浒> 是一款水墨风格的即时对战卡牌手游.该游戏以水浒108将为人物原型,引入阴阳五行学说,结合独创的多种对战玩法,给玩家带来不一样的游戏体验.不同于一般的卡牌游戏,在<梦回水 ...

  5. 卡牌系统psv游戏推荐_《天下HD》荣获App Store首页双位推荐 全新情缘系统盘活游戏社交...

    自上周以来,网易游戏<天下HD>荣获苹果App Store首页两个重要推荐位,对于这样一个上线近两年的手游而言,实属荣幸之至! <天下HD>是网易自主研发的MMORPG手游,世 ...

  6. 冒险、卡牌、养成类游戏的设计要点

    这几种游戏设计好玩的关键点是: 一.收集 游戏中设计1个主要收集项目,如卡牌本身就是一个很好的收集项目;1-2个次要收集项目,如道具.装备.技能等.主要的收集项目在于游戏的UI等引导用户去收集,并且存 ...

  7. Python 对战卡牌

    卡牌=['手枪','ak','手雷'] import random import time def 抽卡():a1=random.randint(0,2)抽到的卡=卡牌[a1]return 抽到的卡 ...

  8. [Unity游戏]卡牌记忆消除游戏

    1. 效果和工程 先来看看游戏是什么样子的,以下是在编辑器中运行的效果 完整的工程 https://github.com/MangoWAY/Unity2DMemoryCard,可以给个Star哈 2. ...

  9. 卡牌系统psv游戏推荐_索尼PSV已经凉了吗?等等,2020年六月还有一款PSV游戏发售...

    哈喽,大家好,今天给大家推荐一款单机游戏,不过这款是掌机游戏来的,还是索尼的PSV掌机游戏,这款PSV游戏掌机大家应该很了解了吧,准备停产那种,现在PSV游戏掌机已经进入末年了,想不到还有新游戏再发售 ...

  10. 卡牌系统psv游戏推荐_PSV精品游戏推荐之一,让你的小V再次发挥余热吧!

    PSV虽然停产了,但是我还是每天放包里,空的时候拿出来玩一下.其实里面还有很多游戏没玩过,这里为大家推荐一下我玩过的几个觉得特别好玩的游戏. 一起来看一下吧 VR网球 这款拥有着极致vita画面的Ga ...

最新文章

  1. Linux 背后的思想
  2. 创建型模式——Factory Method(未完)
  3. c语言删除成绩记录的代码,学校让用c语言编的成绩管理系统,删除的代码有点问题,求教...
  4. selenium定位方法(java实例)
  5. python 期货交易_Python期货量化交易基础教程(8)
  6. Python中yield返回生成器的详细方法
  7. 基于VS Code创建Java command-line app
  8. 程序员过关斩将--cookie和session的关系其实很简单
  9. HDU 最大报销额 (0 1 背包)
  10. 手机测评系列之vivox23
  11. FlashFXP列表参数错误解决方法
  12. python创建文件对象的函数_Python学习笔记之—— File(文件) 对象常用函数
  13. cropperjs裁剪头像功能实现总结
  14. cad快速看图2020|cad迷你画图2020 附安装教程
  15. 相片打印机原理_照片打印机 技术原理介绍_照片打印机_办公打印评测试用-中关村在线...
  16. 手机上该怎么合并PDF?这个方法可不要错过
  17. RGB及sRGB与XYZ坐标转换
  18. C++ string 简单截取字符串使用
  19. linux下为命令设置别名
  20. 南卡和三星哪款蓝牙耳机音质好些?高颜值且音质好的蓝牙耳机测评

热门文章

  1. 用VBA打开PDF文件
  2. UE4C++新建文件夹
  3. 解决Error response from daemon: conflict: unable to delete bf6a13bd36ca (must be forced)
  4. 人脸识别接口_活体检测在人脸识别中不可或缺的一部分
  5. 思科Cisco Telnet(三种认证方式)
  6. VC++6.0共享内存技术总结
  7. 2018 PKU_WC 长沙游 《我到长沙来看雪》
  8. 奥克兰大学计算机it专业介绍,奥克兰大学IT硕士专业介绍
  9. 计算机音乐青旅行,网易云音乐推荐:五一旅行途中必听的10首小清新
  10. 肩外展固定支架的规格参数介绍和使用方法