Практика з нарахуванням балів (Else/If )

Else/If (Практика з нарахуванням балів)

У цьому проекті використовуватимуться умовні оператори для створення частини, яка буде давати або віднімати бали на таблиці лідерів залежно від того, якого кольору ця частина під час дотику. Якщо синій, це дасть гравцям кілька очок. Якщо зелений, то це дасть багато балів. Нарешті, якщо червоний, то він забирає очки.

Налаштування проекту

Частину, яка надає бали, можна додати в будь-який проект, де бали є актуальними. Наприклад, пригодницька гра, де гравці збирають бали.

Відстеження точки

Щоб налаштувати цей проект, вам знадобиться таблиця лідерів для відстеження балів і частина, яка змінює кольори. Буде надано код для таблиці лідерів.

Створіть новий сценарій у ServerScriptService під назвою Leaderboard. Скопіюйте та вставте наведений нижче код у сценарій.

--In ServerScriptService, create a script named PlayerSetup with the contents below.

local Players = game:GetService("Players")

local function onPlayerJoin(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player

-- Example of an IntValue
local points = Instance.new("IntValue")
points.Name = "Points"
points.Value = 0
points.Parent = leaderstats
end
-- Run onPlayerJoin when the PlayerAdded event fires
Players.PlayerAdded:Connect(onPlayerJoin)

Частина, що змінює колір

Сценарій змінюватиме три різні кольори частини. Кожен колір матиме змінну для зберігання його значення RGB, типу даних, який включає набір із трьох чисел (червоний, зелений, синій), які створюють кольори.

Створіть частину під назвою PointPart із вкладеним сценарієм під назвою PointScript.
У PointScript використовуйте script.Parent для посилання на частину.

local pointPart = script.Parent

Створіть змінні для зберігання різних кольорів. Для кожної змінної має бути встановлено значення Color3.fromRGB() , що створює значення кольору.

-- Colors
local blue = Color3.fromRGB(0, 0, 255)
local green = Color3.fromRGB(0, 255, 0)
local red = Color3.fromRGB(255, 0, 0)

Додайте змінні для невеликої кількості балів, більшої кількості балів і третю для видалення балів.

-- Points values
local smallPoints = 10
local largePoints = 50
local losePoints = 100

Додавання сервісу Players

Щоб нараховувати очки, вам потрібно буде отримати доступ до інформації про гравця, яка зберігається в провіднику в розділі «Гравці» та є окремою від об’єкта персонажа. Тут можна знайти таку інформацію, як статистика таблиці лідерів.

Ви можете зробити це, додавши службу Players до свого сценарію. Сервіси — це додаткові набори попередньо створених функцій, створених інженерами Roblox для економії вашого часу.

Отримайте сервіс Players , ввівши:

локальні гравці = game:GetService("гравці")

-- Points values
local smallPoints = 10
local largePoints = 50
local losePoints = 100

-- Services needed
local Players = game:GetService("Players")

Функції та події

PointsScript потребує двох функцій. Перша функція видасть і відніме частини. Друга функція перевіряє, чи гравець торкнувся частини. Потім ці функції будуть пов’язані з подією дотику, яка запускається кожного разу, коли торкається цієї частини.

Створіть нову функцію з назвою givePoints() і параметром з назвою player . Усередину додайте оператор друку для використання для тестування.

local Players = game:GetService("Players")

-- Gives or subtracts points
local function givePoints(player)
        print("Giving player points")
end

Під цим створіть другу функцію під назвою partTouched() з параметром під назвою otherPart .

-- Gives or subtracts points
local function givePoints(player)
        print("Giving player points")
end

-- Checks if player touched the part
local function partTouched(otherPart)

end

Усередині функції використовуйте функцію GetPlayerFromCharacter(), щоб перевірити, чи є гравець у змінній otherPart.

-- Checks if player touched the part
local function partTouched(otherPart)
        local player = Players:GetPlayerFromCharacter(otherPart.Parent)
end

Якщо гравець торкнувся частини, це буде збережено в змінній player. Якщо ні, змінна залишиться порожньою. Самостійно:Усередині функції перевірте, чи гравець має значення. Якщо є, викличте givePoints(player) .
Під функцією підключіть partTouched() до події Touched у pointPart .

-- Checks if player touched the part
local function partTouched(otherPart)
-- Gets the player if one touched the part
local player = Players:GetPlayerFromCharacter(otherPart.Parent)
if player then
givePoints(player)
end
end

pointPart.Touched:Connect(partTouched)

Запустіть проект. Кожного разу, коли гравець торкається частини, у вікні виводу має з’являтися повідомлення: «Нараховуються очки гравця».

Поради щодо усунення несправностей:
  1. Переконайтеся, що слово «Гравці» в game:GetService(«Гравці») написано великими літерами та взято в лапки.
  2. partTouched() має бути підключено до події PointPart Touched .

Створення циклічних кольорів

Для циклічного перегляду кольорів сценарій використовуватиме цикл while =, який змінює колір частини кожні кілька секунд. Умова для цього циклу буде істинною, тому він може працювати нескінченно довго.

Наприкінці сценарію створіть новий цикл while, де умова виконується, тобто цикл завжди виконується.

-- Checks if player touched the part
local function partTouched(otherPart)
-- Gets the player if one touched the part
local player = Players:GetPlayerFromCharacter(otherPart.Parent)
if player then
givePoints(player)
end
end

pointPart.Touched:Connect(partTouched)

-- Loops through 3 colors, waiting between each color
while true do

end

Якщо цикл while true do не розташований у нижній частині сценарію, будь-який код під ним ніколи не буде запущено. Оскільки цикл while не зупиняється, він продовжуватиме виконувати цикл замість будь-якого коду під ним.

Самостійно закодуйте цикл while true do, який змінює pointPart на створені вами змінні кольору. Не забудьте використовувати task.wait() між кольорами. Коли закінчите, перевірте свій код на наведену нижче версію.

-- Loops through 3 colors, waiting between each color
while true do
pointPart.Color = blue
task.wait(3)
pointPart.Color = green
task.wait(2)
pointPart.Color = red
task.wait(1)
end

Пограйте та перевірте, чи всі три кольори повторюються без зупинки.
Поради щодо усунення несправностей:
  • На цьому етапі, якщо цикл кольору не працює належним чином, спробуйте одну з наведених нижче дій.Переконайтеся, що цикл while знаходиться в нижній частині сценарію, під подією Touched. Якщо цикл знаходиться не внизу, інші частини сценарію не працюватимуть належним чином.
  • Перевірте, чи правильно записано кожен колір у Color3.fromRGB() . Має бути три числа від 0 до 255, розділених комами, наприклад (255, 50, 0) .

Нарахування очок гравцям

Гравцям будуть нараховані очки залежно від поточного кольору частини, коли вони торкнуться її.

Пошук поточного кольору

Щоразу, коли гравець торкається частини, скрипту потрібно буде знати поточний колір частини, щоб нарахувати бали пізніше.

Знайдіть givePoints(). Замініть своє тестове повідомлення змінною для поточного кольору pointPart. Ця змінна визначатиме, скільки очок отримує (чи програє) гравець.

local function givePoints(player)
local currentColor = pointPart.Color
end

Щоб впливати на очки гравця, цій функції потрібен доступ до таблиці лідерів гравця. Створіть змінну для її зберігання.

local function givePoints(player)
        local currentColor = pointPart.Color

        local playerStats = player:WaitForChild("leaderstats")
end

Тепер додайте змінну, щоб отримати значення балів гравця, яке є дочірнім показником таблиці лідерів.

local function givePoints(player)
        local currentColor = pointPart.Color

        local playerStats = player:WaitForChild("leaderstats")
        local playerPoints = playerStats:WaitForChild("Points")
end

Нарахування або віднімання балів

Далі ви використаєте if та elseif, щоб додавати або віднімати бали залежно від кольору частини, коли ви торкаєтесь. Пам’ятайте, що синій дає невелику кількість очок, зелений — багато, а червоний віднімає очки.

Усередині givePoints() під змінними використовуйте оператор if, щоб перевірити, чи поточний колір синій, і якщо так, то додайте smallPoints до поточного значення балів гравця.

local function givePoints(player)
        local currentColor = pointPart.Color

        local playerStats = player:WaitForChild("leaderstats")
        local playerPoints = playerStats:WaitForChild("Points")

        if currentColor == blue then
                playerPoints.Value += smallPoints
        end
end

Щоб перевірити наявність зеленого, додайте умову elseif. Якщо зелений, додайте змінну largePoints до очок гравця.

if currentColor == blue then
        playerPoints.Value += smallPoints
elseif currentColor == green then
        playerPoints.Value += largePoints
end

Використовуйте оператор else, щоб відняти точки, якщо pointsPart не був ні синім, ні зеленим.

if currentColor == blue then
        playerPoints.Value += smallPoints
elseif currentColor == green then
        playerPoints.Value += largePoints
else
        playerPoints.Value -= losePoints
end

Нарешті, знищіть частину після оператора if, щоб сценарій не міг продовжувати видавати бали.

if currentColor == blue then
        playerPoints.Value += smallPoints
elseif currentColor == green then
        playerPoints.Value += largePoints
else
        playerPoints.Value -= losePoints
end

pointPart:Destroy()

Зіграйте та переконайтеся, що кожен колір дає бали, як очікувалося. Перевірте всі три умови.

Надання відгуків гравцям

PointPart працює, але гравці можуть не помітити, що щось сталося, якщо вони випадково не дивляться на свою таблицю лідерів. Виправте це, створюючи частинки, коли PointPart руйнується.

Додавання зворотного зв’язку, коли гравці використовують частину, наприклад звуки, тремтіння або частинки, робить взаємодію з об’єктами більш задоволеною для гравців.

Створення ефекту частинок

Ефект частинок матиме той самий колір, що й частина під час дотику. Оскільки кольори зберігалися у змінних, їх легко використовувати повторно.

У givePoints() внизу створіть новий екземпляр ParticleEmitter . Переконайтеся, що ім’я екземпляра написано точно так, як показано.

local particle = Instance.new("ParticleEmitter")
end

ParticleEmitters використовують послідовності кольорів для керування властивістю Color. Створіть нову ColorSequence та передайте поточний колір частини.

-- Destroy part
pointPart:Destroy()

-- Create particles
local particle = Instance.new("ParticleEmitter")
particle.Color = ColorSequence.new(currentColor)

Частинку потрібно присвоїти гравцеві, який її торкнувся. Створіть змінну, щоб отримати модель персонажа гравця. Потім додайте частинку до голови гравця.

local particle = Instance.new("ParticleEmitter")
particle.Color = ColorSequence.new(currentColor)

local playerCharacter = player.Character
particle.Parent = playerCharacter:WaitForChild("Head")


Використовуйте task.wait() на секунду, а потім знищуйте частинки.

local particle = Instance.new("ParticleEmitter")
particle.Color = ColorSequence.new(currentColor)

local playerCharacter = player.Character
particle.Parent = playerCharacter:WaitForChild("Head")

task.wait(1)
particle:Destroy()

Протестуйте гру та переконайтеся, що частинки ненадовго слідують за гравцем після торкання кожного кольору.

Поради щодо усунення несправностей:
  • На цьому етапі, якщо частинки не працюють належним чином, спробуйте одну з наведених нижче дій.Під час створення нового екземпляра переконайтеся, що ParticleEmitter пишеться точно так, як показано, і всередині лапок.
  • Під час створення батьківських частинок обов’язково використовуйте : між playerCharacter і WaitForChild() без пробілів між ними.

Повний PointScript

Готову версію сценарію можна переглянути нижче.
local pointPart = script.Parent
--local storage = game:GetService("ServerStorage")

-- Gives some points
local blue = Color3.fromRGB(0, 0, 255)
-- Gives more points
local green = Color3.fromRGB(0, 255, 0)
-- Makes players lose points
local red = Color3.fromRGB(255, 0, 0)

-- gold given to players
local smallPoints = 10
local largePoints = 50
local losePoints = 100

local Players = game:GetService("Players")

local function givePoints(player)
local currentColor = pointPart.Color

local playerStats = player:WaitForChild("leaderstats")
local playerPoints = playerStats:WaitForChild("Points")

-- Gives player gold based on the color of the part
if currentColor == blue then
playerPoints.Value += smallPoints
elseif currentColor == green then
playerPoints.Value += largePoints
else
playerPoints.Value -= losePoints
end

-- Destroy the part, wait a second, and then destroy the particle
pointPart:Destroy()

-- Creates a sparkles effect and destroys it
local playerCharacter = player.Character
local particle = Instance.new("ParticleEmitter")
particle.Color = ColorSequence.new(currentColor)
particle.Parent = playerCharacter:WaitForChild("Head")
task.wait(1)
particle:Destroy()
end

local function partTouched(otherPart)
local player = Players:GetPlayerFromCharacter(otherPart.Parent)

if player then
givePoints(player)
end
end

Коди для збирання частин

У Workspace створіть папку World. В ній створіть папку Coins, в якій розмістіть частини для збирання.
У ServerScriptService додайте наступний скрипт з налаштуваннями:

-- Initializing services and variables
local Workspace = game:GetService("Workspace")
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")

-- Modules
local Leaderboard = require(ServerStorage.LeaderBoard)
local PlayerData = require(ServerStorage.PlayerData)

local coinsFolder = Workspace.World.Coins
local coins = coinsFolder:GetChildren()

local COIN_KEY_NAME = PlayerData.COIN_KEY_NAME
local COOLDOWN = 10
local COIN_AMOUNT_TO_ADD = 1

local function updatePlayerCoins(player, updateFunction)
-- Update the coin table
local newCoinAmount = PlayerData.updateValue(player, COIN_KEY_NAME, updateFunction)

-- Update the coin leaderboard
Leaderboard.setStat(player, COIN_KEY_NAME, newCoinAmount)
end

-- Defining the event handler
local function onCoinTouched(otherPart, coin)
if coin:GetAttribute("Enabled") then
local character = otherPart.Parent
local player = Players:GetPlayerFromCharacter(character)
if player then
-- Player touched a coin
coin.Transparency = 1
coin:SetAttribute("Enabled", false)
updatePlayerCoins(player, function(oldCoinAmount)
oldCoinAmount = oldCoinAmount or 0
return oldCoinAmount + COIN_AMOUNT_TO_ADD
end)

task.wait(COOLDOWN)
coin.Transparency = 0
coin:SetAttribute("Enabled", true)
end
end
end

-- Setting up event listeners
for _, coin in coins do
coin:SetAttribute("Enabled", true)
coin.Touched:Connect(function(otherPart)
onCoinTouched(otherPart, coin)
end)
end


У ServerStorage додайте наступний модульний скрипт і назвіть його LeaderBoard:

local Leaderboard = {}

-- Creating a new leaderboard
local function setupLeaderboard(player)
local leaderstats = Instance.new("Folder")
-- 'leaderstats' is a reserved name Roblox recognizes for creating a leaderboard
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
return leaderstats
end

-- Creating a new leaderboard stat value
local function setupStat(leaderstats, statName)
local stat = Instance.new("IntValue")
stat.Name = statName
stat.Value = 0
stat.Parent = leaderstats
return stat
end

-- Updating a player's stat value
function Leaderboard.setStat(player, statName, value)
local leaderstats = player:FindFirstChild("leaderstats")
if not leaderstats then
leaderstats = setupLeaderboard(player)
end

local stat = leaderstats:FindFirstChild(statName)
if not stat then
stat = setupStat(leaderstats, statName)
end

stat.Value = value
end

return Leaderboard

У ServerStorage додайте ще один модульний скрипт і назвіть його PlayerData:

local PlayerData = {}
PlayerData.COIN_KEY_NAME = "Coins"

local playerData = {
  --[[
    [userId: string] = {
      ["Coins"] = coinAmount: number
    }
  ]]
}

local DEFAULT_PLAYER_DATA = {
[PlayerData.COIN_KEY_NAME] = 0
}

local function getData(player)
local data = playerData[tostring(player.UserId)] or DEFAULT_PLAYER_DATA
playerData[tostring(player.UserId)] = data
return data
end

function PlayerData.getValue(player, key)
return getData(player)[key]
end

function PlayerData.updateValue(player, key, updateFunction)
local data = getData(player)
local oldValue = data[key]
local newValue = updateFunction(oldValue)

data[key] = newValue
return newValue
end

return PlayerData