Merge front & back
This commit is contained in:
parent
9108f2e726
commit
829926dddf
6 changed files with 140 additions and 18 deletions
11
index.html
11
index.html
|
@ -4,6 +4,7 @@
|
|||
<meta charset="UTF-8">
|
||||
<title>KyFlo Snake</title>
|
||||
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="sources/css/style.css">
|
||||
|
||||
</head>
|
||||
|
@ -14,13 +15,13 @@
|
|||
<div class="col s10 offset-s1" style="padding: 0">
|
||||
<input type="text" id="nickname" placeholder="Choose a nickname :">
|
||||
</div>
|
||||
<button class="col s8 offset-s2">Level 1</button>
|
||||
<button class="col s8 offset-s2">Level 2</button>
|
||||
<button class="col s8 offset-s2">Level 3</button>
|
||||
|
||||
<div class="menu-level col s12 row">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<canvas></canvas>
|
||||
<div id="game">
|
||||
<canvas id="canvas" class="invisible"></canvas>
|
||||
</div>
|
||||
|
||||
<script type="module" src="sources/js/index.js"></script>
|
||||
</body>
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
|
||||
html{
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
body{
|
||||
|
@ -26,7 +30,7 @@ h1{
|
|||
#menu{
|
||||
margin: 0;
|
||||
margin-top: 150px;
|
||||
|
||||
|
||||
}
|
||||
|
||||
#menu>div{
|
||||
|
@ -58,16 +62,16 @@ h1{
|
|||
background-color: rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
.linear-wipe {
|
||||
background: linear-gradient(to right, rgb(255, 136, 0) 20%, #FF0 40%, #FF0 45%, rgb(255, 136, 0) 80%);
|
||||
.linear-wipe {
|
||||
background: linear-gradient(to right, #FF4294 20%, #d919ff 35%, #3af8ff 40%, #d919ff 65%, #FF4294 80%);
|
||||
background-size: 200% auto;
|
||||
|
||||
|
||||
background-clip: text;
|
||||
text-fill-color: transparent;
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
|
||||
animation: shine 1s linear infinite;
|
||||
|
||||
animation: shine 1.5s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes shine {
|
||||
|
@ -94,3 +98,59 @@ h1{
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
.menu-level{
|
||||
height: 25vh;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
}
|
||||
::-webkit-scrollbar-button {
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #FF4294;
|
||||
border: 0px none #ffffff;
|
||||
border-radius: 0px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: #FF4294;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:active {
|
||||
background: #a800a3;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background: #000000;
|
||||
border: 0px none #ffffff;
|
||||
border-radius: 50px;
|
||||
}
|
||||
::-webkit-scrollbar-track:hover {
|
||||
background: #000000;
|
||||
}
|
||||
::-webkit-scrollbar-track:active {
|
||||
background: #000000;
|
||||
}
|
||||
::-webkit-scrollbar-corner {
|
||||
background: transparent;
|
||||
}
|
||||
#canvas {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
border: 3px double rgb(0, 255, 200);
|
||||
color: rgb(0, 255, 200);
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.invisible{
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
#game{
|
||||
height: 75vh;
|
||||
width: 75vh;
|
||||
margin: auto;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ export class Game {
|
|||
throw new InvalidGameOption("size");
|
||||
|
||||
if (direction && Object.values(directions).find(([x,y]) => direction[0] === x && direction[1] === y))
|
||||
this.direction = this.lastDirection = direction;
|
||||
this.direction = this.startDirection = this.lastDirection = direction;
|
||||
else
|
||||
throw new InvalidGameOption("direction");
|
||||
|
||||
|
@ -42,6 +42,8 @@ export class Game {
|
|||
this.apple = false;
|
||||
this.score = 0;
|
||||
this.lives = lives;
|
||||
this.onStart = null;
|
||||
this.onStop = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -60,9 +62,6 @@ export class Game {
|
|||
* Init the canvas
|
||||
*/
|
||||
initCanvas() {
|
||||
this.ctx.canvas.width = window.innerWidth;
|
||||
this.ctx.canvas.height = window.innerHeight;
|
||||
|
||||
this.ctx.canvas.ownerDocument.addEventListener("keyup", ev => {
|
||||
switch (ev.key) {
|
||||
case "ArrowUp":
|
||||
|
@ -98,6 +97,10 @@ export class Game {
|
|||
* Start the party
|
||||
*/
|
||||
start() {
|
||||
if (this.onStart && typeof this.onStart === "function")
|
||||
this.onStart();
|
||||
|
||||
this.direction = this.lastDirection = this.startDirection;
|
||||
this.snake = new Snake({startPos: this.size.map(s => Math.floor(s/2))});
|
||||
|
||||
this.initWorld();
|
||||
|
@ -120,6 +123,8 @@ export class Game {
|
|||
this.ctx.globalCompositeOperation = "destination-out";
|
||||
this.ctx.fillRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
|
||||
this.ctx.globalCompositeOperation = "source-over";
|
||||
if (this.onStop && typeof this.onStop === "function")
|
||||
this.onStop();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -44,7 +44,7 @@ export class Tile {
|
|||
|
||||
switch (this.type) {
|
||||
case tiles.EMPTY:
|
||||
this.game.ctx.strokeStyle = "#000000";
|
||||
this.game.ctx.strokeStyle = "#999999";
|
||||
this.game.ctx.rect(...canvasPos, ...size);
|
||||
break;
|
||||
case tiles.APPLE:
|
||||
|
|
|
@ -1,8 +1,59 @@
|
|||
import { Game } from "./Game.js"
|
||||
const req = new XMLHttpRequest();
|
||||
const canvas = document.getElementById("canvas");
|
||||
const menu = document.getElementById("menu");
|
||||
const menuLevel = document.querySelector(".menu-level");
|
||||
const gameZone = document.getElementById("game");
|
||||
let game;
|
||||
|
||||
req.open("GET", "sources/levels.json");
|
||||
req.onerror = () => console.error("Fail to load XML request");
|
||||
|
||||
req.onload = () => {
|
||||
let levels;
|
||||
if (req.status === 200)
|
||||
levels = JSON.parse(req.responseText);
|
||||
else
|
||||
levels = null;
|
||||
loadLevels(levels);
|
||||
}
|
||||
|
||||
req.send();
|
||||
|
||||
function loadLevels(levels) {
|
||||
if (!levels) {
|
||||
menuLevel.innerHTML = "";
|
||||
menuLevel.insertAdjacentHTML("beforeend", "<button class=\"col s8 offset-s2\" disabled>Fail to load levels :/</button>")
|
||||
} else {
|
||||
for (const [name, level] of Object.entries(levels)) {
|
||||
const b = document.createElement("button");
|
||||
b.classList.add("col", "s8", "offset-s2");
|
||||
b.innerText = name;
|
||||
menuLevel.insertAdjacentElement("beforeend", b);
|
||||
b.addEventListener("click", () => loadGame(level))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const loadGame = data => {
|
||||
game = new Game(canvas, data);
|
||||
|
||||
game.onStart = () => {
|
||||
menu.classList.add("invisible");
|
||||
canvas.classList.remove("invisible");
|
||||
};
|
||||
|
||||
game.onStop = () => {
|
||||
menu.classList.remove("invisible");
|
||||
canvas.classList.add("invisible");
|
||||
};
|
||||
|
||||
game.start();
|
||||
};
|
||||
|
||||
const game = new Game(document.getElementById("canvas"), {snakeSpeed: 200});
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
M.AutoInit();
|
||||
game.start();
|
||||
canvas.width = gameZone.offsetWidth;
|
||||
canvas.height = gameZone.offsetHeight;
|
||||
});
|
||||
|
|
5
sources/levels.json
Normal file
5
sources/levels.json
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"Level 1": {
|
||||
"snakeSpeed": 500
|
||||
}
|
||||
}
|
Reference in a new issue