RoboCatz.com
About FLL | Navigation | Playbook | Strategy | Models | Techniques | RobotC | Programming | Robot News |

Roblox Basics

The art museum is created from a collection of scripts stored in various places in Roblox. You will need to create and install these scripts in your Roblox world in order to see the Art Museum.

ReplicatedStorage

The following scripts need to be added to your ReplicatedStorage area:

genericShapes (genericShapes-ModuleScript.htm)
This module creates the generic shapes used in the art museum.

mazeGenerator (mazeGenerator-ModuleScript.htm)
This module will generate the maze used in the Museum.

artInstallationRoom (artInstallationRoom-ModuleScript.htm)
This module installs the art in a room and coordinates where the room is located in the museum.

studentExhibition (studentExhibition-ModuleScript.htm)
This module creates the student art exhibits and processes any animations once installed in a room.

Baseplate Scripts

The baseplate is loaded when the Roblox world is started. The baseplate may have a Script associated with it. The name of this script should be: baseplateScript and it should be a "Script" added to the baseplate of your Roblox world. Below are a few examples of baseplateScript content to enable you to experiment with different possibilities for coding art exhibits.

Generic small maze

Copy the script below into your baseplateScript file and run the world. You should see a small maze. Parameters that control the size and depth of the maze are stored in a Roblox "dictionary" passed as an argument to the newMaze function. Try changing the number of rows and columns and/or the height.

Example:
--baseplateScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local b = require(ReplicatedStorage.artInstallationRoom)
local e = require(ReplicatedStorage.studentExhibition)
local m = require(ReplicatedStorage.mazeGenerator)
local s = require(ReplicatedStorage.genericShapes)
-- Used to detect where the humanoid is located
local Players = game:GetService("Players")


m.newMaze({numRows=10, numCols=10, cellWidth=20, cellLength=20, withNumbers=false, withColors=true, wallThickness=3, height=3})

Basic Shapes

The code below will help you to explore different shapes and how they can be created.

Example:
--baseplateScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local b = require(ReplicatedStorage.artInstallationRoom)
local e = require(ReplicatedStorage.studentExhibition)
local m = require(ReplicatedStorage.mazeGenerator)
local s = require(ReplicatedStorage.genericShapes)
-- Used to detect where the humanoid is located
local Players = game:GetService("Players")


-- SQUARES
s.square(0, 15, -15, 2, 0.5) -- create a square at the location of 0,5,-15 with the size of 10 and thickness of 0.5
s.square(-20, 5, -15, 4, 0.5, Color3.new(1, 1, 0)) -- create a square ... with the color specified as a Color3 object
s.square(-10, 5, -15, 4, 0.5, "blue") -- create a square ... with the color specified as a string
s.square({ x=0, y=5, z=-15, size=4, thickness=0.5, color="red", luminosity=3, luminosityRange=10, luminosityHue=Color3.new(1,1,0)})

-- CIRCLES
s.circle(0, 5, -5, 2, 0.5) -- create a square at the location of 0,5,-15 with the size of 10 and thickness of 0.5
s.circle(-15, 5, -5, 4, 0.5, Color3.new(1, 1, 0)) -- create a square ... with the color specified as a Color3 object
s.circle(12, 5, -5, 4, 0.5, "blue") -- create a square ... with the color specified as a string
s.circle({ x=0, y=5, z=-35, size=4, thickness=0.5, color="red", luminosity=1, luminosityRange=10, luminosityHue=Color3.new(1,1,0)})

Practice Exhibit Space

The code below will help you to practice creating an art installation.

Example:
--baseplateScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local b = require(ReplicatedStorage.artInstallationRoom)
local e = require(ReplicatedStorage.studentExhibition)
local m = require(ReplicatedStorage.mazeGenerator)
local s = require(ReplicatedStorage.genericShapes)
-- Used to detect where the humanoid is located
local Players = game:GetService("Players")



b.setWidth(75)
b.setLength(75)
local wallWidth = 3

Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
		local iteration = 1
		local currentRoomCenter = nil
		local currentRoomSize = nil
		while humanoidRootPart do
			-- This will load the newQbert space from the studentExhibit module
			-- Once loaded, you can then edit the studentExhibit module newQbert() function to create your exhibit.
			k=e.newQbert(75, 75)
			k.draw()
			local iteration = 1
			k.defineInteractions()
			currentRoomCenter = k.room.center
			currentRoomSize = k.room.size
			while true do
				k.animate({ 
					iteration=iteration, 
					locationInRoom = 100 * ((currentRoomCenter + currentRoomSize/2) - humanoidRootPart.Position)/currentRoomSize
				})
				wait(0.1)
			end
		end
	end)
end)
Once you have created your exhibit, rename it with a new identifier then create another exhibit space. The "identifier" is the name of the function. The student art exhibit functions (contained in the studentExhibition module script) contain functions within themselves. Because these functions "encapsulate" other functions, it is necessary to store the return value in a variable and then access the "encapsulated" functions as "methods" of the object. Please see the section on "Student Exhibits" below for more details.

Student Exhibits

The code below will load a practice student exhibit space.

Example:
--[[

This module is: studentExhibition and is stored in the ReplicatedStorage area

This module will create the artwork and animations used for the art installations
These exhibits will be stored in an array in the baseplateScript

]]
local StudentExhibition = {}
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local s = require(ReplicatedStorage.genericShapes)
local b = require(ReplicatedStorage.artInstallationRoom)

function StudentExhibition.newQbert(x, z)
	local exhibitRoom = { room=b.new({x=x, z=z}), name="newQbert", parts={}, onInteraction=nil }
	exhibitRoom.draw = function() 
		local s1 = s.sphere({position=exhibitRoom.room.center, color="green", material=Enum.Material.Foil, size=40})
		local c1 = s.cube({position=exhibitRoom.room.center, color="red", material=Enum.Material.Foil, size=36, opacity=0.5})
		local negativeSpace = s.subtract(c1, s1)
		for i=1,5 do
			exhibitRoom.parts[i] = s.panel({x=i*3-15,y=i,z=-25, thickness=1, color=Color3.new(math.random()*90,math.random()*90,math.random()*90), rotateby=Vector3.new(0,90,0), material=Enum.Material.Foil})
		end
	end
	exhibitRoom.onInteraction = function(thePart)
		local touchingPartsTable = thePart:GetTouchingParts()
		for i=1,#touchingPartsTable do
			s.fill(touchingPartsTable[i], Color3.new(0, 0.34902, 1))
			s.material(touchingPartsTable[i], Enum.Material.Wood)
		end
	end
	exhibitRoom.defineInteractions = function()
		for i=1,#exhibitRoom.parts do exhibitRoom.parts[i].Touched:Connect(exhibitRoom.onInteraction) end
	end
	exhibitRoom.animate = function(...) 
		for i=1,#exhibitRoom.parts do
			--s.fill(exhibitRoom.parts[i], Color3.new(math.random(),math.random(),math.random()))
		end
	end
	return exhibitRoom

end
Notice that the above StudentExhibition.newQbert() function encapsulates two other functions within itself (See below). These encapsulated function will be called "methods" of the exhibitRoom that is returned from the main function above.

Example:
exhibitRoom.draw = function() 
	exhibitRoom.parts[1] = s.cube(0, 5, -30, "red", Enum.Material.Foil)
	exhibitRoom.parts[2] = s.sphere(-10, 5, -30, 8, "red", Enum.Material.Glass)
end
exhibitRoom.animate = function() 
	s.fill(exhibitRoom.parts[1], Color3.new(math.random(),math.random(),math.random()))
	s.fill(exhibitRoom.parts[2], Color3.new(math.random(),math.random(),math.random()))
end
The .draw() method is executed once when the room is drawn. The .animate() method is executed from within a while loop in the main program. An example of the use of these functions would be to store the exhibitRoom in a variable, then call the methods (see below).

Example:
k=e.newQbert(75, 75)
k.draw()
while true do
	k.animate()
	wait(0.1)
end
In the example above, a variable k is used to store the exhibitRoom and then .draw() method is used to show the art in the room and the .animate() method is used to animate the art.

Completed Art Museum

Notice: in the completed Art Museum, the student exhibits are stored in an array identified as: exhibitReferences. This simple array contains just the identifiers of each student exhibit. Further in the code, the rooms of the museum (expressed as: museum[i][j] are assigned a student exhibit using:

museum[i][j] = exhibitReferences[randomExhibitNdx+1]()

The identifier in the exhibitReferences[] array element is executed using the two parentheses at the end of the line. The student exhibit function then returns the exhibit details to be stored in the museum's room located at: museum[i][j].

Further in the code, the museum[i][j].draw() function is only executed if the humanoidRootPart is positioned inside the museum[i][j].room.region. The room is "destroyed" when exiting the room.

Notice: in the completed Art Museum, the student exhibits are stored in an array identified as: exhibitReferences. This simple array contains just the identifiers of each student exhibit. Further in the code, the rooms of the museum (expressed as: museum[i][j] are assigned a student exhibit using:

museum[i][j] = exhibitReferences[randomExhibitNdx+1]()

The identifier in the exhibitReferences[] array element is executed using the two parentheses at the end of the line. The student exhibit function then returns the exhibit details to be stored in the museum's room located at: museum[i][j].

Example:
--baseplateScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local b = require(ReplicatedStorage.artInstallationRoom)
local e = require(ReplicatedStorage.studentExhibition)
local m = require(ReplicatedStorage.mazeGenerator)
local s = require(ReplicatedStorage.genericShapes)
-- Used to detect where the humanoid is located
local Players = game:GetService("Players")


--print(s.helloWorld())

local numRows = 10
local numCols = 10

b.setWidth(75)
b.setLength(75)
local wallThickness = 3

-- Create an array of exhibit function identifiers
-- The computer will randomly select from this list to determine which should be shown
local exhibitReferences = {

	e.newMatti,        -- MH
	e.newMyArt1,       -- MH
	e.bob,             -- MH
	e.mati,            -- MH
	e.tomato,          -- MH
	e.larryTheCukumber, -- MH
	e.newfallingstars, -- AM
	e.newAidastars,    -- AM
	e.newAidaSpheres,  -- AM
	e.newAidaroblox,   -- AM
	e.MegaBloxAida,    -- AM
	e.spiralStaircase, -- AM
	e.AvramRoblox,     -- AZ
	e.AvramsObby,      -- AZ
	e.newQbert,
	e.newXpert,
	e.newOvert
}

m.newMaze({numRows=numRows, numCols=numCols, cellWidth=b.getWidth(), cellLength=b.getLength(), withNumbers=false, withColors=true, wallThickness=wallThickness, height=30})

local museum = {}     -- Initialize an empty array
-- The For loops below will position the exhibit spaces in a grid by rows and colums
for i = 1, numRows do
	museum[i] = {}    -- This will be part of a 2-dimensional array. Creating the second dimension here.
	for j = 1, numCols do
		local randomExhibitNdx = (math.floor(math.random() * 1000) % #exhibitReferences) -- Randomly select an exhibit to be shown from a list of exhibit references
		local x, z = (i - numRows/2) * (b.getWidth() + wallThickness), ((j+1) - numCols/2) * (b.getLength() + wallThickness) -- Determine the x and z coordinates to be used to position the exhibit space
		museum[i][j] = exhibitReferences[randomExhibitNdx+1](x,z)   -- Execute the exhibit function to create the exhibit space
		b.reposition(museum[i][j], x, z)                         -- Reposition the exhibit space in the museum
	end
end

Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
		local iteration = 1
		local currentRoomCenter = nil
		local currentRoomSize = nil
		while humanoidRootPart do
			--print(player.Name,"is at",tostring(humanoidRootPart.Position))
			for i = 1, numRows do
				for j = 1, numCols do
					if b.isInRoom(humanoidRootPart.Position, museum[i][j].room.region) then
						-- Do you need to make note of it?
						if not museum[i][j].room.isInTheRoom then
							print(`Entering room: {i}, {j} called: {museum[i][j].name}`)
							wait(0.2)
							local currentRoom =  museum[i][j]
							currentRoom.room.isInTheRoom = true
							currentRoom.draw()                       -- Draw the art objects
							currentRoom.defineInteractions()
							currentRoomCenter = currentRoom.room.region.CFrame.Position
							currentRoomSize = currentRoom.room.region.Size
							b.repositionTheArt(museum[i][j])          -- Move them unto the room
						end
						museum[i][j].animate(
							{ 
								iteration=iteration, 
								locationInRoom = 100 * ((currentRoomCenter + currentRoomSize/2) - humanoidRootPart.Position)/currentRoomSize
							}
						)  -- Allow for animation when you are in the room
					else
						if museum[i][j].room.isInTheRoom then
							print("Exiting room: " .. tostring(i) .. "," .. tostring(j))
							museum[i][j].room.isInTheRoom = false
							b.destroy(museum[i][j].parts)
						end
					end
				end
			end
			wait(0.1)
			iteration += 1
		end
	end)
end)



while true do
	-- check the position
	wait(1)
	-- Check to see if you have entered a new exhibit space
end