add some descriptins
This commit is contained in:
parent
fbd1e0d932
commit
4349269aff
5
.editorconfig
Normal file
5
.editorconfig
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# .editorconfig
|
||||||
|
root = true
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -16,6 +16,7 @@ dist-ssr
|
|||||||
.vscode/*
|
.vscode/*
|
||||||
!.vscode/extensions.json
|
!.vscode/extensions.json
|
||||||
.idea
|
.idea
|
||||||
|
.fleet
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*.suo
|
*.suo
|
||||||
*.ntvs*
|
*.ntvs*
|
||||||
|
|||||||
@ -1,11 +1,7 @@
|
|||||||
import { useState } from 'react';
|
|
||||||
|
|
||||||
import './styles/main.less';
|
import './styles/main.less';
|
||||||
import {Game} from './components/game';
|
import {Game} from './components/game';
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
const [count, setCount] = useState<Number>(0)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='main'>
|
<div className='main'>
|
||||||
<Game />
|
<Game />
|
||||||
|
|||||||
@ -7,6 +7,7 @@ interface ButtonGroupProps {
|
|||||||
|
|
||||||
export interface ButtonDefinition {
|
export interface ButtonDefinition {
|
||||||
text: string|JSX.Element;
|
text: string|JSX.Element;
|
||||||
|
title?: string;
|
||||||
onClick: React.MouseEventHandler<HTMLButtonElement>;
|
onClick: React.MouseEventHandler<HTMLButtonElement>;
|
||||||
cssProps: CSSProperties;
|
cssProps: CSSProperties;
|
||||||
buttonProps?: React.ButtonHTMLAttributes<HTMLButtonElement>
|
buttonProps?: React.ButtonHTMLAttributes<HTMLButtonElement>
|
||||||
@ -20,6 +21,7 @@ const ButtonGroup = ({buttons, buttonStyleProps}: ButtonGroupProps) => {
|
|||||||
<button
|
<button
|
||||||
key={index}
|
key={index}
|
||||||
onClick={btn.onClick}
|
onClick={btn.onClick}
|
||||||
|
title={btn.title}
|
||||||
style={{
|
style={{
|
||||||
...buttonStyleProps,
|
...buttonStyleProps,
|
||||||
...btn.cssProps
|
...btn.cssProps
|
||||||
|
|||||||
@ -7,10 +7,6 @@ interface CellProps {
|
|||||||
updateCell: (newVal: boolean, position: number) => void
|
updateCell: (newVal: boolean, position: number) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultClasses: string[] = [
|
|
||||||
'cell'
|
|
||||||
];
|
|
||||||
|
|
||||||
let currentDragValue = true;
|
let currentDragValue = true;
|
||||||
|
|
||||||
const Cell = ({value, position, updateCell}: CellProps) => {
|
const Cell = ({value, position, updateCell}: CellProps) => {
|
||||||
@ -32,6 +28,7 @@ const Cell = ({value, position, updateCell}: CellProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
// style={{width: '50px', height:'50px'}}
|
||||||
className={cellClasses}
|
className={cellClasses}
|
||||||
draggable={false}
|
draggable={false}
|
||||||
onMouseDown={handleCellMouseDown}
|
onMouseDown={handleCellMouseDown}
|
||||||
|
|||||||
@ -1,76 +0,0 @@
|
|||||||
import {ButtonDefinition, ButtonGroup} from '../button';
|
|
||||||
import {
|
|
||||||
AiOutlineClear,
|
|
||||||
BsFillPlayFill,
|
|
||||||
BsFillStopFill,
|
|
||||||
CiSettings,
|
|
||||||
IoAdd,
|
|
||||||
IoRemove,
|
|
||||||
TbArrowsRandom
|
|
||||||
} from 'react-icons/all';
|
|
||||||
import React, {useCallback, useMemo} from 'react';
|
|
||||||
import {GameOptions, GameState} from './Game';
|
|
||||||
|
|
||||||
interface ControlPanelProps {
|
|
||||||
gameOptions: GameOptions;
|
|
||||||
handleStart: React.MouseEventHandler<HTMLButtonElement>;
|
|
||||||
handleStop: React.MouseEventHandler<HTMLButtonElement>;
|
|
||||||
handleRandomFill: React.MouseEventHandler<HTMLButtonElement>;
|
|
||||||
handleClear: React.MouseEventHandler<HTMLButtonElement>;
|
|
||||||
handleUpdateSpeed: (newVal: number) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ControlPanel = ({
|
|
||||||
gameOptions,
|
|
||||||
handleStart,
|
|
||||||
handleStop,
|
|
||||||
handleRandomFill,
|
|
||||||
handleClear,
|
|
||||||
handleUpdateSpeed
|
|
||||||
}: ControlPanelProps) => {
|
|
||||||
const controlButtons: ButtonDefinition[] = useMemo(() => [
|
|
||||||
{text: <BsFillPlayFill />, onClick: handleStart, cssProps: {}, buttonProps: {disabled: gameOptions.gameState === GameState.Running}},
|
|
||||||
{text: <BsFillStopFill />, onClick: handleStop, cssProps: {}, buttonProps: {disabled: gameOptions.gameState === GameState.Stopped}},
|
|
||||||
{text: <TbArrowsRandom />, onClick: handleRandomFill, cssProps: {}},
|
|
||||||
{text: <AiOutlineClear />, onClick: handleClear, cssProps: {}}
|
|
||||||
], [handleStart, handleStop, handleRandomFill, handleClear, gameOptions]);
|
|
||||||
|
|
||||||
const handleSpeedChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
|
|
||||||
const value = event.target.value;
|
|
||||||
handleUpdateSpeed(Number(value));
|
|
||||||
}, [handleUpdateSpeed]);
|
|
||||||
|
|
||||||
const handleSpeedUp = useCallback((event: React.MouseEvent<HTMLButtonElement>) => {
|
|
||||||
const newVal = gameOptions.speed + 100;
|
|
||||||
handleUpdateSpeed(newVal);
|
|
||||||
}, [handleUpdateSpeed, gameOptions]);
|
|
||||||
|
|
||||||
const handleSpeedDown = useCallback((event: React.MouseEvent<HTMLButtonElement>) => {
|
|
||||||
const newVal = gameOptions.speed - 100;
|
|
||||||
handleUpdateSpeed(newVal);
|
|
||||||
}, [handleUpdateSpeed, gameOptions]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className='control-panel'>
|
|
||||||
<ButtonGroup
|
|
||||||
buttons={controlButtons}
|
|
||||||
buttonStyleProps={{
|
|
||||||
width: '50px'
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div className='speed-selector'>
|
|
||||||
<button onClick={handleSpeedUp}><IoAdd /></button>
|
|
||||||
<input
|
|
||||||
value={gameOptions.speed}
|
|
||||||
onChange={handleSpeedChange}
|
|
||||||
/>
|
|
||||||
<button onClick={handleSpeedDown}><IoRemove /></button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button><CiSettings/></button>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ControlPanel;
|
|
||||||
@ -2,7 +2,7 @@ import CellContainer from './CellContainer';
|
|||||||
import {useCallback, useEffect, useRef, useState} from 'react';
|
import {useCallback, useEffect, useRef, useState} from 'react';
|
||||||
|
|
||||||
import '../../styles/game.less';
|
import '../../styles/game.less';
|
||||||
import ControlPanel from './ControlPanel';
|
import {ControlPanel} from './controlPanel';
|
||||||
|
|
||||||
interface GameProps {
|
interface GameProps {
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ const defaultGameOptions: GameOptions = {
|
|||||||
gameState: GameState.Stopped,
|
gameState: GameState.Stopped,
|
||||||
width: 25,
|
width: 25,
|
||||||
height: 25,
|
height: 25,
|
||||||
speed: 1000,
|
speed: 200,
|
||||||
minSpeed: 10,
|
minSpeed: 10,
|
||||||
randomizerDensity: 0.3,
|
randomizerDensity: 0.3,
|
||||||
gameRules: {
|
gameRules: {
|
||||||
|
|||||||
22
src/components/game/controlPanel/ControlElement.tsx
Normal file
22
src/components/game/controlPanel/ControlElement.tsx
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
interface ControlElementProps {
|
||||||
|
title?: string;
|
||||||
|
children?: React.ReactNode;
|
||||||
|
alignment?: 'start'|'center'|'end';
|
||||||
|
}
|
||||||
|
|
||||||
|
const ControlElement = ({title, children, alignment = 'start'}: ControlElementProps) => {
|
||||||
|
return (
|
||||||
|
<div className='control-element' style={{alignItems: alignment}}>
|
||||||
|
<div>
|
||||||
|
{title}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ControlElement;
|
||||||
62
src/components/game/controlPanel/ControlPanel.tsx
Normal file
62
src/components/game/controlPanel/ControlPanel.tsx
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import {ButtonDefinition, ButtonGroup} from '../../button';
|
||||||
|
import {
|
||||||
|
AiOutlineClear,
|
||||||
|
BsFillPlayFill,
|
||||||
|
BsFillStopFill,
|
||||||
|
CiSettings,
|
||||||
|
TbArrowsRandom
|
||||||
|
} from 'react-icons/all';
|
||||||
|
import React, {useMemo} from 'react';
|
||||||
|
import {GameOptions, GameState} from '../Game';
|
||||||
|
import SpeedSelector from "./SpeedSelector";
|
||||||
|
import ControlElement from "./ControlElement";
|
||||||
|
|
||||||
|
interface ControlPanelProps {
|
||||||
|
gameOptions: GameOptions;
|
||||||
|
handleStart: React.MouseEventHandler<HTMLButtonElement>;
|
||||||
|
handleStop: React.MouseEventHandler<HTMLButtonElement>;
|
||||||
|
handleRandomFill: React.MouseEventHandler<HTMLButtonElement>;
|
||||||
|
handleClear: React.MouseEventHandler<HTMLButtonElement>;
|
||||||
|
handleUpdateSpeed: (newVal: number) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ControlPanel = ({
|
||||||
|
gameOptions,
|
||||||
|
handleStart,
|
||||||
|
handleStop,
|
||||||
|
handleRandomFill,
|
||||||
|
handleClear,
|
||||||
|
handleUpdateSpeed
|
||||||
|
}: ControlPanelProps) => {
|
||||||
|
const controlButtons: ButtonDefinition[] = useMemo(() => [
|
||||||
|
{text: <BsFillPlayFill />, title: 'Start', onClick: handleStart, cssProps: {}, buttonProps: {disabled: gameOptions.gameState === GameState.Running}},
|
||||||
|
{text: <BsFillStopFill />, title: 'Stop', onClick: handleStop, cssProps: {}, buttonProps: {disabled: gameOptions.gameState === GameState.Stopped}},
|
||||||
|
{text: <TbArrowsRandom />, title: 'Randomize Cells', onClick: handleRandomFill, cssProps: {}},
|
||||||
|
{text: <AiOutlineClear />, title: 'Clear Cells', onClick: handleClear, cssProps: {}}
|
||||||
|
], [handleStart, handleStop, handleRandomFill, handleClear, gameOptions]);
|
||||||
|
return (
|
||||||
|
<div className='control-panel'>
|
||||||
|
<ControlElement title='Actions'>
|
||||||
|
<ButtonGroup
|
||||||
|
buttons={controlButtons}
|
||||||
|
buttonStyleProps={{
|
||||||
|
width: '50px'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</ControlElement>
|
||||||
|
|
||||||
|
<ControlElement title='Change Speed'>
|
||||||
|
<SpeedSelector
|
||||||
|
handleUpdateSpeed={handleUpdateSpeed}
|
||||||
|
speed={gameOptions.speed}
|
||||||
|
/>
|
||||||
|
</ControlElement>
|
||||||
|
|
||||||
|
<ControlElement>
|
||||||
|
<button><CiSettings/></button>
|
||||||
|
</ControlElement>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ControlPanel;
|
||||||
37
src/components/game/controlPanel/SpeedSelector.tsx
Normal file
37
src/components/game/controlPanel/SpeedSelector.tsx
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import React, { useCallback } from "react";
|
||||||
|
import {IoAdd, IoRemove} from "react-icons/all";
|
||||||
|
|
||||||
|
interface SpeedSelectorProps {
|
||||||
|
handleUpdateSpeed: (newVal: number) => void;
|
||||||
|
speed: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SpeedSelector = ({handleUpdateSpeed, speed}: SpeedSelectorProps) => {
|
||||||
|
const handleSpeedChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const value = event.target.value;
|
||||||
|
handleUpdateSpeed(Number(value));
|
||||||
|
}, [handleUpdateSpeed]);
|
||||||
|
|
||||||
|
const handleSpeedUp = useCallback((event: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
|
const newVal = speed + 100;
|
||||||
|
handleUpdateSpeed(newVal);
|
||||||
|
}, [handleUpdateSpeed, speed]);
|
||||||
|
|
||||||
|
const handleSpeedDown = useCallback((event: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
|
const newVal = speed - 100;
|
||||||
|
handleUpdateSpeed(newVal);
|
||||||
|
}, [handleUpdateSpeed, speed]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='speed-selector'>
|
||||||
|
<button onClick={handleSpeedUp}><IoAdd /></button>
|
||||||
|
<input
|
||||||
|
value={speed}
|
||||||
|
onChange={handleSpeedChange}
|
||||||
|
/>
|
||||||
|
<button onClick={handleSpeedDown}><IoRemove /></button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SpeedSelector;
|
||||||
1
src/components/game/controlPanel/index.ts
Normal file
1
src/components/game/controlPanel/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export {default as ControlPanel} from './ControlPanel';
|
||||||
@ -12,6 +12,14 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
|
|
||||||
|
.control-element {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 5px;
|
||||||
|
|
||||||
|
justify-content: end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.speed-selector {
|
.speed-selector {
|
||||||
@ -38,7 +46,6 @@
|
|||||||
border: 1px solid @col-dark-light;
|
border: 1px solid @col-dark-light;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
//pointer-events: none;
|
|
||||||
|
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
||||||
|
|||||||
@ -11,8 +11,7 @@ body {
|
|||||||
|
|
||||||
|
|
||||||
.main {
|
.main {
|
||||||
height: 100vh;
|
min-height: 100vh;
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user