犯了个严重错误,把孩子带进了游戏的大坑!

去年写过一篇文章坏了,我把闺女培养成程序员了,讲了讲孩子从玩游戏开始,到主动学编程,写游戏的经历。

很多人很感兴趣,问我后续怎么样了,很惭愧,掉进了一个大坑。

这个大坑就是Unity。

01

原因是这样的,之前孩子用Scratch,编程猫来写游戏,慢慢地就发现这些图形化软件实在太简单了,功能非常受限,想做个复杂的游戏比如一个简版的《帝国时代》,基本上不可能。

闺女的很多想法都无法实现,而她编写游戏最重要的目的就是表达自己内心的一些想法,这些想法单纯用写作、绘画不好表达。

我告诉她,想自由自在地、不受限制地编写游戏,只有学习正经的游戏引擎了。

比如Unity,学会了可以做任何复杂的游戏。

她很感兴趣,虽然Unity用的是C#,但她有Python经验,再说游戏用的都是基本的C# 语法,我估计主要的难点还是在引擎本身的特性和API上,有我这个老程序员“坐镇”,应该不是问题。

于是就下载IDE,找了一本教程《轻松上手2D游戏开发:Unity入门》,开始了Unity之旅。

刚开始还挺顺利,跟着教程走,理解了一些概念,C# 代码也相对简单,很快就实现了一些关卡。

但随着游戏复杂度提升,一大堆概念扑面而来,Camera、Transfrom、Render、Collider、RigidBody、Tag、Layer、Animator、Tile.....

每个概念背后都有复杂的配置,密密麻麻的属性让人望而生畏。

教程对用到的属性也有讲解,但是这么多的知识点如果不是熟手,很难灵活地运用起来。

C# 中用的到Unity API也越来越多,比如:

//判断是否在地面onGround = Physics2D.Linecast(transform.position,transform.position - (transform.up *0.1f),groundLayer);
// 取消玩家碰撞体积GetComponent<CapsuleCollider2D>().enabled = false;
// 展现玩家向上稍稍跳起的效果rbody.AddForce(new Vector2(0,5),ForceMode2D.Impulse);

为了把这些API彻底搞清楚,得花费很多的时间,这就让人很崩溃。

我们俩就像在一个黑乎乎的山洞中前行,手中的火把只能照亮周边的一小块儿区域,山洞有多大有多深,完全没有概念。

更要命的是,走过的崎岖道路也很容易忘记,感觉心里没底。

我对孩子说:要不这样,我们采用快速通过的策略,先不考虑那些细节,大概知道那些属性的用途和代码的基本含义就行,等到游戏做完了,也许就明白了。

于是就不再恋战,跟着教程迅速推进,很快把游戏做了个七七八八,但是回头来看,真正掌握的东西并不多。

尤其想利用Unity实现自己的创意的时候,感觉束手束脚,不像编程猫那样自由自在,这就违背了学习Unity的初衷。

我反思了一下,从图形化编程一下子进入到Unity,这个跨度还是太大了。

有点像刚学会四则运算,马上就要开始解一元二次方程的感觉。

Unity这个引擎非常强大,细节很多,需要长时间的锻炼才能掌握,而闺女刚上初中,学业紧张,每周也只能挤出一两个小时来学,是远远不够的。

后来打开Unity的次数越来越少,不知不觉中停止了。

02

今年暑假,孩子有了大块儿的时间,又想开始自己的“游戏事业”。

不知道她听谁说有个叫RPGMaker的东西,好像做游戏很方便,让我给她下载。

下载下来,她玩了一会儿,立刻就爱上了。

虽然只能做RPG类型的游戏,但是相比Unity,这个RPGMaker非常适合孩子来玩儿,比如走动、地图、碰撞几乎都是内置的,她可以把心思放到游戏设计上来,而不是底层的技术细节。

她自己从B站上找了一个RPGMaker的教程,投入地看了起来,一边看,一边自己仿照着做。

之前早上还睡个懒觉,有了RPGMaker以后,好家伙,我一起床就看到她坐在电脑前,奋力学习编写游戏了。

几十节课的教程,两三天就看完,并且做了一个简单的游戏。

然后自己又去找游戏设计的书籍,让我给她买《游戏设计的艺术》,看得不亦乐乎。

然后又找我讨论要设计的游戏情节,她要做一个校园类的魔法游戏,开始画草稿。

看到她的这种状态,让我非常感慨:兴趣的力量实在是太大了!简直是不可阻挡啊!

可惜,假期很快结束,开学了......

03

从孩子学游戏编程的经历可以很清楚地看出一点:兴趣真的是第一驱动力。

但如果台阶太高,再热烈的兴趣也会被耗尽。

最好的学习路径,是那种“刚好跳一跳就够得着”的台阶。

另外就是要能很快就看到成果,带来成就感,如果一直在摸索、积累,迟迟无法做出一点儿东西出来,就会心生怀疑,也很容易丧失信心。

就像我们学习计算机知识的时候,如果一直学计算机网络,操作系统,数据库,编译原理、数据结构这些偏向底层理论的东西,就会非常枯燥。但是如果做点儿项目如一个支持高并发的网站,写个简单的OS,数据库,自己弄个编程语言,知识形象化了,就有趣得多。

### 代码作用 代码 `if(number.size()<2||symbol.size()<1)return;` 的作用是进行条件判断,如果满足 `number.size()<2` 或者 `symbol.size()<1` 这两个条件中的任意一个,就会直接从当前函数中返回,不再执行后续的代码。 从逻辑上推测,`number` 可能是一个存储数字的容器(如 `std::vector`),`symbol` 可能是一个存储符号(如运算符)的容器。当 `number` 中的元素数量少于 2 或者 `symbol` 中的元素数量少于 1 时,后续的代码逻辑可能无法正常执行,所以提前返回以避免错误。 ### 避免运行时错误(RE)的原理 运行时错误通常是在程序运行过程中出现的错误,例如访问越界、除零错误等。假设后续的代码逻辑需要至少 2 个数字和 1 个符号才能正常执行,比如进行一个简单的数学运算,至少需要两个操作数和一个运算符。如果 `number` 中的元素数量少于 2 或者 `symbol` 中的元素数量少于 1,在后续代码中尝试访问这些容器的元素时,就可能会导致访问越界的错误。 例如,后续代码可能有类似 `number[i]` 或者 `symbol[j]` 的操作,当容器元素数量不足时,`i` 或 `j` 的值可能超出容器的有效范围,从而引发运行时错误。通过在代码开头进行条件判断并提前返回,可以避免这种情况的发生,保证程序的健壮性。 ### 避免编译错误(CE)的原理 编译错误通常是在代码编译阶段出现的错误,例如语法错误、类型不匹配等。在这段代码中,`number.size()` 和 `symbol.size()` 是合法的操作,不会引发编译错误。而提前返回的逻辑主要是为了避免运行时错误,而不是编译错误。所以严格来说,这段代码本身并不能直接避免编译错误,但是它可以保证在运行时不会因为容器元素数量不足而导致后续代码出现运行时错误,从而间接提高程序的稳定性。 以下是一个简单的示例代码,展示了类似逻辑的应用: ```cpp #include <iostream> #include <vector> void performOperation(std::vector<int> number, std::vector<char> symbol) { if (number.size() < 2 || symbol.size() < 1) return; // 后续代码逻辑 int result = number[0] + number[1]; std::cout << "Result: " << result << std::endl; } int main() { std::vector<int> numbers = {1, 2}; std::vector<char> symbols = {'+'}; performOperation(numbers, symbols); return 0; } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值