Robloxで簡易電卓をつくってみた

## はじめに
robloxでゲームを作るための練習として、電卓を作ってみました。
ボタンを押して、なんか処理をしてくれることがしたかったんですね。
[calculator-with-only-plus](https://www.roblox.com/games/11573158010/calculator-with-only-plus)


## 構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486826/a6797de1-699e-b96e-7bc2-dbc0b39dd6ba.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486826/86a2da03-f37d-5077-ac34-87f0983a1790.png)
- 数字ボタンButtonPart1~9
- クリアボタン ButtonPartClear
- 足すボタン　ButtonPartPlus
- イコールボタン　ButtonPartEqual
## コード
```lua:ButtonPart1~9
local ButtonPart =  script.Parent
local clickdetector = ButtonPart.ClickDetector
local displayPart = workspace.DisplayPart
local colorMemory = ButtonPart.BrickColor
local MY_NUMBER = tonumber(ButtonPart.SurfaceGui.TextLabel.Text)

--先に宣言しておかないといけない
local function countMouseClick(player)
	print(MY_NUMBER)
	ButtonPart.BrickColor = BrickColor.new(0.7,0.9, 0.9)
	displayPart.setValueFunction:Invoke(MY_NUMBER)  --他の関数に記載されている関数を呼び出す
	wait(0.2)
	ButtonPart.BrickColor = colorMemory
end

wait(1)
--初期化中はanswerValueを叩かれると困る

clickdetector.MouseClick:Connect(countMouseClick)


while true do
	wait(1)
end
```
```lua:ButtonPartClear
--電卓のクリア

local ButtonPart =  script.Parent
local clickdetector = ButtonPart.ClickDetector
local displayPart = workspace.DisplayPart
local colorMemory = ButtonPart.BrickColor

--先に宣言しておかないといけない
local function countMouseClick(player)
	print("+")
	ButtonPart.BrickColor = BrickColor.new(0.7,0.9, 0.9)
	displayPart.clear:Invoke()
	wait(0.2)
	ButtonPart.BrickColor = colorMemory
end

wait(1)
--初期化中はanswerValueを叩かれると困る

clickdetector.MouseClick:Connect(countMouseClick)


while true do
	wait(1)
end
```
```lua:ButtonPartEqual
--電卓のイコール

local ButtonPart =  script.Parent
local clickdetector = ButtonPart.ClickDetector
local displayPart = workspace.DisplayPart
local colorMemory = ButtonPart.BrickColor

--先に宣言しておかないといけない
local function countMouseClick(player)
	print("=")
	ButtonPart.BrickColor = BrickColor.new(0.7,0.9, 0.9)
	displayPart.calculate:Invoke()
	wait(0.2)
	ButtonPart.BrickColor = colorMemory
end

wait(1)
--初期化中はanswerValueを叩かれると困る

clickdetector.MouseClick:Connect(countMouseClick)


while true do
	wait(1)
end
```
```lua:ButtonPlus
--電卓のプラス

local ButtonPart =  script.Parent
local clickdetector = ButtonPart.ClickDetector
local displayPart = workspace.DisplayPart
local colorMemory = ButtonPart.BrickColor
local MY_NUMBER = 1 --it means plus

--先に宣言しておかないといけない
local function countMouseClick(player)
	print("+")
	ButtonPart.BrickColor = BrickColor.new(0.7,0.9, 0.9)
	displayPart.setOperator:Invoke(MY_NUMBER)
	wait(0.2)
	ButtonPart.BrickColor = colorMemory
end

wait(1)
--初期化中はanswerValueを叩かれると困る

clickdetector.MouseClick:Connect(countMouseClick)


while true do
	wait(1)
end
```
```lua:DisplayPart

local displayPart = script.Parent
local answerValue = Instance.new("IntValue")
answerValue.Name = "answerValue"
answerValue.Value = 0
answerValue.Parent = displayPart



while true do
	displayPart.SurfaceGui.TextLabel.Text = displayPart.answerValue.Value
	wait(0.2)
end
```
```lua:calculate
local bindableFunction = script.Parent
local displayPart = bindableFunction.Parent



wait(1)

local function calclate()
	if displayPart.flagOperator.Value == false then
		if displayPart.operator.Value == 1 then
			displayPart.answerValue.Value = displayPart.valueMemory.Value + displayPart.answerValue.Value
		end
		displayPart.valueMemory.Value = displayPart.answerValue.Value
		displayPart.flagOperator.Value = true
		displayPart.operator = 0
	end
end

bindableFunction.OnInvoke = calclate

```
```lua:clear
local bindableFunction = script.Parent
local displayPart = bindableFunction.Parent



wait(1)

local function clear()
	displayPart.valueMemory.Value = 0
	displayPart.answerValue.Value = 0
	displayPart.flagOperator.Value = false
	displayPart.operator.Value = 0
end

bindableFunction.OnInvoke = clear

```
```lua:setOperator
local bindableFunction = script.Parent
local displayPart = bindableFunction.Parent
displayPart.flagOperator.Value = false


wait(1)

local function setOperator(operator)
	if displayPart.flagOperator.Value == false then
		displayPart.answerValue.Value = displayPart.answerValue.Value + displayPart.valueMemory.Value
	end
	displayPart.operator.Value = operator
	displayPart.flagOperator.Value = true
	displayPart.valueMemory.Value = displayPart.answerValue.Value
end

bindableFunction.OnInvoke = setOperator

```

```lua:setValueFanction
local bindableFunction = script.Parent
local displayPart = bindableFunction.Parent

wait(1)

local function setValue(intValue)
	if displayPart.flagOperator.Value == true then
		displayPart.answerValue.Value = intValue
		displayPart.flagOperator.Value = false
	else
		displayPart.answerValue.Value = displayPart.answerValue.Value * 10 + intValue
	end
end

bindableFunction.OnInvoke = setValue
```

## つかったもの
- 非同期処理もどき
- クリックのイベント処理
- オブジェクト指向もどき
- 変数値の表示
robloxでは、各オブジェクト（Part）ごとにプログラムが（非同期的に）走っているのがゲーム作りしやすいと感じました。他のプログラムの値を参照できる（変更できる）のも出来ました。なので、出来ることが増えますね。

## おわりに

必要な要素は揃ったので、次は作りたいゲームをつくろうと思います。
エラーが含まれてもなんとか動いてくれるのは、プログラムしやすいです。デバッグも出来るので、エラー箇所も推定しやすいです。あと、ローカル環境で動いてたら、本番環境でも同じように動いてくれるのはつよつよです。