DynamicModule[{playerY=0,velY=0,gravity=-0.003,jumpPower=0.06,jumpCount=0,
maxJump=3, groundY=-0.7,blocks={},greenBlocks={},blockSpeed=0.016,frame=0,

score=0, gameState="title",safe=False,invincibleFrames=0,gameSpeed=1},

Column[{Dynamic[Switch[gameState,(*タイトル画面*)"title",
Graphics[{Text[Style["三段ジャンプゲーム",30,Bold],{0,0.3}],
Text[Style["難易度を選んでください",20],{0,0.1}],
Inset[Row[{Button[Style["ふつう",16],(gameSpeed=1;gameState="playing"),ImageSize->{100,30}],
Spacer[30],Button[Style["爆速",16],(gameSpeed=2.5;gameState="playing"),ImageSize->{100,30}]}],{0,-0.3}],
Text[Style["あそびかた",14],{0,-0.55}],Text[Style["Jumpボタンをクリックで最大3回までジャンプ可能",12],
{0,-0.65}],Text[Style["赤ブロックにぶつかるとゲームオーバー・緑ブロックは一回セーフになる",12],{0,-0.75}],
Text[Style["時間経過でゲームスピード・スコアの獲得速度が上昇",12],{0,-0.85}]},
PlotRange->{{-1.2,1.2},{-1,1}},ImageSize->500,Background->RGBColor[0.5,0.75,1]],


(*プレイ中*)"playing",(frame++;
score+=Ceiling[gameSpeed];
If[Mod[frame,300]==0,gameSpeed+=0.1];
If[invincibleFrames>0,invincibleFrames--];
velY+=gravity*gameSpeed;
maxFallSpeed=-0.04*gameSpeed;
If[velY<maxFallSpeed,velY=maxFallSpeed];
playerY+=velY;
If[playerY<=groundY,playerY=groundY;velY=0;jumpCount=0;];
If[RandomReal[]<0.02,With[{h=RandomReal[]},AppendTo[blocks,{1.2,groundY+(1-h)^2*0.6}]]];
If[RandomReal[]<0.001,With[{h=RandomReal[]},AppendTo[greenBlocks,{1.2,groundY+(1-h)^2*0.6}]]];
blockSpeedNow=blockSpeed*gameSpeed;
blocks=Select[Map[{#[[1]]-blockSpeedNow,#[[2]]}&,blocks],#[[1]]>-1.2&];
greenBlocks=Select[Map[{#[[1]]-blockSpeedNow,#[[2]]}&,greenBlocks],#[[1]]>-1.2&];
Do[If[Abs[gb[[1]]+0.8]<0.05&&Abs[playerY-gb[[2]]]<0.1,score+=100;
safe=True;
greenBlocks=DeleteCases[greenBlocks,gb];],{gb,greenBlocks}];
Do[If[Abs[block[[1]]+0.8]<0.05&&Abs[playerY-block[[2]]]<0.1,If[safe||invincibleFrames>0,safe=False;
invincibleFrames=100,gameState="gameover"];],{block,blocks}];
Graphics[{Text[Style["Score: "<>ToString[score],14],{0.6,0.9}],Text[Style["Speed: "<>
ToString[NumberForm[gameSpeed,{2,1}]],14],{-0.9,0.9}],(*自機描画:無敵中点滅+SAFE表示*)
If[invincibleFrames==0||Mod[invincibleFrames,18]<9,If[safe,{EdgeForm[{Thick,Green}],
FaceForm[RGBColor[1,0.85,0]],Disk[{-0.8,playerY+0.05},0.05]},
{RGBColor[1,0.85,0],Disk[{-0.8,playerY+0.05},0.05]}],Nothing],(*地面・ブロック描画*)Brown,
Rectangle[{-1.2,-1},{1.2,groundY}],Red,Rectangle[#-{0.05,0},#+{0.05,0.1}]&/@blocks,
Green,Rectangle[#-{0.05,0},#+{0.05,0.1}]&/@greenBlocks},PlotRange->{{-1.2,1.2},{-1,1}},
ImageSize->500,Background->RGBColor[0.5,0.75,1]]),


(*ゲームオーバー画面*)"gameover",Graphics[{Text[Style["Game Over",24,Red],{0,0.3}],
Text[Style["Final Score: "<>ToString[score],16],{0,0}],
Inset[Button[Style["Restart",16],(playerY=0;velY=0;jumpCount=0;
blocks={};greenBlocks={};frame=0;score=0;
safe=False;invincibleFrames=0;
gameState="title";gameSpeed=1;),ImageSize->{120,35}],{0,-0.4}]},
PlotRange->{{-1.2,1.2},{-1,1}},ImageSize->500,
Background->RGBColor[0.5,0.75,1]]],UpdateInterval->1/(60*gameSpeed)],

(*ジャンプボタン*)Dynamic[If[gameState==="playing",Button[Style["Jump",16],
If[jumpCount<maxJump,velY=jumpPower*Sqrt[gameSpeed];
jumpCount++;],ImageSize->{100,30}],Null]]}]]