使用HTML CSS和JavaScript设计“龙之世界”游戏
项目简介: 《龙之世界》是一个游戏,一个龙试图通过跳过它所遇到的其他龙来拯救自己。当一个龙成功躲过另一个龙时,分数将得到更新。
该项目将包含HTML、CSS和JavaScript文件。HTML文件添加游戏结构,CSS用于样式设计,JavaScript为游戏添加功能。
文件结构:
- index.html
- style.css
- script.js
HTML代码:
-
标题部分: 显示游戏的名称。
- 游戏结束部分: 当你输掉游戏时显示。
- 障碍部分: 包含龙需要躲过的障碍物。
- 龙部分: 包含需要从障碍物(即其他龙)中拯救的龙。
- 分数部分: 显示当前游戏的分数。
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content=
"width=device-width, initial-scale=1.0">
<link rel="stylesheet" href=
"style.css?_cacheOverride=1606401798626">
<link href=
"https://fonts.googleapis.com/css2?family=Ubuntu:ital,
wght@0, 300;1, 700&display=swap"
rel="stylesheet">
</head>
<body>
<h1 id="gameName">Welcome to Dragon's world</h1>
<div class="container">
<div class="gameover">Game Over</div>
<div id="scorecount">Your score : 0</div>
<div class="obstacle animateobstacle"></div>
<div class="dragon" style="left: 426px;"></div>
</div>
</body>
</html>
CSS代码:
- 游戏名称的定位: 游戏名称通过CSS的absolute属性进行定位。
- 背景图片的样式: 在container类中,我们使用background-size属性设置为cover来添加游戏的背景图片。
- 计分卡的样式: 我们将计分卡定位到页面的右上角,并为其提供适当的背景颜色,使其更具吸引力。其中的文本将显示为白色。
- 障碍物图像的样式: 我们将障碍物定位到页面的左下角,并为其提供动画效果,使其向左移动。
- 龙的样式: 我们将龙定位到页面的左下角,并为其提供动画效果,使其能够跳起来自救。
- 游戏结束的样式: 我们将游戏结束部分定位到页面的中心,并且当龙被障碍物击中时,它将出现。
style.css
/* CSS Reset */
*{
margin:0px;
padding:0px;
}
body {
/* Hides the bottom scrollbar */
overflow: hidden;
}
/* Styling of the Game's Name */
#gameName {
position: absolute;
top:30vh;
left:38vw;
}
/* Background image styling */
.container {
background-image: url(cover.png);
background-size: cover;
width:100vw;
height:100vh;
}
/* ScoreCard Styling */
#scorecount {
position: absolute;
top:20px;
right:20px;
background-color: black;
padding: 28px;
border-radius: 20px;
color: white;
}
/* Obstacle image styling and positioning */
.obstacle {
background-image: url(obstacle.png);
background-size: cover;
width:154px;
height: 126px;
position: absolute;
bottom:0px;
right:120px;
}
/* Applying animation to the obstacle
so that it can move towards left */
.animateobstacle {
animation: aniob 5s linear infinite;
}
@keyframes aniob {
0% {
left:100vw;
}
100% {
left:-10vw;
}
}
/* Dragon's styling */
.dragon {
background-image: url(dragon.png);
background-size: cover;
width: 194px;
height: 126px;
position: absolute;
bottom:0px;
left:90px;
}
/* Applying animation to the dragon so
that it can save himself by jumping up */
.animatedragon {
animation: ani 1s linear;
}
@keyframes ani {
0% {
bottom:0px;
}
25% {
bottom:150px;
}
50% {
bottom:300px;
}
75% {
bottom:211px;
}
100% {
bottom:0px;
}
}
/* gameover styling and positioning */
.gameover {
visibility: hidden;
font-family: 'Ubuntu', sans-serif;
position: absolute;
top: 50vh;
left: 35vw;
color: red;
font-weight: bold;
font-size: 6rem;
background-color: firebrick;
border-radius: 20px;
}
JavaScript代码:
1. 龙的移动: 这由 onkeydown 事件提供。
- 上箭头键: 按下时,龙将向上跳跃(由CSS提供动画)。
- 左箭头键: 按下时,龙将向左移动(由CSS提供动画)。
- 右箭头键: 按下时,龙将向右移动(由CSS提供动画)。
document.onkeydown = function(e) {
console.log(e.keyCode);
if (e.keyCode == 38) {
dragon = document.querySelector('.dragon');
dragon.classList.add('animatedragon');
setTimeout(() => {
dragon.classList.remove('animatedragon');
}, 700);
}
if (e.keyCode == 37) {
dragon = document.querySelector('.dragon');
dragonx = parseInt(window.getComputedStyle(dragon, null)
.getPropertyValue('left'));
dragon.style.left = dragonx - 112 + "px";
}
if (e.keyCode == 39) {
dragon = document.querySelector('.dragon');
dragonx = parseInt(window.getComputedStyle(
dragon, null).getPropertyValue('left'));
dragon.style.left = dragonx + 112 + "px";
}
}
2. 更新分数: 只有在满足特定条件时分数才会增加。我们将计算障碍物和龙的左边和底部值,然后根据一个适当的值增加分数,以显示龙从障碍物中脱身。为此,我们使用了一个“cross”变量,并将其赋值为“true”。当龙安全地穿过障碍物时,我们将值设置为“false”。大约1秒后,我们将cross的值改为“true”。我们还使障碍物在每次穿过后运行得更快,从而增加了难度水平。
setInterval(() => {
dragon = document.querySelector('.dragon');
gameover = document.querySelector('.gameover');
obstacle = document.querySelector('.obstacle');
dx = parseInt(window.getComputedStyle(
dragon, null).getPropertyValue('left'));
dy = parseInt(window.getComputedStyle(
dragon, null).getPropertyValue('bottom'));
ox = parseInt(window.getComputedStyle(
obstacle, null).getPropertyValue('left'));
oy = parseInt(window.getComputedStyle(
obstacle, null).getPropertyValue('bottom'));
offsetx = Math.abs(dx - ox);
offsety = Math.abs(dy - oy);
console.log(offsetx, offsety);
if (offsetx < 120 && offsety <= 144) {
gameover.style.visibility = 'visible';
obstacle.classList.remove('animateobstacle');
} else if (offsetx < 125 && cross) {
score += 1;
updateScore(score);
cross = false;
setTimeout(() => {
cross = true;
}, 1000);
setInterval(() => {
obsanidur = parseFloat(window
.getComputedStyle(obstacle, null)
.getPropertyValue('animation-duration'));
obstacle.style.animationDuration
= obsanidur - 0.01 + 's';
}, 500);
}
}, 10);
function updateScore(score) {
scorecount.innerHTML = "Your score : " + score;
}
script.js
<script>
cross = true;
score = 0;
document.onkeydown = function(e) {
console.log(e.keyCode);
if (e.keyCode == 38) {
dragon = document.querySelector('.dragon');
dragon.classList.add('animatedragon');
setTimeout(() => {
dragon.classList.remove('animatedragon');
}, 700);
}
if (e.keyCode == 37) {
dragon = document.querySelector('.dragon');
dragonx = parseInt(window.getComputedStyle(
dragon, null).getPropertyValue('left'));
dragon.style.left = dragonx - 112 + "px";
}
if (e.keyCode == 39) {
dragon = document.querySelector('.dragon');
dragonx = parseInt(window.getComputedStyle(
dragon, null).getPropertyValue('left'));
dragon.style.left = dragonx + 112 + "px";
}
}
setInterval(() => {
dragon = document.querySelector('.dragon');
gameover = document.querySelector('.gameover');
obstacle = document.querySelector('.obstacle');
dx = parseInt(window.getComputedStyle(
dragon, null).getPropertyValue('left'));
dy = parseInt(window.getComputedStyle(
dragon, null).getPropertyValue('bottom'));
ox = parseInt(window.getComputedStyle(
obstacle, null).getPropertyValue('left'));
oy = parseInt(window.getComputedStyle(
obstacle, null).getPropertyValue('bottom'));
offsetx = Math.abs(dx - ox);
offsety = Math.abs(dy - oy);
console.log(offsetx, offsety);
if (offsetx < 120 && offsety <= 144) {
if (score != 0)
scorecount.innerHTML = "Your score : " + score;
gameover.style.visibility = 'visible';
obstacle.classList.remove('animateobstacle');
} else if (offsetx < 125 && cross) {
score += 1;
updateScore(score);
cross = false;
setTimeout(() => {
cross = true;
}, 1000);
setInterval(() => {
obsanidur = parseFloat(window
.getComputedStyle(obstacle, null)
.getPropertyValue('animation-duration'));
obstacle.style.animationDuration
= obsanidur - 0.01 + 's';
}, 500);
}
}, 10);
function updateScore(score) {
scorecount.innerHTML = "Your score : " + score;
}
</script>
极客教程