This commit is contained in:
TreetopFlyer 2022-11-18 17:09:33 -05:00
parent 4ea26b08a3
commit 34d0c591a9
1 changed files with 24 additions and 21 deletions

45
app.js
View File

@ -6,21 +6,21 @@ import * as RTF from 'https://esm.sh/@react-three/fiber'
import { useGLTF, useAnimations, PerspectiveCamera } from 'https://esm.sh/@react-three/drei'
import {html} from 'https://esm.sh/htm/react'
/**@typedef {[x:number, y:number, z:number]} V3 */
/**
* @typedef {{Type:"click", Payload:number}} ActionClick
* @typedef {{Type:"round"}} ActionRound
* @typedef {ActionClick | ActionRound} Action
*/
/**
* @typedef {{Done:boolean, Pos:V3}} StateGoal
*/
/**
* @typedef {{Round:number, Done:boolean, Goals:Array<StateGoal>}} State
*/
/** @typedef {(inState:State, inAction:Action)=>void} Reducer */
/** @typedef {{Initial:State, Reducer:React.Reducer<State, Action>, Consume:()=>GameBinding}} Game */
/** @typedef {[State:State, Dispatcher:React.Dispatch<Action>]} GameBinding */
@typedef {[x:number, y:number, z:number]} V3
@typedef {{Type:"click", Payload:number}} ActionClick
@typedef {{Type:"round"}} ActionRound
@typedef {ActionClick | ActionRound} Action
@typedef {{Done:boolean, Pos:V3}} StateGoal
@typedef {{Round:number, Done:boolean, Goals:Array<StateGoal>}} State
@typedef {(inState:State, inAction:Action)=>void} Reducer
@typedef {{Initial:State, Reducer:React.Reducer<State, Action>, Consume:()=>GameBinding}} Game
@typedef {[State:State, Dispatcher:React.Dispatch<Action>]} GameBinding
*/
/** @type Game */
const Game =
@ -28,8 +28,8 @@ const Game =
Initial:
{
Round:0,
Goals:[{Done:false, Pos:[0, 0, 0]}, {Done:true, Pos:[2, 0, 0]}],
Done:false
Goals:[],
Done:true
},
Reducer(inState, inAction)
{
@ -38,7 +38,7 @@ const Game =
{
for(let i=0; i<inGoals.length; i++)
{
if(!clone.Goals[i].Done)
if(!inGoals[i].Done)
{
return false;
}
@ -50,6 +50,8 @@ const Game =
{
case "click":
{
if(clone.Done){break;}
/**@type StateGoal|undefined*/
const goal = clone.Goals[inAction.Payload];
if(goal)
@ -64,7 +66,7 @@ const Game =
clone.Round++;
clone.Goals = [];
clone.Done = false;
for(let i=0; i<1+Math.random()*10; i++)
for(let i=0; i<clone.Round; i++)
{
/**@type StateGoal*/ const goal = {Done:false, Pos:[
(Math.random()-0.5)*5,
@ -83,7 +85,7 @@ const Game =
}
};
/** @type {(props:{goal:StateGoal, handler:()=>void})=>JSX.Element}*/
/** @type {(props:{goal:StateGoal, handler:()=>void})=>JSX.Element} */
function Model(props)
{
const { nodes, animations } = useGLTF("/bounce.gltf");
@ -102,13 +104,14 @@ function Model(props)
castShadow
receiveShadow
geometry=${nodes.Cube.geometry}
material=${nodes.Cube.material}
onClick=${e=>
{
e.stopPropagation();
props.handler();
}
} />
}>
<meshStandardMaterial color=${props.goal.Done ? "yellow" : "blue"}/>
</mesh>
</group>`
}