Needs["NETLink`"]
InstallNET[];
ser=NETNew["System.IO.Ports.SerialPort","COM3",9600]
ser@Open[]


windowSizeX=300;
windowSizeY=300;

ballSpeedX = 1.5;
ballSpeedY = -2;
ballPosX=0.0;
ballPosY=0.0;

paddleSize = 40;
paddlePosX = 0.0;
paddlePosY = -windowSizeY+50;

gameRunFlag = True
resetCounter = 0;
score =0;

arduino = 2;

Dynamic[Refresh[
(*計算*)
(*壁との衝突判定*)
If[ballPosX < -windowSizeX && ballSpeedX < 0 ,ballSpeedX*= -1];
If[ballPosX > windowSizeX && ballSpeedX > 0 ,ballSpeedX*= -1];
If[ballPosY > windowSizeY && ballSpeedY > 0 ,ballSpeedY*= -1];
If[ballPosY < -windowSizeY && ballSpeedY < 0 ,gameRunFlag = False];

(*パドル操作*)
arduino = ser@ReadChar[];                          (*arduinoから送られてくる傾き情報(だいたい2が水平 1が右に傾いている、3が左に傾いている)*)
paddleSpeed = Which[
(arduino < 2 && paddlePosX + 5.0  < windowSizeX -paddleSize),5.0,
(arduino > 2 && paddlePosX - 5.0 > -windowSizeX +paddleSize), -5.0,
(True),0.0
];
paddlePosX  += paddleSpeed;


(*パドルとの衝突判定*)
If[Abs[ballPosY - paddlePosY] < 0.1 && Abs[ballPosX-paddlePosX] < paddleSize, ballSpeedY *= -1];
score++;
info="Score : "<>ToString[score];
fontSize = 10;
textPosition={windowSizeX-70, windowSizeY-40};
If[gameRunFlag == False,
If[resetCounter <50,
 {
(*ゲームオーバー*)
resetCounter++;
info="GameOver";
fontSize = 40;
textPosition={0,0}
},
{
(*リセット*)
resetCounter=0; 
gameRunFlag = True;
score=0;
ballPosX = 0;
ballPosY=0;
ballSpeedY *= -1;
}
]
];
ballPosX += ballSpeedX;
ballPosY += ballSpeedY;




Graphics[
{
(*描画*)
Red,Disk[{ballPosX, ballPosY}, 5],
Thick,Line[{{paddlePosX-paddleSize,paddlePosY},{paddlePosX+paddleSize,paddlePosY}}],
Gray, 
Text[Style[info,FontSize->fontSize],textPosition]

},
PlotRange->{{-windowSizeX,windowSizeX},{-windowSizeY,windowSizeY}},
Frame->True,
FrameTicks->None
],UpdateInterval->3]]