How to make this draw better?

I am working on a number recognition system that is going to use a neural network that I am going to open source, but currently, it is very hard to draw something. Like for real. Try to draw the number one. I bet you 99% you won’t be able to do it.

Here is the GUI:

It goes in StarterGui (Obviously)

Here is the code the I am using to draw:

local parent = script.Parent
local players = game:GetService("Players")
local player = players.LocalPlayer
local mouse = player:GetMouse()
local mouseDown = nil -- The very first line of code that was ever written and this is what I feel when I think about the first thine of code that was ever written: https://www.youtube.com/watch?v=6eb_zYknomY ...
local camera = workspace:WaitForChild("Camera")
local viewPortSize = camera.ViewportSize
local pix3lFrame = parent:WaitForChild("DrawFrame")
local pix3ls = {}
local mouseXScaleOffset = 0
local mouseYScaleOffset = 0

for i, v in pairs(pix3lFrame:GetChildren()) do
	if v:IsA("Frame") then
		if v.Name == "Pixel" then
			table.insert(pix3ls, v)
		end
	end
end

function draw()
	while mouseDown do
		game:GetService("RunService").Heartbeat:Wait()
		local mouseX = mouse.X / viewPortSize.X
		local mouseY = mouse.Y / viewPortSize.Y
		for i, v in pairs(pix3ls) do
			if math.abs(v.Position.X.Scale - (mouseX + mouseXScaleOffset)) < v.Size.X.Scale and math.abs(v.Position.Y.Scale - (mouseY + mouseYScaleOffset)) < v.Size.Y.Scale then
				v.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
			end 
		end
	end
end

mouse.Button1Down:Connect(function()
	mouseDown = true
	print(mouse.X / workspace.CurrentCamera.ViewportSize)
	spawn(function()
	draw()	
	end)
end)

mouse.Button1Up:Connect(function()
	mouseDown = false
	print(mouse.X / workspace.CurrentCamera.ViewportSize)
end)

The more help I get, and the faster it is, then the faster this can get open sourced. So … Can someone please tell me how to keep this from happening?

3 Likes

Hello,

While I will tell you of a better way to detect the mouse’s position, you must first know that there is an issue with the approach you have taken. Your for loop goes through 360 Frame instances and has to check each one, every frame of the game. If someone is playing at 60 FPS, this results to 21,600 checks every second, to color squares.

The solution to that issue is to not have pre-made frames, but to rather create a frame when a “pixel” is hovered over, by using some math and a table to keep track of colored pixels.

Anyways, here is a segment of modified, commented code.

function draw()
	while mouseDown do
		game:GetService("RunService").Heartbeat:Wait()
		local mouseX = mouse.X
		local mouseY = mouse.Y
		
		for i, v in pairs(pix3ls) do
			--print(1) --if I print here, the program grinds to a halt, because printing (or most things, really) 20000 times per second is very intensive
			if (mouseX > v.AbsolutePosition.X and --mouse is beyond the left wall
				mouseX < v.AbsolutePosition.X + v.AbsoluteSize.X and --but not past the right wall
				mouseY > v.AbsolutePosition.Y and --and below the top wall
				mouseY < v.AbsolutePosition.Y + v.AbsoluteSize.Y) then --aboove the bottom wall
				
				v.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
			end 
		end
	end
end

mouse.Button1Down:Connect(function()
	mouseDown = true
	draw() --This Button1Down event has already executed this block of code on a new coroutine; no need to spawn it.
end)

mouse.Button1Up:Connect(function()
	mouseDown = false
end)

The solution to square collision detection is simply checking the walls of the square to the individual points. Converting it from scale to offset tends to simplify the problem as well.

3 Likes