add redux state & figures logic

This commit is contained in:
Firesieht 2022-06-14 21:49:07 +03:00
parent 5eb2b68299
commit 6963f3af50
5 changed files with 185 additions and 9 deletions

View File

@ -1,10 +1,15 @@
import React from 'react'; import React from 'react';
import { Board } from './components/board'; import { Board } from './components/board';
import {changeFigurePosition, FigurePositionIE} from "./app/boardSlice"
import { useDispatch } from 'react-redux';
function App() { function App() {
let dispath = useDispatch()
let position = {row:6, col:4} as FigurePositionIE
return ( return (
<div className="App"> <div className="App">
<Board></Board> <Board></Board>
<button onClick={()=>dispath(changeFigurePosition({id:1, pos: position}))}>CLICK</button>
</div> </div>
); );
} }

106
src/app/boardSlice.ts Normal file
View File

@ -0,0 +1,106 @@
import { createSlice, PayloadAction, createSelector } from '@reduxjs/toolkit'
import { RootState } from './store'
export interface FigurePositionIE{
row: number
col:number
}
export interface FigureIE{
position:FigurePositionIE
type:string
id:number
}
export interface BoardStateIE{
active: boolean,
figures: FigureIE[]
}
let currentBoardState = {
active:false,
figures:[
{
position:{
row:8,
col:4
},
type:"pawn",
id:0
},
{
type:"elephant",
id:1,
position:{
row:8,
col:5
}
},
{
type:"rook",
id:2,
position:{
row:8,
col:6
}
}
] as FigureIE[]
} as BoardStateIE
const boardSlice = createSlice(
{
name:"boardSlice",
initialState: currentBoardState,
reducers:{
setBoardActive(state, action:PayloadAction<boolean>){
state.active = action.payload
},
addFigure(state, action:PayloadAction<FigureIE>){
state.figures = state.figures.concat(action.payload)
},
removeFigure(state, action:PayloadAction<number>){
let ind = -1;
state.figures.forEach(figure => {
if (figure.id == action.payload){
ind = figure.id
}
});
if(ind != -1){
state.figures = state.figures.splice(ind,1)
}
else{
console.error("id is missing");
}
},
changeFigurePosition(state, action:PayloadAction<{id:number, pos:FigurePositionIE}>){
let ind = -1;
state.figures.forEach(figure => {
if (figure.id == action.payload.id){
ind = figure.id
}
});
if(ind != -1){
state.figures[ind].position = action.payload.pos
}
else{
console.error("id is missing");
}
}
}
}
)
export const getBoardFigures = createSelector(
(state:RootState) => state.figures,
(field) => field
)
export const getBoardActive = createSelector(
(state:RootState) => state.active,
(field) => field
)
export const {
changeFigurePosition,
addFigure,
removeFigure,
setBoardActive
} = boardSlice.actions
export default boardSlice.reducer

View File

@ -1,9 +1,9 @@
import { configureStore, ThunkAction, Action } from '@reduxjs/toolkit'; import { configureStore, ThunkAction, Action, createStore } from '@reduxjs/toolkit';
import boardSlice from "./boardSlice"
export const store = configureStore({ export const store = configureStore({
reducer: { reducer:boardSlice
}, })
});
export type AppDispatch = typeof store.dispatch; export type AppDispatch = typeof store.dispatch;
export type RootState = ReturnType<typeof store.getState>; export type RootState = ReturnType<typeof store.getState>;

View File

@ -1,8 +1,12 @@
import React, { useEffect } from "react"; import React, { useEffect } from "react";
import * as THREE from 'three'; import * as THREE from 'three';
import { Canvas, RootState, useFrame, useThree } from '@react-three/fiber' import { Canvas, useFrame, useThree } from '@react-three/fiber'
import { Cell } from "./cell"; import { Cell } from "./cell";
import { useSelector } from "react-redux";
import { getBoardFigures } from "../app/boardSlice";
import { RootState } from "../app/store";
import { Figure } from "./figure";
function ThreeSettings(){ function ThreeSettings(){
const set = useThree((state)=>state.set) const set = useThree((state)=>state.set)
@ -16,29 +20,38 @@ function ThreeSettings(){
cam.rotation.set(-Math.PI/4,0,0) cam.rotation.set(-Math.PI/4,0,0)
cam.position.set(0,6,7) cam.position.set(0,6,7)
set({ set({
size:{width:512, height:512}, size:{width:1024, height:512},
}) })
} }
) )
return(null); return(null);
} }
export const Board:React.FC = () =>{ export const Board:React.FC = () =>{
let state = useSelector((state:RootState)=>getBoardFigures(state))
let cells = new Array<JSX.Element>() let cells = new Array<JSX.Element>()
let color = true let color = true
for (let i = 0; i<64; i++){ for (let i = 0; i<64; i++){
color = (((i%8) +Math.floor(i/8)) %2 == 0)
cells.push( cells.push(
<Cell color={color? "white":"black"} position={[i%9 - 4,1,Math.floor(i/9)]}></Cell> <Cell color={color? "white":"black"} position={[i%8 - 4,1,Math.floor(i/8)-2]}></Cell>
) )
color = !color
} }
let figuries = new Array<JSX.Element>()
state.map((params) =>{
figuries.push(<Figure position={params.position} id={params.id} type={params.type}></Figure>)
})
let objects = cells.concat(figuries)
return( return(
<Canvas> <Canvas>
<ThreeSettings/> <ThreeSettings/>
<ambientLight /> <ambientLight />
<pointLight position={[10, 10, 10]} /> <pointLight position={[10, 10, 10]} />
{ {
cells objects
} }
</Canvas> </Canvas>
); );
} }

52
src/components/figure.tsx Normal file
View File

@ -0,0 +1,52 @@
import React, { useRef, useState } from "react";
import { Canvas, useFrame, Vector3 } from '@react-three/fiber'
import { FigureIE, FigurePositionIE, getBoardActive, getBoardFigures, setBoardActive } from "../app/boardSlice";
import { skipPartiallyEmittedExpressions } from "typescript";
import { hover } from "@testing-library/user-event/dist/types/convenience";
import { useDispatch, useSelector } from "react-redux";
import { RootState } from "../app/store";
export const Figure:React.FC<FigureIE> = (props:FigureIE) => {
const [hover, setHover] = useState(false)
const [active, setActive] = useState(false)
let boardActive = useSelector((state: RootState) => getBoardActive(state))
let dispath = useDispatch()
const onClick = () =>{
if (boardActive == false){
// dispath(setBoardActive(true))
setActive(true)
}
}
const mesh = useRef()
let color;
if (props.type == "elephant"){
color = "red"
}
else if (props.type == "rook"){
color="blue"
}
else{
color = "yellow"
}
color = hover? "green":color
color = active? "purple":color
return(
<mesh
position={[props.position.col-5, 1.5, props.position.row-3 ]}
ref={mesh as any}
scale={1}
onPointerOver={()=>setHover(true)}
onPointerOut={()=>setHover(false)}
onPointerDown={()=>setActive(true)}
>
<boxGeometry args={[0.5, 1, 0.5]} />
<meshStandardMaterial color={color} />
</mesh>
);
}