Compare commits
41 Commits
df62a40c2a
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 051fc223e9 | |||
| 9feaa3c098 | |||
| 3175e7b7ad | |||
| 4281bf1735 | |||
| ff37cb7823 | |||
| 2a8df78d22 | |||
| 344575bdc4 | |||
| 2453b2f6b6 | |||
| 25a98bf42d | |||
| 022512a5e6 | |||
| d56af40362 | |||
| f33723a786 | |||
| df95139650 | |||
| d3b527570c | |||
| a1722a700d | |||
| 6cc8a9e645 | |||
| 9023252822 | |||
| 9bf3c0de0c | |||
| 09f4785ef4 | |||
| bf9554d917 | |||
| c33d80facb | |||
| 9282f94956 | |||
| fda289dc9c | |||
| b6e58b41aa | |||
| bd5c7dad3b | |||
| 7faae294dc | |||
| 3b59534f90 | |||
| ec08747066 | |||
| db8a9a3f74 | |||
| 0ac36444c4 | |||
| 5d451db8f9 | |||
| ab023ec982 | |||
| d75696fbc3 | |||
| f97b5f0cf9 | |||
| ffefb77f3f | |||
| 21929261e4 | |||
| 58389623cc | |||
| 04f6eaf5dc | |||
| d56a8a6b06 | |||
| e1992f4c1e | |||
| 27d7a0689d |
5
README.md
Normal file
5
README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# Quatuor
|
||||
|
||||
Falling blocks
|
||||
|
||||

|
||||
276
css/binaural.css
Normal file
276
css/binaural.css
Normal file
@ -0,0 +1,276 @@
|
||||
body {
|
||||
background-image: url(binaural/bg.jpg),
|
||||
radial-gradient(
|
||||
circle at center,
|
||||
#39444f 0%,
|
||||
#2c323b 25%,
|
||||
#293036 28%,
|
||||
#252b32 34%,
|
||||
#242930 38%,
|
||||
#1a1d22 52%,
|
||||
#191c22 53%,
|
||||
#151519 63%,
|
||||
#141418 65%,
|
||||
#0f0f12 74%,
|
||||
#0a0c0d 100%
|
||||
);
|
||||
background-repeat: round;
|
||||
}
|
||||
|
||||
#sceneDiv {
|
||||
perspective: 500px;
|
||||
}
|
||||
|
||||
#sceneDiv * {
|
||||
transform-style: preserve-3d;
|
||||
}
|
||||
|
||||
#screenRow {
|
||||
display: block;
|
||||
transform: translateZ(var(--tZ)) rotateX(var(--rX)) rotateY(var(--rY));
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
#screenRow:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
#screenRow * {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#screenRow .col {
|
||||
display: inline-block !important;
|
||||
width: max-content;
|
||||
height: 100%;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: #36394180;
|
||||
}
|
||||
|
||||
#matrixCard {
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
#screenRow .card > * {
|
||||
transform: translateZ(var(--cell-side));
|
||||
}
|
||||
|
||||
#screenRow .card-header {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.minoes-table th,
|
||||
.minoes-table td {
|
||||
display: inline-block !important;
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
.minoes-table tr {
|
||||
width: max-content;
|
||||
height: var(--cell-side);
|
||||
}
|
||||
|
||||
#statsTable tr {
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#statsTable th,
|
||||
#statsTable td {
|
||||
display: table-cell;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
tr.matrix td:not(.mino) {
|
||||
border: 0;
|
||||
will-change: transform;
|
||||
transform: translateZ(0);
|
||||
}
|
||||
|
||||
.minoes-table td {
|
||||
width: var(--cell-side) !important;
|
||||
height: var(--cell-side);
|
||||
}
|
||||
|
||||
.minoes-table .mino {
|
||||
background: radial-gradient(circle at -150% -200%, #fffb 0%, var(--background-color) 100%);
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.mino::before,
|
||||
.mino::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
display: block;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
}
|
||||
|
||||
.mino::before {
|
||||
background: var(--light-color);
|
||||
transform: translateZ(calc(-1 * var(--cell-side))) rotateY(-90deg);
|
||||
transform-origin: left;
|
||||
}
|
||||
|
||||
.right .mino::before {
|
||||
background: var(--dark-color);
|
||||
transform: translateZ(calc(-1 * var(--cell-side))) rotateY(90deg);
|
||||
transform-origin: right;
|
||||
}
|
||||
|
||||
.mino::after {
|
||||
background: var(--light-color);
|
||||
transform: translateZ(calc(-1 * var(--cell-side))) rotateX(90deg);
|
||||
transform-origin: top;
|
||||
}
|
||||
|
||||
.bottom .mino::after {
|
||||
background: var(--dark-color);
|
||||
transform: translateZ(calc(-1 * var(--cell-side))) rotateX(-90deg);
|
||||
transform-origin: bottom;
|
||||
}
|
||||
|
||||
.I.mino {
|
||||
--background-color: #42afe1b0;
|
||||
--light-color: #6ceaff80;
|
||||
--dark-color: #00a4b0b0;
|
||||
}
|
||||
|
||||
.J.mino {
|
||||
--background-color: #1165b5b0;
|
||||
--light-color: #339bff80;
|
||||
--dark-color: #00009db0;
|
||||
}
|
||||
|
||||
.L.mino {
|
||||
--background-color: #f38927b0;
|
||||
--light-color: #ffba5980;
|
||||
--dark-color: #c54800b0;
|
||||
}
|
||||
|
||||
.O.mino {
|
||||
--background-color: #f6d03cb0;
|
||||
--light-color: #ffff7f80;
|
||||
--dark-color: #ca9501b0;
|
||||
}
|
||||
|
||||
.S.mino {
|
||||
--background-color: #51b84db0;
|
||||
--light-color: #84f88080;
|
||||
--dark-color: #1cbc02b0;
|
||||
}
|
||||
|
||||
.T.mino {
|
||||
--background-color: #9739a2b0;
|
||||
--light-color: #d958e980;
|
||||
--dark-color: #6e019ab0;
|
||||
}
|
||||
|
||||
.Z.mino {
|
||||
--background-color: #eb4f65b0;
|
||||
--light-color: #ff7f7980;
|
||||
--dark-color: #ad1936b0;
|
||||
}
|
||||
|
||||
.ghost.mino {
|
||||
--background-color: #8886;
|
||||
--light-color: #ccc6;
|
||||
--dark-color: #3336;
|
||||
}
|
||||
|
||||
.locking.mino {
|
||||
--background-color: #eeeb;
|
||||
--light-color: #fffb;
|
||||
--dark-color: #dddb;
|
||||
}
|
||||
|
||||
.disabled.mino {
|
||||
--background-color: #888b;
|
||||
--light-color: #cccb;
|
||||
--dark-color: #333b;
|
||||
}
|
||||
|
||||
@keyframes cleared-line-animation {
|
||||
from {
|
||||
background-color: #ceffff66;
|
||||
box-shadow: -200px 0 5px white, 200px 0 5px white;
|
||||
}
|
||||
to {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes show-level-animation {
|
||||
from {
|
||||
opacity: 1;
|
||||
transform: translateY(200%);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(0) scaleY(1);
|
||||
line-height: var(--bs-body-line-height);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(-100%) scaleY(0);
|
||||
line-height: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes zoom-in-animation {
|
||||
from {
|
||||
opacity: 1;
|
||||
transform: scale3d(0.3, 0.3, 0.3);
|
||||
line-height: var(--bs-body-line-height);
|
||||
}
|
||||
30% {
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
80% {
|
||||
transform: scale3d(1, 1, 1);
|
||||
line-height: var(--bs-body-line-height);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale3d(1.5, 0, 1);
|
||||
line-height: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes rotate-in-animation {
|
||||
0% {
|
||||
opacity: 1;
|
||||
transform: rotate(200deg);
|
||||
line-height: var(--bs-body-line-height);
|
||||
}
|
||||
30% {
|
||||
transform: translateZ(0);
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
80% {
|
||||
transform: scale3d(1, 1, 1);
|
||||
line-height: var(--bs-body-line-height);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale3d(1.5, 0, 1);
|
||||
line-height: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes game-over-animation {
|
||||
from {
|
||||
opacity: 1;
|
||||
transform: translateY(200%);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0) scaleY(1);
|
||||
line-height: var(--bs-body-line-height);
|
||||
}
|
||||
}
|
||||
BIN
css/binaural/bg.jpg
Normal file
BIN
css/binaural/bg.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 62 KiB |
@ -84,13 +84,15 @@
|
||||
|
||||
.ghost.mino {
|
||||
margin: 1px;
|
||||
background: rgba(0, 0, 0, 10%) !important;
|
||||
border: 3px solid #646464 !important;
|
||||
background: transparent !important;
|
||||
border: 2px solid var(--light-color) !important;
|
||||
box-shadow:
|
||||
-2px -2px 6px rgba(128, 128, 128, 25%),
|
||||
-2px 2px 6px rgba(128, 128, 128, 25%),
|
||||
2px -2px 6px rgba(128, 128, 128, 25%),
|
||||
2px 2px 6px rgba(128, 128, 128, 25%);
|
||||
-2px -2px 6px #FFF8,
|
||||
-2px 2px 6px #FFF8,
|
||||
2px -2px 6px #FFF8,
|
||||
2px 2px 6px #FFF8;
|
||||
opacity: 65%;
|
||||
|
||||
}
|
||||
|
||||
.moving.mino {
|
||||
@ -100,20 +102,25 @@
|
||||
.locking.mino {
|
||||
filter: saturate(50%) brightness(200%);
|
||||
box-shadow:
|
||||
-1px -1px 4px rgba(128, 128, 128, 25%),
|
||||
-1px 1px 4px rgba(128, 128, 128, 25%),
|
||||
1px -1px 4px rgba(128, 128, 128, 25%),
|
||||
1px 1px 4px rgba(128, 128, 128, 25%);
|
||||
-1px -1px 4px #FFF2,
|
||||
-1px 1px 4px #FFF2,
|
||||
1px -1px 4px #FFF2,
|
||||
1px 1px 4px #FFF2;
|
||||
}
|
||||
|
||||
.disabled.mino {
|
||||
filter: brightness(50%) contrast(80%);
|
||||
opacity: 70%;
|
||||
}
|
||||
|
||||
@keyframes locked-animation {
|
||||
from {
|
||||
filter: saturate(50%) brightness(400%);
|
||||
box-shadow:
|
||||
-1px -1px 4px rgba(255, 255, 255, 25%),
|
||||
-1px 1px 4px rgba(255, 255, 255, 25%),
|
||||
1px -1px 4px rgba(255, 255, 255, 25%),
|
||||
1px 1px 4px rgba(255, 255, 255, 25%);
|
||||
-1px -1px 4px #FFF2,
|
||||
-1px 1px 4px #FFF2,
|
||||
1px -1px 4px #FFF2,
|
||||
1px 1px 4px #FFF2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
:root {
|
||||
--cell-side: 24px;
|
||||
--rX: -15deg;
|
||||
--rY: 0;
|
||||
--tZ: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
@ -12,17 +15,17 @@ body {
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
background-color: rgba(33, 37, 41, 30%);
|
||||
background-color: #2125294d;
|
||||
backdrop-filter: blur(15px);
|
||||
}
|
||||
}
|
||||
|
||||
.card {
|
||||
background-color: rgb(37, 41, 45);
|
||||
background-color: #25292d;
|
||||
}
|
||||
|
||||
#matrixCard {
|
||||
background: radial-gradient(#222, rgb(37, 41, 45))
|
||||
background-image: radial-gradient(#222, #25292d)
|
||||
}
|
||||
|
||||
.card-header {
|
||||
@ -79,7 +82,7 @@ td {
|
||||
|
||||
@keyframes trail-animation {
|
||||
from {
|
||||
background-color: rgb(206, 255, 255, 25%);
|
||||
background-color: #ceffff40;
|
||||
filter: saturate(50%) brightness(300%);
|
||||
}
|
||||
to {
|
||||
@ -93,7 +96,7 @@ td.trail-animation {
|
||||
|
||||
@keyframes cleared-line-animation {
|
||||
from {
|
||||
background-color: rgb(206, 255, 255, 40%);
|
||||
background-color: #ceffff66;
|
||||
filter: saturate(50%) brightness(300%);
|
||||
box-shadow: -200px 0 5px white, 200px 0 5px white;
|
||||
}
|
||||
@ -124,8 +127,8 @@ tr.cleared-line-animation {
|
||||
top: 5%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 0);
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
text-shadow: 1px 1px rgba(0, 0, 0, 0.8);
|
||||
color: #fffc;
|
||||
text-shadow: 1px 1px #000c;
|
||||
font-size: 3vmin;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@ -15,7 +15,12 @@ body[data-bs-theme="dark"] {
|
||||
background-color: rgba(37, 41, 45, 40%);
|
||||
}
|
||||
|
||||
.mino:not(.ghost):not(.locking) {
|
||||
tr.matrix td:not(.mino) {
|
||||
border-left : none;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.mino:not(.ghost):not(.locking):not(.disabled) {
|
||||
padding: 1px;
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
@ -46,8 +51,8 @@ body[data-bs-theme="dark"] {
|
||||
}
|
||||
|
||||
.ghost.mino {
|
||||
background: transparent;
|
||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||
background: rgba(242, 255, 255, 10%);
|
||||
border : 2px solid rgba(255, 255, 255, 0.3);
|
||||
border-radius: 3px;
|
||||
box-shadow: 0px 0px 10px rgba(242, 255, 255, 75%);
|
||||
}
|
||||
@ -71,6 +76,15 @@ body[data-bs-theme="dark"] {
|
||||
box-shadow: 0px 0px 10px rgba(242, 255, 255, 100%);
|
||||
}
|
||||
|
||||
.disabled.mino {
|
||||
opacity: 60%;
|
||||
}
|
||||
|
||||
.disabled.mino:before {
|
||||
opacity: 50%;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
@keyframes locked-animation {
|
||||
from {
|
||||
opacity: 1;
|
||||
|
||||
@ -32,42 +32,42 @@ tr.matrix td:not(.mino) {
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
display: block;
|
||||
box-shadow: 0 -6px 0 var(--light-color);
|
||||
box-shadow: 0 -6px 0 var(--box-shadow-color);
|
||||
}
|
||||
|
||||
.I.mino {
|
||||
--background-color: #42AFE1;
|
||||
--light-color: #6CEAFF;
|
||||
--box-shadow-color: #6CEAFF;
|
||||
}
|
||||
|
||||
.J.mino {
|
||||
--background-color: #1165B5;
|
||||
--light-color: #339BFF;
|
||||
--box-shadow-color: #339BFF;
|
||||
}
|
||||
|
||||
.L.mino {
|
||||
--background-color: #F38927;
|
||||
--light-color: #FFBA59;
|
||||
--box-shadow-color: #FFBA59;
|
||||
}
|
||||
|
||||
.O.mino {
|
||||
--background-color: #F6D03C;
|
||||
--light-color: #FFFF7F;
|
||||
--box-shadow-color: #FFFF7F;
|
||||
}
|
||||
|
||||
.S.mino {
|
||||
--background-color: #51B84D;
|
||||
--light-color: #84F880;
|
||||
--box-shadow-color: #84F880;
|
||||
}
|
||||
|
||||
.T.mino {
|
||||
--background-color: #9739A2;
|
||||
--light-color: #D958E9;
|
||||
--box-shadow-color: #D958E9;
|
||||
}
|
||||
|
||||
.Z.mino {
|
||||
--background-color: #EB4F65;
|
||||
--light-color: #FF7F79;
|
||||
--box-shadow-color: #FF7F79;
|
||||
}
|
||||
|
||||
.ghost.mino {
|
||||
@ -88,6 +88,10 @@ tr.matrix td:not(.mino) {
|
||||
animation-duration: 0.2s;
|
||||
}
|
||||
|
||||
.disabled.mino {
|
||||
filter: brightness(50%) contrast(50%);
|
||||
}
|
||||
|
||||
@keyframes locked-animation {
|
||||
from {
|
||||
filter: saturate(50%) brightness(300%);
|
||||
|
||||
155
css/opera.css
Normal file
155
css/opera.css
Normal file
@ -0,0 +1,155 @@
|
||||
body {
|
||||
--bs-gutter-x: 0;
|
||||
background: black !important;
|
||||
}
|
||||
|
||||
#screenRow {
|
||||
gap: 0 !important;
|
||||
margin: 0;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .1em;
|
||||
}
|
||||
|
||||
#screenRow {
|
||||
--bs-gutter-x: 0;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: black;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
margin-bottom: 0.5em !important;
|
||||
}
|
||||
|
||||
.card-header,
|
||||
.card-header th{
|
||||
background: transparent;
|
||||
font-weight: 400 !important;
|
||||
font-size: 1.3em;
|
||||
border: none;
|
||||
}
|
||||
|
||||
#screenRow .table {
|
||||
--bs-border-width: 0;
|
||||
}
|
||||
|
||||
#holdTable {
|
||||
margin: 0 0 0 auto !important;
|
||||
}
|
||||
|
||||
#holdTable,
|
||||
#nextTable {
|
||||
border-bottom: 2px solid white;
|
||||
}
|
||||
|
||||
#statsTable {
|
||||
margin-right: 1.5em;
|
||||
}
|
||||
|
||||
#statsTable tr {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#statsTable td,
|
||||
#statsTable th {
|
||||
margin: 0;
|
||||
padding: 0 !important;
|
||||
width: auto;
|
||||
height: auto;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
#statsTable th {
|
||||
display: inline;
|
||||
flex-flow: row;
|
||||
font-size: 0.8em;
|
||||
text-align: center;
|
||||
width: 200%;
|
||||
}
|
||||
|
||||
#statsTable td {
|
||||
font-size: 1.3em;
|
||||
font-weight: 600;
|
||||
color: white;
|
||||
}
|
||||
|
||||
#matrixCard {
|
||||
background: transparent;
|
||||
border-top: none;
|
||||
border-left: 4px solid white;
|
||||
border-right: 4px solid white;
|
||||
border-bottom: 4px solid white;
|
||||
}
|
||||
|
||||
.mino {
|
||||
padding: 0;
|
||||
opacity: 100%;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.I.mino {
|
||||
background-color: #42AFE1;
|
||||
border-color: #6CEAFF;
|
||||
}
|
||||
|
||||
.J.mino {
|
||||
background-color: #1165B5;
|
||||
border-color: #339BFF;
|
||||
}
|
||||
|
||||
.L.mino {
|
||||
background-color: #F38927;
|
||||
border-color: #FFBA59;
|
||||
}
|
||||
|
||||
.O.mino {
|
||||
background-color: #F6D03C;
|
||||
border-color: #FFFF7F;
|
||||
}
|
||||
|
||||
.S.mino {
|
||||
background-color: #32ee3e;
|
||||
border-color: #84F880;
|
||||
}
|
||||
|
||||
.T.mino {
|
||||
background-color: #9739A2;
|
||||
border-color: #D958E9;
|
||||
}
|
||||
|
||||
.Z.mino {
|
||||
background-color: #EB4F65;
|
||||
border-color: #FF7F79;
|
||||
}
|
||||
|
||||
.ghost.mino {
|
||||
background-color: #fff4;
|
||||
border-color: #fff8;
|
||||
}
|
||||
|
||||
.moving.mino {
|
||||
filter: saturate(80%) brightness(150%);
|
||||
}
|
||||
|
||||
.locking.mino {
|
||||
filter: saturate(50%) brightness(200%);
|
||||
}
|
||||
|
||||
.disabled.mino {
|
||||
filter: brightness(50%) contrast(80%);
|
||||
opacity: 70%;
|
||||
}
|
||||
|
||||
@keyframes locked-animation {
|
||||
from {
|
||||
filter: saturate(50%) brightness(400%);
|
||||
}
|
||||
}
|
||||
|
||||
.locked.mino {
|
||||
animation: locked-animation;
|
||||
animation-duration: 0.2s;
|
||||
}
|
||||
46
css/pop.css
46
css/pop.css
@ -11,20 +11,18 @@ body[data-bs-theme="dark"] {
|
||||
--bs-btn-bg: #2125296b;
|
||||
}
|
||||
|
||||
.card {
|
||||
background-color: rgba(37, 41, 45, 50%);
|
||||
.card,
|
||||
#matrixCard {
|
||||
background: repeating-linear-gradient(transparent, #111 1px);
|
||||
backdrop-filter: blur(3px);
|
||||
}
|
||||
|
||||
@supports (backdrop-filter: blur()) {
|
||||
.card {
|
||||
background-color: rgba(33, 37, 41, 20%);
|
||||
backdrop-filter: blur(3px);
|
||||
}
|
||||
.card-header {
|
||||
background-color: rgba(37, 41, 45, 50%);
|
||||
}
|
||||
|
||||
#matrixTable {
|
||||
border-spacing: 1px;
|
||||
background: repeating-linear-gradient(transparent, #1118 1px);
|
||||
}
|
||||
|
||||
tr.matrix td:not(.mino) {
|
||||
@ -37,7 +35,7 @@ tr.matrix td:not(.mino) {
|
||||
border-radius: 0;
|
||||
outline: 1px solid #0006;
|
||||
opacity: 100%;
|
||||
box-shadow: 0 0 4px var(--color);
|
||||
box-shadow: 0 0 12px var(--color);
|
||||
}
|
||||
|
||||
.I.mino {
|
||||
@ -92,4 +90,34 @@ tr.matrix td:not(.mino) {
|
||||
.locked.mino {
|
||||
animation: locked-animation;
|
||||
animation-duration: 0.2s;
|
||||
}
|
||||
|
||||
.disabled.mino {
|
||||
outline: 0px;
|
||||
box-shadow: none;
|
||||
filter: contrast(40%) brightness(50%);
|
||||
}
|
||||
|
||||
tr.cleared-line-animation {
|
||||
animation: none;
|
||||
}
|
||||
|
||||
tr.cleared-line-animation::after {
|
||||
content: "";
|
||||
width: 100%;
|
||||
height: var(--cell-side);
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
display: block;
|
||||
background: repeating-linear-gradient(transparent, #fffb 1px);
|
||||
opacity: 0;
|
||||
animation: cleared-line-animation ease-out .3s;
|
||||
}
|
||||
|
||||
@keyframes cleared-line-animation {
|
||||
25% {
|
||||
width: 200%;
|
||||
opacity: 100%;
|
||||
}
|
||||
}
|
||||
@ -129,7 +129,8 @@ td {
|
||||
animation: blinker 0.08s step-start infinite;
|
||||
}
|
||||
|
||||
.ghost.mino {
|
||||
.ghost.mino,
|
||||
.disabled.mino {
|
||||
opacity: 50%;
|
||||
}
|
||||
|
||||
|
||||
BIN
css/retro/edo3adc8h2re1.jpeg
Normal file
BIN
css/retro/edo3adc8h2re1.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 298 KiB |
21
index.html
21
index.html
@ -15,10 +15,21 @@
|
||||
<link rel="alternate stylesheet" href="css/electro.css" title="Électro">
|
||||
<link rel="alternate stylesheet" href="css/pop.css" title="Pop">
|
||||
<link rel="alternate stylesheet" href="css/retro.css" title="Rétro">
|
||||
<link rel="alternate stylesheet" href="css/opera.css" title="Opéra">
|
||||
<link rel="alternate stylesheet" href="css/binaural.css" title="Binaural">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="favicons/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="favicons/T-2.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="favicons/favicon-16x16.png">
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<meta property="og:title" content="Quatuor"/>
|
||||
<meta property="og:type" content="game"/>
|
||||
<meta property="og:url" content="https://adrien.malingrey.fr/jeux/quatuor/"/>
|
||||
<meta property="og:image" content="https://adrien.malingrey.fr/jeux/quatuor/thumbnail.png"/>
|
||||
<meta property="og:image:width" content="288"/>
|
||||
<meta property="og:image:height" content="288"/>
|
||||
<meta property="og:description" content="Un jeu avec un quatuor de blocs qui tombent."/>
|
||||
<meta property="og:locale" content="fr_FR"/>
|
||||
<meta property="og:site_name" content="adrien.malingrey.fr"/>
|
||||
</head>
|
||||
|
||||
<body data-bs-theme="dark">
|
||||
@ -63,6 +74,8 @@
|
||||
<option value="css/pop.css">Pop</option>
|
||||
<option value="css/electro.css">Électro</option>
|
||||
<option value="css/retro.css">Rétro</option>
|
||||
<option value="css/opera.css">Opéra</option>
|
||||
<option value="css/binaural.css">Binaural</option>
|
||||
</select></div>
|
||||
<div class="col-4 d-flex align-items-baseline"><input name="sfxVolumeRange" id="sfxVolumeRange" class="form-range" type="range" min="0" max="1" step="any" value="0.7"></div>
|
||||
<label for="sfxVolumeRange" class="col-2 col-form-label">Volume</label>
|
||||
@ -82,11 +95,11 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid d-flex vh-100 justify-content-center d-flex align-items-center">
|
||||
<div id="sceneDiv" class="container-fluid d-flex vh-100 justify-content-center d-flex align-items-center">
|
||||
|
||||
<div id="screenRow" class="row row-cols-auto align-items-start gap-2">
|
||||
<div class="col d-flex flex-column align-items-end">
|
||||
<div class="card mb-4 w-100">
|
||||
<div class="card shadow mb-4 w-100">
|
||||
<div class="card-header fw-bold text-uppercase text-center">Hold</div>
|
||||
<div class="card-body p-0">
|
||||
<table id="holdTable" class="minoes-table m-auto">
|
||||
@ -218,8 +231,6 @@
|
||||
<script src="js/game_logic.js" language="Javascript" type="text/javascript"></script>
|
||||
<script src="js/interface.js" language="Javascript" type="text/javascript"></script>
|
||||
<script src="js/app.js" language="Javascript" type="text/javascript"></script>
|
||||
<script>
|
||||
|
||||
</script>
|
||||
<script>navigator?.serviceWorker.register('js/service-worker.js')</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
88
js/app.js
88
js/app.js
@ -1,11 +1,11 @@
|
||||
let scheduler = new Scheduler()
|
||||
let settings = new Settings()
|
||||
let stats = new Stats()
|
||||
let holdQueue = new MinoesTable("holdTable")
|
||||
let holdQueue = new HoldQueue()
|
||||
let matrix = new Matrix()
|
||||
let nextQueue = new NextQueue()
|
||||
let playing = false
|
||||
let lastActionSucceded = true
|
||||
//let lastActionSucceded = true
|
||||
let favicon
|
||||
|
||||
window.onload = function(event) {
|
||||
@ -19,6 +19,7 @@ window.onload = function(event) {
|
||||
function restart() {
|
||||
stats.modal.hide()
|
||||
holdQueue.init()
|
||||
holdQueue.redraw()
|
||||
stats.init()
|
||||
matrix.init()
|
||||
nextQueue.init()
|
||||
@ -96,7 +97,8 @@ function ticktack() {
|
||||
|
||||
function generate(piece) {
|
||||
matrix.piece = piece || nextQueue.shift()
|
||||
lastActionSucceded = true
|
||||
if (!piece && holdQueue.piece) holdQueue.drawPiece()
|
||||
//lastActionSucceded = true
|
||||
favicon.href = matrix.piece.favicon_href
|
||||
|
||||
if (matrix.piece.canMove(TRANSLATION.NONE)) {
|
||||
@ -130,14 +132,13 @@ let playerActions = {
|
||||
if (matrix.piece.holdEnabled) {
|
||||
scheduler.clearInterval(fall)
|
||||
scheduler.clearTimeout(lockDown)
|
||||
|
||||
let heldPiece = holdQueue.piece
|
||||
matrix.piece.facing = FACING.NORTH
|
||||
matrix.piece.locked = false
|
||||
holdQueue.piece = matrix.piece
|
||||
holdQueue.piece.holdEnabled = false
|
||||
holdQueue.piece.locked = false
|
||||
generate(heldPiece)
|
||||
|
||||
let piece = matrix.piece
|
||||
piece.facing = FACING.NORTH
|
||||
piece.locked = false
|
||||
generate(holdQueue.piece)
|
||||
matrix.piece.holdEnabled = false
|
||||
holdQueue.piece = piece
|
||||
}
|
||||
},
|
||||
|
||||
@ -159,12 +160,13 @@ function onkeydown(event) {
|
||||
if (!pressedKeys.has(event.key)) {
|
||||
pressedKeys.add(event.key)
|
||||
action = settings.keyBind[event.key]
|
||||
if (action()) {
|
||||
/*if (action()) {
|
||||
lastActionSucceded = true
|
||||
} else if (lastActionSucceded || !(action in REPEATABLE_ACTIONS)) {
|
||||
playSound(wallSound)
|
||||
lastActionSucceded = false
|
||||
}
|
||||
}*/
|
||||
action()
|
||||
if (REPEATABLE_ACTIONS.includes(action)) {
|
||||
actionsQueue.unshift(action)
|
||||
scheduler.clearTimeout(repeat)
|
||||
@ -186,12 +188,13 @@ function repeat() {
|
||||
|
||||
function autorepeat() {
|
||||
if (actionsQueue.length) {
|
||||
if (actionsQueue[0]()) {
|
||||
/*if (actionsQueue[0]()) {
|
||||
lastActionSucceded = true
|
||||
} else if (lastActionSucceded) {
|
||||
wallSound.play()
|
||||
lastActionSucceded = false
|
||||
}
|
||||
}*/
|
||||
actionsQueue[0]()
|
||||
}
|
||||
else scheduler.clearInterval(autorepeat)
|
||||
}
|
||||
@ -206,7 +209,7 @@ function onkeyup(event) {
|
||||
scheduler.clearTimeout(repeat)
|
||||
scheduler.clearInterval(autorepeat)
|
||||
if (actionsQueue.length) {
|
||||
if (action == playerActions.softDrop) scheduler.setInterval(autorepeat, settings.fallPeriod/20)
|
||||
if (actionsQueue[0] == playerActions.softDrop) scheduler.setInterval(autorepeat, settings.fallPeriod/20)
|
||||
else scheduler.setTimeout(repeat, settings.das)
|
||||
} else {
|
||||
matrix.drawPiece()
|
||||
@ -241,7 +244,7 @@ messagesSpan.onanimationend = function(event) {
|
||||
}
|
||||
|
||||
function gameOver() {
|
||||
matrix.piece.locked = false
|
||||
matrix.piece.locked = true
|
||||
matrix.drawPiece()
|
||||
|
||||
document.onkeydown = null
|
||||
@ -258,7 +261,54 @@ window.onbeforeunload = function(event) {
|
||||
if (playing) return false;
|
||||
}
|
||||
|
||||
// Play with 3D
|
||||
let mousedown = false
|
||||
let rX0 = 0
|
||||
let rY0 = 0
|
||||
let clientX0 = 0
|
||||
let clientY0 = 0
|
||||
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.register('service-worker.js');
|
||||
sceneDiv.onmousedown = function(event) {
|
||||
mousedown = true
|
||||
rX0 = parseInt(getComputedStyle(screenRow).getPropertyValue("--rX"))
|
||||
dy0 = parseInt(getComputedStyle(screenRow).getPropertyValue("--rY"))
|
||||
clientX0 = event.clientX
|
||||
clientY0 = event.clientY
|
||||
}
|
||||
|
||||
sceneDiv.onmousemove = function(event) {
|
||||
if (mousedown) {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
rX = (rX0 - event.clientY + clientY0 + 360) % 360
|
||||
screenRow.style.setProperty("--rX", rX + "deg")
|
||||
if (rX <= 180) {
|
||||
screenRow.classList.remove("top")
|
||||
screenRow.classList.add("bottom")
|
||||
} else {
|
||||
screenRow.classList.add("top")
|
||||
screenRow.classList.remove("bottom")
|
||||
}
|
||||
rY = (rY0 + event.clientX - clientX0 + 360) % 360
|
||||
screenRow.style.setProperty("--rY", rY + "deg")
|
||||
if (rY >= 180) {
|
||||
screenRow.classList.remove("left")
|
||||
screenRow.classList.add("right")
|
||||
} else {
|
||||
screenRow.classList.add("left")
|
||||
screenRow.classList.remove("right")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sceneDiv.onmouseup = document.onmouseleave = function(event) {
|
||||
mousedown = false
|
||||
}
|
||||
|
||||
sceneDiv.onwheel = function(event) {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
let tZ = parseInt(getComputedStyle(screenRow).getPropertyValue("--tZ"))
|
||||
tZ += event.deltaY
|
||||
screenRow.style.setProperty("--tZ", tZ + "px")
|
||||
}
|
||||
@ -171,6 +171,20 @@ class MinoesTable {
|
||||
MinoesTable.prototype.init_center = [2, 2]
|
||||
|
||||
|
||||
class HoldQueue extends MinoesTable {
|
||||
constructor() {
|
||||
super("holdTable")
|
||||
}
|
||||
|
||||
drawPiece(piece=this.piece, className=piece.className) {
|
||||
if (!matrix.piece.holdEnabled) {
|
||||
className += " disabled"
|
||||
}
|
||||
super.drawPiece(piece, className)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class NextQueue extends MinoesTable {
|
||||
constructor() {
|
||||
super("nextTable")
|
||||
|
||||
@ -16,7 +16,7 @@ Copyright 2015, 2019, 2020 Google LLC. All Rights Reserved.
|
||||
const OFFLINE_VERSION = 1;
|
||||
const CACHE_NAME = "offline";
|
||||
// Customize this with a different URL if needed.
|
||||
const OFFLINE_URL = "index.html";
|
||||
const OFFLINE_URL = "../index.html";
|
||||
|
||||
self.addEventListener("install", (event) => {
|
||||
event.waitUntil(
|
||||
Reference in New Issue
Block a user