Menu
CoddyTech

Frappe au sol

Leçon 9 sur 20 du cours Jeu Roblox : Arènes de combat de Coddy.

Une deuxième capacité, avec E : un coup au sol qui frappe tout le monde autour de toi et les projette au loin. workspace:GetPartBoundsInRadius(position, radius, params) trouve les pièces à une certaine distance, et ApplyImpulse appliqué à une racine pousse tout son corps. Une impulsion correspond à une variation de vitesse multipliée par la masse, donc multiplier par AssemblyMass projette les rigs légers et lourds de la même manière :

theirRoot:ApplyImpulse((away * Settings.SlamKnockback + Vector3.new(0, 40, 0)) * theirRoot.AssemblyMass)

Le jeu a maintenant deux façons de blesser quelqu’un, et d’autres arrivent. Chaque coup passe par une seule fonction, hurt(humanoid, amount), afin qu’une règle concernant les dégâts (le blocage, dans la prochaine leçon) soit écrite une seule fois.

challenge icon

Défi

Moyen
  1. Écris hurt(humanoid, amount) au-dessus de swing : retourne si le Humanoid est déjà vaincu, sinon TakeDamage(amount). Fais en sorte que swing l’appelle.
  2. Ajoute abilities.Slam : tous les personnages (une seule fois chacun, sauf toi) ayant une racine dans un rayon de Settings.SlamRadius subissent Settings.SlamDamage via hurt et sont repoussés loin de toi avec Settings.SlamKnockback et une force de 40 vers le haut.
  3. Dans BattleClient, associe "Slam" à E et ajoute cette capacité à l’affichage du temps de recharge.

Appuie sur Play, puis sur Check.

Essayez vous-même

local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local Settings = require(game.ReplicatedStorage.Settings)

local remotes = game.ReplicatedStorage.Remotes
local lastSwing = {} -- player -> moment de son dernier coup d'épée

-- Les animations d'épée de Roblox
local slash = Instance.new("Animation")
slash.AnimationId = "rbxassetid://522635514"

print("Swords deal " .. Settings.SwordDamage .. " damage")

-- Un coup d'épée : l'animation se joue, puis tous ceux qui se trouvent dans la zone devant vous sont touchés
local function swing(player)
	local character = player.Character
	local root = character and character:FindFirstChild("HumanoidRootPart")
	if not root or character.Humanoid.Health <= 0 then
		return
	end
	local now = time()
	if lastSwing[player] and now - lastSwing[player] < Settings.SwingCooldown then
		return
	end
	lastSwing[player] = now
	character.Humanoid.Animator:LoadAnimation(slash):Play()
	-- la zone devant vous, jamais votre propre corps
	local params = OverlapParams.new()
	params.FilterDescendantsInstances = { character }
	local box = root.CFrame * CFrame.new(0, 0, -3)
	local hit = {} -- chaque humanoïde une seule fois par coup d'épée
	for _, part in workspace:GetPartBoundsInBox(box, Settings.HitboxSize, params) do
		local humanoid = part.Parent:FindFirstChildOfClass("Humanoid")
		if humanoid and not hit[humanoid] then
			hit[humanoid] = true
			humanoid:TakeDamage(Settings.SwordDamage)
		end
	end
end

-- Les capacités, par nom : ce que chacune fait
local abilities = {}

function abilities.Dash(player, character, root)
	root.AssemblyLinearVelocity = root.CFrame.LookVector * Settings.DashSpeed + Vector3.new(0, 15, 0)
end

-- Le client demande une capacité par son nom. Le serveur vérifie qu'il s'agit bien d'une
-- capacité, que le joueur est en vie et que son temps de recharge est écoulé. Le moment où elle sera de nouveau disponible
-- est un attribut du joueur, ce qui permet de l'afficher à l'écran.
remotes.Ability.OnServerEvent:Connect(function(player, name)
	if typeof(name) ~= "string" or not abilities[name] then
		return
	end
	local character = player.Character
	local root = character and character:FindFirstChild("HumanoidRootPart")
	if not root or character.Humanoid.Health <= 0 then
		return
	end
	local now = workspace:GetServerTimeNow()
	if now < (player:GetAttribute(name .. "ReadyAt") or 0) then
		return
	end
	player:SetAttribute(name .. "ReadyAt", now + Settings.Cooldowns[name])
	abilities[name](player, character, root)
end)

-- Chaque joueur reçoit Kills dans le classement, ainsi qu'une épée à chaque vie
Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player

	local kills = Instance.new("IntValue")
	kills.Name = "Kills"
	kills.Parent = leaderstats

	player.CharacterAdded:Connect(function()
		local sword = ServerStorage.Sword:Clone()
		sword.Parent = player.Backpack
		sword.Activated:Connect(function()
			swing(player)
		end)
	end)
end)

-- Le mannequin d'entraînement : sa barre de vie suit sa santé et, une fois vaincu, le
-- mannequin réapparaît peu après, sous forme d'une nouvelle copie au même endroit
local function setupDummy(dummy)
	local humanoid = dummy.Humanoid
	humanoid.HealthChanged:Connect(function(health)
		dummy.HealthBar.Back.Fill.Size = UDim2.fromScale(health / humanoid.MaxHealth, 1)
	end)
	humanoid.Died:Connect(function()
		local spot = dummy:GetPivot()
		task.wait(0.5)
		dummy:Destroy()
		task.wait(Settings.DummyRespawn)
		local fresh = ServerStorage.Dummy:Clone()
		fresh:PivotTo(spot)
		fresh.Parent = workspace
		setupDummy(fresh)
	end)
end
setupDummy(workspace.Dummy)
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Jeu Roblox : Arènes de combat