New functional features and fog images

This commit is contained in:
aronmal 2022-08-10 23:25:34 +02:00
parent 2a8f25a6e6
commit febb6b1607
Signed by: aronmal
GPG key ID: 816B7707426FC612
6 changed files with 221 additions and 68 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 659 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 631 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View file

@ -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 { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { CSSProperties } from 'react'; import { CSSProperties, useState } from 'react';
import './App.scss'; import './styles/App.scss';
function App() { 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: { let elems2: {
field: string, field: string,
x: number, x: number,
y: number, y: number,
}[] = []; }[] = [];
let elems: { let hitElems: {
field: string, field: string,
x: number, x: number,
y: number, y: number,
}[] = [], }[] = [],
count = 12; 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++) { 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++) { 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 ( return (
<div className="App"> <div className="App">
<header className="App-header"> <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,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"> <div id="game-frame">
{ borders } {/* Bordes */}
{ borderTiles }
{/* Collumn lettes and row numbers */}
{elems2.map((obj, i) => {elems2.map((obj, i) =>
<span key={i} className={`${obj.field} r1`} style={{'--x': obj.x, '--y': obj.y} as CSSProperties}>{obj.field}</span> <span key={i} className={`${obj.field} r1`} style={{'--x': obj.x, '--y': obj.y} as CSSProperties}>{obj.field}</span>
)} )}
{/* <div id='game'> */} { hitSVGs }
{elems.map((obj, i) =>
<div key={i} className={`${obj.field} svg-r1`} style={{'--x': obj.x, '--y': obj.y} as CSSProperties}> {/* Ships */}
<FontAwesomeIcon key={i} className={`${obj.field} r1`} icon={faXmark} /> {/* { shipElems } */}
</div>)}
{[1,2,3,4,5,6].map((num, i) => {/* Fog images */}
<div key={i} id='test-ship' className={`s${num}`} style={{'--i': i+3} as CSSProperties}> {/* <img className='fog-left' src={`/fog/fog2.png`} alt={`fog1.png`} />
<img src={`/svgs/${num}.svg`} alt={`${num}.svg`}/> <img className='fog-right' src={`/fog/fog2.png`} alt={`fog1.png`} />
</div>)} <img className='fog-middle' src={`/fog/fog4.png`} alt={`fog4.png`} /> */}
{/* <div id='test-ship' className='s2'> <div className={`hit-svg target ${target.event ? 'show' : ''}`} style={{'--x': target.x+1, '--y': target.y+1} as CSSProperties}>
<img src={`/svgs/${3}.svg`} alt={`${3}.svg`} /> <FontAwesomeIcon icon={faCrosshairs} />
</div> */} </div>
{/* </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> </div>
<p> <p>
Edit <code>src/App.tsx</code> and save to reload. Edit <code>src/App.tsx</code> and save to reload.

View file

@ -1,3 +1,7 @@
@use './mixins/display' as *;
@use './mixins/effects' as *;
@import './mixins/variables';
.App { .App {
text-align: center; text-align: center;
} }
@ -14,10 +18,9 @@
} }
.App-header { .App-header {
background-color: #282c34; background-color: $theme;
min-height: 100vh; min-height: 100vh;
display: flex; @include flex-col;
flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-size: calc(10px + 2vmin); font-size: calc(10px + 2vmin);
@ -38,61 +41,81 @@
} }
#game-frame { #game-frame {
border: 1px solid orange; // border: 1px solid orange;
// position: relative; // position: relative;
height: 900px; height: 945px;
width: 900px; width: 945px;
display: grid; display: grid;
align-items: center; align-items: center;
justify-items: center; justify-items: center;
grid-template-rows: .5fr repeat(12, 1fr) .5fr; grid-template-rows: .75fr repeat(12, 1fr) .75fr;
grid-template-columns: .5fr repeat(12, 1fr) .5fr; grid-template-columns: .75fr repeat(12, 1fr) .75fr;
// grid-gap: 1px solid blue; // grid-gap: 1px solid blue;
> .r1 { > .r1 {
grid-column: var(--x); grid-column: var(--x);
grid-row: var(--y); grid-row: var(--y);
} }
> .border { > .border-tile {
box-sizing: border-box; box-sizing: border-box;
border: 1px solid blue; border: 1px solid blue;
height: 100%; height: 100%;
width: 100%; width: 100%;
grid-column: var(--x); grid-column: var(--x);
grid-row: var(--y); 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) { > :not(.border) {
box-sizing: border-box; box-sizing: border-box;
border: 1px solid red; // border: 1px solid red;
} }
> span { > span {
vertical-align: center; vertical-align: center;
user-select: none;
} }
// }
// #game { .ship {
// 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 {
height: 100%; height: 100%;
width: 100%; width: 100%;
position: relative; position: relative;
display: flex; @include flex-col;
flex-direction: column;
align-items: center; align-items: center;
// justify-content: center; // justify-content: center;
border: 1px solid yellow; border: 1px solid yellow;
@ -129,7 +152,7 @@
} }
} }
.svg-r1 { .hit-svg {
// border: 2px solid blue; // border: 2px solid blue;
// height: 50px; // height: 50px;
@ -137,13 +160,13 @@
height: 100%; height: 100%;
width: 100%; width: 100%;
position: relative; position: relative;
display: flex; @include flex;
// flex-direction: column;
// align-items: center; // align-items: center;
// align-self: center; // align-self: center;
// justify-self: center; // justify-self: center;
grid-column: var(--x); grid-column: var(--x);
grid-row: var(--y); grid-row: var(--y);
pointer-events: none;
svg { svg {
position: absolute; position: absolute;
@ -152,6 +175,28 @@
box-sizing: border-box; box-sizing: border-box;
padding: 25%; 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 { .r2 {
@ -160,4 +205,21 @@
.r3 { .r3 {
border: 2px solid yellowgreen; 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;
}
} }