unityP1笔记——C#部分

目录

C#基础语法专题1

变量、数据类型

数组

运算符 

C#基础语法专题2

关系逻辑三目运算符

 枚举

 循环

C# Class基础(1)

Class构造函数和析构函数

 继承

封装

多态

​编辑

覆盖和重载的区别 

this和base关键字的区别

静态类

抽象类

 密封类

 C# Class基础(2)

泛型类和泛型方法

接口

抽象类和接口的对比

Struct 结构体

类型转换

 C# 设计模式专题

 委托的定义和使用

 系统内置Action委托

 系统内置Func委托

匿名事件、Event事件、多播委托

单例模式

观察者模式 

工厂模式

适配器模式

C# IO操作专题

String常用API

 StringBuilder常用API

数据结构

数组 

泛型类集合List<>

哈希表

字典 

HashSet

双向链表

堆栈Stack

队列

实现栈

 实现队列

 一些VS快捷键


C#基础语法专题1

变量、数据类型

简化形式

数组

数组声明

 数组初始化几种方式:

①一维数组

 

 ②二维数组

  ③三维数组

小作业:调试函数,更改数组某个下标的值,通过跟踪调试看设置的值有没有生效 

运算符 

<<n:左移n位,即乘以n的次方

>>n:右移n位,即除以n的次方

C#基础语法专题2

关系逻辑三目运算符

位运算符

 枚举

 头文件 using System;

String 转换为 Enum 类型

 int 转换为 Enum 类型

 *用枚举解决switch可读性的问题

switch(mAction)
        {
            case emAction.Getup:
                {
                    Debug.Log("1.起床");
                }
                break;
            case emAction.Wash:
                {
                    Debug.Log("2.洗漱");
                }
                break;
            case emAction.Eat:
                {
                    Debug.Log("3.吃饭");
                }
                break;
            case emAction.Study:
                {
                    Debug.Log("4.学习");
                }
                break;
            default:
                {
                    Debug.Log("不知道做什么");
                }
                break;
        }

 循环

continue :跳过单词循环

break :跳出循环体

C# Class基础(1)

Class构造函数和析构函数

构造函数可以传入参数,析构函数不可以

作用域:

 继承

class 子类 : 父类{}

不支持多重继承(不能继承多个父类)

封装

 关于如何计算不同图形面积:

①用枚举来做

public enum POLYGON
{
    Rectangle,
    Triangle,
}
public class Polygon  //父类
{
    public int Length;
    public int Width;
    public string color;
    public string name;

    public float Area;

    public POLYGON emPolygon;

    public void CalcArea()
    {
        if(emPolygon == POLYGON.Rectangle)
        {
            Area = Length * Width;
        }
        else if(emPolygon == POLYGON.Triangle)
        {
            Area = Length * Width / 2;
        }
    }
}
void Start()
    {
        // 矩形面积 = 长 * 宽
        Rectangle rectangle = new Rectangle();
        rectangle.emPolygon = POLYGON.Rectangle;
        rectangle.Length = 3;
        rectangle.Width = 4;
        rectangle.name = "矩形";
        rectangle.color = "红色";
        rectangle.CalcArea();
        Debug.Log("矩形面积" + rectangle.Area);

        // 三角形面积 = 长 * 宽 / 2
        Triangle triangle = new Triangle();
        triangle.emPolygon = POLYGON.Triangle;
        triangle.Length = 3;
        triangle.Width = 4;
        triangle.name = "三角形";
        triangle.color = "黄色";
        triangle.CalcArea();
        Debug.Log("三角形面积" + triangle.Area);
    }

②用虚函数来做(更改上述代码)

 

多态

使用 virtual 体现多态

注意:

覆盖和重载的区别 

覆盖:发生在继承关系中,通过 virtual 和 override 来实现,函数名和参数都一模一样

重载:发生在任何关系,是通过函数名相同,参数不同实现的(参数顺序、个数都影响)

this和base关键字的区别

 即:base访问父类,this访问父类(如果继承了)+当前子类

静态类

 静态类一般用于工具类

const:

①const 在声明时就必须赋初值初始化

②因此某种程度上,是不可变值

③在类内声明的 const 常量,外部访问时,必须通过类名

 readonly:

 ①readonly 和 const 不可共存

②只能在声明时或构造函数里初始化,并且不能修改值

③用 readonly 修饰的变量,不会发生 const ③情况(可被实例访问)

 变量访问修饰符的控制:get set 以及 value赋值

 静态构造函数

①静态构造函数中不允许出现访问修饰符

 ②如果父类 static 了,那么无论多少实例,父类的构造函数只被系统自动调用一次

静态类

①静态类不允许有实例构造函数,只有一个静态构造函数(并不会被执行)

 ②静态类不允许被实例化

③静态类里内部成员必须是静态成员/常量 

④静态类无法作为分类 

抽象类

①不允许实例化

②支持构造函数

③抽象类可继承抽象类

④静态构造函数只执行一次。其他构造函数则根据不同实例分别再次调用

public abstract class MyClass1
{

}
public abstract class MyClass2 : MyClass1
{
    public MyClass2() { Debug.Log("MyClass2 默认构造函数"); }
    static MyClass2() { Debug.Log("MyClass2 静态构造函数"); }
}
public class MyClass3 : MyClass2
{
    public MyClass3() { Debug.Log("MyClass3 默认构造函数"); }
}

/*-------------Abstract类里------------------*/
void Start()
    {
        MyClass3 myclass3 = new MyClass3();

    }

 

如果实例化了两个对象:

 ⑤允许 virtual 虚函数

⑥若函数声明为 abstract,则不允许包含函数体,且子类必须覆盖父类的该方法

 密封类

 C# Class基础(2)

泛型类和泛型方法

public class MyClass6<T>
{
    private T[] m_array;

    public MyClass6(int size)
    {
        m_array = new T[size];  // 容量
    }

    public void Set(int index, T value)
    {
        m_array[index] = value;
    }
    public T Get(int index)
    {
        return m_array[index];
    }

}

这个T,它甚至可以是一个类啊!

public class MyClassType
{
    public int a;

    public MyClassType(int value)
    {
        this.a = value;
    }
}

在Start()函数里的代码:

void Start()
    {
        MyClass6<int> myclass6 = new MyClass6<int>(5);
        myclass6.Set(0, 666);
        myclass6.Set(1, 1);
        int a = myclass6.Get(0);
        int b = myclass6.Get(1);

        Debug.LogFormat("第{0}号位,值:{1}", 0, a);
        Debug.LogFormat("第{0}号位,值:{1}", 1, b);

        MyClass6<string> myclass6_1 = new MyClass6<string>(5);
        myclass6_1.Set(0,"你好");
        myclass6_1.Set(1, "唐老鸭");
        string c = myclass6_1.Get(0);
        string d = myclass6_1.Get(1);

        Debug.LogFormat("第{0}号位,值:{1}", 0, c);
        Debug.LogFormat("第{0}号位,值:{1}", 1, d);

        MyClass6<MyClassType> myclass6_2 = new MyClass6<MyClassType>(5);
        myclass6_2.Set(0, new MyClassType(1));
        myclass6_2.Set(1, new MyClassType(2));
        MyClassType e = myclass6_2.Get(0);
        MyClassType f = myclass6_2.Get(1);

        Debug.LogFormat("第{0}号位,值:{1}", 0, e.a);
        Debug.LogFormat("第{0}号位,值:{1}", 1, f.a);

    }

得到结果

!!!!改进!!!!

增加上述部分代码后,可以直接引用.a了

此时不用再e.a, f.a,直接引用e, f 即可 

 注意 where T 中 T 的范围

注意泛型类和泛型方法的运用

接口

 

 不能将函数声明改为私有

 不能实例化接口

 可以多重继承

类继承接口:需要实现接口功能

 如图

抽象类和接口的对比

 相同点

不同点

1.变量

接口不允许声明变量,抽象类可以

2.构造函数

接口不允许使用构造函数/静态构造函数,抽象类可以

 

 3.函数实现

接口不允许函数实现,抽象类可以

4.访问修饰符

①接口默认 public  不允许变为private

②抽象类默认 private 

函数前若为abstract,那访问修饰符也不能是 private;

非abstract声明函数可以允许private potected

5.多重继承

接口允许多重继承,而抽象类不允许

Struct 结构体

Struct 和 Class 的对比

相同点

1.结构体和类都支持静态构造函数

2.结构体和类都支持自定义函数

不同点

1.结构体不能定义无参构造函数,只允许构造有参构造函数,而类都可以

2.结构体不允许定义析构函数,但是类可以

3.函数修饰符

结构体函数不允许声明为 virtual 虚函数,但类可以

4.结构体类型不允许声明为 abstract,但类可以

5.关于变量

结构体声明的全局普通变量(不带修饰符的),不能在声明里赋值(且必须要赋值),即只能在构造函数里赋值;但是类在哪里都可以

const变量都只能且必须在声明时赋初值(这是个相同点,但是放一起方便总结)

 readonly变量

结构体只能在构造函数里赋值,而类都可以

6.关于继承

结构体只能继承自接口,不可以互相继承

但是类与类之间是可以继承的(sealed密封类除外)

7.访问变量

结构体可给变量显示赋值,直接访问成员变量

而类必须实例化对象才可以访问

8. 访问函数

结构体变量和类对象 都必须进行初始化,才可以访问

9.new

结构体的new并不会分配内存,仅仅调用结构体的构造函数初始化而已

类属于引用类型,类的new会在堆上分配内存,也会调用类的构造函数进行初始化

类型转换

引用类型存储在堆上,值类型存储在栈上

is 

as

举例:

public class Monster
{
    public string name = "骷髅兵";
    public int hp = 100;
}
/*---------- HeapStack : MonoBehaviour ---------------*/
void Start()
    {
        Example1();
    }

public void Example1()
    {
        Monster[] monsters = { new Monster(), new Monster(), new Monster() };
        Monster monster1 = monsters[0];
        monster1.name = "石头人";
        Monster monster2 = monsters[0];
        monster2.name = "嗜血蝙蝠";

        Debug.Log(monster1.name);

    }

原理:通过引用的方式,由地址一层层找到堆里的地址,然后修改堆里的数据,会对其他所有指向该位置的变量产生影响

 C# 设计模式专题

 委托的定义和使用

和函数相似,只是前面加了delegate,后面不进行函数的实现

 

 含参的使用方式:

 返回值的使用方式:

 泛型使用方式:

 

 系统内置Action委托

 需要使用命名空间 using System;

 系统内置Func委托

* Func<T1, T2, T3,...,Tn>,返回值类型将是Tn的类型,非最后一个泛型T的声明,需要与实现函数的参数个数及类型保持一致

同样 需要使用命名空间 using System;

System.Func 可以不带参数,但是必须带一个返回值

/*---------- Start()函数 ----------*/
Func<string, int> func2 = Show2;
/*---------------------------------*/

int Show2(String a)
    {
        return int.Parse(a);
    }

或是

/*-------- Start() ----------*/
Func<int, string> func2 = Show2;
string b = func2(1000);
Debug.Log(b);
/*---------------------------*/

string Show2(int a)
{
    return a.ToString();
}

匿名事件、Event事件、多播委托

 匿名函数的用法:

 多播委托的用法:

void Start()
    {
        Action action = Show1;
        action += Show2;
        action();
    }

private void Show1()
    {
        Debug.Log("Show1");
    }
    private void Show2()
    {
        Debug.Log("Show2");
    }

 

注意:

 

 *此时若再次移除Show1,则会报错,原因如下

因此需要增加一个判断 

 event事件

不能在函数的内部进行声明

 而要在函数外部进行

单例模式

设计模式分类

单例模式定义

——一般应用在管理器中

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MySingleton
{
    public MySingleton()
    {
        Debug.Log("构造函数执行");
    }
}

public class Singleton : MonoBehaviour
{
    void Start()
    {
        MySingleton single1 = new MySingleton();
        MySingleton single2 = new MySingleton();
        MySingleton single3 = new MySingleton();

        Debug.Log("single1 = " + single1.GetHashCode() + ",single2 = " + single2.GetHashCode() + ",single3 = " + single3.GetHashCode()); ;
    }
}

 GetHashCode()得到 不同堆对象引用的地址

下面进行单例设计:

 

观察者模式 

示例程序

/*基类*/
public class Animal
{
    protected string Name;
    public Animal(string name)
    {
        this.Name = name;
    }
    public virtual void Run()
    {

    }
}
/*猫和老鼠*/

public class Cat : Animal
{
    public Action actions;  // 发布者

    public Cat(string name) : base(name)   // 调用基类的构造函数
    {

    }
    public void coming()
    {
        Debug.Log(Name + "来啦");
        if(actions != null)
        {
            actions();   //通过多播委托,实现一对多的关系        
        }
        this.Run();
    }
    public override void Run()
    {
        Debug.Log(Name + "开始追三只老鼠...");
    }
}

public class Mouse: Animal
{
    public Mouse(string name, Cat cat) : base(name)    // 调用基类的构造函数
    {
        cat.actions += this.Run;   // 订阅者
    }
    public override void Run()
    {
        Debug.Log(Name + "逃跑");
    }
}
public class Visit : MonoBehaviour
{
    void Start()
    {
        Cat cat = new Cat("娘口三三");
        //此处 Animal 构成多态
        Animal mouseA = new Mouse("老鼠A", cat);
        Animal mouseB = new Mouse("老鼠B", cat);
        Animal mouseC = new Mouse("老鼠C", cat);

        cat.coming();
    }
}

 

若再需增加老鼠,只需增加这一句即可

工厂模式

简单工厂模式 

——只处理一个工厂 

工厂模式

——可分多个工厂

抽象工厂模式

 现在为了避免重名问题,引入命名空间

简单工厂模式

按照这种方式,现在想要增加一个苹果鼠标,就要采用 增加一个AppleMouse类 --> 增加枚举 --> 多态创建appleMouse实例 --> 修改switch 来达成。这违反了开闭原则(不修改原有方法,添加不影响)

因此使用工厂模式(中间件由一变为多)

 现在如果还想加入其他类别的产品,比如键盘,为了更加方便管理,使用抽象工厂模式

适配器模式

/*--------------Adaptor------------------*/
    //接口用于拓展原始类不足的功能
    public interface IAdaptor
    {
        /// <summary>
        /// 统一调用接口,完成不同的行为
        /// </summary>
        /// <param name="emAdaptorType"></param>
        void Charge(AdaptorType emAdaptorType);
    }
    public class Adaptor : IAdaptor
    {
        AndroidLine androidLine = new AndroidLine();
        IosLine iosLine = new IosLine();

        public void Charge(AdaptorType emAdaptorType)
        {
            if(emAdaptorType == AdaptorType.Android)
            {
                androidLine.AndroidCharge();
            }
            else if(emAdaptorType == AdaptorType.IOS)
            {
                iosLine.IOSCharge();
            }
        }
    }
/*--------------AdaptorMain----------------*/
namespace Adaptor
{
    public class AdaptorMain : MonoBehaviour
    {
        void Start()
        {
            IAdaptor adaptor = new Adaptor();
            adaptor.Charge(AdaptorType.Android);
            adaptor.Charge(AdaptorType.IOS);
        }
    }
}

C# IO操作专题

String常用API

https://www.runoob.com/csharp/csharp-string.html

 

 

 

 

 StringBuilder常用API

 https://blog.csdn.net/sibaison/article/details/72356393

String 对象是不可改变的。如果要修改字符串而不创建新的对象,则可以使用 System.Text.StringBuilder 类。

 

 

 

区别:

数据结构

数组 

动态数组ArrayList

/*
 *一、添加并打印元素
 *    方法一:Add()
 */
//定义动态数组
ArrayList arrayList1 = new ArrayList();

arrayList1.Add(45);
arrayList1.Add(25);
arrayList1.Add(12);        
foreach(var v in arrayList1)
{
    Debug.Log(v);
}

/*
 *    方法二:直接添加数组 AddRange()
 */

int[] array1 = new int[4] { 1, 2, 3, 4 };

arrayList1.AddRange(array1);
/*
 * 二、清空
 */
arrayList1.Clear();
/*
 * 三、判断某元素是否存在
 *     Contains()
 */
if (arrayList1.Contains(12))
{
    Debug.Log("存在元素12");
}
/*
 * 四、输出一个元素存在且第一次出现的下标
 *     IndexOf()
 */
Debug.Log(arrayList1.IndexOf(12));
        //若不存在则返回-1
/*
 * 五、插入
 *    Insert()
 *    两个参数:插入的下标,插入的元素
 */
arrayList1.Insert(3, 66);
/*
 * 六、删除某元素(而不是下标)(只删除第一次出现的)
 *    Remove()
 */
arrayList1.Remove(12);
/*
 * 七、逆转元素————把元素倒序输出
 *    Reverse()
 */
arrayList1.Reverse();
/*
 * 八、排序(从小到大)
 *    Sort()
 */
arrayList1.Sort();

泛型类集合List<>

List<int> list1 = new List<int>();

用法与ArrayList基本相同,且更优

哈希表

    Hashtable ht1 = new Hashtable();
    //注意是 Hashtable 而不是 HashTable

具体用法类似ArrayList,例子如下

        ht1.Add("1", 100);  //Object key, Object Value
        ht1.Add(1, 99);
        //ht1.Clear();
        if(ht1.ContainsKey("1"))
        {
            Debug.Log("包含Key为" + "1" + "的数据");
        }
        ht1.Remove("1");  //Key
        Debug.Log(ht1["1"]);  //取某个键的值的写法为 ht1[key]
        Debug.Log(ht1[1]);

        ht1[1] = 999;  //修改,使用时最好先判断是否Contains再修改

        ICollection key = ht1.Keys;  //ICollection 接口
        foreach(var k in key)
        {
            Debug.Log(ht1[k]);
        }

字典 

Dictionary<string, string> dic1 = new Dictionary<string, string>();  //Dictionary<TKey, TValue>

        dic1.Add("1", "100");
        dic1.Add("2", "200");
        dic1.Add("3", "300");

        if (dic1.ContainsKey("1"))
        {
            Debug.Log("键存在");
        }

        dic1["1"] = "1000";  //修改

        ICollection key = dic1.Keys;
        foreach(string k in key)
        {
            Debug.Log(dic1[k]);
        }
        //另一种遍历写法:
        foreach( KeyValuePair<string, string> kvp in dic1)
        {
            Debug.Log(kvp.Key + " " + kvp.Value);
        }

        dic1.Remove("2");
        dic1.Clear();

*字典和哈希表的区别

Dictionary在定义时是个泛型,Key和Value都需要指定好类型,则使用时不需要装箱拆箱转换类型的操作,执行效率高;

而Hashtable定义时由于是Object类型,则执行效率肯定会低一些

HashSet

    HashSet<int> hs1 = new HashSet<int>();
    HashSet<int> hs2 = new HashSet<int>();
        hs1.Add(1);
        hs1.Add(2);
        hs1.Add(2);  //由于不能添加重复项,因此不会再添加一个 2
        Debug.Log(hs1.Count);  //2

        hs2.Add(2);
        hs2.Add(3);

        //hs1.IntersectWith(hs2);  //与hs2取交集后的hs1
        //hs1.UnionWith(hs2);  //取并集
        //hs1.ExceptWith(hs2);  //取差集
        hs1.SymmetricExceptWith(hs2);   //取对称差集(去掉共同有的,留下剩下的)
        foreach(var v in hs1)
        {
            Debug.Log(v);  //交集后只有元素2
                                    //并集后是 1 2 3
                                    //差集后是只有元素1
                                    //对称差集后是 1 3
        }

双向链表

    LinkedList<int> linkList = new LinkedList<int>();
    LinkedListNode<int> node;  //结点
        node = linkList.AddFirst(1);  //首结点
        linkList.AddAfter(node, 2);  //在node结点后添加值为2
        linkList.AddBefore(node, 0);  //首结点变为0

        Debug.Log(linkList.Count);  //打印链表长度

        Debug.Log(linkList.First.Value);
        Debug.Log(linkList.Last.Value);

        if(node.Previous != null)
        {
            Debug.Log(node.Previous.Value);
        }
        if (node.Next != null)
        {
            Debug.Log(node.Next.Value);
        }

链表与List、数组的比较:

List和数组都是顺序存储,存储空间连续;链表的存储空间靠指针连接。因此在执行删除、插入操作时链表效率更高,执行查找操作时链表无法通过索引而只能遍历(O(n)),List和数组都可以直接索引(O(1))

堆栈Stack

先进后出

Stack stk1 = new Stack();
        stk1.Push("a");
        stk1.Push("b");
        stk1.Push("c");
        stk1.Push("d");
        Debug.Log(stk1.Count);
        string v = (string) stk1.Pop();   //Pop出来是Object类型所以需要强制转换
        Debug.Log(v);
        Debug.Log(stk1.Count);

        v = (string) stk1.Peek();  //Peek() 获取栈顶元素但不取出
        Debug.Log(v);
        Debug.Log(stk1.Count);

        Debug.Log("遍历输出:");
        foreach(var v2 in stk1)
        {
            Debug.Log(v2);
        }

队列

先进先出

    Queue queue = new Queue();  //Object类型
    Queue<int> queue2 = new Queue<int>();  //泛型
        Debug.Log("Queue2长度:" + queue2.Count);
        queue.Enqueue("1");  //入队
        queue2.Enqueue(1);
        queue2.Enqueue(2);
        queue2.Enqueue(3);

        int x = queue2.Dequeue();  //队首出队
        Debug.Log("出队元素 " + x);
        Debug.Log("Queue2长度:" + queue2.Count);

        Debug.Log("遍历队列:");
        foreach(var v in queue2)
        {
            Debug.Log(v);
        }

实现栈

class MyStack
    {
        class StackData
        {
            public StackData nextItem;  //下一个结点
            public object topData;  
            public StackData(StackData next, object data)
            {
                this.nextItem = next;
                this.topData = data;
            }
            StackData top;  //栈顶标志
            public void Push(object data)
            {
                top = new StackData(top, data);  //更新栈顶
            }
            public object Pop()
            {
                object rs1 = top.topData;
                top = top.nextItem;
                return rs1;
            }


        }
    }
 private void Start()
    {
        MyStack ms = new MyStack();
        ms.Push(1);
        ms.Push(2);
        ms.Push(3);

        Debug.Log(ms.Pop());
        Debug.Log(ms.Pop());
        Debug.Log(ms.Pop());
    }

入栈123,出栈321

 实现队列

class MyQueue
    {
        class QueueData
        {
            public QueueData nextItem;
            public object topData;
            public QueueData(QueueData last, object data)
            {
                last.nextItem = this;
                this.topData = data;
            }
            public QueueData(object data)
            {
                this.topData = data;
            }
        }
        QueueData top;
        QueueData lastData;
        public void Enqueue(object data)
        {
            if(top == null)
            {
                top = new QueueData(data);
                lastData = top;
            }
            else
            {
                lastData = new QueueData(lastData, data);
            }
        }
        public object Dequeue()
        {
            object rs1 = top.topData;
            top = top.nextItem;
            return rs1;
        }
    }


    void Start()
    {
        MyQueue mq1 = new MyQueue();
        mq1.Enqueue(1);
        mq1.Enqueue(2);
        mq1.Enqueue(3);

        Debug.Log(mq1.Dequeue());
        Debug.Log(mq1.Dequeue());
        Debug.Log(mq1.Dequeue());
    }

入队123,出队123

 一些VS快捷键

F12:快速访问函数

F9:选中某一行,断点

F11:进入函数体内

F10:单步调试

F5:结束调试

Ctrl + K + C:选择多行注释

Ctrl + K + U:选择多行取消注释

Ctrl + H:替换关键词

C#的部分到此暂告一段落,之后如果有补充知识再更新

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
      本套C#语言教程,全部采用案例化教学模式。结合C#知识点在实际游戏中具体的应用场景,让初级学员快速、深入的学好C#语言,为进一步全面、高效的学习Unity游戏引擎,制作精良的游戏产品,打下坚实的语言基础!       真正学好Unity,其先决条件是一定要有稳固、扎实的编程基础!因此目前绝大多数(线下)Unity培训机构(一般4-5个月)都会先给学员讲解C# for Unity 的编程加强课程。(一般高校的编程课程内容少、不深入...)        本套《C# for Unity》课程共分为“入门篇”、“基础篇”、“中级篇”、“进阶篇”,分别对应于完全“零”编程基础、较少编程基础、需要强化C#编程、需要深入学习C#脚本,等各类型学员群体。      说明:  本课程使用Virtual Studio2012,以及Unity5.2 进行开发与讲解。(学员使用更高版本,对学习影响不大) 一、热更新系列(技术含量:中高级):A:《lua热更新技术中级篇》https://edu.csdn.net/course/detail/27087B:《热更新框架设计之Xlua基础视频课程》https://edu.csdn.net/course/detail/27110C:《热更新框架设计之热更流程与热补丁技术》https://edu.csdn.net/course/detail/27118D:《热更新框架设计之客户端热更框架(上)》https://edu.csdn.net/course/detail/27132E:《热更新框架设计之客户端热更框架(中)》https://edu.csdn.net/course/detail/27135F:《热更新框架设计之客户端热更框架(下)》https://edu.csdn.net/course/detail/27136二:框架设计系列(技术含量:中级): A:《游戏UI界面框架设计系列视频课程》https://edu.csdn.net/course/detail/27142B:《Unity客户端框架设计PureMVC篇视频课程(上)》https://edu.csdn.net/course/detail/27172C:《Unity客户端框架设计PureMVC篇视频课程(下)》https://edu.csdn.net/course/detail/27173D:《AssetBundle框架设计_框架篇视频课程》https://edu.csdn.net/course/detail/27169三、Unity脚本从入门到精通(技术含量:初级)A:《C# For Unity系列之入门篇》https://edu.csdn.net/course/detail/4560B:《C# For Unity系列之基础篇》https://edu.csdn.net/course/detail/4595C: 《C# For Unity系列之中级篇》https://edu.csdn.net/course/detail/24422D:《C# For Unity系列之进阶篇》https://edu.csdn.net/course/detail/24465四、虚拟现实(VR)与增强现实(AR):(技术含量:初级)A:《虚拟现实之汽车仿真模拟系统 》https://edu.csdn.net/course/detail/26618五、Unity基础课程系列(技术含量:初级) A:《台球游戏与FlappyBirds—Unity快速入门系列视频课程(第1部)》 https://edu.csdn.net/course/detail/24643B:《太空射击与移动端发布技术-Unity快速入门系列视频课程(第2部)》https://edu.csdn.net/course/detail/24645 C:《Unity ECS(二) 小试牛刀》https://edu.csdn.net/course/detail/27096六、Unity ARPG课程(技术含量:初中级):A:《MMOARPG地下守护神_单机版实战视频课程(上部)》https://edu.csdn.net/course/detail/24965B:《MMOARPG地下守护神_单机版实战视频课程(中部)》https://edu.csdn.net/course/detail/24968C:《MMOARPG地下守护神_单机版实战视频课程(下部)》https://edu.csdn.net/course/detail/24979
FPGA自学笔记——设计与验证JMB FPGA(可编程逻辑门阵列)是一种可编程的硬件平台,可以实现各种数字电路的设计与验证。本文将简要介绍使用FPGA自学设计与验证JMB(低功耗、高效能、集成度高的多媒体芯片)的过程。 首先,我们需要了解JMB的功能和特性。JMB是一种面向多媒体应用的芯片,具备低功耗、高效能和高集成度的优势。我们需要详细研究JMB的硬件架构和内部模块,包括处理器核、存储器模块、图像和音频处理模块等。 接下来,我们可以使用FPGA开发板来设计和验证JMB。首先,我们需要熟悉FPGA设计工具,例如Vivado或Quartus等。这些工具提供了图形化界面和硬件描述语言(HDL)等设计方法。我们可以使用HDL编写JMB的功能模块,并将其综合为FPGA可执行的位流文件。 在设计完成后,我们需要验证JMB的功能和性能。我们可以使用仿真工具(例如ModelSim或ISE Simulator)来模拟JMB在不同情况下的行为。通过设计测试程序并运行仿真,我们可以验证JMB的各个模块是否正确地工作,是否满足设计要求。 在验证完成后,我们可以将位流文件下载到FPGA开发板中进行智能芯片的物理实现和测试。通过与外部设备的连接以及相关测试程序的运行,我们可以验证JMB在实际硬件中的功能和性能。 总结起来,学习FPGA设计与验证JMB,我们需要熟悉JMB的硬件架构和内部模块,并使用FPGA开发工具进行设计与验证。通过仿真和物理实现测试,我们可以验证JMB的功能和性能。这些过程需要理论知识和实践经验的结合,希望这些笔记能够给你提供一些参考和指导。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值