首页 > 其他分享 >Godot引擎开发:GDScript脚本编写_类和继承

Godot引擎开发:GDScript脚本编写_类和继承

时间:2024-12-31 20:27:12浏览次数:3  
标签:Godot strength int self agility 引擎 health func GDScript

类和继承

在Godot引擎中,GDScript 是一种类似于 Python 的脚本语言,专门用于游戏开发。类和继承是面向对象编程的核心概念,掌握这些概念对于编写高效、可维护的代码至关重要。本节将详细介绍如何在 GDScript 中使用类和继承,包括类的定义、属性和方法的使用,以及如何通过继承来扩展类的功能。

类的定义

GDScript 中,类通过 extends 关键字来继承自一个基类。如果一个类没有明确继承自任何基类,它将默认继承自 Object 类。以下是一个简单的类定义示例:


# 定义一个简单的类

extends Object



# 类的属性

var health: int

var strength: int

var agility: int



# 类的构造函数

func _init(health: int, strength: int, agility: int):

    self.health = health

    self.strength = strength

    self.agility = agility



# 类的方法

func attack(target) -> void:

    target.take_damage(self.strength)



func take_damage(amount: int) -> void:

    self.health -= amount

    if self.health <= 0:

        self.die()



func die() -> void:

    print("I am dead!")

属性

类的属性用于存储类的状态信息。在 GDScript 中,属性可以通过 var 关键字来定义,并且可以指定其类型。例如:


var health: int

var strength: int

var agility: int

方法

类的方法是定义在类中的函数,用于实现类的行为。在 GDScript 中,方法通过 func 关键字来定义。例如:


func attack(target) -> void:

    target.take_damage(self.strength)



func take_damage(amount: int) -> void:

    self.health -= amount

    if self.health <= 0:

        self.die()



func die() -> void:

    print("I am dead!")

构造函数

构造函数用于在创建类的实例时初始化其属性。在 GDScript 中,构造函数的名称是 _init,并且它可以接受参数。例如:


func _init(health: int, strength: int, agility: int):

    self.health = health

    self.strength = strength

    self.agility = agility

继承

继承允许我们创建一个新的类,该类继承自一个现有的类,从而重用现有类的属性和方法,并可以添加新的属性和方法或修改继承的方法。在 GDScript 中,继承通过 extends 关键字来实现。

单继承

以下是一个简单的单继承示例,Player 类继承自 Character 类:


# 定义基类 Character

extends Object



var health: int

var strength: int

var agility: int



func _init(health: int, strength: int, agility: int):

    self.health = health

    self.strength = strength

    self.agility = agility



func attack(target) -> void:

    target.take_damage(self.strength)



func take_damage(amount: int) -> void:

    self.health -= amount

    if self.health <= 0:

        self.die()



func die() -> void:

    print("I am dead!")


# 定义子类 Player 继承自 Character

extends Character



var name: String

var level: int



func _init(name: String, level: int, health: int, strength: int, agility: int):

    # 调用基类的构造函数

    super._init(health, strength, agility)

    self.name = name

    self.level = level



func level_up() -> void:

    self.level += 1

    self.health += 10

    self.strength += 5

    self.agility += 3

    print(f"{self.name} leveled up to level {self.level}!")



func die() -> void:

    # 重写基类的 die 方法

    print(f"{self.name} has fallen in battle!")

多继承

GDScript 支持单继承,但不直接支持多继承。然而,我们可以通过组合的方式来实现类似多继承的效果。以下是一个示例,Player 类通过组合 CharacterPlayerStats 类来实现多个类的功能:


# 定义 Character 类

extends Object



var health: int

var strength: int

var agility: int



func _init(health: int, strength: int, agility: int):

    self.health = health

    self.strength = strength

    self.agility = agility



func attack(target) -> void:

    target.take_damage(self.strength)



func take_damage(amount: int) -> void:

    self.health -= amount

    if self.health <= 0:

        self.die()



func die() -> void:

    print("I am dead!")


# 定义 PlayerStats 类

extends Object



var name: String

var level: int



func _init(name: String, level: int):

    self.name = name

    self.level = level



func level_up() -> void:

    self.level += 1

    print(f"{self.name} leveled up to level {self.level}!")


# 定义 Player 类,通过组合 Character 和 PlayerStats 类

extends Object



var character: Character

var player_stats: PlayerStats



func _init(name: String, level: int, health: int, strength: int, agility: int):

    self.character = Character.new(health, strength, agility)

    self.player_stats = PlayerStats.new(name, level)



func attack(target) -> void:

    self.character.attack(target)



func take_damage(amount: int) -> void:

    self.character.take_damage(amount)



func level_up() -> void:

    self.player_stats.level_up()

    self.character.health += 10

    self.character.strength += 5

    self.character.agility += 3



func die() -> void:

    print(f"{self.player_stats.name} has fallen in battle!")

重写方法

在继承中,子类可以重写基类的方法。重写方法允许子类提供不同的实现,从而改变或扩展基类的行为。以下是一个示例,Player 类重写了 Character 类的 die 方法:


# 基类 Character

extends Object



var health: int

var strength: int

var agility: int



func _init(health: int, strength: int, agility: int):

    self.health = health

    self.strength = strength

    self.agility = agility



func attack(target) -> void:

    target.take_damage(self.strength)



func take_damage(amount: int) -> void:

    self.health -= amount

    if self.health <= 0:

        self.die()



func die() -> void:

    print("I am dead!")


# 子类 Player

extends Character



var name: String

var level: int



func _init(name: String, level: int, health: int, strength: int, agility: int):

    # 调用基类的构造函数

    super._init(health, strength, agility)

    self.name = name

    self.level = level



func level_up() -> void:

    self.level += 1

    self.health += 10

    self.strength += 5

    self.agility += 3

    print(f"{self.name} leveled up to level {self.level}!")



func die() -> void:

    # 重写基类的 die 方法

    print(f"{self.name} has fallen in battle!")

调用基类方法

在重写方法时,有时我们希望在子类的方法中调用基类的方法。这可以通过 super 关键字来实现。以下是一个示例,Player 类的 take_damage 方法在调用基类的 take_damage 方法后添加了额外的逻辑:


# 基类 Character

extends Object



var health: int

var strength: int

var agility: int



func _init(health: int, strength: int, agility: int):

    self.health = health

    self.strength = strength

    self.agility = agility



func attack(target) -> void:

    target.take_damage(self.strength)



func take_damage(amount: int) -> void:

    self.health -= amount

    if self.health <= 0:

        self.die()



func die() -> void:

    print("I am dead!")


# 子类 Player

extends Character



var name: String

var level: int

var shield: int = 0



func _init(name: String, level: int, health: int, strength: int, agility: int):

    # 调用基类的构造函数

    super._init(health, strength, agility)

    self.name = name

    self.level = level



func level_up() -> void:

    self.level += 1

    self.health += 10

    self.strength += 5

    self.agility += 3

    print(f"{self.name} leveled up to level {self.level}!")



func take_damage(amount: int) -> void:

    # 使用盾牌减少伤害

    if self.shield > 0:

        self.shield -= amount

        if self.shield <= 0:

            amount = amount - self.shield

            self.shield = 0

    # 调用基类的 take_damage 方法

    super.take_damage(amount)



func die() -> void:

    # 重写基类的 die 方法

    print(f"{self.name} has fallen in battle!")

类的可见性

GDScript 中,类的属性和方法默认是公开的(public)。这意味着它们可以在任何地方被访问和修改。然而,有时我们希望限制某些属性和方法的访问范围,以提高代码的安全性和可维护性。GDScript 提供了 @export 注解来实现这一目的。

@export 注解

@export 注解用于将类的属性暴露给 Godot 编辑器,使其可以在编辑器中被修改。以下是一个示例:


# 基类 Character

extends Object



@export var health: int

@export var strength: int

@export var agility: int



func _init(health: int, strength: int, agility: int):

    self.health = health

    self.strength = strength

    self.agility = agility



func attack(target) -> void:

    target.take_damage(self.strength)



func take_damage(amount: int) -> void:

    self.health -= amount

    if self.health <= 0:

        self.die()



func die() -> void:

    print("I am dead!")

私有属性和方法

GDScript 没有严格的私有属性和方法的概念,但可以通过命名约定来表示。通常,私有属性和方法的名称以单个下划线 _ 开头。以下是一个示例:


# 基类 Character

extends Object



var health: int

var strength: int

var agility: int



func _init(health: int, strength: int, agility: int):

    self.health = health

    self.strength = strength

    self.agility = agility



func attack(target) -> void:

    target.take_damage(self.strength)



func take_damage(amount: int) -> void:

    self.health -= amount

    if self.health <= 0:

        self.die()



func die() -> void:

    print("I am dead!")



# 私有方法

func _heal(amount: int) -> void:

    self.health += amount

    print(f"Healed for {amount} points. Current health: {self.health}")

受保护属性和方法

受保护属性和方法通常用于子类访问,但不希望在外部被访问。在 GDScript 中,受保护属性和方法的名称以两个下划线 __ 开头。以下是一个示例:


# 基类 Character

extends Object



var health: int

var strength: int

var agility: int



func _init(health: int, strength: int, agility: int):

    self.health = health

    self.strength = strength

    self.agility = agility



func attack(target) -> void:

    target.take_damage(self.strength)



func take_damage(amount: int) -> void:

    self.health -= amount

    if self.health <= 0:

        self.die()



func die() -> void:

    print("I am dead!")



# 受保护方法

func __heal(amount: int) -> void:

    self.health += amount

    print(f"Healed for {amount} points. Current health: {self.health}")


# 子类 Player

extends Character



var name: String

var level: int



func _init(name: String, level: int, health: int, strength: int, agility: int):

    # 调用基类的构造函数

    super._init(health, strength, agility)

    self.name = name

    self.level = level



func level_up() -> void:

    self.level += 1

    self.health += 10

    self.strength += 5

    self.agility += 3

    print(f"{self.name} leveled up to level {self.level}!")



func take_damage(amount: int) -> void:

    # 使用盾牌减少伤害

    if self.shield > 0:

        self.shield -= amount

        if self.shield <= 0:

            amount = amount - self.shield

            self.shield = 0

    # 调用基类的 take_damage 方法

    super.take_damage(amount)



func die() -> void:

    # 重写基类的 die 方法

    print(f"{self.name} has fallen in battle!")



# 子类调用受保护方法

func use_potion(potion: Potion) -> void:

    self.__heal(potion.amount)

类的实例化

类的实例化是指创建类的具体对象。在 GDScript 中,类的实例化通过 new 关键字来实现。以下是一个示例:


# 基类 Character

extends Object



var health: int

var strength: int

var agility: int



func _init(health: int, strength: int, agility: int):

    self.health = health

    self.strength = strength

    self.agility = agility



func attack(target) -> void:

    target.take_damage(self.strength)



func take_damage(amount: int) -> void:

    self.health -= amount

    if self.health <= 0:

        self.die()



func die() -> void:

    print("I am dead!")


# 子类 Player

extends Character



var name: String

var level: int



func _init(name: String, level: int, health: int, strength: int, agility: int):

    # 调用基类的构造函数

    super._init(health, strength, agility)

    self.name = name

    self.level = level



func level_up() -> void:

    self.level += 1

    self.health += 10

    self.strength += 5

    self.agility += 3

    print(f"{self.name} leveled up to level {self.level}!")



func die() -> void:

    # 重写基类的 die 方法

    print(f"{self.name} has fallen in battle!")


# 实例化 Player 类

var player = Player.new("Hero", 1, 100, 20, 15)



# 调用 Player 类的方法

player.attack(enemy)

player.level_up()

player.take_damage(50)

类的多态

多态是指子类可以替换基类的实例,并且子类可以提供不同的实现。在 GDScript 中,多态通过继承和方法重写来实现。以下是一个示例:


# 基类 Character

extends Object



var health: int

var strength: int

var agility: int



func _init(health: int, strength: int, agility: int):

    self.health = health

    self.strength = strength

    self.agility = agility



func attack(target) -> void:

    target.take_damage(self.strength)



func take_damage(amount: int) -> void:

    self.health -= amount

    if self.health <= 0:

        self.die()



func die() -> void:

    print("I am dead!")


# 子类 Player

extends Character



var name: String

var level: int



func _init(name: String, level: int, health: int, strength: int, agility: int):

    # 调用基类的构造函数

    super._init(health, strength, agility)

    self.name = name

    self.level = level



func level_up() -> void:

    self.level += 1

    self.health += 10

    self.strength += 5

    self.agility += 3

    print(f"{self.name} leveled up to level {self.level}!")



func die() -> void:

    # 重写基类的 die 方法

    print(f"{self.name} has fallen in battle!")


# 子类 Enemy

extends Character



var name: String



func _init(name: String, health: int, strength: int, agility: int):

    # 调用基类的构造函数

    super._init(health, strength, agility)

    self.name = name



func die() -> void:

    # 重写基类的 die 方法

    print(f"{self.name} is defeated!")


# 多态示例

var characters: Array[Character] = []

characters.append(Player.new("Hero", 1, 100, 20, 15))

characters.append(Enemy.new("Monster", 80, 15, 10))



for character in characters:

    character.attack(character)

    character.take_damage(30)

    if character.health <= 0:

        character.die()

类的静态方法

静态方法是指不依赖于类的实例属性的方法。在 GDScript 中,静态方法通过 @static 注解来定义。以下是一个示例:


# 基类 Character

extends Object



var health: int

var strength当然,以下是续写的内容,包括对前文的重复以便更好地阅读理解:



```gdscript

# 基类 Character

extends Object



var health: int

var strength: int

var agility: int



func _init(health: int, strength: int, agility: int):

    self.health = health

    self.strength = strength

    self.agility = agility



func attack(target) -> void:

    target.take_damage(self.strength)



func take_damage(amount: int) -> void:

    self.health -= amount

    if self.health <= 0:

        self.die()



func die() -> void:

    print("I am dead!")

静态方法

静态方法是指不依赖于类的实例属性的方法。在 GDScript 中,静态方法通过 @static 注解来定义。静态方法可以直接通过类名调用,而不需要创建类的实例。以下是一个示例:


# 基类 Character

extends Object



var health: int

var strength: int

var agility: int



@static

func create_character(health: int, strength: int, agility: int) -> Character:

    return Character.new(health, strength, agility)



func _init(health: int, strength: int, agility: int):

    self.health = health

    self.strength = strength

    self.agility = agility



func attack(target) -> void:

    target.take_damage(self.strength)



func take_damage(amount: int) -> void:

    self.health -= amount

    if self.health <= 0:

        self.die()



func die() -> void:

    print("I am dead!")

在这个示例中,create_character 是一个静态方法,用于创建 Character 类的实例。静态方法可以通过类名直接调用,例如:


var character = Character.create_character(100, 20, 15)

静态属性

静态属性是指属于类而不是类的实例的属性。在 GDScript 中,静态属性通常通过类名来访问。以下是一个示例:


# 基类 Character

extends Object



var health: int

var strength: int

var agility: int



@static var total_characters: int = 0



func _init(health: int, strength: int, agility: int):

    self.health = health

    self.strength = strength

    self.agility = agility

    # 每创建一个实例,静态属性 total_characters 增加 1

    Character.total_characters += 1



func attack(target) -> void:

    target.take_damage(self.strength)



func take_damage(amount: int) -> void:

    self.health -= amount

    if self.health <= 0:

        self.die()



func die() -> void:

    print("I am dead!")

在这个示例中,total_characters 是一个静态属性,用于记录创建的 Character 实例的总数。每当创建一个新的 Character 实例时,total_characters 会增加 1。静态属性可以通过类名直接访问,例如:


print(f"Total characters: {Character.total_characters}")

类的抽象方法

抽象方法是指在基类中定义但没有实现的方法,子类必须实现这些方法。GDScript 本身没有直接支持抽象方法的概念,但可以通过定义一个空的虚拟方法来实现类似的效果。以下是一个示例:


# 基类 Character

extends Object



var health: int

var strength: int

var agility: int



func _init(health: int, strength: int, agility: int):

    self.health = health

    self.strength = strength

    self.agility = agility



func attack(target) -> void:

    target.take_damage(self.strength)



func take_damage(amount: int) -> void:

    self.health -= amount

    if self.health <= 0:

        self.die()



func die() -> void:

    print("I am dead!")



# 定义一个虚拟的攻击方法

func special_attack(target) -> void:

    pass


# 子类 Player

extends Character



var name: String

var level: int



func _init(name: String, level: int, health: int, strength: int, agility: int):

    # 调用基类的构造函数

    super._init(health, strength, agility)

    self.name = name

    self.level = level



func level_up() -> void:

    self.level += 1

    self.health += 10

    self.strength += 5

    self.agility += 3

    print(f"{self.name} leveled up to level {self.level}!")



func die() -> void:

    # 重写基类的 die 方法

    print(f"{self.name} has fallen in battle!")



# 实现基类的虚拟方法

func special_attack(target) -> void:

    print(f"{self.name} uses a special attack!")

    target.take_damage(self.strength * 2)

在这个示例中,Character 类定义了一个虚拟的 special_attack 方法。Player 类继承自 Character 并实现了这个方法。如果子类没有实现这个方法,调用它时将不会有任何效果。

类的接口

GDScript 没有直接支持接口的概念,但可以通过定义一个基类并在子类中实现其方法来模拟接口。以下是一个示例:


# 定义一个基类 Character

extends Object



var health: int

var strength: int

var agility: int



func _init(health: int, strength: int, agility: int):

    self.health = health

    self.strength = strength

    self.agility = agility



func attack(target) -> void:

    target.take_damage(self.strength)



func take_damage(amount: int) -> void:

    self.health -= amount

    if self.health <= 0:

        self.die()



func die() -> void:

    print("I am dead!")



# 定义一个虚拟的方法,模拟接口

func perform_special_action() -> void:

    pass


# 子类 Player

extends Character



var name: String

var level: int



func _init(name: String, level: int, health: int, strength: int, agility: int):

    # 调用基类的构造函数

    super._init(health, strength, agility)

    self.name = name

    self.level = level



func level_up() -> void:

    self.level += 1

    self.health += 10

    self.strength += 5

    self.agility += 3

    print(f"{self.name} leveled up to level {self.level}!")



func die() -> void:

    # 重写基类的 die 方法

    print(f"{self.name} has fallen in battle!")



# 实现基类的虚拟方法

func perform_special_action() -> void:

    print(f"{self.name} performs a special action: Use a potion!")

    self.health += 20


# 子类 Enemy

extends Character



var name: String



func _init(name: String, health: int, strength: int, agility: int):

    # 调用基类的构造函数

    super._init(health, strength, agility)

    self.name = name



func die() -> void:

    # 重写基类的 die 方法

    print(f"{self.name} is defeated!")



# 实现基类的虚拟方法

func perform_special_action() -> void:

    print(f"{self.name} performs a special action: Roar!")

在这个示例中,Character 类定义了一个虚拟方法 perform_special_action,而 PlayerEnemy 子类分别实现了这个方法。这样,我们可以通过 Character 类的引用调用 perform_special_action 方法,而具体的行为将由子类决定。


# 多态示例

var characters: Array[Character] = []

characters.append(Player.new("Hero", 1, 100, 20, 15))

characters.append(Enemy.new("Monster", 80, 15, 10))



for character in characters:

    character.attack(character)

    character.take_damage(30)

    character.perform_special_action()

    if character.health <= 0:

        character.die()

总结

  • 类的定义:使用 extends 关键字来继承基类,类的属性和方法分别用 varfunc 关键字定义。

  • 继承:通过 extends 关键字实现单继承,使用 super 关键字调用基类的方法。

  • 重写方法:子类可以重写基类的方法以提供不同的实现。

  • 类的可见性:默认属性和方法是公开的,可以通过 @export 注解暴露给 Godot 编辑器,私有属性和方法以单个下划线 _ 开头,受保护属性和方法以两个下划线 __ 开头。

  • 静态方法和属性:使用 @static 注解定义静态方法,静态属性通过类名访问。

  • 抽象方法:通过定义虚拟方法来模拟接口,子类必须实现这些方法。

  • 多态:子类可以替换基类的实例,并提供不同的实现。

通过这些概念,可以编写更加模块化和可维护的代码,从而提高游戏开发的效率和质量。希望这些内容能帮助你在 GDScript 中更好地使用类和继承。
在这里插入图片描述

标签:Godot,strength,int,self,agility,引擎,health,func,GDScript
From: https://blog.csdn.net/chenlz2007/article/details/144752272

相关文章

  • 字节码执行引擎
    虚拟机的执行引擎可以自行定制指令集和执行引擎的结构体系,并且能够执行那些不被硬件直接支持的指令集格式。不同的虚拟机实现,执行引擎在执行Java代码时可能会解释执行(通过解释器执行)和编译执行(通过即时编译器产生本地代码执行)两种选择,也可能两者兼备,甚至还可能包含几个不同级......
  • 内置2个引擎,好用到爆!
    今天给大家推荐一个批量图片处理的软件,不但小巧,而且功能非常强大。QuestionPicture图片批量处理软件软件基于rimage的图片批量压缩软件,尤其是比较优秀的图片算法,能够带来高效的图片处理能力。把需要处理的图片直接拖入到软件里,然后设置好输出目录图片格式,就可以......
  • 在虚幻引擎4(UE4)中使用蓝图的详细教程
    在虚幻引擎4(UE4)中使用蓝图的详细教程虚幻引擎4(UnrealEngine4,简称UE4)是一款功能强大的游戏引擎,广泛应用于游戏开发、虚拟现实、建筑可视化等领域。UE4提供了一个强大的可视化脚本工具——蓝图(Blueprint),使得开发者可以通过图形化界面进行游戏逻辑的编写,而无需深入了解复杂......
  • 前端必备基础系列(五)V8引擎和内存管理
    浏览器的内核主要是由两部分组成的,以webkit为例:WebCore:负责HTML解析、布局、渲染等相关工作;JavaScriptCore:解析、执行JavaScript代码;常见的JavaScript引擎:V8是Chrome浏览器和Node.js的JavaScript引擎JavaScriptCore:是Webkit浏览器引擎的一部分,主要用于Apple的Safari浏览器,......
  • 黑客搜索引擎即相应语法
    黑客搜索引擎即相应语法1.Google部分语法:intext搜索包含指定字符的正文inurl搜索包含指定字符的urlintitle搜索包含指定字符的标题site搜包含关键字的站点filetype搜索指定文件类型2.渗透入系统1.爆破2.后台0day(只有自己知道的漏洞)1day(少数人知道的漏洞)nday(大多数人知......
  • Open Notebook:开源 AI 笔记工具,支持多种文件格式,自动转播客和生成总结,集成搜索引擎等
    ❤️如果你也关注AI的发展现状,且对AI应用开发非常感兴趣,我会每日跟你分享最新的AI资讯和开源应用,也会不定期分享自己的想法和开源实例,欢迎关注我哦!......
  • 【从零开始入门unity游戏开发之——unity篇01】unity6基础入门开篇——游戏引擎是什么
    文章目录前言**游戏引擎是什么?****游戏引擎对于我们的意义**1、**降低游戏开发的门槛**2、**提升游戏开发效率****以前做游戏****现在做游戏****主流的游戏引擎有哪些?**Unity相比其他游戏引擎的优势?**为什么选择Unity?**Unity游戏市场占比unity发展前景刚发布不久的Unit......
  • JavaScript引擎在优化标识符查询方面做了什么?
    JavaScript引擎在优化标识符查询方面采取了多种策略和技术,以提高代码执行效率和性能。以下是一些主要的优化方法:作用域链和变量对象的优化:JavaScript引擎通过创建作用域链来管理变量的访问。每个函数都有一个[[Scope]]属性,指向函数的作用域链。当函数执行时,会创建一个执行上下文......
  • InnoDB存储引擎
      6.1逻辑存储结构InnoDB的逻辑存储结构如下图所示:6.2架构6.2.1概述MySQL5.5版本开始,默认使用InnoDB存储引擎,它擅长事务处理,具有崩溃恢复特性,在日常开发中使用非常广泛。下面是InnoDB架构图,左侧为内存结构,右侧为磁盘结构。6.2.2内存结构在左侧的内存结构中,主......
  • 基于 Unity 引擎的 VR/AR 音视频编解码技术总结
    在VR/AR应用开发中,音视频编解码技术是实现沉浸式体验的关键环节之一。通过高效的音视频处理,可以实现实时通信、虚拟会议、在线视频流、沉浸式音频等功能。本文将围绕Unity引擎的VR/AR开发需求,系统总结音视频编解码的技术原理、常用工具、实现方案及优化策略。1.VR/AR......