Add new retro theme & fix touch input problem
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1 +1 @@
|
||||
.idea/*
|
||||
.idea/
|
@@ -31,6 +31,10 @@
|
||||
<input id="theme-modern" name="theme" data-theme="modern" type="radio">
|
||||
<label for="theme-modern" class="radio-label" data-string="themeModern">Modern</label>
|
||||
</div>
|
||||
<div class="radio">
|
||||
<input id="theme-retro" name="theme" data-theme="retro" type="radio">
|
||||
<label for="theme-retro" class="radio-label" data-string="themeRetro">Retro</label>
|
||||
</div>
|
||||
<div class="radio">
|
||||
<input id="theme-snakes" name="theme" data-theme="snakes" type="radio">
|
||||
<label for="theme-snakes" class="radio-label" data-string="themeSnakes">Snakes</label>
|
||||
|
@@ -2,6 +2,7 @@ class Arena {
|
||||
constructor(gameInfo, game) {
|
||||
this.g = gameInfo;
|
||||
this.game = game;
|
||||
this.p = this.g.player;
|
||||
this.field = createMatrix(this.g.fieldSize.x, this.g.fieldSize.y);
|
||||
}
|
||||
|
||||
|
15
js/game.js
15
js/game.js
@@ -18,6 +18,8 @@ class Game {
|
||||
}
|
||||
|
||||
drawHolding() {
|
||||
if (this.p.holdingTile === null)
|
||||
return;
|
||||
this.g.contextHold.clearRect(0, 0, this.g.canvasHold.width, this.g.canvasHold.height);
|
||||
const offset = centerOffset(this.p.holdingTile);
|
||||
const x = 3 - (this.p.holdingTile[0].length / 2) + offset.x;
|
||||
@@ -35,8 +37,7 @@ class Game {
|
||||
});
|
||||
}
|
||||
|
||||
drawTile(x, y, offset, color, matrix, useContext = this.g.context) {
|
||||
const ctx = useContext;
|
||||
drawTile(x, y, offset, color, matrix, ctx = this.g.context) {
|
||||
switch (this.g.theme) {
|
||||
case "default":
|
||||
ctx.fillStyle = color;
|
||||
@@ -74,6 +75,9 @@ class Game {
|
||||
}
|
||||
drawRoundRect(ctx, x + offset.x, y + offset.y, 1, 1, [r1, r2, r3, r4]);
|
||||
break;
|
||||
case "retro":
|
||||
drawReliefRect(ctx, x + offset.x, y + offset.y, 1, 1, .15, color);
|
||||
break;
|
||||
default:
|
||||
this.g.theme = "default";
|
||||
this.drawTile(x, y, offset, color, matrix, ctx);
|
||||
@@ -115,6 +119,13 @@ class Game {
|
||||
this.drawArena();
|
||||
}
|
||||
|
||||
redrawScreen() {
|
||||
this.draw();
|
||||
this.drawArena();
|
||||
this.drawHolding();
|
||||
this.drawUpcoming();
|
||||
}
|
||||
|
||||
registerListeners() {
|
||||
// Keyboard controls
|
||||
document.addEventListener('keydown', event => {
|
||||
|
@@ -13,6 +13,7 @@ const en = {
|
||||
counterTime: "Time: ",
|
||||
themeDefault: "Default",
|
||||
themeModern: "Modern",
|
||||
themeRetro: "Retro",
|
||||
themeSnakes: "Snakes",
|
||||
titleAppearance: "Appearance",
|
||||
titleControls: "Controls",
|
||||
@@ -36,6 +37,7 @@ const de = {
|
||||
counterTime: "Zeit: ",
|
||||
themeDefault: "Standard",
|
||||
themeModern: "Modern",
|
||||
themeRetro: "Retro",
|
||||
themeSnakes: "Schlangen",
|
||||
titleAppearance: "Aussehen",
|
||||
titleControls: "Steuerung",
|
||||
|
33
js/menu.js
33
js/menu.js
@@ -7,10 +7,7 @@ let escState = 1;
|
||||
|
||||
window.onresize = () => {
|
||||
scaleWindow();
|
||||
game.draw();
|
||||
game.drawArena();
|
||||
game.drawUpcoming();
|
||||
game.drawHolding();
|
||||
game.redrawScreen();
|
||||
};
|
||||
|
||||
function scaleWindow() {
|
||||
@@ -93,7 +90,8 @@ document.getElementById("game-reset").addEventListener("click", () => {
|
||||
|
||||
document.getElementsByName("theme").forEach((el) => {
|
||||
el.addEventListener("change", (e) => {
|
||||
game.theme = e.target.getAttribute("data-theme");
|
||||
game.g.theme = e.target.getAttribute("data-theme");
|
||||
game.redrawScreen();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -185,25 +183,10 @@ function fadeBlurOut() {
|
||||
const scoreEl = document.getElementById("score");
|
||||
const nativeTransform = getComputedStyle(scoreEl).transform;
|
||||
function scoreUpdateAni() {
|
||||
const scale = 1.5;
|
||||
const finalScale = 1;
|
||||
let currentScale = 1;
|
||||
let upscaling = true;
|
||||
|
||||
const id = setInterval(frame, 5);
|
||||
|
||||
function frame() {
|
||||
if(currentScale <= scale && upscaling) {
|
||||
currentScale += 0.02;
|
||||
scoreEl.style.transform = nativeTransform + " scale(" + currentScale + ")";
|
||||
} else if (currentScale >= finalScale) {
|
||||
upscaling = false;
|
||||
currentScale -= 0.02;
|
||||
scoreEl.style.transform = nativeTransform + " scale(" + currentScale + ")";
|
||||
} else {
|
||||
clearInterval(id);
|
||||
}
|
||||
}
|
||||
scoreEl.classList.add("update");
|
||||
setTimeout(() => {
|
||||
scoreEl.classList.remove("update");
|
||||
}, 1500);
|
||||
}
|
||||
|
||||
function showMenu() {
|
||||
@@ -235,7 +218,7 @@ function hideMenu() {
|
||||
game.g.lastTimeUpdate = Date.now();
|
||||
fadeBlurOut();
|
||||
if(!firstRun) {
|
||||
game.update(lastTime);
|
||||
game.update(game.g.lastTime);
|
||||
}
|
||||
}
|
||||
|
||||
|
64
js/tetris.js
64
js/tetris.js
@@ -164,6 +164,47 @@ function drawRoundRect(ctx, x, y, w, h, r) {
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
function drawReliefRect(ctx, x, y, w, h, l, clr) {
|
||||
ctx.fillStyle = clr;
|
||||
ctx.fillRect(x + l, y + l, w - (2 * l), h - (2 * l));
|
||||
|
||||
ctx.fillStyle = colorLuminance(clr, .6);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x, y);
|
||||
ctx.lineTo(x + w, y);
|
||||
ctx.lineTo(x + w - l, y + l);
|
||||
ctx.lineTo(x + l, y + l);
|
||||
ctx.fill();
|
||||
ctx.closePath();
|
||||
|
||||
ctx.fillStyle = colorLuminance(clr, .3);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x, y);
|
||||
ctx.lineTo(x, y + h);
|
||||
ctx.lineTo(x + l, y + h - l);
|
||||
ctx.lineTo(x + l, y + l);
|
||||
ctx.fill();
|
||||
ctx.closePath();
|
||||
|
||||
ctx.fillStyle = colorLuminance(clr, -.6);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x, y + h);
|
||||
ctx.lineTo(x + w, y + h);
|
||||
ctx.lineTo(x + w - l, y + h - l);
|
||||
ctx.lineTo(x + l, y + h - l);
|
||||
ctx.fill();
|
||||
ctx.closePath();
|
||||
|
||||
ctx.fillStyle = colorLuminance(clr, -.3);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x + w, y);
|
||||
ctx.lineTo(x + w, y + h);
|
||||
ctx.lineTo(x + w - l, y + h - l);
|
||||
ctx.lineTo(x + w - l, y + l);
|
||||
ctx.fill();
|
||||
ctx.closePath();
|
||||
}
|
||||
|
||||
function formatMillis(millis) {
|
||||
const d = new Date(1000 * Math.round(millis / 1000));
|
||||
return (d.getUTCMinutes() < 10 ? "0" : "") + d.getUTCMinutes() + ":" + (d.getUTCSeconds() < 10 ? "0" : "") + d.getUTCSeconds();
|
||||
@@ -242,4 +283,27 @@ const game = new Game();
|
||||
|
||||
function startGame() {
|
||||
game.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
function colorLuminance(hex, lum) {
|
||||
|
||||
// validate hex string
|
||||
hex = String(hex).replace(/[^0-9a-f]/gi, '');
|
||||
if (hex.length < 6) {
|
||||
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
|
||||
}
|
||||
lum = lum || 0;
|
||||
|
||||
// convert to decimal and change luminosity
|
||||
let rgb = "#", c, i;
|
||||
for (i = 0; i < 3; i++) {
|
||||
c = parseInt(hex.substr(i * 2, 2), 16);
|
||||
c = Math.round(Math.min(Math.max(0, c + (c * lum)), 255)).toString(16);
|
||||
rgb += ("00" + c).substr(c.length);
|
||||
}
|
||||
|
||||
return rgb;
|
||||
}
|
@@ -1,27 +1,27 @@
|
||||
const hammertime = new Hammer(document.getElementById("tetris"));
|
||||
|
||||
hammertime.on('swipeleft', (e) => {
|
||||
keys.left.action();
|
||||
game.g.keys.left.action();
|
||||
});
|
||||
|
||||
hammertime.on('swiperight', (e) => {
|
||||
keys.right.action();
|
||||
game.g.keys.right.action();
|
||||
});
|
||||
|
||||
hammertime.on('swipeup', () => {
|
||||
keys.holdTile.action();
|
||||
game.g.keys.holdTile.action();
|
||||
});
|
||||
|
||||
hammertime.on('pandown swipedown', (e) => {
|
||||
keys.down.action();
|
||||
game.g.keys.down.action();
|
||||
});
|
||||
|
||||
hammertime.on('tap', (e) => {
|
||||
if (e.tapCount >= 2) {
|
||||
keys.rotateRight.action();
|
||||
game.g.keys.rotateRight.action();
|
||||
}
|
||||
});
|
||||
|
||||
hammertime.on('press', () => {
|
||||
keys.down.action();
|
||||
game.g.keys.down.action();
|
||||
});
|
24
style.css
24
style.css
@@ -212,11 +212,29 @@ body {
|
||||
|
||||
#score {
|
||||
font-weight: 900;
|
||||
bottom: 0;
|
||||
bottom: initial;
|
||||
top: 2.5vh;
|
||||
font-size: 5vh;
|
||||
}
|
||||
|
||||
#score.update {
|
||||
animation: scoreUpdate .5s;
|
||||
}
|
||||
|
||||
@keyframes scoreUpdate {
|
||||
0% {
|
||||
transform: translateX(-50%) scale(1);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: translateX(-50%) scale(1.5);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateX(-50%) scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
#time:before, #score:before {
|
||||
content: attr(data-prefix);
|
||||
}
|
||||
@@ -230,6 +248,10 @@ body {
|
||||
max-width: 20vw;
|
||||
}
|
||||
|
||||
.game-over #score {
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
#footer {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
|
Reference in New Issue
Block a user