浏览器打不开网页,深圳教师招聘信息,网路电话
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")); }
下面是enoughmoney,明天再看
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
Blazor server side 自家的一些开源的, 实用型项目的进度之 CEF客户端
.NET IoC模式依赖反转(DIP)、控制反转(Ioc)、依赖注入(DI)
vue+.netcore可支持业务代码扩展的开发框架 VOL.Vue 2.0版本发布
网友评论