您的位置:首页 > 编程语言 > Go语言

Q&A:通过一个情景理解GDScript中的继承机制(Godot游戏引擎萌新向)

2020-04-19 20:10 1011 查看

很多萌新在学习Godot Engine和GDScript之前并没有接触过面向对象编程,所以看《手把手带你Godot游戏开发 第一弹》时遇到“继承”这个概念,感到很困惑,什么场景下使用继承呢?而且有小伙伴反映,翻了教科书和网络上的一些文章,反而有越看越迷糊的趋势。
老王也是从萌新一路走来,所以对这种困惑很理解,问题并不在于教科书和网文,而是由于萌新缺乏编程的实践,导致阅读一些抽象的叙述时,脑海中没有足够的情景来唤起共鸣。此类困惑的根本解决方案只有一个,那就是 “硬着头皮死磕” ,多实践,多碰钉子,多积累。最终能够让你豁然开朗的,并不是某一个答案,而恰恰是你积累的问题。

今天老王也用Godot的GDScript提供一个使用继承机制的情景。

文章目录

  • 当萌新学会了继承
  • 小结
  • 情景

    这是一个Godot游戏小萌新的故事。。。

    如果没有继承

    游戏策划案第一版

    游戏策划对萌新说:“要在游戏中实现三种小怪物,小怪A、小怪B和小怪C”。

    小怪A是治愈系的,它的概念设计如下:

    成员 说明
    level
    等级
    hp
    体力
    loyalty
    忠诚度
    cure()
    调用它就可以释放治愈技能

    小怪B是攻击系的,它的概念设计如下:

    成员 说明
    level
    等级
    hp
    体力
    loyalty
    忠诚度
    attack()
    调用它就可以释放攻击技能

    小怪C是魔法系的,它的概念设计如下:

    成员 说明
    level
    等级
    hp
    体力
    loyalty
    忠诚度
    magic()
    调用它就可以释放魔法技能

    看起来并不难实现,于是萌新开工了:

    #MonsterA.gd
    extends Node
    var level = 1
    var hp = 5
    var loyalty = 10
    func cure():
    """具体逻辑略"""
    print("MonsterA的治愈技能")

    然后

    Ctrl + C
    /
    Ctrl + V
    删掉
    func cure()
    改成
    func attack()
    实现逻辑…

    #MonsterB.gd
    extends Node
    var level = 1
    var hp = 5
    var loyalty = 10
    func attack():
    """具体逻辑略"""
    print("MonsterB的攻击技能")

    继续

    Ctrl + C
    /
    Ctrl + V
    删掉
    func attack()
    改成
    func magic()
    实现逻辑…

    #MonsterC.gd
    extends Node
    var level = 1
    var hp = 5
    var loyalty = 10
    func magic():
    """具体逻辑略"""
    print("MonsterC的魔法技能")

    耶!看起起来还不错!

    游戏策划案第二版

    还没来得及高兴,策划带来了策划案的第二版。

    “我们希望增加更多种类的小怪,嗯…大约有100种吧。它们和小怪A、B、C的关系相似。都具有相同的属性,也有各自不同的方法 ”策划说。

    “啊?。。。好吧”萌新小伙伴,皱了皱眉,又开工了。。。

    过程略… 这次耗时有点长,期间由于手抖眼花,还弄出了不少Bug…

    游戏策划案第三版

    刚打算收工,策划又来了:“ 这次要去掉所有小怪中的

    loyalty
    属性,增加一个共同的“咆哮”技能”。

    萌新:“……&*%……&¥%……#))——”

    当萌新学会了继承

    游戏策划案第一版

    #MonsterBase.gd
    extends Node
    class_name MonsterBase #从Godot3.1开始可以给类起名字了
    var level = 1
    var hp = 5
    var loyalty = 10
    #MonsterA.gd
    extends MonsterBase #继承MonsterBase
    func cure():
    """具体逻辑略"""
    print("MonsterA的治愈技能")
    #MonsterB.gd
    extends MonsterBase #继承MonsterBase
    func attack():
    """具体逻辑略"""
    print("MonsterB的攻击技能")
    #MonsterC.gd
    extends MonsterBase #继承MonsterBase
    func magic():
    """具体逻辑略"""
    print("MonsterC的魔法技能")

    多定义了一个基类,少写了几行重复的代码。

    游戏策划案第二版

    过程略。。。少了重复的代码,出错的概率小了些,不过没看出什么太神奇的地方。

    游戏策划案第三版

    #MonsterBase.gd
    extends Node
    class_name MonsterBase #从Godot3.1开始可以给类起名字了
    var level = 1
    var hp = 5
    #var loyalty = 10
    func roar():
    print("路见不平一声吼,该出手时就出手")

    什么?!!H(&(……%&%…………,这么简单就实现了?!!!

    曾经让萌新和策划决裂的问题不再是问题,从此他们幸福地生活在一起…

    小结

    言归正传,从上文两种情况的对比我们不难发现,继承机制说白了就是把派生类的共同特征放到(抽象到)基类,当存在大量具有共同特征的类,而且共同特征可能发生改变时,使用继承会大大提高代码的可维护性。

    • 点赞 12
    • 收藏
    • 分享
    • 文章举报
    开发游戏的老王 博客专家 发布了413 篇原创文章 · 获赞 1723 · 访问量 26万+ 私信 关注
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: