Extreme Drift赛车游戏C#源码详解(1)

C#我只是一个萌新,由于搞过Java,还是可以看懂C#的

偶然间得到赛车游戏Extreme Drift的源码

接下来我会花一段时间来解读,这是一个我学习的过程,记录在博客

等到我完全解读之后,我也许会考虑再加入联机功能等

当然,这个游戏用的是Unity引擎

首先,我先展示一下这个游戏的效果:

选车:

然后选图,进入比赛:

WASD,SHIFT氮气,空格漂移

不得不说,车辆的手感非常不错!

作为育碧的老玩家,讲真的,这个小游戏的手感比育碧的赛车手感好多了

甚至就我感觉,车辆除了一些参数感觉需要调整,整体来看,手感和GTA5的感觉有点像

不多说了,我打包出来一个Windows可运行的程序,双击就可以体验赛车游戏:

链接:https://pan.baidu.com/s/1kF61eguRJf1Gd7aGn4w5jg 
提取码:ks1l

源码的地址:花钱买的,免费分享了!

链接:https://pan.baidu.com/s/1yiayLBXOBcSoJstHJQw33A 
提取码:eyyq

下面正式开始查看源码:

导入之后目录结构:并且会自动导入Unity自带资源ImageEffects

打开Scenes的MainMenu场景,启动游戏:

然而第一次启动在加载地图的时候会报错,因为这一步:

    IEnumerator LoadLevelAsync(){yield return new WaitForSeconds(0.4f);sceneLoadingOperation = Application.LoadLevelAsync(currentLevelNumber + 1);sceneLoadingOperation.allowSceneActivation = false;while (!sceneLoadingOperation.isDone || sceneLoadingOperation.progress < 0.9f){menuLoadTime += Time.deltaTime;yield return 0;}}

这里异步加载索引为currentLevelNumber+1的场景,然而,实际上不存在这个索引,所以,我们需要在Build Setting设置好这些场景:

然后在启动,就可以顺利游戏了!

有六个场景,那么就先从主菜单MainMenu场景来看:

负责UGUI的事件系统:

Standalone Input Module:专为鼠标/键盘/控制器输入而设计:

这里没有做什么多余操作,只是添加了这个组件,一个参数也没有改

Touch Input Module:为触摸屏设备而设计,暂时与我无关

接下来看UGUI部分:

一个Canvas,里面有八个对象

Top Panel是顶部的一个横条,右边有金币设置选项

观察金币,发现这只是一个简单的图片,而金币之内,包含GameScore对象,这个应该是处理金币的核心

猜错了,观察GameScore对象发现,这也是一个简单的Text,那么金币相关功能应该是find这个对象来处理的

然后看设置,是一个Button,绑定了MainMenu里面的一个函数,而且播放点击声音,另外有一个Shadow组件:作用是给按钮添加阴影轮廓

查看这个函数:

    public void SettingActive(bool activePanel){menuPanels.Settings.gameObject.SetActive(activePanel);}

OK,只是使另一个UI对象active,可以理解为:点击设置按钮后跳转到另一个页面

MainMenu相当于是全屏幕,包含了左上的logo和底部的一个Panel:

标题Tilt:一个简单的图片,在它下面的Image有点意思,是一个较亮的矩形,反复从右到左位移,配合Logo实现发光的效果

实现机制:Image利用Aminator组件将自身和Tilt这个Logo绑定,实现循环动画

然后就是底部的Panel,里面有四个对象,退出,资源,油管,选车进行下一步

退出:绑定了Shadow、点击音效的一个按钮,以及一个MainMenu的函数:就是简单的退出

    public void ClickExitButton(){Application.Quit();}

资源和油管都是链接,本质一个按钮带Shadow和Audio,绑定OpenURL脚本的函数:传入URL,打开,简单

    public void OpenTab (string URL) {Application.OpenURL(URL);}

选车:一个简单的按钮,带Shadow,绑定MainMenu的一个函数:我在下面的注释中将会详细解释

    public void CurrentPanel(int current){//这里为什么要传一个INT呢?因为开头有定义//public enum Panels { MainMenu = 0, SelectVehicle = 1, SelectLevel = 2, Settings = 3 }//activePanel默认为0,这里传入的是1,就是选车activePanel = (Panels)current;//PlayerPrefs是数据持久化,从存档取出数据验证if (currentVehicleNumber != PlayerPrefs.GetInt("CurrentVehicle")){currentVehicleNumber = PlayerPrefs.GetInt("CurrentVehicle");//循环所有的车辆foreach (VehicleSetting VSetting in vehicleSetting){//当前车激活状态,否则不激活if (VSetting == vehicleSetting[currentVehicleNumber]){VSetting.vehicle.SetActive(true);currentVehicle = VSetting;}else{VSetting.vehicle.SetActive(false);}}}//根据传入值做一些操作switch (activePanel){case Panels.MainMenu:menuPanels.MainMenu.SetActive(true);menuPanels.SelectVehicle.SetActive(false);menuPanels.SelectLevel.SetActive(false);if (menuGUI.wheelColor) menuGUI.wheelColor.gameObject.SetActive(true);break;//这里传入的是1,进入选车case Panels.SelectVehicle:menuPanels.MainMenu.gameObject.SetActive(false);menuPanels.SelectVehicle.SetActive(true);menuPanels.SelectLevel.SetActive(false);break;case Panels.SelectLevel:menuPanels.MainMenu.SetActive(false);menuPanels.SelectVehicle.SetActive(false);menuPanels.SelectLevel.SetActive(true);break;case Panels.Settings:menuPanels.MainMenu.SetActive(false);menuPanels.SelectVehicle.SetActive(false);menuPanels.SelectLevel.SetActive(false);break;}}

VehicleGarage:车库情景,下面有五个对象

Top:顶部。左边一个logo:带有Outline的一个Text。中下是汽车的名字,也是一个Outline的Text

然后是三个车辆性能信息,速度,刹车,氮气,都是简单的Text+Slider

NextVehicle:绑定点击声音和MainMenu的一个函数:

    public void NextVehicle(){if (menuGUI.wheelColor) { menuGUI.wheelColor.gameObject.SetActive(false); }currentVehicleNumber++;//取模运算,防止越界currentVehicleNumber = (int)Mathf.Repeat(currentVehicleNumber, vehicleSetting.Length);foreach (VehicleSetting VSetting in vehicleSetting){if (VSetting == vehicleSetting[currentVehicleNumber]){VSetting.vehicle.SetActive(true);//循环到下一辆车赋值给当前currentVehicle = VSetting;}else{VSetting.vehicle.SetActive(false);}}}

PreviousVehicle是类似的:

    public void PreviousVehicle(){if (menuGUI.wheelColor) { menuGUI.wheelColor.gameObject.SetActive(false); }currentVehicleNumber--;currentVehicleNumber = (int)Mathf.Repeat(currentVehicleNumber, vehicleSetting.Length);foreach (VehicleSetting VSetting in vehicleSetting){if (VSetting == vehicleSetting[currentVehicleNumber]){VSetting.vehicle.SetActive(true);currentVehicle = VSetting;}else{VSetting.vehicle.SetActive(false);}}}

Bottom下有四个对象:

Back:一个按钮,返回上一场景,原理和上边的选车按钮一直,调用同一个函数

Next:下一步地图选择页面,也和上面的原理一样,都是调用一个函数CurrentPanel

CustomizeVehicle:自定义车辆,按钮绑定函数,点击后隐藏一些场景,开启自定义场景

BuyNewVehicle:买车,默认是不激活的,点击后激活下一个对象BuyConfirm

BuyConfirm:一个不激活的Panel,被激活后有两个选项,Yes的话掉MainMenu的函数,否则返回:

    public void BuyVehicle(){//金币足够或者车辆未买才会执行if ((gameScore >= vehicleSetting[currentVehicleNumber].price) && !vehicleSetting[currentVehicleNumber].Bought){//数据持久化PlayerPrefs.SetInt("BoughtVehicle" + currentVehicleNumber.ToString(), 1);//减钱gameScore -= vehicleSetting[currentVehicleNumber].price;//防止负数if (gameScore <= 0) { gameScore = 1; }//保存金币数量PlayerPrefs.SetInt("GameScore", gameScore);//保存车辆购买状态vehicleSetting[currentVehicleNumber].Bought = true;}else{menuPanels.EnoughMoney.SetActive(true);}}

CustomizeVehicle:自定义车辆,下面有三个对象

Top:简单的一个顶部Logo,Colors里面有八个颜色对象,绑定了MainMenu的一个函数:

    public void ActiveCurrentColor(Image activeImage){mainColor = activeImage.color;//根据传参持久化数据if (menuGUI.wheelColor.gameObject.activeSelf){vehicleSetting[currentVehicleNumber].ringMat.SetColor("_Color", mainColor);PlayerPrefsX.SetColor("VehicleWheelsColor" + currentVehicleNumber, mainColor);}else if (menuGUI.smokeColor.gameObject.activeSelf){vehicleSetting[currentVehicleNumber].smokeMat.SetColor("_TintColor", new Color(mainColor.r, mainColor.g, mainColor.b, 0.2f));PlayerPrefsX.SetColor("VehicleSmokeColor" + currentVehicleNumber, new Color(mainColor.r, mainColor.g, mainColor.b, 0.2f));}}

Bottom下面很多的对象,首先是一个返回,机制和函数上边提到了

WheelColor、SmokeColor和RandomColor都是绑定MainMenu几个函数,这几个函数不难:

    public void ActiveWheelColor(Image activeImage){randomColorActive = false;activeImage.gameObject.SetActive(true);menuGUI.wheelColor = activeImage;menuGUI.smokeColor.gameObject.SetActive(false);}public void ActiveSmokeColor(Image activeImage){randomColorActive = false;activeImage.gameObject.SetActive(true);menuGUI.smokeColor = activeImage;menuGUI.wheelColor.gameObject.SetActive(false);}
    public void RandomColor(){randomColorActive = true;menuGUI.wheelColor.gameObject.SetActive(false);menuGUI.smokeColor.gameObject.SetActive(false);//随机数函数vehicleSetting[currentVehicleNumber].ringMat.SetColor("_Color", new Color(Random.Range(0.0f, 1.1f), Random.Range(0.0f, 1.1f), Random.Range(0.0f, 1.1f)));vehicleSetting[currentVehicleNumber].smokeMat.SetColor("_TintColor", new Color(Random.Range(0.0f, 1.1f), Random.Range(0.0f, 1.1f), Random.Range(0.0f, 1.1f), 0.2f));//持久化PlayerPrefsX.SetColor("VehicleWheelsColor" + currentVehicleNumber, vehicleSetting[currentVehicleNumber].ringMat.GetColor("_Color"));PlayerPrefsX.SetColor("VehicleSmokeColor" + currentVehicleNumber, vehicleSetting[currentVehicleNumber].smokeMat.GetColor("_TintColor"));}

Extreme Drift赛车游戏C#源码详解(1)相关推荐

  1. 【C语言/C++】项目实战:猜拳游戏(源码详解)

    这是一个简单的猜拳游戏(剪子包子锤),让你与电脑对决.你出的拳头由你自己决定,电脑则随机出拳,最后判断胜负. 下面的代码会实现一个猜拳游戏,让你与电脑对决.你出的拳头由你自己决定,电脑则随机出拳,最后 ...

  2. 【Live555】live555源码详解(九):ServerMediaSession、ServerMediaSubsession、live555MediaServer

    [Live555]live555源码详解系列笔记 继承协作关系图 下面红色表示本博客将要介绍的三个类所在的位置: ServerMediaSession.ServerMediaSubsession.Dy ...

  3. 【Live555】live555源码详解系列笔记

    [Live555]liveMedia下载.配置.编译.安装.基本概念 [Live555]live555源码详解(一):BasicUsageEnvironment.UsageEnvironment [L ...

  4. 【Live555】live555源码详解(八):testRTSPClient

    [Live555]live555源码详解系列笔记 继承协作关系图 下面红色表示本博客将要介绍的testRTSPClient实现的三个类所在的位置: ourRTSPClient.StreamClient ...

  5. 【Live555】live555源码详解(七):GenericMediaServer、RTSPServer、RTSPClient

    [Live555]live555源码详解系列笔记 继承协作关系图 下面红色表示本博客将要介绍的三个类所在的位置: GenericMediaServer.RTSPServer.RTSPClient 14 ...

  6. 【Live555】live555源码详解(六):FramedSource、RTPSource、RTPSink

    [Live555]live555源码详解系列笔记 继承协作关系图 下面红色表示本博客将要介绍的三个类所在的位置: FramedSource.RTPSource.RTPSink 11.FramedSou ...

  7. 【Live555】live555源码详解(五):MediaSource、MediaSink、MediaSession、MediaSubsession

    [Live555]live555源码详解系列笔记 继承协作关系图 下面红色表示本博客将要介绍的四个类所在的位置: MediaSource.MediaSink.MediaSession.MediaSub ...

  8. 【Live555】live555源码详解(四):Medium媒体基础类

    [Live555]live555源码详解系列笔记 7.Media Medai所依赖关系图 依赖Medai关系图 Media和UsageEnvironment关联图

  9. 【Live555】live555源码详解(二):BasicHashTable、DelayQueue、HandlerSet

    [Live555]live555源码详解系列笔记 3.BasicHashTable 哈希表 协作图: 3.1 BasicHashTable BasicHashTable 继承自 HashTable 重 ...

最新文章

  1. rtsp流 转 http播放视频
  2. 云计算读书笔记(五)
  3. java数组 序列化_程序猿的日常——Java基础之clone、序列化、字符串、数组
  4. rabbitmq java 应用实例
  5. OPA 4 - createButtonTest
  6. 敲了几年代码,是时候考虑以后的发展了
  7. java怎样自动调用鼠标点击屏幕固定地方_python办公自动化:让PyAutoGUI来帮你干活...
  8. python在统计中的应用_Python在简单数据统计中的应用--随笔记
  9. SpaceX 火箭发射成功,一文了解所用的软件技术栈!
  10. 2016 ICPC 大连网络赛 部分题解
  11. 基于华为云IoT设计的智能门锁
  12. java环境已经弄好jar文件还是打不开解决方法
  13. Python:实现miller rabin米勒-拉宾素性检验算法(附完整源码)
  14. [蓝桥杯][算法提高VIP]盾神与砝码称重
  15. android简易播放器2:activity和service同步显示
  16. dataframe 按条件筛选行
  17. 冒泡排序法和选择排序法比较(从小到大,升序)
  18. 洛谷P1478,陶陶摘苹果(升级版)
  19. java正则表达式校验是否特殊字符以及空格
  20. 淘宝SEO定义、优化淘宝SEO的技巧,优化店铺,流量、排名不是问题

热门文章

  1. 从一个简洁的进度刻度绘制中了解自定义View的思路流程
  2. a+=b和a=a+b区别
  3. disable和readonly的区别和使用
  4. 滴滴java开发面经_滴滴 Java研发 社招面经
  5. 李彦宏200亿抄底团购还是建新仓?
  6. 什么软件可以语音实时翻译?这些软件你值得拥有
  7. HDU1693 Eat the Trees —— 插头DP
  8. 不知道为什么。郁闷中....
  9. 人工智能动物农场的猪、牛和蟑螂
  10. [Canvas绘图] 第31节 藏图阁(11) AlphaGo与李世石的围棋大战之第一局