roblox-royale-camp/pages/Day 3.md
2020-08-05 11:47:47 -07:00

5.1 KiB

Day 3

Overview 👀

Today we will utilize BindableEvents and script out the logic for our game's timer.

Follow Along! 👍

First, we will download today's file here. Once downloaded, let's open it up in Roblox studio and begin our quest for today.

Fun Quiz 🧠

Here are some quiz questions that we will be able to answer as we complete today's instructions.

What does 'WaitForChild' do? The 'WaitForChild' method is used by variables that represent folders in our explorer. This method allows us to reach into the folder that it's instance represents and pick a file programmatically.
What does 'Connect' do? The 'Connect' method takes a function as its argument and calls it once the event is resolved (completed).
What does 'Wait' do? The 'Wait' method stops the script from continuing until the event has been resolved (completed).

Then we will work on programming by following these instructions.

When we are done, our scripts should resemble the following samples:

ServerScriptService > GameManager

-- Services
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
 
-- Module Scripts
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local matchManager = require(moduleScripts:WaitForChild("MatchManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
 
-- Events
local events = ServerStorage:WaitForChild("Events")
local matchEnd = events:WaitForChild("MatchEnd")
 
while true do
	repeat
		wait(gameSettings.intermissionDuration)
		print("Restarting intermission")
	until Players.NumPlayers >= gameSettings.minimumPlayers
 
	print("Intermission over")
	wait(gameSettings.transitionTime)
	
	matchManager.prepareGame()
	-- Placeholder wait for the length of the game.
	matchEnd.Event:Wait()
 
end

ServerStorage > ModuleScripts > MatchManager

local MatchManager = {}
 
-- Services
local ServerStorage = game:GetService("ServerStorage")
 
-- Module Scripts
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local timer = require(moduleScripts:WaitForChild("Timer"))
 
-- Events
local events = ServerStorage:WaitForChild("Events")
local matchStart = events:WaitForChild("MatchStart")
local matchEnd = events:WaitForChild("MatchEnd")
 
-- Creates a new timer object to be used to keep track of match time. 
local myTimer = timer.new()
 
-- Local Functions
local function timeUp()
	print("Time is up!")
end
 
local function startTimer()
	print("Timer started")
	myTimer:start(gameSettings.matchDuration)
	myTimer.finished:Connect(timeUp)	
end
 
-- Module Functions
function MatchManager.prepareGame()
	playerManager.sendPlayersToMatch()
	matchStart:Fire()
end
 
matchStart.Event:Connect(startTimer)
 
return MatchManager

ServerStorage > ModuleScripts > Timer

local Timer = {}
Timer.__index = Timer
 
function Timer.new()
	local self = setmetatable({}, Timer)
 
	self._finishedEvent = Instance.new("BindableEvent")
	self.finished = self._finishedEvent.Event
	
	self._running = false
	self._startTime = nil
	self._duration = nil
	
	return self
end
 
function Timer:start(duration)
	if not self._running then
		local timerThread = coroutine.wrap(function()
			self._running = true
			self._duration = duration
			self._startTime = tick()
			while self._running and tick() - self._startTime < duration do
				wait()
			end
			local completed = self._running
			self._running = false
			self._startTime = nil
			self._duration = nil
			self._finishedEvent:Fire(completed)
		end)
		timerThread()
	else
		warn("Warning: timer could not start again as it is already running.")
	end
end
 
function Timer:getTimeLeft()
	if self._running then
		local now = tick()
		local timeLeft = self._startTime + self._duration - now
		if timeLeft < 0 then
			timeLeft = 0
		end
		return timeLeft
	else
		warn("Warning: could not get remaining time, timer is not running.")
	end
end
 
function Timer:isRunning()
	return self._running
end
 
function Timer:stop()
	self._running = false
end
 
return Timer

A complete example project of the scripting we have done in class today can be found here.

Optional Homework 📄

Read the following articles to acheive a full understanding of what we are working on for day 4.


See you tomorrow for day 4!