饥荒Mod 开发(二十):显示打怪伤害值

2023-12-22 20:02:27

饥荒Mod 开发(十九):显示简易血量

源码
当我们和怪物战斗的时候,无论是被攻击还是攻击怪物都不会有伤害显示,画面感太差了,这次我们给打怪增加点乐趣,可以看到掉血。

原理

有生命值的怪物或者角色,如果血量发生变化,无论是加血还是掉血都会收到一个通知,所以我们只需要监听 这个通知就可以,当我们监听到通知的时候显示一个红色文本标签,然后淡淡的消失就可以了

监听生命值变化

-- 在 "health" 组件初始化后执行的函数
AddComponentPostInit("health", function(Health, inst)
    -- 监听 "healthdelta" 事件,当健康值发生变化时执行的函数
    inst:ListenForEvent("healthdelta", function(inst, data)
        -- 如果实例有 "health" 组件
        if inst.components.health then
            -- 计算健康值的变化量
            local amount = (data.newpercent - data.oldpercent) * inst.components.health:GetMaxHealth()
            -- 如果健康值的变化量的绝对值大于 0.99,则创建伤害指示器
            if math.abs(amount) > 0.99 then
                --接下来需要创建一个 伤害文本
                --CreateDamageIndicator(inst, amount)
            end
        end
    end)
end)

创建伤害显示文本

-- 创建标签的函数,参数为实例和父对象
local function CreateLabel(inst, parent)
    -- 设置实例不持久化
    inst.persists = false
    -- 如果实例没有 Transform 组件,则添加一个
    if not inst.Transform then
        inst.entity:AddTransform()
    end
    -- 设置实例的位置为父对象的世界位置
    inst.Transform:SetPosition(parent.Transform:GetWorldPosition())
    -- 返回实例
    return inst
end

显示伤害文本动画

--伤害显示
local HEALTH_LOSE_COLOR = {
	r = 0.7,
	g = 0,
	b = 0
  }
local HEALTH_GAIN_COLOR = {
	r = 0,
	g = 0.7,
	b = 0
  }

local LIFT_ACC = 0.003

local LABEL_TIME_DELTA = 0.05
local function CreateDamageIndicator(inst, amount)
	-- 创建标签实体
	local labelEntity = CreateLabel(GLOBAL.CreateEntity(), inst)
	-- 添加标签组件
	local label = labelEntity.entity:AddLabel()
	-- 设置字体和字号
	label:SetFont(GLOBAL.NUMBERFONT)
	label:SetFontSize(70)
	-- 设置位置
	label:SetPos(0, 4, 0)
	-- 根据伤害数值的正负,设置颜色
	local color
	if amount < 0 then
		color = HEALTH_LOSE_COLOR
	else
		color = HEALTH_GAIN_COLOR
	end
	-- 设置颜色和文本
	label:SetColour(color.r, color.g, color.b)
	label:SetText(string.format("%d", amount))

	-- 在新的线程中开始执行动画
	labelEntity:StartThread(function()
		-- 初始化一些变量
		local t = 0
		local ddy = 0.0
		local dy = 0.05
		local side = 0
		local dside = 0.0
		local ddside = 0.0
		local t_max = 0.5
		local y = 4
		-- 当标签实体有效且时间未达到最大值时,进行循环
		while labelEntity:IsValid() and t < t_max do
			-- 计算新的位置和大小
			ddy = LIFT_ACC * (math.random() * 0.5 + 0.5)
			dy = dy + ddy
			y = y + dy
			ddside = -side * math.random()* 0.15
			dside = dside + ddside
			side = side + dside
			-- 根据相机的朝向,设置标签的位置
			local headingtarget = 45 --[[TheCamera.headingtarget]] % 180
			if headingtarget == 0 then
				label:SetPos(0, y, 0)  		-- from 3d plane x = 0
			elseif headingtarget == 45 then
				label:SetPos(side, y, 0)	-- from 3d plane x + z = 0
			elseif headingtarget == 90 then
				label:SetPos(side, y, 0)		-- from 3d plane z = 0
			elseif headingtarget == 135 then
				label:SetPos(side, y, 0)		-- from 3d plane z - x = 0
			end
			-- 更新时间和字号
			t = t + LABEL_TIME_DELTA
			label:SetFontSize(70 * math.sqrt(1 - t / t_max))
			-- 暂停一段时间
			GLOBAL.Sleep(LABEL_TIME_DELTA)
		end
		-- 移除标签实体
		labelEntity:Remove()
	end)
end

在这里插入图片描述

文章来源:https://blog.csdn.net/wanliaixie/article/details/135096475
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。