一.复杂数据结构
1.1枚举
基本概念:被命名的整型常量的集合
声明枚举和声明枚举变量:前者是创建自定义的枚举类型,后者是使用自定义的枚举类型创建枚举变量。
作用:用于表示状态,类型等
声明枚举:
enum E_自定义枚举名//以E开头区分枚举
{
自定义枚举项名字,//不赋值就默认为0,后面依次累加;如果已赋值,则以后就在此基础上累加
自定义枚举项名字=100,
自定义枚举项名字,//默认101
}
声明枚举的位置:在命名空间namespace语句块中声明,以及在class和struct语句块中,不能在函数语句块声明
实例:
enum E_MonsterType
{
Normol,
boss,
}
使用方法:
与普通的类型使用方法一致
(1)E_MonsterType PlayerType=E_MonsterType.boss;
(2)if(playerType==E_MonsterType.boss)
{
console.WriteLine("是个Boss");
}
(3)一般枚举用来配合条件分支语句
switch(monsterType)
{
case E_MonsterType.boss:
break;
case E_MonsterType.Normol:
break;
}
枚举的类型转换:
(1)枚举和int转换
int i=(int)playerType;
console.WriteLine(i);//打印出值
(2) 枚举转string
string str=player.Tostring();
console.WriteLine(i);//打印出枚举项的名字
(3)string转成枚举
//Parse后第一个参数:你要转换为哪个枚举类型 第二个参数:用于转换为相应枚举项的字符串
//转换完毕后,是一个通用类型,需要用括号强转成我们想要的目标
playerType=(E_PlayerType)Enum.parse(typeof(E_PlayerType),"boss")
(4)整型变量强转成枚举
E_PlayerType Player=(E_PlayerType)type;//这里的Type是枚举
枚举作用:
对于游戏开发中,对象有很多状态,比如玩家有一个动作状态,需要一个变量或标识来表示
当前玩家处于哪种状态
综合考虑可能会使用int来表示他的状态:1 行走 2 待机 3 跑步 4 跳跃。。。。。
枚举可以帮我们清晰的分清楚状态的含义。
1.2数组
一维数组:
基本概念:数组是存储一组相同数据类型的集合,分为一维,多维,交错数组,一般情况下 一维数组简称数组
数组声明:
变量类型[] 数组名;//只是申明了数组,但未分配内存
int [] arr1;
变量类型[] 数组名=new 变量类型[数组长度];
int[]arr2=new int [5];//开辟了内存空间,对于int 默认放0
变量类型[] 数组名=new 变量类型[数组长度]{内容1,内容2,内容3.....};
int [] arr3=new int [5]{1,1,1,1,1};
变量类型[] 数组名=new 变量类型[]{内容1,内容2,内容3.....};
int[] arr4 =new int []{1,23,45,6,643};//根据括号里的数字确认长度。
变量类型[] 数组名={内容1,内容2,内容3.....};
int [] arr5={1,2,3,4,5,6};//后面内容决定长度
数组使用:
int[] array={1,2,3,4,5};
(1)数组长度
Console.WriteLine(array.Length);
(2)获取数组元素(都是从0开始)
Console.WriteLine(array[0]);
Console.WriteLine(array[2]);
注意:访问时不能越界(下标最大Length-1)
(3)修改数组中的元素
array[0]=99;//直接赋值,统一类型的值
(4)遍历数组
for(int i=0;i<array.Length;i++)
{
Console.WriteLine(array[i]);
}
(5)增加数组元素
//数组初始化以后不能直接添加新的元素的
//先开新内存,再搬家,然后将原来的数组指向新的内存地址
int [] array2=new int [6];
for(int i=0;i<array.Length;i++)
{
array2[i]=array[i];
}
array=array2; //表示原来的指针指向现在的内存空间,指针重新指向后,原来的就变成垃圾了,C#会自动回收
for(int i=0;i<array.Length;i++)
{
Console.WriteLine(array[i]);//这时就会是6个元素,原来只有5个
}
(6)删除数组的元素
int array3=new int [5];
for(int i=0;i<array3.Length;i++)
{
array3[i]=array[i];//保留前5个元素
}
array=array3;//转换指针
(7)查找元素
//查找元素位置
//遍历每个数组元素是否等于查找的数,然后输出位置
总结:声明,遍历,增删查改,所有的变量类型都可以声明为数组,它是用来批量存储游戏中的同一类型对象的容器 比如:所有的怪物,创建一个就在数组里面
1.3二维数组
基本概念:使用两个下标(索引)来确定元素的数组
下标理解为行标和列表,每行放完,放列
二维数组的声明:
变量类型[,]数组名;//在后面初始化
int[,]arr;
变量类型[,]数组名=new 变量类型[行,列];
int [,]arr2=new int[3,3];
变量类型[,]数组名=new 变量类型[行,列]{{0行内容1,0行内容2,0行内容3...},{1行内容1,1行内容2,1行内容3...}...};
int [,]arr3=new int[3,3]{{1,2,3},
{1,2,3,}
{1,2,3}};
变量类型[,]数组名=new 变量类型[行,列]{{0行内容1,0行内容2,0行内容3...},{1行内容1,1行内容2,1行内容3...}...};
int [,]arr4=new int[,]{{1,2,3},
{4,5,6},
{7,8,9}};
变量类型[,]数组名={{0行内容1,0行内容2,0行内容3...},{1行内容1,1行内容2,1行内容3...}...};
int [,]arr4={{1,2,3},
{4,5,6},
{7,8,9}};
二维数组使用:
int[,]array=new int[,]{{1,2,3},{4,5,6}};
(1)二维数组的长度
得行:Console.WriteLine(array.GetLength(0));
得列:Console.WriteLine(array.GetLength(1));
(2)获取元素
注意第一个元素索引是0,最后一个是长度-1;
Console.WriteLine(array[0,1]);
Console.WriteLine(array[1,2]);
(3)修改二维数组中得元素
array[0,0]=99;
Console.WriteLine(array[0,0]);
(4)遍历二维数组
for(int i=0;i<array.GetLength(0);i++)
{
for(int j=0;j<array.GetLength(1);j++)
{
Console.WriteLine(array[i,j]);
}
}
(5)增加数组元素
数组声明过后,不能在原有得基础上进行添加或者删除
目标两行三列变成三行三列
int[,]array2=new int[3,3];
for(int i=0;i<array.GetLength(0);i++)
{
for(int j=0;j<array.GetLength(1);j++)
{
array2[i,j]=array[i,j];
}
}
array=array2;
array[2,0]=7;//其余多的可以单独赋值
array[2,1]=8;
array[2,2]=9;
删除,查找都可参考一维数组
总结:同一变量类型的行列数据集合,一定掌握的内容:申明,遍历,增删查改
游戏中一般用来存储矩阵或者在控制台小游戏中可以用二维数组来表示地图格子。
1.3交错数组
基本概念:是数组的数组,每个维度的数量可以不同
声明:
变量类型[][]交错数组名;
int[][]arr1;
变量类型[][]arr2=new int[3][];
int[][]arr2=new int [3][];
变量类型[][]交错数组名=new 变量类型[行数][]{一维数组1,一维数组2,一维数组3}
int[][]arr3=new int[3][]{new int[]{1,2,3},
new int[]{1,2},
new int[]{1} };
变量类型[][]交错数组名=new 变量类型[][]{一维数组1,一维数组2,一维数组3}
int[][]arr3=new int[][]{new int[]{1,2,3},
new int[]{1,2},
new int[]{1} };
变量类型[][]交错数组名={一维数组1,一维数组2,一维数组3}
int[][]arr3={new int[]{1,2,3},
new int[]{1,2},
new int[]{1} };
数组的使用:
(1)数组的长度
//行
Console.WriteLine(array.GetLength(0));
//得某一行得列数
Console.WriteLine(array[0].Length);
(2)获取数组元素
Console.WriteLine(array[0][1]);
(3)修改交错数组中得元素
array[0][1]=99;
Console.WriteLine(array[0][1]);
(4)遍历交错数组
for(int i=0;i<array.GetLength(0);i++)
{
for(int j=0;j<array[i].Length;j++)
{
Console.Write(array[i][j]+" ");
}
Console.WriteLine();
}
1.4值类型和引用类型
变量类型的复习:
无符号整型:byte b=1;
ushort us=1;
uint ui=1;
ulong ul=1;
有符号的整型:
sbyte sb=1;
short s=1;
int i=1;
long l=1;
浮点数:
float =1f;
double d=1.1;
decimal de=1.1m;
特殊类型:
boolbo=true;
char c=‘A‘;
string str="strs";
复杂数据类型
enum 枚举
数组(一维,二维,交错)
把以上类型进行分类
引用类型:string,数组,类
值类型:其他,结构体
值类型与引用类型的区别:
(1)使用上的区别
//值类型
int a=10;
//引用类型
int[]arr=new int[]{1,2,3,4};
//声明了一个b让其等于之前的a;
int b=a;
//声明一个arr2让其等于之前的arr
int[] arr2=arr;
Console. WriteLine("a={0},b={1}",a,b);
Console. WriteLine("arr[0]={0},arr2[0]={1}",arr[0],arr2[0]);
此时输出相同(a=10,b=10;arr[0]=1,arr2[0]=1)
b=20;
arr2[0]=5;
Console. WriteLine("a={0},b={1}",a,b);
Console. WriteLine("arr[0]={0},arr2[0]={1}",arr[0],arr2[0]);
此时输出(a=10,b=20;arr[0]=5,arr2[0]=5)
总结:值类型在相互赋值时,把内容拷贝给了对方,它变我不变
引用类型的相互赋值时让两者指向同一个值,它变我也变
为什么值类型和引用类型在使用不同?
值类型存储在栈空间——由系统分配,自动回收,小而快
引用类型 存储在堆空间——手动申请和释放,达大而慢
注意:如果上面不是相互赋值而是arr2=new int[]{99,1,2,3};
则arr2指向新地址,不和arr相同了
1.5特殊引用类型——string
string的它变我不变
string str1="123";
string str2=str1;
//因为string是引用类型,按理说,应该是它变我也变
str2=str1;
str2="321";
Console.WriteLine(str1);
Console.WriteLine(str2);
//这时可以发现str2改变了,这是因为c#对string做了特殊的处理,使得string可以拥有值类型的它变我不变得特征,string在赋值得时候会在堆上重新分配空间
//string虽然方便,但是有一个缺点,就是频繁得改变string,重新赋值,会产生内存垃圾,影响性能
补充:监视内存方法
打开调式->窗口->监视->在监视窗口中监视想监视得内容(如:str1,str2,&str1,&str2)
1.6函数
基本概念 :
本质是一块具有名称得代码块,可以使用函数(方法)得名称来执行该代码块,是封装代码进行重复使用得一种机制。
主要作用:
1.封装代码
2.提升代码复用率
3.抽象行为
函数声明在哪里?
可以写在class和struct语句块中
static 返回类型 函数名(参数类型 参数名1,参数类型 参数名2,参数类型 参数名1,...)
{
函数逻辑;
函数逻辑;
return 返回值;(如果有返回类型才返回)
}
1.关于static 不是必须的 在没有学习类和结构体之前,都必须写
2.返回类型可以返回任意的变量类型,14种变量类型+复杂数据类型(枚举,数组,结构体,类)
3.函数名 使用帕斯卡命名法,MyName(每个拼写首字母大写)