New functional features and fog images
This commit is contained in:
parent
2a8f25a6e6
commit
febb6b1607
6 changed files with 221 additions and 68 deletions
BIN
frontend/public/fog/fog1.png
Normal file
BIN
frontend/public/fog/fog1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 659 KiB |
BIN
frontend/public/fog/fog2.png
Normal file
BIN
frontend/public/fog/fog2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 199 KiB |
BIN
frontend/public/fog/fog3.png
Normal file
BIN
frontend/public/fog/fog3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 631 KiB |
BIN
frontend/public/fog/fog4.png
Normal file
BIN
frontend/public/fog/fog4.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 35 KiB |
|
@ -1,60 +1,151 @@
|
|||
import { faXmark } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faBurst, faCrosshairs, faXmark } from '@fortawesome/free-solid-svg-icons';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { CSSProperties } from 'react';
|
||||
import './App.scss';
|
||||
import { CSSProperties, useState } from 'react';
|
||||
import './styles/App.scss';
|
||||
|
||||
function App() {
|
||||
|
||||
let borders: JSX.Element[] = [];
|
||||
const [target, setTarget] = useState({
|
||||
event: false,
|
||||
x: 0,
|
||||
y: 0
|
||||
})
|
||||
const [targetPreview, setTargetPreview] = useState({
|
||||
event: false,
|
||||
x: 0,
|
||||
y: 0,
|
||||
style: {
|
||||
height: 0,
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: 0
|
||||
}
|
||||
})
|
||||
|
||||
let borderTiles: JSX.Element[] = [];
|
||||
let shipElems: JSX.Element[] = [];
|
||||
let elems2: {
|
||||
field: string,
|
||||
x: number,
|
||||
y: number,
|
||||
}[] = [];
|
||||
let elems: {
|
||||
let hitElems: {
|
||||
field: string,
|
||||
x: number,
|
||||
y: number,
|
||||
}[] = [],
|
||||
count = 12;
|
||||
for (let x = 0; x < count; x++) {
|
||||
elems2.push(...[
|
||||
{ field: String.fromCharCode(65+x), x: x+2, y: 1 },
|
||||
{ field: (x+1).toString(), x: 1, y: x+2 },
|
||||
{ field: String.fromCharCode(65+x), x: x+2, y: count+2 },
|
||||
{ field: (x+1).toString(), x: count+2, y: x+2 }
|
||||
])
|
||||
for (let y = 0; y < count; y++) {
|
||||
elems.push({ field: String.fromCharCode(65+x)+(y), x: x+2, y: y+2 })
|
||||
elems2.push(...[
|
||||
// Up
|
||||
{ field: String.fromCharCode(65+y), x: y+2, y: 1 },
|
||||
// Left
|
||||
{ field: (y+1).toString(), x: 1, y: y+2 },
|
||||
// Bottom
|
||||
{ field: String.fromCharCode(65+y), x: y+2, y: count+2 },
|
||||
// Right
|
||||
{ field: (y+1).toString(), x: count+2, y: y+2 }
|
||||
]);
|
||||
for (let x = 0; x < count; x++) {
|
||||
hitElems.push({ field: String.fromCharCode(65+x)+(y), x: x+2, y: y+2 })
|
||||
}
|
||||
}
|
||||
for (let x = 0; x < count+2; x++) {
|
||||
const hitSVGs = hitElems.map((obj, i) =>
|
||||
<div key={i} className='hit-svg' style={{'--x': obj.x, '--y': obj.y} as CSSProperties}>
|
||||
<FontAwesomeIcon icon={faBurst} />
|
||||
</div>);
|
||||
for (let y = 0; y < count+2; y++) {
|
||||
borders.push(<div className='border' style={{'--x': (x + 1), '--y': (y + 1)} as CSSProperties}></div>)
|
||||
for (let x = 0; x < count+2; x++) {
|
||||
const corner = [
|
||||
x === 0 && y === 0 ? 'left-top-corner' : '',
|
||||
x === count+1 && y === 0 ? 'right-top-corner' : '',
|
||||
x === 0 && y === count+1 ? 'left-bottom-corner' : '',
|
||||
x === count+1 && y === count+1 ? 'right-bottom-corner' : ''
|
||||
].filter(s => s);
|
||||
const border = [
|
||||
x === 0 ? 'left' : '',
|
||||
y === 0 ? 'top' : '',
|
||||
x === count+1 ? 'right' : '',
|
||||
y === count+1 ? 'bottom' : ''
|
||||
].filter(s => s);
|
||||
const borderType = corner.length ? corner[0] : border[0];
|
||||
const action = x > 0 && x < count+1 && y > 0 && y < count+1;
|
||||
const classNames = [
|
||||
'border-tile',
|
||||
borderType ? `edge ${borderType}` : '',
|
||||
action ? 'action' : ''
|
||||
].join(' ')
|
||||
borderTiles.push(
|
||||
<div
|
||||
key={y*(count+2)+x}
|
||||
className={classNames}
|
||||
style={{'--x': (x + 1), '--y': (y + 1)} as CSSProperties}
|
||||
onClick={action ? () => setTarget({ event: true, x, y }) : () => {}}
|
||||
onMouseEnter={e => {
|
||||
const target = e.target as HTMLDivElement
|
||||
if (action) {
|
||||
setTargetPreview({
|
||||
event: true,
|
||||
x,
|
||||
y,
|
||||
style: {
|
||||
height: target.offsetHeight,
|
||||
left: target.offsetLeft,
|
||||
top: target.offsetTop,
|
||||
width: target.offsetWidth,
|
||||
}
|
||||
})
|
||||
} else {
|
||||
setTargetPreview(e => Object.assign({...e}, {
|
||||
style: {
|
||||
height: target.offsetHeight,
|
||||
left: target.offsetLeft,
|
||||
top: target.offsetTop,
|
||||
width: target.offsetWidth,
|
||||
}
|
||||
}))
|
||||
}
|
||||
}}
|
||||
onMouseLeave={action ? () => setTargetPreview(e => Object.assign({...e}, {event: false})) : () => {}}
|
||||
></div>)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (let i = 1; i <= 6; i++) {
|
||||
shipElems.push(
|
||||
<div key={i} className={`ship s${i}`} style={{'--i': i+3} as CSSProperties}>
|
||||
<img src={`/svgs/${i}.svg`} alt={`${i}.svg`}/>
|
||||
</div>);
|
||||
}
|
||||
return (
|
||||
<div className="App">
|
||||
<header className="App-header">
|
||||
{[1,2,3,4,5,6,11,12,13,14].map((num, i) => <img key={i} src={`/svgs/${num}.svg`} alt={`${num}.svg`} />)}
|
||||
{[1,2,3,4].map((num, i) => <img key={i} src={`/fog/fog${num}.png`} alt={`fog${num}.png`} />)}
|
||||
<div id="game-frame">
|
||||
{ borders }
|
||||
{/* Bordes */}
|
||||
{ borderTiles }
|
||||
|
||||
{/* Collumn lettes and row numbers */}
|
||||
{elems2.map((obj, i) =>
|
||||
<span key={i} className={`${obj.field} r1`} style={{'--x': obj.x, '--y': obj.y} as CSSProperties}>{obj.field}</span>
|
||||
)}
|
||||
{/* <div id='game'> */}
|
||||
{elems.map((obj, i) =>
|
||||
<div key={i} className={`${obj.field} svg-r1`} style={{'--x': obj.x, '--y': obj.y} as CSSProperties}>
|
||||
<FontAwesomeIcon key={i} className={`${obj.field} r1`} icon={faXmark} />
|
||||
</div>)}
|
||||
{[1,2,3,4,5,6].map((num, i) =>
|
||||
<div key={i} id='test-ship' className={`s${num}`} style={{'--i': i+3} as CSSProperties}>
|
||||
<img src={`/svgs/${num}.svg`} alt={`${num}.svg`}/>
|
||||
</div>)}
|
||||
{/* <div id='test-ship' className='s2'>
|
||||
<img src={`/svgs/${3}.svg`} alt={`${3}.svg`} />
|
||||
</div> */}
|
||||
{/* </div> */}
|
||||
{ hitSVGs }
|
||||
|
||||
{/* Ships */}
|
||||
{/* { shipElems } */}
|
||||
|
||||
{/* Fog images */}
|
||||
{/* <img className='fog-left' src={`/fog/fog2.png`} alt={`fog1.png`} />
|
||||
<img className='fog-right' src={`/fog/fog2.png`} alt={`fog1.png`} />
|
||||
<img className='fog-middle' src={`/fog/fog4.png`} alt={`fog4.png`} /> */}
|
||||
<div className={`hit-svg target ${target.event ? 'show' : ''}`} style={{'--x': target.x+1, '--y': target.y+1} as CSSProperties}>
|
||||
<FontAwesomeIcon icon={faCrosshairs} />
|
||||
</div>
|
||||
<div className={`hit-svg target-preview ${targetPreview.event && (target.x !== targetPreview.x || target.y !== targetPreview.y) ? 'show' : ''}`} style={targetPreview.style}>
|
||||
<FontAwesomeIcon icon={faCrosshairs} />
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
Edit <code>src/App.tsx</code> and save to reload.
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
@use './mixins/display' as *;
|
||||
@use './mixins/effects' as *;
|
||||
@import './mixins/variables';
|
||||
|
||||
.App {
|
||||
text-align: center;
|
||||
}
|
||||
|
@ -14,10 +18,9 @@
|
|||
}
|
||||
|
||||
.App-header {
|
||||
background-color: #282c34;
|
||||
background-color: $theme;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@include flex-col;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: calc(10px + 2vmin);
|
||||
|
@ -38,61 +41,81 @@
|
|||
}
|
||||
|
||||
#game-frame {
|
||||
border: 1px solid orange;
|
||||
// border: 1px solid orange;
|
||||
// position: relative;
|
||||
height: 900px;
|
||||
width: 900px;
|
||||
height: 945px;
|
||||
width: 945px;
|
||||
display: grid;
|
||||
align-items: center;
|
||||
justify-items: center;
|
||||
grid-template-rows: .5fr repeat(12, 1fr) .5fr;
|
||||
grid-template-columns: .5fr repeat(12, 1fr) .5fr;
|
||||
grid-template-rows: .75fr repeat(12, 1fr) .75fr;
|
||||
grid-template-columns: .75fr repeat(12, 1fr) .75fr;
|
||||
// grid-gap: 1px solid blue;
|
||||
|
||||
> .r1 {
|
||||
grid-column: var(--x);
|
||||
grid-row: var(--y);
|
||||
}
|
||||
> .border {
|
||||
> .border-tile {
|
||||
box-sizing: border-box;
|
||||
border: 1px solid blue;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
grid-column: var(--x);
|
||||
grid-row: var(--y);
|
||||
|
||||
&.edge {
|
||||
border: 1px solid gray;
|
||||
}
|
||||
|
||||
&.left-top-corner {
|
||||
-webkit-mask-image: -webkit-gradient(linear, right bottom,
|
||||
left top, color-stop(0, rgba(0,0,0,1)), color-stop(0.5, rgba(0,0,0,0)));
|
||||
}
|
||||
&.right-top-corner {
|
||||
-webkit-mask-image: -webkit-gradient(linear, left bottom,
|
||||
right top, color-stop(0, rgba(0,0,0,1)), color-stop(0.5, rgba(0,0,0,0)));
|
||||
}
|
||||
&.left-bottom-corner {
|
||||
-webkit-mask-image: -webkit-gradient(linear, right top,
|
||||
left bottom, color-stop(0, rgba(0,0,0,1)), color-stop(0.5, rgba(0,0,0,0)));
|
||||
}
|
||||
&.right-bottom-corner {
|
||||
-webkit-mask-image: -webkit-gradient(linear, left top,
|
||||
right bottom, color-stop(0, rgba(0,0,0,1)), color-stop(0.5, rgba(0,0,0,0)));
|
||||
}
|
||||
|
||||
&.left {
|
||||
-webkit-mask-image: -webkit-gradient(linear, right top,
|
||||
left top, from(rgba(0,0,0,1)), to(rgba(0,0,0,0)));
|
||||
}
|
||||
&.right {
|
||||
-webkit-mask-image: -webkit-gradient(linear, left top,
|
||||
right top, from(rgba(0,0,0,1)), to(rgba(0,0,0,0)));
|
||||
}
|
||||
&.top {
|
||||
-webkit-mask-image: -webkit-gradient(linear, left bottom,
|
||||
left top, from(rgba(0,0,0,1)), to(rgba(0,0,0,0)));
|
||||
}
|
||||
&.bottom {
|
||||
-webkit-mask-image: -webkit-gradient(linear, left top,
|
||||
left bottom, from(rgba(0,0,0,1)), to(rgba(0,0,0,0)));
|
||||
}
|
||||
}
|
||||
> :not(.border) {
|
||||
box-sizing: border-box;
|
||||
border: 1px solid red;
|
||||
// border: 1px solid red;
|
||||
}
|
||||
> span {
|
||||
vertical-align: center;
|
||||
user-select: none;
|
||||
}
|
||||
// }
|
||||
|
||||
// #game {
|
||||
// grid-area: 2 / 2 / -2 / -2;
|
||||
// border: 5px solid orange;
|
||||
// // position: relative;
|
||||
// display: grid;
|
||||
// // grid-gap: 1px solid blue;
|
||||
|
||||
// .missle {
|
||||
// height: 50px;
|
||||
// width: 50px;
|
||||
// position: absolute;
|
||||
// border: 1px solid red;
|
||||
// top: calc(50px + 100px * var(--y));
|
||||
// left: calc(50px + 100px* var(--x));
|
||||
// transform: translateX(-50%) translateY(-50%);
|
||||
// }
|
||||
|
||||
#test-ship {
|
||||
.ship {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@include flex-col;
|
||||
align-items: center;
|
||||
// justify-content: center;
|
||||
border: 1px solid yellow;
|
||||
|
@ -129,7 +152,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.svg-r1 {
|
||||
.hit-svg {
|
||||
// border: 2px solid blue;
|
||||
|
||||
// height: 50px;
|
||||
|
@ -137,13 +160,13 @@
|
|||
height: 100%;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
display: flex;
|
||||
// flex-direction: column;
|
||||
@include flex;
|
||||
// align-items: center;
|
||||
// align-self: center;
|
||||
// justify-self: center;
|
||||
grid-column: var(--x);
|
||||
grid-row: var(--y);
|
||||
pointer-events: none;
|
||||
|
||||
svg {
|
||||
position: absolute;
|
||||
|
@ -152,6 +175,28 @@
|
|||
|
||||
box-sizing: border-box;
|
||||
padding: 25%;
|
||||
|
||||
&.fa-burst {
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
&.target {
|
||||
color: red;
|
||||
opacity: 0;
|
||||
|
||||
&.show {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
&.target-preview {
|
||||
color: orange;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
@include transition(.2s);
|
||||
|
||||
&.show {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
.r2 {
|
||||
|
@ -160,4 +205,21 @@
|
|||
.r3 {
|
||||
border: 2px solid yellowgreen;
|
||||
}
|
||||
|
||||
.fog-left {
|
||||
grid-area: 1 / 1 / -1 / -1;
|
||||
align-self: flex-start;
|
||||
width: inherit;
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
.fog-right {
|
||||
grid-area: 1 / 1 / -1 / -1;
|
||||
align-self: flex-end;
|
||||
width: inherit;
|
||||
}
|
||||
.fog-middle {
|
||||
grid-area: 4 / 4 / -4 / -4;
|
||||
// align-self: flex-end;
|
||||
width: inherit;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue