欢迎光临散文网 会员登陆 & 注册

从零开始做游戏(六)写个抛硬币游戏

2018-01-15 15:28 作者:枫2  | 我要投稿

之前的项目暂时中断下,因为UP发现再写下去就越来越不是从零了,所以UP考虑来个更容易入门的项目,

起因是这样的,UP今天偶然的一个这样那样的需求总之就是突然说到来抛个硬币试试,正面就这样,背面就那样,然后现在都是扫码支付时代嘛,找个硬币都够折腾的,于是UP找了许多抛硬币app,不是弹窗广告就是弹网页广告,用户体验极差,感觉很不愉快,不过也是都为了挣钱嘛也能理解。

于是UP决定自己动手写一个非常干净的简单的抛硬币游戏,就把这种简单的东西分享给大家吧,或许以后有人会感谢我的,对吧。

那么我们就开始动手吧,打开我的Unity,什么居然还是用unity写,是的UP就对Unity熟悉,所以就不要折腾其他开发工具了!

主界面与素材

首先建立项目,为项目起名,创建一个2D的项目,这些都挺简单的就不再描述了,如果想了解UP可是写过这些文章的哦。

然后我们需要个素材,简单的画个线框图硬币吧,打开PS,可能你会想,搜索个图片作为素材不就可以了么,不过这样你有考虑过版权么,UP可是一直都在强调版权的,所以我们仿着1元硬币画了个,也不一样是吧,只是那个1字特别像,虽然有点丑不过是那个意思吧。


其实就是仿着画了下

然后导出图片成PNG格式,不过这里需要注意下图片正反面的大小一定要保持一致哦。

PS的相关技术各位可以请教下PS大佬,UP根本就是画图废人,所以就不教学这方面了


总之最后我们得到了2张素材


打开UNITY,将图片拖到场景里


这个工程中,我们修改了背景颜色,至于怎么修改,仔细看上图,有什么地方显示出了蓝色的字体呢,对啦,就是调节那个修改的,自己找找吧。

为什么我想让背景颜色深一点呢,是因为考虑到不要那么瞎眼。

使用Unity代码来写按钮

如果你是UP的忠实观众,那么你应该记得UP曾教学过UGUI这个Unity里自带的可视化UI系统,当然如果不是的话也不必去查找那一期啦,不如从现在开始成为UP的忠实观众好不好呀。(这个不要脸的UP)

其实在Unity中,UGUI出现以前,还有一个官方的GUI代码模块,具体是什么参见下面的代码。

    void OnGUI()

    {

        //这个意思就是这里面的内容会被认为是GUI模块

    }

在unity中用void声明的有许多内容,比如Start,Update等等,UP在曾经的教学中也有提到过,所以大家可以回去翻....是的,谁想翻啊,所以UP只能再来一遍并补充一点。

首先需要明白的是,写Unity的代码时,要写在声明(就是void的那个大括号里面)

void Awake ():在游戏开始前就调用一次

void Start():在Awake后调用一次

void Update():在Start后调用,而且是无限循环的调用

void OnGUI():在Update后调用,在这里可以写入GUI代码,无限循环的调用

其实Unity里还有许多这样的声明,这里仅简单的说了常用的4种,一定要记得运行的先后顺序,因为未来很多报错的可能性都是先后顺序搞反了造成的,所以大家记住顺序了吗,没有?没关系,接着往下看,用多了就记住了,不必背诵,背了也没用。

我们来用代码写个按钮,可能你不太明白具体的意思,复制粘贴就好,不必深入理解。


写好后拖代码


然后运行(记得先保存一下,记得随时存档啊存档啊,如果你发现你的场景名字后面有个*,就像上图一样就是你没有存档,如果突然停电了系统崩溃了等等等情况发生你会崩溃的)


你会发现屏幕里多了个按钮,以及点击按钮后,控制台会给你一句这样的提示,这代码这个按钮是有用的

对按钮进行改造

我们成功的将按钮功能实现了,但是有些问题,比如按钮的位置好像很奇怪啊,所以我们改一下。

GUI.Button(new Rect(10, 10, 50, 50)

上面这段代码有4个数字看到了吗,其中10,10代表在屏幕的坐标X=10 Y= 10.

后两位数字50 50代表的是长X宽

所以我们要把它放在屏幕下面居中,需要什么位置呢,算一下坐标????

你会发现,不同的分辨率下按钮的位置都不一样,所以这时候我们需要一个相对固定坐标的算法。

这里有个新知识:Screen.width获取屏幕宽度,Screen.height获取屏幕高度,所以UP想怎样呢。

这里教学一个可能专业课里也学不到的算法:

通过屏幕宽绝对居中按钮:屏幕宽度分辨率/2 - 按钮长度/2

而高度,我们只希望他比屏幕最低的地方往上数10分辨率为间隙,所以直接用Screen.height - 50,为什么是50,因为我们的按钮高度是40,想一想有明白吗。

这个算法怎么来的,常年的经验,不断的摸索,有时候也可以由老司机程序员传授给你,其实并不需要你是数学家,只需要你经验丰富。


现在按钮绝对居中了

实际上按钮的大小也可以根据分辨率修改,不过UP认为这个项目没必要做那么复杂,所以就没有做这个功能了,不然就会开发时间增加增加再增加,开发项目的时候,多多思考下效率的问题,即用最少的时间将项目上线。

当然,按钮的皮肤也可以修改,不过在一个项目根本就不知道有多少人用的情况下,这些就暂时不改了,如果发现莫名的使用的人还很多,UP就会去继续增加新功能,好像UP把这么多年总结的产品制作经验也顺带告知大家了。

实现后端功能

抛硬币的功能是怎么实现的,其实是这样的:

首先硬币的正反实际上是在后端用随机2个数字来展示的,0是背面,1是正面,而硬币的图像其实是随着结果(0或1数字)所显示的部分,其中数字0、1叫后端,图片显示叫前端。

(顺带一说,实际上现在网上的抽奖都是这样的,在你点击的那么一瞬间,后端就给出了所代表奖品的数字,而那个表盘转啊转只是给你看的假象而已,只是它们的后端是在服务器里,如果不在服务器你就可以用修改器作弊了)

这个随机数生成的代码非常的简单,不过需要注意的是,大家看注释里写的是0-1这2个随机数,而我所填写的是0,2,如果这里写0,1,你永远只能抽到0了。

Random.Range(0,2)就是生成随机数0-1,如果想生成0-2需要写成什么呢:

Random.Range(0,3);

而print(目的是为了让其结果打印在控制台里,让我可以测试并看见)

测试了一下,出现了这么多次0和1

前端的表现

实际上到刚才那里功能已经实现一大半了,接下来要做的就是用图像显示真反面,实现原理是这样:

通过随机数0或1生成图片,如果0生成背面,1生成正面。

首先我们需要想个办法让程序把图片记住,这个办法UP已经帮你想好了


撰写个叫做GameObject的类型

关于命名类型实际上有许多知识,比如INT,String,Float等等,其实各位大可不必在此时了解,也不必背诵。

这里使用的GameObject就是可以存储游戏组件的类型,总之用来存素材是没问题啦。

为什么需要存素材,你暂时别想这个问题,看到UP把功能写好了后,你返回来看肯定能懂。

接下来UP把图片1,2都导入到了Unity场景中,并把它们移到了屏幕外面,这样的作用就是你看不见它了。


移到外面,你看到我

为了安全起见,UP把它们的坐标设置成了9999,我相信这么远的距离你用4K显示器全屏也不会露馅,然后当随机数为0的时候,我们就把图片一的坐标改成X=0 Y=0就可以了。

其实要实现出现硬币的方法有许多,如果要老老实实的写,还要写成加载图片之类的,这里UP选择了一种最懒的办法,总之用户只管用起来有没有问题,没谁管你是怎么实现的,他又不知道你是把硬币隐藏到屏幕外面了对吧。

然后我们把1和2拖入到设定的GameObject里。


跟着UP箭头的那样拖,注意要选择Main Camera

这里就需要注意了,public GameObject前面的public 一定要写,否则你会找不到该拖哪,不信你照着UP的做法试验下。

接下来,我写了个代码:int i; 

这个的意思是,我要用一个字母i来存储数据,为什么是i,其实你用a,b,c,d都可以,只是很多程序员都习惯用i来存储数据,大概是用来存储数据吧,UP初学程序的时候就发现他们都这样,于是UP也就这样了,一种习惯,如果有大佬知道原因还请告之。

i用来存储数据

至于为什么要用个i来存数据,因为不存的话你就无法用if代码来判断,看下面的代码。

上面的代码看懂了吗?

首先你需要明白一个知识,if(如果),可以说写程序100%会用到的功能

if (i == 0)  意思就是如果 i = 0,不过这里一定要记住,在程序里“等于”,要2个等号==,写一个会报错,总之记住在if里判断i是否等于0要用 == 。

上图代码里,有一段叫做: i = Random.Range(0, 2),在程序里一个等号=叫做赋值; 

这里的意思就是把0-1的随机数结果赋值给i,所以用了一个等号=。

经历了这个赋值的操作后,i就变成0或者1了(这个要根据随机数随机赋予),所以下面if(i == 0)就是判断i现在等于不等于0啊。

如果等于,执行下面一行内容,如果不等于,在看看else里面的内容。

在else里,UP又写了一段if (i == 1),在i不等于0的时候再判断下i是不是等于1啊。

实际上else后面可以不用再加if (i == 1)的,因为随机数结果只有0或者1嘛,按理说else里的内容就是前面的if (i == 0)  不满足,就强行执行else后面的东西了。

在学校里,老师肯定不会讲到这个,如果代码写的专业点的话,一定要在else后面写上if (i == 1),因为你不知道程序会不会出BUG,多写一点避免BUG。

以上对于初学程序的你来说会复杂么,或者会不会没有讲的很清楚,UP也不得而知,不过UP自己能看懂就是了。

UP好好总结以及补充上面的教学:

  1. =等号是赋值,== 双等号才叫等于

  2. if(条件) .A. else .B. 是写代码100%会用到的一种方法,意思是 如果满足if(括号里的条件),执行A,否则执行B。

  3. 当然也可以if(条件A) .C. else if(条件B) .D,意思是如果条件A满足执行C,不满足再看看条件B满足吗,满足执行D,还不满足,这段代码不执行。

  4. 条件A可以为1行或者多行代码,1行就写在if代码的下一行,多行需要添加{大括号把多行代码括起来,

    大括号中间可以回车,分号加在大括号中间;}

而代码中id1.transform.position = new Vector2(0, 0);的意思就是让id1的坐标变成X=0 Y=0,为什么要这样写,不必思考,反正你知道这样写可以实现这个功能就OK了,你把它复制过来就可以。

接下来开始测试与排除BUG,其实肯定有许多问题和优化的

首先我们运行下程序,发现原本我们把代码调整到屏幕外面去了,程序一运行正面的图片就自动进入了屏幕中间(这里就不用图展示了,相信你能懂)

实际上问题发生的原因是,程序一开始i就自动赋予的0这个值,所以我们做一些修改。

    int i = -1; 我们将程序顶部的i初始赋予了-1的值,这样运行程序的时候屏幕中间什么也没有。


我们点击抛硬币按钮,会发现某个硬币在屏幕里显示了(实际上大家都知道只是修改了那个图片的坐标,把坐标改成0了而已)


接下来我们多点了几下,发现结果和上图一样,出现硬币永远都是最初出现的第一枚。

那是因为程序功能还没有写完,出现了BUG,这时候就需要找问题修改问题了,这种模式叫做DEBUG,排除BUG,好的程序员,找到BUG和排除BUG的效率绝对高。


修改了下代码,UP没有在代码里写任何注释,你试试可以读懂每一句是什么意思吗。

如果能读懂,哦恭喜你程序入门了!

你那知道之前的BUG造成的原因是什么吗,是因为UP只写了让硬币坐标变成0,忽略了再把不用的硬币扔出屏幕外的代码,所以造成图片重叠了(这个你都发现了,看来你很有写代码的天赋)


好了,这个程序写完了!

*下面内容有难度, 不建议初学者学习,否则你会懵逼甚至从开始到放弃,所以下面这段内容类似于游戏中的hard模式关卡,只要求部有能力的玩家玩通,普通玩家看不懂也没什么问题。

这个功能就写完了,但是UP觉得有一个小问题会非常影响用户体验,即是如果连续点击“抛硬币”按钮,连续出现同一个面,你还以为按钮死机了,所以我们需要优化一下这个问题,这个不是BUG,是用户体验问题,在初次成型的项目里,这种严重影响用户体验的地方还是需要修改一下的。

我们可以用程序做一段小动画:


这段动画是通过改变图像的x轴大小来实现的,每次点击后,程序会按照0.01秒计算一次的方式将x从-2变化到2,所以UP也不再多解释这一段了,确实是初学程序时搞不定的地方。


后来UP发现了个问题,抛硬币按钮在高分辨率手机上太小,所以我们改了下按钮的大小代码,改成这样了,你能看懂意思吗,如果可以,恭喜你有天赋,加油学!

GUI.Button(new Rect(Screen.width / 2 - (Screen.width - 10) /2, Screen.height - (Screen.height * 0.15f + 10), Screen.width - 10, Screen.height * 0.15f)


后记

好了,通过一篇文章介绍了一个非常简单的游戏是如何完成的,虽然这个“游戏”某方面来说只是个工具,不过却可以通过这个简单的项目教会大家如何制作完整的项目。

unity做游戏有个最大的缺点是,打包出来的安卓比较大,这个游戏居然20多M,UP还以为500K就搞定了呢,如果大家想看一看这个项目可以访问pan.baidu.com/s/1dw1HVK下载安卓版,所以B站什么时候推出网络硬盘呢。

写完这篇文章的时候已经半夜1点多了...

从零开始做游戏(六)写个抛硬币游戏的评论 (共 条)

分享到微博请遵守国家法律