我如何将其他类型的动作状态效果、治疗、统计提升、队伍切换添加到基于回合的系统中

如何解决我如何将其他类型的动作状态效果、治疗、统计提升、队伍切换添加到基于回合的系统中

我目前正在尝试实现一些不同的动作而不是攻击,但我想专注于一个派对功能,看起来像这样,我可以弄清楚我想要的动作类型,但我想将战斗功能更改为适应一个可以接受多个动作而不仅仅是攻击的角色

func change_party(inventory,index): # Inventory being if enemy or player
    if inventory[index].fainted == false: # Checks if the monster is not dead
        var hold = inventory[0] # Holds the first slot and then applys it later to the selected slot
        inventory[0] = inventory[index]
        inventory[index] = hold
    

这改变了由按钮输入的索引并将其与数组中的第一个槽交换这是因为第一个槽是首先显示的怪物,我也有这个战斗功能:

func _battle():
    participants = [player_inventory[0],enemy_inventory[0]]
    participants.sort_custom(self,"check_speed")
    for attacker in participants:
        var player_move = player_inventory[0].move_slot[action_index]
        var random_move = randi() % 3 + 1
        var enemy_move = attacker.move_slot[0] # Use random_move currently 0
        
        var target = _choose_target(attacker,participants)
        if attacker == player_inventory[0]:
            yield(attack(attacker,target,player_move),"completed")
        else:
            yield(attack(attacker,enemy_move),"completed")
            
        if player_inventory[0].current_hp <= 0:
            player_inventory[0].current_hp = 0
            player_inventory[0].fainted = true
            Battle_Ui_Updater()
            self.current_state = GameState.LOST
            return
        if enemy_inventory[0].current_hp <= 0:
            enemy_inventory[0].current_hp = 0
            enemy_inventory[0].fainted = true
            Battle_Ui_Updater()
            self.current_state = GameState.WON
            return

    self.current_state = GameState.ACTION

我想到的一个解决方案是尝试将所有操作都放在一个数组中,然后根据输入调用我想要的操作,但我不知道如何使其看起来可读或没有错误

在这个函数中,它是如何根据速度决定轮到谁的,但有时我希望玩家先走,例如当我想改变队员时,当玩家改变时我想让敌人开始攻击,但我正在摸索如何让它改变动作,我知道如果我想让它做其他事情应该改变攻击功能,但我也希望能够根据什么类型来控制谁的回合使用了action,如果我没有解释清楚,我很抱歉,希望你们理解,我不想通过制作另一个类似战斗功能的重复我自己,那么我如何避免重复,同时做我想做的事?

战斗脚本:

func attack(attacker,move):
    print(str(attacker.name) + " used " + str(move.name) + " " + str((move)))
    var new_text = (attacker.name + " attacked with " + move.name)
    text_scroller(new_text)
    var data = recieve_damage(move,attacker,target)
    #var data = target.take_damage(move,attacker) # Calls the function to take damage
    yield(get_tree().create_timer(2),"timeout") #Wait for 2 seconds
    Battle_Ui_Updater()
    if data:
        yield(critical_hit(attacker),"completed")
        
func critical_hit(attacker):
    var new_text = (attacker.name + " has landed a critical hit! ")
    text_scroller(new_text)
    print(attacker.name + " has landed a critical hit!")
    yield(get_tree().create_timer(2.5),"timeout")

func Get_effectiveness(attack_type,defence_type):
    if attack_type == TypeData.types.none or defence_type == TypeData.types.none:
        return 1
    print("row : " + str(attack_type))
    print("col : " + str(defence_type))
    return TypeData.chart[attack_type][defence_type]

func recieve_damage(action,defender):
    var critical = 1
    var critical_chance = randi() % 100 + 1
    if critical_chance <= 6.25:
        critical = 2
    var attack_mode
    var defence_mode
    if action.is_special == true:
        attack_mode = attacker.special_attack
        defence_mode = defender.special_defence
    else:
        attack_mode = attacker.attack
        defence_mode = defender.defence
    
    var type : float = Get_effectiveness(action.type,defender.type_1) * Get_effectiveness(action.type,defender.type_2)
    var modifier : float = rand_range(0.85,1.0) * type * critical
    var a : float = (2.0 * attacker.level / 5.0 + 2.0)
    var b : float = (a * attack_mode * action.power / defence_mode) / 50.0
    var c : float = (b + 2.0) * modifier
    var damage = int(c)
    defender.current_hp -= damage
    print(str(attacker.name) + " = " + str(damage))
    return critical > 1

与当前成员交换党员:

func change_party(inventory,index):
    if inventory[index].fainted == false:
        var hold = inventory[0]
        inventory[0] = inventory[index]
        inventory[index] = hold
        print(inventory[0].hp)
        Battle_Ui_Updater()
        move_ui_updater(player_inventory[0])
        yield(get_tree().create_timer(2),"timeout")

解决方法

我想出了这个:

class_name Task

class Skipper:
    signal skip
    
    func emit() -> void:
        emit_signal("skip")

var _instance:Object
var _method:String
var _parameters:Array
var _result = null

func _init(instance:Object,method:String,parameters:Array = []) -> void:
    _instance = instance
    _method = method
    _parameters = parameters

func execute():
    var instance = _instance
    var parameters = _parameters
    if instance != null and instance.has_method(_method):
        _instance = null
        _parameters = []
        _result = instance.callv(_method,parameters)
        if _result is GDScriptFunctionState && _result.is_valid():
            _result = yield(_result,"completed")
            return _result

    var skipper = Skipper.new()
    skipper.call_deferred("emit")
    yield(skipper,"skip")
    return _result

这就是你初始化它的方式:

var parameters = [player_inventory[0],enemy_inventory[0],player_inventory[0].move_slot[action_index]]

player_action = Task.new(self,"attack",parameters)

这就是你如何使用它:

yield(player_action.execute(),"completed")

这个类的新特性是无论它调用的方法是否异步,它都会是异步的(所以你不必担心它调用的方法是否会产生)。无论哪种方式,它都会在它调用的方法完成后完成。它甚至会返回(如果它调用的内容没有返回则为 null)!

注意:此代码将 memoize 结果,并删除它所链接到的参数和实例。对 execute 的后续调用将简单地返回记忆的结果。这样它就不会不必要地持有引用。


我们该怎么做?

好吧,首先,我们使用 callv 通过名称调用带有参数数组的方法。 Godot 中有一个类 FuncRef 可以以类似的方式使用。但是,不使用它会更方便。

其次,调用异步将是 yield(...,"completed") 但我们不知道我们调用的是否是异步的。所以我们检查。如何?如果它是异步的,它实际上将它离开执行时的状态作为 GDScriptFunctionState 返回,因此我们检查它。

如果它是GDScriptFunctionState,那么我们可以在它上面使用yield(...,"completed")

如果不是。我们需要以某种方式使函数异步。我们将通过用 call_deferred 发出信号来做到这一点。我决定将它作为内部类,这样它就不会暴露在脚本之外。

还要注意,代码会检查实例是否为空并且方法是否已通过。但如果没有,它将简单地返回它存储的结果。这是记忆机制的一部分,然而,这也意味着如果你传递了错误的方法名写错的实例,你将没有反馈。


最后,它应该适用于这个版本的 _battle

func _battle():
    participants = [player_inventory[0],enemy_inventory[0]]
    participants.sort_custom(self,"check_speed")
    for current_participant in participants:
        if current_participant == player_inventory[0]:
            yield(player_action.execute(),"completed")
        else:
            yield(enemy_action.execute(),"completed")

        var state = decide_battle_state()
        if state != GameState.BATTLE:
            self.current_state = state
            return

    self.current_state = GameState.ACTION

func decide_battle_state():
    if check_fainted(player_inventory[0]):
        return GameState.LOST

    if check_fainted(enemy_inventory[0]):
        return GameState.WON

    return GameState.BATTLE

func check_fainted(participant) -> bool:
    if participant.current_hp > 0:
        return false

    participant.current_hp = 0
    participant.fainted = true
    Battle_Ui_Updater()
    return true

您可以使用 Task 生成 speed

class_name BattleAction extends Task

# warning-ignore:unused_class_variable
var speed

func _init(instance:Object,parameters:Array = []).(instance,method,parameters) -> void:
    pass

然后像这样使用:

var parameters = [player_inventory[0],player_inventory[0].move_slot[action_index]]

player_action = BattleAction.new(self,parameters)
player_action.speed = player_inventory[0].speed

最后 _battle 看起来像这样:

使用具有 BattleActionspeed,您可以这样做:

func _battle():
    actions = [player_action,enemy_action]
    actions.sort_custom(self,"check_speed")
    for action in actions:
        yield(action.execute(),"completed")
        var state = decide_battle_state()
        if state != GameState.BATTLE:
            self.current_state = state
            return

    self.current_state = GameState.ACTION

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-