html 俄罗斯方块w /高分跟踪
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了html 俄罗斯方块w /高分跟踪相关的知识,希望对你有一定的参考价值。
Tetris w/ high score tracking
-----------------------------
Hope you have fun playing! Feature suggestions and improvements are very welcome!
Browser version available here: https://dutchbones.github.io/tetris
A [Pen](https://codepen.io/harunpehlivan/pen/pZzLze) by [HARUN PEHLİVAN](https://codepen.io/harunpehlivan) on [CodePen](https://codepen.io).
[License](https://codepen.io/harunpehlivan/pen/pZzLze/license).
$darkBlue:#202028;
$white: #fff;
$transBlack: rgba(0, 0, 0, .65);
body, html {
background-image: url('https://s19.postimg.cc/53hmmyd9f/stars-3000x2000-pink-cosmos-hd-7164.jpg');
background-size: cover;
background-repeat: no-repeat;
background-position: center;
color:$white;
font-family: 'Lucida Console';
height: 100%;
overflow: hidden;
text-align: center;
min-width: 700px;
}
.wrapper {
display: inline-flex;
justify-content: center;
margin: 1vh 0;
padding: 1% 1% .5% 1%;
background: $transBlack;
box-shadow: -1px 5px 5px rgba(0, 0, 0, .75);;
}
.modal {
margin-top: 20vh !important;
border: solid .05em $white;
box-shadow: -15px 20px 20px rgba(0, 0, 0, .75) !important;
}
.modal-content {
background: $darkBlue;
}
.modal-content .btn {
font-size: 18px !important;
}
.modal-content input {
color: white;
font-size: 24px !important;
width: 50% !important;
text-align: center;
}
.modal-content label {
font-size: 16px !important;
}
.btn:focus {
background-color: #00bfa5 !important;
}
.btn {
background-color: #009688 !important;
}
.yourScore {
padding-bottom: 0px;
}
.detailsLeft {
width: 130px;
position: relative;
height: 90vh;
margin: 0% 2%;
text-align: right;
font-size: 16px;
}
.highScores {
position: absolute;
bottom: 35px;
right: 0px;
line-height: 10px;
font-size: 14px;
}
.detailsRight {
position: relative;
height: 90vh;
margin: 2% 2% 0% 2%;
text-align: left;
}
.next {
height: 15vh;
border: solid .1em $white;
}
.controls {
position: absolute;
bottom: 50px;
left: 0px;
font-size: 14px;
line-height: 8px;
}
.tetris {
height: 90vh;
border: solid .25em $white;
}
.footer {
position: absolute;
bottom: 0;
font-size: 12px;
color: rgba(255, 255, 255, .85);
line-height: 0px;
}
.footer a:link, a:visited, a:active {
color: rgba(255, 255, 255, .85);
text-decoration: none;
}
.footer a:link:hover {
color: white;
text-decoration: none;
}
@media (max-width: 920px), (max-height: 800px){
body, html {
font-size: 16px;
margin: 0px !important;
}
.modal {
width: 25vw !important;
margin-top: 20vh !important;
border: solid .05em $white;
box-shadow: -15px 20px 20px rgba(0, 0, 0, .75) !important;
min-width: 500px;
}
.modal-content {
background: $darkBlue;
}
.modal-content .btn {
font-size: 14px !important;
}
.modal-content input {
color: white;
font-size: 12px !important;
width: 50% !important;
text-align: center;
}
.modal-content label {
font-size: 14px !important;
}
.wrapper {
display: inline-flex;
justify-content: center;
background: rgba(0, 0, 0, .5) !important;
padding: 0% 0%;
background: $transBlack;
margin: 0px !important;
height: 100%;
width: 100%;
}
.detailsLeft {
height: 80vh;
width: 110px;
margin: 5% 1% 0% 0%;
font-size: 14px;
}
.score-title {
font-size: 14px;
}
.highScores {
line-height: 8px;
font-size: 12px;
}
.detailsRight {
height: 80vh;
width: 120px;
margin: 5% 0% 0% 1%;
text-align: left;
}
.next {
border: solid .1em $white;
height: 12vh;
}
.controls {
line-height: 8px;
font-size: 12px;
}
.tetris {
height: 85vh;
border: solid .25em $white;
margin-bottom: 2%;
margin-top: 2%;
}
.footer {
font-size: 12px;
}
}
$(document).ready(function(){
$('#newGame').modal(
{'dismissible': false});
$('#newGame').modal('open');
$("#newGameBtn").focus()
});
let highScoreMin;
function loadHighScores() {
$.ajax({
url: 'https://api.mlab.com/api/1/databases/tetrishighscores/collections/scores?s={"score":-1}&apiKey=E8dx03lqLdc5pG_K002t_lJrPOwDi1vG',
type: "GET",
success: (data) => {
let scoreLog = `<p class="score-title"><u>High Scores:</u></p>`;
highScoreMin = data[10].score;
for(var i = 0; i <= 10; i++){
scoreLog += `<p>${data[i].name.slice(0, 7)}: ${data[i].score}</p>`;
}
$('.highScores').html(scoreLog);
},
error: (xhr, status, err) => {
console.log(err);
}
});
}
let pause = true;
const canvas = document.querySelector('.tetris');
const context = canvas.getContext('2d');
const nextCanvas = document.querySelector('.next');
const nextContext = nextCanvas.getContext('2d');
context.scale(20, 20);
nextContext.scale(30, 30);
const arena = createMatrix(12, 20);
const nextArena = createMatrix(6, 6);
const player = {
pos: {x: 0, y: 0},
matrix: null,
score: 0,
level: 1,
dropInterval: 1000,
DROP_SLOW: 100,
next: null,
};
let dropCounter = 0;
let DROP_FAST = 50;
function arenaSweep(){
let rowCount = 1;
outer: for(y=arena.length - 1; y > 0; y--){
for(x=0; x < arena[y].length; x++){
if(arena[y][x] === 0) {
continue outer;
}
}
const row = arena.splice(y, 1)[0].fill(0);
arena.unshift(row);
y++;
player.score += rowCount * 100;
rowCount *= 2;
let scoreStr = player.score.toString();
if(scoreStr.length > 3){
let num = Number(scoreStr.slice(0, scoreStr.length - 3));
player.level = num + 1;
player.dropInterval = 1000 - (num * 50);
player.DROP_SLOW = 1000 - (num * 50);
}
}
}
function collide(arena, player){
const [m, o] = [player.matrix, player.pos];
for(y=0; y<m.length; y++){
for(x=0; x < m[y].length; x++){
if(m[y][x] !== 0 && ( arena[y + o.y] && arena[y + o.y][x + o.x]) !== 0){
return true;
}
}
}
return false;
}
function createMatrix(w, h){
const matrix = [];
while(h--){
matrix.push(new Array(w).fill(0));
}
return matrix;
}
function createPiece(type){
if (type === 'I'){
return [
[0, 1, 0, 0],
[0, 1, 0, 0],
[0, 1, 0, 0],
[0, 1, 0, 0]
];
} else if (type === 'J'){
return [
[0, 2, 0],
[0, 2, 0],
[2, 2, 0]
];
} else if (type === 'L'){
return [
[0, 3, 0],
[0, 3, 0],
[0, 3, 3]
];
} else if (type === 'O'){
return [
[4,4],
[4,4]
];
} else if (type === 'S'){
return [
[0, 5, 5],
[5, 5, 0],
[0, 0, 0]
];
} else if (type === 'T'){
return [
[0, 0, 0],
[6, 6, 6],
[0, 6, 0]
];
} else if (type === 'Z'){
return [
[7, 7, 0],
[0, 7, 7],
[0, 0, 0]
];
}
}
function drawNext(){
nextContext.fillStyle = '#000';
nextContext.fillRect(0, 0, nextCanvas.width, nextCanvas.height);
drawMatrix(nextArena, {x: 0, y:0}, nextContext);
drawMatrix(player.next, {x: 1, y: 1}, nextContext);
}
function draw(){
context.fillStyle = '#000';
context.fillRect(0, 0, canvas.width, canvas.height);
drawMatrix(arena, {x: 0, y: 0}, context);
drawMatrix(player.matrix, player.pos, context);
}
function drawMatrix(mat, offset, cont){
mat.forEach((row, y) => {
row.forEach((value, x) =>{
if(value !== 0){
cont.fillStyle = colors[value];
cont.fillRect(x + offset.x, y + offset.y, 1, 1);
}
});
});
}
function merge(arena, player){
player.matrix.forEach((row, y) => {
row.forEach((value, x) => {
if(value !== 0){
arena[y + player.pos.y][x + player.pos.x] = value;
}
});
});
}
function playerDrop(){
player.pos.y++;
if(collide(arena, player)){
player.pos.y--;
merge(arena, player);
playerReset();
arenaSweep();
updateScore();
}
dropCounter = 0;
}
function playerMove(dir){
player.pos.x += dir;
if(collide(arena, player)){
player.pos.x -= dir;
}
}
function playerReset(){
const pieces = 'IJLOSTZ';
if(player.next === null){
player.matrix = createPiece(pieces[pieces.length * Math.random() | 0]);
player.next = createPiece(pieces[pieces.length * Math.random() | 0]);
} else {
player.matrix = player.next;
player.next = createPiece(pieces[pieces.length * Math.random() | 0]);
}
drawNext();
player.pos.y = 0;
player.pos.x = (arena[0].length / 2 | 0) - (player.matrix[0].length / 2 | 0);
if(collide(arena, player)){
pauseGame();
document.removeEventListener('keydown', keyListener);
document.removeEventListener('keyup', keyListener);
// clearPlayer();
}
}
function clearPlayer(){
player.dropInterval = 1000;
player.DROP_SLOW = 1000;
player.score = 0;
player.level = 1;
arena.forEach(row => row.fill(0));
updateScore();
}
function playerRotate(dir){
const pos = player.pos.x
let offset = 1;
rotate(player.matrix, dir);
while(collide(arena, player)){
player.pos.x += offset;
offset = -(offset + (offset > 0 ? 1 : -1));
if(offset > player.matrix[0].length) {
rotate(player.matrix, -dir);
player.pos.x = pos;
return;
}
}
}
function rotate(matrix, dir){
for(y=0; y < matrix.length; y++){
for(x=0; x < y; x++){
[ matrix[x][y], matrix[y][x], ] = [ matrix[y][x], matrix[x][y], ];
}
}
if(dir > 0){
matrix.forEach(row => row.reverse());
} else {
matrix.reverse();
}
}
let lastTime = 0;
function update(time = 0){
$('#pause').off();
if(!pause){
const deltaTime = time - lastTime;
lastTime = time;
dropCounter += deltaTime;
if(dropCounter > player.dropInterval) {
playerDrop();
}
draw();
requestAnimationFrame(update);
} else {
draw();
}
}
function updateScore(){
document.querySelector('.score').innerHTML = `<p><b><u>Score:</u> ${player.score}</b></p>`;
document.querySelector('.level').innerHTML = `<p><b><u>Level:</u> ${player.level}</b></p>`;
}
const colors = [
null,
'#03A9F4',//I
'#9C27B0',//J
'#FFC107',//L
'#E91E63',//O
'#00BCD4',//S
'#8BC34A',//T
'#3F51B5'//Z
];
function keyListener(e){
if(e.type === 'keydown'){
if(e.keyCode === 37){
playerMove(-1)
} else if(e.keyCode === 39){
playerMove(1);
} else if(e.keyCode === 81){
playerRotate(-1);
} else if(e.keyCode === 87 || e.keyCode === 38){
playerRotate(1);
} else if(e.keyCode === 27){
pauseGame();
}
}
if (e.keyCode === 40) {
if (e.type === 'keydown') {
if (player.dropInterval !== DROP_FAST) {
playerDrop();
player.dropInterval = DROP_FAST;
}
} else {
player.dropInterval = player.DROP_SLOW;
}
}
};
function pauseGame(){
if(pause === true){
pause = false;
$('#pause').modal({"onCloseStart": update() });
$('#pause').modal('close');
} else {
if(collide(arena, player)){
pause = true;
if(player.score > 0){
$('#gameOver').modal({
'dismissible': false,
"onOpenEnd": function(){ $('#name').focus(); }
});
$('#gameOver').modal('open');
$('.yourScore').html(`<p>Your Score: ${player.score}`)
} else {
$('#newGame').modal({'dismissible': false});
$('#newGame').modal('open');
}
} else {
pause = true;
document.createEventListener
$('#pause').modal({
"dismissible": false,
"onCloseStart": update() });
$('#pause').modal('open');
$("#pauseBtn").focus();
$('body').on('keydown', (e)=>{
if(e.keyCode === 39){
$('#StartNewBtn').focus();
}
if(e.keyCode === 37){
$("#pauseBtn").focus();
}
})
}
}
}
function newGame(){
loadHighScores();
clearPlayer();
pause = false;
playerReset();
update();
updateScore();
document.addEventListener('keydown', keyListener);
document.addEventListener('keyup', keyListener);
}
$('#highScore').on('submit', (e) => {
e.preventDefault();
let name = $('#name').val();
$.ajax({
url: 'https://api.mlab.com/api/1/databases/tetrishighscores/collections/scores?apiKey=E8dx03lqLdc5pG_K002t_lJrPOwDi1vG',
data: JSON.stringify({
"date": new Date,
"name": name,
"score": player.score,
"level": player.level
}),
type: "POST",
contentType: "application/json",
success: (data) => {
$('#highScore').html( '<h4>Thank You!</h4>' );
},
error: (xhr, status, err) => {
console.log(err);
}
});
});
update();
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Tetris</title>
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-rc.2/css/materialize.min.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
</head>
<body>
<div class="wrapper">
<div id="newGame" class="modal">
<div class="modal-content">
<h4>Tetris</h4>
<button onclick="newGame()" id="newGameBtn" class="modal-close waves-effect waves-light btn" style="width:250px">New Game</button>
</div>
</div>
<div id="pause" class="modal">
<div class="modal-content">
<h4>Game Paused</h4>
<button onclick="pauseGame()" id="pauseBtn" class="modal-close waves-effect waves-light btn">Resume Game</button>
<button onclick="newGame()" id="StartNewBtn" class="modal-close waves-effect waves-light btn">Start New Game</button>
</div>
</div>
<div id="gameOver" class="modal">
<div class="modal-content">
<h4>Game Over</h4>
<div class="yourScore"></div>
<label for="name">Submit Your Score</label>
<br><br>
<form id="highScore">
<input type="text" id="name" maxlength="7" placeholder="name..." onfocus="this.placeholder = ''" autocomplete="off" required/>
<button type="submit" id="submit" class="waves-effect waves-light btn">Submit</button>
</form>
<br>
<a onclick="newGame()" class="modal-close waves-effect waves-light btn">Start New Game</a>
</div>
</div>
<div class="detailsLeft">
<div class="score"></div>
<div class="level"></div>
<div class="highScores"></div>
</div>
<canvas class="tetris" width="240" height="400"></canvas>
<div class="detailsRight">
<canvas class="next" width="160" height="160"></canvas>
<br>
<div class="controls">
<p><i class="fas fa-arrow-left"></i></span> Move Left</p>
<p><i class="fas fa-arrow-right"></i></span> Move Right</p>
<p><i class="fas fa-arrow-down"></i></span> Move Down</p>
<p><i class="fas fa-arrow-up"></i></span> Rotate Right</p>
<p><span style="font-size : 18px">Q</span> Rotate Left</p>
<p><span style="font-size : 18px">W</span> Rotate Right</p>
<p><span style="font-size: 18px">Esc</span> Pause Game</p>
</div>
</div>
<div class="footer"><p>by <a href="https://github.com/harunpehlivan" target="_blank"><i class="fab fa-github"></i> HARUN PEHLİVAN</a></p></div>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-rc.2/js/materialize.min.js"></script>
<script src="js/main.js"></script>
</body>
</html>
以上是关于html 俄罗斯方块w /高分跟踪的主要内容,如果未能解决你的问题,请参考以下文章