Stylistic rework
- interfaces instead of types - remove semicolons - use functions instead of anonymous arrow functions - rename vars/types for better understanding - fix typo
This commit is contained in:
parent
77aabd5901
commit
46a899b0ec
14 changed files with 203 additions and 189 deletions
|
@ -1,6 +1,6 @@
|
||||||
import { CSSProperties, Dispatch, SetStateAction } from 'react';
|
import { CSSProperties, Dispatch, SetStateAction } from 'react'
|
||||||
import { borderCN, cornerCN, fieldIndex } from '../helpers';
|
import { borderCN, cornerCN, fieldIndex } from '../helpers'
|
||||||
import { LastLeftTileType, TargetPreviewPosType } from '../interfaces';
|
import { Position, MouseCursor } from '../interfaces'
|
||||||
|
|
||||||
type TilesType = {
|
type TilesType = {
|
||||||
key: number,
|
key: number,
|
||||||
|
@ -10,27 +10,27 @@ type TilesType = {
|
||||||
y: number
|
y: number
|
||||||
}
|
}
|
||||||
|
|
||||||
function BorderTiles({ props: { count, settingTarget, setTargetPreviewPos, setLastLeftTile } }: {
|
function BorderTiles({ props: { count, settingTarget, setMouseCursor, setLastLeftTile } }: {
|
||||||
props: {
|
props: {
|
||||||
count: number,
|
count: number,
|
||||||
settingTarget: (isGameTile: boolean, x: number, y: number) => void,
|
settingTarget: (isGameTile: boolean, x: number, y: number) => void,
|
||||||
setTargetPreviewPos: Dispatch<SetStateAction<TargetPreviewPosType>>,
|
setMouseCursor: Dispatch<SetStateAction<MouseCursor>>,
|
||||||
setLastLeftTile: Dispatch<SetStateAction<LastLeftTileType>>
|
setLastLeftTile: Dispatch<SetStateAction<Position>>
|
||||||
}
|
}
|
||||||
}) {
|
}) {
|
||||||
let tilesProperties: TilesType[] = [];
|
let tilesProperties: TilesType[] = []
|
||||||
|
|
||||||
for (let y = 0; y < count + 2; y++) {
|
for (let y = 0; y < count + 2; y++) {
|
||||||
for (let x = 0; x < count + 2; x++) {
|
for (let x = 0; x < count + 2; x++) {
|
||||||
const key = fieldIndex(count, x, y);
|
const key = fieldIndex(count, x, y)
|
||||||
const cornerReslt = cornerCN(count, x, y);
|
const cornerReslt = cornerCN(count, x, y)
|
||||||
const borderType = cornerReslt ? cornerReslt : borderCN(count, x, y);
|
const borderType = cornerReslt ? cornerReslt : borderCN(count, x, y)
|
||||||
const isGameTile = x > 0 && x < count + 1 && y > 0 && y < count + 1;
|
const isGameTile = x > 0 && x < count + 1 && y > 0 && y < count + 1
|
||||||
const classNames = ['border-tile'];
|
const classNames = ['border-tile']
|
||||||
if (borderType)
|
if (borderType)
|
||||||
classNames.push('edge', borderType);
|
classNames.push('edge', borderType)
|
||||||
if (isGameTile)
|
if (isGameTile)
|
||||||
classNames.push('game-tile');
|
classNames.push('game-tile')
|
||||||
const classNameString = classNames.join(' ')
|
const classNameString = classNames.join(' ')
|
||||||
tilesProperties.push({ key, classNameString, isGameTile, x: x + 1, y: y + 1 })
|
tilesProperties.push({ key, classNameString, isGameTile, x: x + 1, y: y + 1 })
|
||||||
}
|
}
|
||||||
|
@ -42,11 +42,11 @@ function BorderTiles({ props: { count, settingTarget, setTargetPreviewPos, setLa
|
||||||
className={classNameString}
|
className={classNameString}
|
||||||
style={{ '--x': x, '--y': y } as CSSProperties}
|
style={{ '--x': x, '--y': y } as CSSProperties}
|
||||||
onClick={() => settingTarget(isGameTile, x, y)}
|
onClick={() => settingTarget(isGameTile, x, y)}
|
||||||
onMouseEnter={() => setTargetPreviewPos({ x, y, shouldShow: isGameTile })}
|
onMouseEnter={() => setMouseCursor({ x, y, shouldShow: isGameTile })}
|
||||||
onMouseLeave={() => setLastLeftTile({ x, y })}
|
onMouseLeave={() => setLastLeftTile({ x, y })}
|
||||||
></div>
|
></div>
|
||||||
})}
|
})}
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
|
||||||
export default BorderTiles;
|
export default BorderTiles
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import Image from "next/image";
|
import Image from "next/image"
|
||||||
|
|
||||||
function FogImages() {
|
function FogImages() {
|
||||||
return <>
|
return <>
|
||||||
|
@ -8,4 +8,4 @@ function FogImages() {
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
|
||||||
export default FogImages;
|
export default FogImages
|
||||||
|
|
|
@ -1,30 +1,30 @@
|
||||||
import { CSSProperties } from 'react';
|
import { CSSProperties } from 'react'
|
||||||
// import Bluetooth from './Bluetooth';
|
// import Bluetooth from './Bluetooth'
|
||||||
import BorderTiles from './BorderTiles';
|
import BorderTiles from './BorderTiles'
|
||||||
// import FogImages from './FogImages';
|
// import FogImages from './FogImages'
|
||||||
import HitElems from './HitElems';
|
import HitElems from './HitElems'
|
||||||
import Labeling from './Labeling';
|
import Labeling from './Labeling'
|
||||||
import Ships from './Ships';
|
import Ships from './Ships'
|
||||||
import useGameEvent from './useGameEvent';
|
import useGameEvent from './useGameEvent'
|
||||||
|
|
||||||
function Gamefield() {
|
function Gamefield() {
|
||||||
|
|
||||||
const count = 12;
|
const count = 12
|
||||||
const {
|
const {
|
||||||
targets,
|
targets,
|
||||||
eventBar,
|
eventBar,
|
||||||
setLastLeftTile,
|
setLastLeftTile,
|
||||||
settingTarget,
|
settingTarget,
|
||||||
setTargetPreviewPos,
|
setMouseCursor,
|
||||||
hits
|
hits
|
||||||
} = useGameEvent(count);
|
} = useGameEvent()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id='gamefield'>
|
<div id='gamefield'>
|
||||||
{/* <Bluetooth /> */}
|
{/* <Bluetooth /> */}
|
||||||
<div id="game-frame" style={{ '--i': count } as CSSProperties}>
|
<div id="game-frame" style={{ '--i': count } as CSSProperties}>
|
||||||
{/* Bordes */}
|
{/* Bordes */}
|
||||||
<BorderTiles props={{ count, settingTarget, setTargetPreviewPos, setLastLeftTile }} />
|
<BorderTiles props={{ count, settingTarget, setMouseCursor, setLastLeftTile }} />
|
||||||
|
|
||||||
{/* Collumn lettes and row numbers */}
|
{/* Collumn lettes and row numbers */}
|
||||||
<Labeling count={count} />
|
<Labeling count={count} />
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { faCrosshairs } from '@fortawesome/pro-solid-svg-icons';
|
import { faCrosshairs } from '@fortawesome/pro-solid-svg-icons'
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
import { CSSProperties } from 'react';
|
import { CSSProperties } from 'react'
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames'
|
||||||
import { faRadar } from '@fortawesome/pro-thin-svg-icons';
|
import { faRadar } from '@fortawesome/pro-thin-svg-icons'
|
||||||
|
|
||||||
function GamefieldPointer({ props: {
|
function GamefieldPointer({ props: {
|
||||||
preview,
|
preview,
|
||||||
|
|
|
@ -3,7 +3,9 @@ import { CSSProperties, useEffect, useMemo, useState } from 'react'
|
||||||
|
|
||||||
function Grid() {
|
function Grid() {
|
||||||
|
|
||||||
const floorClient = (number: number) => Math.floor(number / 50)
|
function floorClient(number: number) {
|
||||||
|
return Math.floor(number / 50)
|
||||||
|
}
|
||||||
|
|
||||||
const [columns, setColumns] = useState(0)
|
const [columns, setColumns] = useState(0)
|
||||||
const [rows, setRows] = useState(0)
|
const [rows, setRows] = useState(0)
|
||||||
|
@ -47,15 +49,21 @@ function Grid() {
|
||||||
const yDiff = (y - position[1]) / 20
|
const yDiff = (y - position[1]) / 20
|
||||||
const pos = (Math.sqrt(xDiff * xDiff + yDiff * yDiff)).toFixed(2)
|
const pos = (Math.sqrt(xDiff * xDiff + yDiff * yDiff)).toFixed(2)
|
||||||
|
|
||||||
const doEffect = (posX: number, posY: number) => {
|
function doEffect(posX: number, posY: number) {
|
||||||
if (active)
|
if (active)
|
||||||
return
|
return
|
||||||
setPosition([posX, posY])
|
setPosition([posX, posY])
|
||||||
setActve(true)
|
setActve(true)
|
||||||
|
|
||||||
const xDiff = (x: number) => (x - posX) / 20
|
function xDiff(x: number) {
|
||||||
const yDiff = (y: number) => (y - posY) / 20
|
return (x - posX) / 20
|
||||||
const pos = (x: number, y: number) => Math.sqrt(xDiff(x) * xDiff(x) + yDiff(y) * yDiff(y))
|
}
|
||||||
|
function yDiff(y: number) {
|
||||||
|
return (y - posY) / 20
|
||||||
|
}
|
||||||
|
function pos(x: number, y: number) {
|
||||||
|
return Math.sqrt(xDiff(x) * xDiff(x) + yDiff(y) * yDiff(y))
|
||||||
|
}
|
||||||
const diagonals = [pos(0, 0), pos(params.columns, 0), pos(0, params.rows), pos(params.columns, params.rows)]
|
const diagonals = [pos(0, 0), pos(params.columns, 0), pos(0, params.rows), pos(params.columns, params.rows)]
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|
|
@ -3,7 +3,9 @@ import { CSSProperties, useEffect, useMemo, useState } from 'react'
|
||||||
|
|
||||||
function Grid2() {
|
function Grid2() {
|
||||||
|
|
||||||
const floorClient = (number: number) => Math.floor(number / 50)
|
function floorClient(number: number) {
|
||||||
|
return Math.floor(number / 50)
|
||||||
|
}
|
||||||
|
|
||||||
const [columns, setColumns] = useState(0)
|
const [columns, setColumns] = useState(0)
|
||||||
const [rows, setRows] = useState(0)
|
const [rows, setRows] = useState(0)
|
||||||
|
@ -47,16 +49,22 @@ function Grid2() {
|
||||||
const yDiff = (y - position[1]) / 20
|
const yDiff = (y - position[1]) / 20
|
||||||
const pos = (Math.sqrt(xDiff * xDiff + yDiff * yDiff)).toFixed(2)
|
const pos = (Math.sqrt(xDiff * xDiff + yDiff * yDiff)).toFixed(2)
|
||||||
|
|
||||||
const doEffect = (posX: number, posY: number) => {
|
function doEffect(posX: number, posY: number) {
|
||||||
if (action)
|
if (action)
|
||||||
return
|
return
|
||||||
setPosition([posX, posY])
|
setPosition([posX, posY])
|
||||||
setActve(e => !e)
|
setActve(e => !e)
|
||||||
setAction(true)
|
setAction(true)
|
||||||
|
|
||||||
const xDiff = (x: number) => (x - posX) / 50
|
function xDiff(x: number) {
|
||||||
const yDiff = (y: number) => (y - posY) / 50
|
return (x - posX) / 20
|
||||||
const pos = (x: number, y: number) => Math.sqrt(xDiff(x) * xDiff(x) + yDiff(y) * yDiff(y))
|
}
|
||||||
|
function yDiff(y: number) {
|
||||||
|
return (y - posY) / 20
|
||||||
|
}
|
||||||
|
function pos(x: number, y: number) {
|
||||||
|
return Math.sqrt(xDiff(x) * xDiff(x) + yDiff(y) * yDiff(y))
|
||||||
|
}
|
||||||
const diagonals = [pos(0, 0), pos(params.columns, 0), pos(0, params.rows), pos(params.columns, params.rows)]
|
const diagonals = [pos(0, 0), pos(params.columns, 0), pos(0, params.rows), pos(params.columns, params.rows)]
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { faBurst, faXmark } from '@fortawesome/pro-solid-svg-icons';
|
import { faBurst, faXmark } from '@fortawesome/pro-solid-svg-icons'
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
import { CSSProperties } from 'react';
|
import { CSSProperties } from 'react'
|
||||||
import { HitType } from '../interfaces';
|
import { Hit } from '../interfaces'
|
||||||
|
|
||||||
function HitElems({hits}: {hits: HitType[]}) {
|
function HitElems({hits}: {hits: Hit[]}) {
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
{hits.map(({hit, x, y}, i) =>
|
{hits.map(({hit, x, y}, i) =>
|
||||||
|
@ -14,4 +14,4 @@ function HitElems({hits}: {hits: HitType[]}) {
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
|
||||||
export default HitElems;
|
export default HitElems
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames'
|
||||||
import { CSSProperties } from 'react'
|
import { CSSProperties } from 'react'
|
||||||
import { fieldIndex } from '../helpers';
|
import { fieldIndex } from '../helpers'
|
||||||
import { FieldType } from '../interfaces';
|
import { Field } from '../interfaces'
|
||||||
|
|
||||||
function Labeling({count}: {count: number}) {
|
function Labeling({count}: {count: number}) {
|
||||||
let elems: (FieldType & {
|
let elems: (Field & {
|
||||||
orientation: string
|
orientation: string
|
||||||
})[] = [];
|
})[] = []
|
||||||
for (let x = 0; x < count; x++) {
|
for (let x = 0; x < count; x++) {
|
||||||
elems.push(
|
elems.push(
|
||||||
// Up
|
// Up
|
||||||
|
@ -17,9 +17,9 @@ function Labeling({count}: {count: number}) {
|
||||||
{field: String.fromCharCode(65+x), x: x+2, y: count+2, orientation: 'bottom'},
|
{field: String.fromCharCode(65+x), x: x+2, y: count+2, orientation: 'bottom'},
|
||||||
// Right
|
// Right
|
||||||
{field: (x+1).toString(), x: count+2, y: x+2, orientation: 'right'}
|
{field: (x+1).toString(), x: count+2, y: x+2, orientation: 'right'}
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
elems = elems.sort((a, b) => fieldIndex(count, a.x, a.y)-fieldIndex(count, b.x, b.y));
|
elems = elems.sort((a, b) => fieldIndex(count, a.x, a.y)-fieldIndex(count, b.x, b.y))
|
||||||
return <>
|
return <>
|
||||||
{elems.map(({field, x, y, orientation}, i) =>
|
{elems.map(({field, x, y, orientation}, i) =>
|
||||||
<span key={i} className={classNames('label', orientation, field)} style={{'--x': x, '--y': y} as CSSProperties}>{field}</span>
|
<span key={i} className={classNames('label', orientation, field)} style={{'--x': x, '--y': y} as CSSProperties}>{field}</span>
|
||||||
|
@ -27,4 +27,4 @@ function Labeling({count}: {count: number}) {
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Labeling;
|
export default Labeling
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames'
|
||||||
import { CSSProperties } from 'react'
|
import { CSSProperties } from 'react'
|
||||||
|
|
||||||
function Ships() {
|
function Ships() {
|
||||||
|
@ -9,7 +9,7 @@ function Ships() {
|
||||||
{ size: 3, index: 3 },
|
{ size: 3, index: 3 },
|
||||||
{ size: 4, index: 1 },
|
{ size: 4, index: 1 },
|
||||||
{ size: 4, index: 2 }
|
{ size: 4, index: 2 }
|
||||||
];
|
]
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
{shipIndexes.map(({ size, index }, i) => {
|
{shipIndexes.map(({ size, index }, i) => {
|
||||||
|
@ -23,4 +23,4 @@ function Ships() {
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Ships;
|
export default Ships
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
import { io } from 'socket.io-client';
|
import { io } from 'socket.io-client'
|
||||||
|
|
||||||
function SocketIO() {
|
function SocketIO() {
|
||||||
const socket = io("ws://localhost:5001");
|
const socket = io("ws://localhost:5001")
|
||||||
socket.on('test2', (warst) => {
|
socket.on('test2', (warst) => {
|
||||||
console.log('Test2:', warst, socket.id)
|
console.log('Test2:', warst, socket.id)
|
||||||
})
|
})
|
||||||
socket.on("connect", () => {
|
socket.on("connect", () => {
|
||||||
console.log(socket.connected); // true
|
console.log(socket.connected) // true
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
socket.emit('test', "warst")
|
socket.emit('test', "warst")
|
||||||
socket.emit('test', "tsra")
|
socket.emit('test', "tsra")
|
||||||
socket.emit('test', "1234")
|
socket.emit('test', "1234")
|
||||||
// socket.disconnect()
|
// socket.disconnect()
|
||||||
}, 1000)
|
}, 1000)
|
||||||
});
|
})
|
||||||
|
|
||||||
socket.on("test", () => {
|
socket.on("test", () => {
|
||||||
console.log("Got test1234"); // false
|
console.log("Got test1234") // false
|
||||||
});
|
})
|
||||||
|
|
||||||
socket.on("disconnect", () => {
|
socket.on("disconnect", () => {
|
||||||
console.log(socket.connected); // false
|
console.log(socket.connected) // false
|
||||||
});
|
})
|
||||||
return (
|
return (
|
||||||
<div>SocketIO</div>
|
<div>SocketIO</div>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,50 +1,49 @@
|
||||||
import { useCallback, useEffect, useMemo, useReducer, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useReducer, useState } from 'react'
|
||||||
import { hitReducer, initlialLastLeftTile, initlialTarget, initlialTargetPreview, initlialTargetPreviewPos, isHit } from '../helpers';
|
import { hitReducer, initlialLastLeftTile, initlialTarget, initlialTargetPreview, initlialMouseCursor, isHit } from '../helpers'
|
||||||
import { HitType, ItemsType, LastLeftTileType, ModeType, TargetPreviewPosType, TargetType } from '../interfaces';
|
import { Hit, Items, Mode, MouseCursor, Target, Position } from '../interfaces'
|
||||||
import Item from './Item';
|
import Item from './Item'
|
||||||
import GamefieldPointer from './GamefieldPointer';
|
import GamefieldPointer from './GamefieldPointer'
|
||||||
|
|
||||||
function useGameEvent(count: number) {
|
function useGameEvent() {
|
||||||
const [lastLeftTile, setLastLeftTile] = useState<LastLeftTileType>(initlialLastLeftTile);
|
const [lastLeftTile, setLastLeftTile] = useState<Position>(initlialLastLeftTile)
|
||||||
const [target, setTarget] = useState<TargetType>(initlialTarget);
|
const [target, setTarget] = useState<Target>(initlialTarget)
|
||||||
const [eventReady, setEventReady] = useState(false);
|
const [eventReady, setEventReady] = useState(false)
|
||||||
const [appearOK, setAppearOK] = useState(false);
|
const [appearOK, setAppearOK] = useState(false)
|
||||||
const [targetPreview, setTargetPreview] = useState<TargetType>(initlialTargetPreview);
|
const [targetPreview, setTargetPreview] = useState<Target>(initlialTargetPreview)
|
||||||
const [targetPreviewPos, setTargetPreviewPos] = useState<TargetPreviewPosType>(initlialTargetPreviewPos);
|
const [mouseCursor, setMouseCursor] = useState<MouseCursor>(initlialMouseCursor)
|
||||||
const [hits, DispatchHits] = useReducer(hitReducer, [] as HitType[]);
|
const [hits, DispatchHits] = useReducer(hitReducer, [] as Hit[])
|
||||||
// const [mode, setMode] = useState<[number, string]>([0, ''])
|
|
||||||
const [mode, setMode] = useState(0)
|
const [mode, setMode] = useState(0)
|
||||||
|
|
||||||
const modes = useMemo<ModeType[]>(() => [
|
const modes = useMemo<Mode[]>(() => [
|
||||||
{ pointerGrid: Array.from(Array(3), () => Array.from(Array(3))), type: 'radar' },
|
{ pointerGrid: Array.from(Array(3), () => Array.from(Array(3))), type: 'radar' },
|
||||||
{ pointerGrid: Array.from(Array(3), () => Array.from(Array(1))), type: 'htorpedo' },
|
{ pointerGrid: Array.from(Array(3), () => Array.from(Array(1))), type: 'htorpedo' },
|
||||||
{ pointerGrid: Array.from(Array(1), () => Array.from(Array(3))), type: 'vhtorpedo' },
|
{ pointerGrid: Array.from(Array(1), () => Array.from(Array(3))), type: 'vtorpedo' },
|
||||||
{ pointerGrid: [[{ x: 0, y: 0 }]], type: 'missle' }
|
{ pointerGrid: [[{ x: 0, y: 0 }]], type: 'missile' }
|
||||||
], [])
|
], [])
|
||||||
|
|
||||||
const settingTarget = useCallback((isGameTile: boolean, x: number, y: number) => {
|
const settingTarget = useCallback((isGameTile: boolean, x: number, y: number) => {
|
||||||
if (!isGameTile || isHit(hits, x, y).length)
|
if (!isGameTile || isHit(hits, x, y).length)
|
||||||
return;
|
return
|
||||||
setTargetPreviewPos(e => ({ ...e, shouldShow: false }))
|
setMouseCursor(e => ({ ...e, shouldShow: false }))
|
||||||
setTarget(t => {
|
setTarget(t => {
|
||||||
if (t.x === x && t.y === y && t.show) {
|
if (t.x === x && t.y === y && t.show) {
|
||||||
DispatchHits({ type: 'fireMissle', payload: { hit: (x + y) % 2 !== 0, x, y } });
|
DispatchHits({ type: 'fireMissile', payload: { hit: (x + y) % 2 !== 0, x, y } })
|
||||||
return { preview: false, show: false, x, y };
|
return { preview: false, show: false, x, y }
|
||||||
} else {
|
} else {
|
||||||
return { preview: false, show: true, x, y };
|
return { preview: false, show: true, x, y }
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}, [])
|
}, [hits])
|
||||||
|
|
||||||
const targetList = useCallback((target: TargetType) => {
|
const targetList = useCallback((target: Target) => {
|
||||||
const { pointerGrid, type } = modes[mode]
|
const { pointerGrid, type } = modes[mode]
|
||||||
const xLength = pointerGrid.length
|
const xLength = pointerGrid.length
|
||||||
const yLength = pointerGrid[0].length
|
const yLength = pointerGrid[0].length
|
||||||
const { x: targetX, y: targetY } = target
|
const { x: targetX, y: targetY } = target
|
||||||
return pointerGrid.map((arr, i) => {
|
return pointerGrid.map((arr, i) => {
|
||||||
return arr.map((_, i2) => {
|
return arr.map((_, i2) => {
|
||||||
const relativeX = -Math.floor(xLength / 2) + i;
|
const relativeX = -Math.floor(xLength / 2) + i
|
||||||
const relativeY = -Math.floor(yLength / 2) + i2;
|
const relativeY = -Math.floor(yLength / 2) + i2
|
||||||
const x = targetX + (relativeX ?? 0)
|
const x = targetX + (relativeX ?? 0)
|
||||||
const y = targetY + (relativeY ?? 0)
|
const y = targetY + (relativeY ?? 0)
|
||||||
return {
|
return {
|
||||||
|
@ -65,7 +64,7 @@ function useGameEvent(count: number) {
|
||||||
|
|
||||||
const isSet = useCallback((x: number, y: number) => !!targetList(target).filter(field => x === field.x && y === field.y).length && target.show, [target, targetList])
|
const isSet = useCallback((x: number, y: number) => !!targetList(target).filter(field => x === field.x && y === field.y).length && target.show, [target, targetList])
|
||||||
|
|
||||||
const composeTargetTiles = useCallback((target: TargetType) => {
|
const composeTargetTiles = useCallback((target: Target) => {
|
||||||
const { preview, show } = target
|
const { preview, show } = target
|
||||||
const result = targetList(target).map(({ x, y, type, edges }) => {
|
const result = targetList(target).map(({ x, y, type, edges }) => {
|
||||||
return {
|
return {
|
||||||
|
@ -81,53 +80,53 @@ function useGameEvent(count: number) {
|
||||||
})
|
})
|
||||||
// .filter(({ isborder }) => !isborder)
|
// .filter(({ isborder }) => !isborder)
|
||||||
return result
|
return result
|
||||||
}, [count, hits, isSet, targetList])
|
}, [hits, isSet, targetList])
|
||||||
|
|
||||||
// if (!targetPreviewPos.shouldShow)
|
// if (!targetPreviewPos.shouldShow)
|
||||||
// return
|
// return
|
||||||
|
|
||||||
// handle visibility and position change of targetPreview
|
// handle visibility and position change of targetPreview
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const { show, x, y } = targetPreview;
|
const { show, x, y } = targetPreview
|
||||||
// if mouse has moved too quickly and last event was entering and leaving the same field, it must have gone outside the grid
|
// if mouse has moved too quickly and last event was entering and leaving the same field, it must have gone outside the grid
|
||||||
const hasLeft = x === lastLeftTile.x && y === lastLeftTile.y
|
const hasLeft = x === lastLeftTile.x && y === lastLeftTile.y
|
||||||
const isSet = x === target.x && y === target.y && target.show
|
const isSet = x === target.x && y === target.y && target.show
|
||||||
|
|
||||||
if (show && !appearOK)
|
if (show && !appearOK)
|
||||||
setTargetPreview(e => ({ ...e, show: false }));
|
setTargetPreview(e => ({ ...e, show: false }))
|
||||||
if (!show && targetPreviewPos.shouldShow && eventReady && appearOK && !isHit(hits, x, y).length && !isSet && !hasLeft)
|
if (!show && mouseCursor.shouldShow && eventReady && appearOK && !isHit(hits, x, y).length && !isSet && !hasLeft)
|
||||||
setTargetPreview(e => ({ ...e, show: true }));
|
setTargetPreview(e => ({ ...e, show: true }))
|
||||||
}, [targetPreview, targetPreviewPos.shouldShow, hits, eventReady, appearOK, lastLeftTile, target])
|
}, [targetPreview, mouseCursor.shouldShow, hits, eventReady, appearOK, lastLeftTile, target])
|
||||||
|
|
||||||
// enable targetPreview event again after 200 mil. sec.
|
// enable targetPreview event again after 200 ms.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setEventReady(false);
|
setEventReady(false)
|
||||||
if (targetPreview.show || !appearOK)
|
if (targetPreview.show || !appearOK)
|
||||||
return;
|
return
|
||||||
const autoTimeout = setTimeout(() => {
|
const autoTimeout = setTimeout(() => {
|
||||||
setTargetPreview(e => ({ ...e, x: targetPreviewPos.x, y: targetPreviewPos.y }));
|
setTargetPreview(e => ({ ...e, x: mouseCursor.x, y: mouseCursor.y }))
|
||||||
setEventReady(true);
|
setEventReady(true)
|
||||||
setAppearOK(true);
|
setAppearOK(true)
|
||||||
}, 300);
|
}, 300)
|
||||||
|
|
||||||
// or abort if state has changed early
|
// or abort if state has changed early
|
||||||
return () => {
|
return () => {
|
||||||
clearTimeout(autoTimeout);
|
clearTimeout(autoTimeout)
|
||||||
}
|
}
|
||||||
}, [appearOK, targetPreview.show, targetPreviewPos.x, targetPreviewPos.y]);
|
}, [appearOK, targetPreview.show, mouseCursor.x, mouseCursor.y])
|
||||||
|
|
||||||
// approve targetPreview new position after 200 mil. sec.
|
// approve targetPreview new position after 200 mil. sec.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// early return to start cooldown only when about to show up
|
// early return to start cooldown only when about to show up
|
||||||
const autoTimeout = setTimeout(() => {
|
const autoTimeout = setTimeout(() => {
|
||||||
setAppearOK(!targetPreview.show)
|
setAppearOK(!targetPreview.show)
|
||||||
}, targetPreview.show ? 500 : 300);
|
}, targetPreview.show ? 500 : 300)
|
||||||
|
|
||||||
// or abort if movement is repeated early
|
// or abort if movement is repeated early
|
||||||
return () => {
|
return () => {
|
||||||
clearTimeout(autoTimeout);
|
clearTimeout(autoTimeout)
|
||||||
}
|
}
|
||||||
}, [targetPreview.show]);
|
}, [targetPreview.show])
|
||||||
|
|
||||||
const targets = useMemo(() => [
|
const targets = useMemo(() => [
|
||||||
...composeTargetTiles(target).map((props, i) => <GamefieldPointer key={'t' + i} props={props} />),
|
...composeTargetTiles(target).map((props, i) => <GamefieldPointer key={'t' + i} props={props} />),
|
||||||
|
@ -135,17 +134,23 @@ function useGameEvent(count: number) {
|
||||||
], [composeTargetTiles, target, targetPreview])
|
], [composeTargetTiles, target, targetPreview])
|
||||||
|
|
||||||
const eventBar = useMemo(() => {
|
const eventBar = useMemo(() => {
|
||||||
const items: ItemsType[] = [
|
const items: Items[] = [
|
||||||
{ icon: 'burger-menu', text: 'Menu' },
|
{ icon: 'burger-menu', text: 'Menu' },
|
||||||
{ icon: 'radar', text: 'Radar scan', mode: 0, amount: 1 },
|
{ icon: 'radar', text: 'Radar scan', mode: 0, amount: 1 },
|
||||||
{ icon: 'missle', text: 'Fire torpedo', mode: 1, amount: 1 },
|
{ icon: 'torpedo', text: 'Fire torpedo', mode: 1, amount: 1 },
|
||||||
{ icon: 'scope', text: 'Fire missle', mode: 2 },
|
{ icon: 'scope', text: 'Fire missile', mode: 2 },
|
||||||
{ icon: 'gear', text: 'Settings' }
|
{ icon: 'gear', text: 'Settings' }
|
||||||
]
|
]
|
||||||
return (
|
return (
|
||||||
<div className='event-bar'>
|
<div className='event-bar'>
|
||||||
{items.map((e, i) => (
|
{items.map((e, i) => (
|
||||||
<Item key={i} props={{ ...e, callback: () => { e.mode !== undefined ? setMode(e.mode) : {}; setTarget(e => ({ ...e, show: false })) } }} />
|
<Item key={i} props={{
|
||||||
|
...e, callback: () => {
|
||||||
|
if (e.mode !== undefined)
|
||||||
|
setMode(e.mode)
|
||||||
|
setTarget(e => ({ ...e, show: false }))
|
||||||
|
}
|
||||||
|
}} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -155,7 +160,7 @@ function useGameEvent(count: number) {
|
||||||
eventBar,
|
eventBar,
|
||||||
setLastLeftTile,
|
setLastLeftTile,
|
||||||
settingTarget,
|
settingTarget,
|
||||||
setTargetPreviewPos,
|
setMouseCursor,
|
||||||
hits
|
hits
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,59 +1,63 @@
|
||||||
import { HitType, HitDispatchType } from "./interfaces";
|
import { Hit, HitDispatch } from "./interfaces"
|
||||||
|
|
||||||
export const borderCN = (count: number, x: number, y: number) => {
|
export function borderCN(count: number, x: number, y: number) {
|
||||||
if (x === 0)
|
if (x === 0)
|
||||||
return 'left';
|
return 'left'
|
||||||
if (y === 0)
|
if (y === 0)
|
||||||
return 'top';
|
return 'top'
|
||||||
if (x === count+1)
|
if (x === count + 1)
|
||||||
return 'right';
|
return 'right'
|
||||||
if (y === count+1)
|
if (y === count + 1)
|
||||||
return 'bottom';
|
return 'bottom'
|
||||||
return '';
|
return ''
|
||||||
};
|
}
|
||||||
export const cornerCN = (count: number, x: number, y: number) => {
|
export function cornerCN(count: number, x: number, y: number) {
|
||||||
if (x === 0 && y === 0)
|
if (x === 0 && y === 0)
|
||||||
return 'left-top-corner';
|
return 'left-top-corner'
|
||||||
if (x === count+1 && y === 0)
|
if (x === count + 1 && y === 0)
|
||||||
return 'right-top-corner';
|
return 'right-top-corner'
|
||||||
if (x === 0 && y === count+1)
|
if (x === 0 && y === count + 1)
|
||||||
return 'left-bottom-corner';
|
return 'left-bottom-corner'
|
||||||
if (x === count+1 && y === count+1)
|
if (x === count + 1 && y === count + 1)
|
||||||
return 'right-bottom-corner';
|
return 'right-bottom-corner'
|
||||||
return '';
|
return ''
|
||||||
};
|
}
|
||||||
export const fieldIndex = (count: number, x: number, y: number) => y*(count+2)+x;
|
export function fieldIndex(count: number, x: number, y: number) {
|
||||||
export const hitReducer = (formObject: HitType[], action: HitDispatchType) => {
|
return y * (count + 2) + x
|
||||||
|
}
|
||||||
|
export function hitReducer(formObject: Hit[], action: HitDispatch) {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
|
|
||||||
case 'fireMissle': {
|
case 'fireMissile': {
|
||||||
const result = [...formObject, action.payload];
|
const result = [...formObject, action.payload]
|
||||||
return result;
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return formObject;
|
return formObject
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export const initlialLastLeftTile = {
|
export const initlialLastLeftTile = {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0
|
y: 0
|
||||||
};
|
}
|
||||||
export const initlialTarget = {
|
export const initlialTarget = {
|
||||||
preview: false,
|
preview: false,
|
||||||
show: false,
|
show: false,
|
||||||
x: 2,
|
x: 2,
|
||||||
y: 2
|
y: 2
|
||||||
};
|
}
|
||||||
export const initlialTargetPreview = {
|
export const initlialTargetPreview = {
|
||||||
preview: true,
|
preview: true,
|
||||||
show: false,
|
show: false,
|
||||||
x: 2,
|
x: 2,
|
||||||
y: 2
|
y: 2
|
||||||
};
|
}
|
||||||
export const initlialTargetPreviewPos = {
|
export const initlialMouseCursor = {
|
||||||
shouldShow: false,
|
shouldShow: false,
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0
|
y: 0
|
||||||
};
|
}
|
||||||
export const isHit = (hits: HitType[], x: number, y: number) => hits.filter(h => h.x === x && h.y === y);
|
export function isHit(hits: Hit[], x: number, y: number) {
|
||||||
|
return hits.filter(h => h.x === x && h.y === y)
|
||||||
|
}
|
||||||
|
|
|
@ -1,61 +1,50 @@
|
||||||
export type LastLeftTileType = {
|
export interface Position {
|
||||||
x: number,
|
x: number,
|
||||||
y: number
|
y: number
|
||||||
}
|
}
|
||||||
export type TargetType = {
|
export interface Target extends Position {
|
||||||
preview: boolean,
|
preview: boolean,
|
||||||
show: boolean,
|
show: boolean
|
||||||
x: number,
|
|
||||||
y: number
|
|
||||||
};
|
|
||||||
export type TargetPreviewPosType = {
|
|
||||||
shouldShow: boolean,
|
|
||||||
x: number,
|
|
||||||
y: number
|
|
||||||
}
|
}
|
||||||
export type TargetListType = {
|
export interface MouseCursor extends Position {
|
||||||
x: number,
|
shouldShow: boolean
|
||||||
y: number,
|
}
|
||||||
|
export interface TargetList extends Position {
|
||||||
type: string,
|
type: string,
|
||||||
edges: string[]
|
edges: string[]
|
||||||
}
|
}
|
||||||
export type ModeType = {
|
export interface Mode {
|
||||||
pointerGrid: any[][],
|
pointerGrid: any[][],
|
||||||
type: string
|
type: string
|
||||||
}
|
}
|
||||||
export type ItemsType = {
|
export interface Items {
|
||||||
icon: string,
|
icon: string,
|
||||||
text: string,
|
text: string,
|
||||||
mode?: number,
|
mode?: number,
|
||||||
amount?: number,
|
amount?: number,
|
||||||
}
|
}
|
||||||
export type FieldType = {
|
export interface Field extends Position {
|
||||||
field: string,
|
field: string
|
||||||
x: number,
|
}
|
||||||
y: number,
|
export interface Hit extends Position {
|
||||||
};
|
hit: boolean
|
||||||
export type HitType = {
|
}
|
||||||
hit: boolean,
|
|
||||||
x: number,
|
|
||||||
y: number,
|
|
||||||
};
|
|
||||||
|
|
||||||
type fireMissle = {
|
interface fireMissile {
|
||||||
type: 'fireMissle',
|
type: 'fireMissile',
|
||||||
payload: {
|
payload: {
|
||||||
x: number,
|
x: number,
|
||||||
y: number,
|
y: number,
|
||||||
hit: boolean
|
hit: boolean
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
type removeMissle = {
|
interface removeMissile {
|
||||||
type:
|
type: 'removeMissile',
|
||||||
'removeMissle',
|
|
||||||
payload: {
|
payload: {
|
||||||
x: number,
|
x: number,
|
||||||
y: number,
|
y: number,
|
||||||
hit: boolean
|
hit: boolean
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
export type HitDispatchType = fireMissle | removeMissle;
|
export type HitDispatch = fireMissile | removeMissile
|
||||||
|
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
Loading…
Add table
Add a link
Reference in a new issue