🏜哈喽,大家好,我是小浪。前段时间羊了个羊火遍了大江南北,大家是否都通过第二关了呢?哈哈,没关系,既然通不过,那咋们不如自己来做一个这样的羊了个羊的仿写页面,学会了赶紧拿去在同学面前展示展示;OK,接下来,我们开始仿写这种游戏规则模式,写一个我们自己做出来的游戏——🍅果了个果🍅;
💡声明:本游戏只涉及到一个html文件+几张图片即可完成,不要配置其他任何的东西,如果你在寻找简单好运行的代码,那么本文将是您的不二之选。
🌄那么,学习制作这个游戏之前,你需要掌握前端三剑客的相关知识点:前端客栈。
🎑如果你之前掌握了相关前端的知识点,或者你大概只需要获取这个游戏的源码,知道如何给这个游戏换换背景,换换图片等,那么你可以直接翻到本篇博客最后获取源码即可,每个地方的细节博主都描述的很清楚哈!
📲目录
一、大概游戏思想
二、具体实现方法及代码
三、运行结果展示
四、完整代码
一、大概游戏思想
📠我们要制作的游戏规则很简单,就是仿照羊了个羊的规则,选取三个相同的图片就可以进行消除,用来放置图片的格子我这里给的是七个,如果填满了七个格子还没有进行消除的话那么游戏就失败了,进行一个"游戏失败"的弹窗提示。
🏟这里博主给的是20*20的方格,也就是可以放置四百个图片,那么图片太小的话我们不太看的清楚,这里我们可以设置成四个方格大小存放一张图片,那样就减少了存放图片的数量,同时游戏的界面也会更加好看,因为图片的尺寸要大一些,看起来也清楚许多。
二、具体实现方法及代码
首先我们需要创建一个坐标系:
// 坐标系的创建
let scene = document.querySelector(".scene");
let obj = {};
for (let i = 0; i < 20; i++) {
for (let j = 0; j < 20; j++) {
let block = document.createElement("div");
block.className = "block";
scene.appendChild(block);
obj[j + "-" + i] = block;
}
}
设置背景:
可以根据自己的喜好来设置喜欢的背景颜色;
设置整体坐标系大小:
.scene {
width: 500px;
height: 500px;
margin: 0 auto;
}
设置每个格子:
.block {
width: 25px;
height: 25px;
float: left;
position: relative;
}
设置7个格子用来存放选择的卡片:
.choose {
width: 357px;
height: 51px;
border-top: 1px solid red;
border-left: 1px solid red;
margin: 30px auto;
}
注意这里用来存放卡片的格子我们首先构建的格子的上、左两条边的样式,还需要设置格子的右、下两条边的格式;
.item {
width: 50px;
height: 50px;
border-right: 1px solid red;
border-bottom: 1px solid red;
float: left;
position: relative;
}
设置卡片的样式:
.card {
width: 50px;
height: 50px;
background-color: rgb(23, 228, 43);
position: absolute;
left: 0;
top: 0;
border-bottom: 3px solid #1cd241;
box-shadow: 0 0 3px #000;
background-size: 70%;
background-position: center;
background-repeat: no-repeat;
cursor: pointer;
}
卡片的背景和底色我们都是可以调的,直接修改background-color:rgb()即可。
创建卡片的代码:
// 创建卡片
let cardarr = []; //放置所有卡片的数组
function draw(level = 1) {
let posarr = [];
for (let i = 0; i < 20; i++) {
posarr.push([]);
for (let j = 0; j < 20; j++) {
posarr[i][j] = 0;
}
}
for (let i = level; i < 19 - level; i++) {
for (let j = 1; j < 10; j++) {
if (Math.random() < 0.2 && check(i, j, posarr)) {
posarr[i][j] = 1;
posarr[i][18 - j] = 1;
}
}
}
for (let i = 0; i < 20; i++) {
for (let j = 0; j < 20; j++) {
if (posarr[i][j] === 1) {
let card = document.createElement("div");
card.className = "card";
card.style.zIndex = 10 - level;
obj[j + "-" + i].appendChild(card);
cardarr.push(card);
// if (level > 1) {
// let mask = document.createElement("div");
// mask.className = "mask";
// mask.style.zIndex = 10 - level;
// obj[j + "-" + i].appendChild(mask);
// }
}
}
}
}
我们这里设置的七个格子,也就是图片的叠加层数是七层,既然有叠加,所以我们需要渲染叠加的遮罩;
// 渲染遮罩
function renderMask() {
let masks = document.querySelectorAll(".mask");
for (let i = 0; i < masks.length; i++)
masks[i].parentNode.removeChild(masks[i]);
for (let i = 0; i < cardarr.length; i++) {
let item = cardarr[i];
let rect = item.getBoundingClientRect();
let { x, y } = rect;
let one = document.elementFromPoint(x, y);
let two = document.elementFromPoint(x + 49, y);
let three = document.elementFromPoint(x, y + 49);
let four = document.elementFromPoint(x + 49, y + 49);
if (!(item.isSameNode(one) && item.isSameNode(two) && item.isSameNode(three) && item.isSameNode(four))) {
let mask = document.createElement("div");
mask.className = "mask";
mask.style.zIndex = getComputedStyle(cardarr[i]).zIndex;
cardarr[i].parentNode.appendChild(mask);
}
cardarr[i].index = i;
}
}
style中代码:
.mask {
width: 50px;
height: 50px;
background-color: #000000ae;
position: absolute;
left: 0;
top: 0;
}
图片渲染:
// 图片渲染
let imgarr = [];
for (let i = 0; i < cardarr.length / 3; i++) {
let n = Math.floor(Math.random() * 10);
imgarr.push(n);
}
let allimg = [...imgarr, ...imgarr, ...imgarr];
allimg.sort(function () {
if (Math.random() > 0.5) {
return 1;
}
else {
return -1;
}
});
for (let i = 0; i < cardarr.length; i++) {
cardarr[i].style.backgroundImage = "url(" + allimg[i] + ".png)";
cardarr[i].n=allimg[i];
}
触发点击事件:
// 点击事件
let choosedarr = [];
let items = document.querySelectorAll(".item");
scene.onclick = function (e) {
if (e.target.className === "card") {
let item = e.target;
// 删除页面的卡片
item.parentNode.removeChild(item);
// 从cardarr当中也去进行删除
cardarr.splice(item.index, 1);
if(cardarr.length===0){
alert("游戏成功");
location.reload();
}
// 重新绘制所有的遮罩
renderMask();
// 将当前被删除的卡片对象添加到choosedarr中
if(choosedarr.length===7){
alert("游戏失败");
location.reload();
}
choosedarr.push(item);
choosedarr.sort((a,b)=>a.n-b.n);
let count={};
for(let i=0;i<choosedarr.length;i++){
if(!count[choosedarr[i].n]){
count[choosedarr[i].n]=1;
}else{
count[choosedarr[i].n]+=1;
}
}
for(let i in count){
if(count[i]===3){
let length=choosedarr.length;
for(let j=0;j<choosedarr.length;j++){
if(choosedarr[j].n==i){
choosedarr.splice(j,1);
j--;
}
}
}
}
// 向item中添加卡片标签
for(let i=0;i<items.length;i++){
items[i].innerHTML="";
}
for (let i = 0; i < choosedarr.length; i++) {
items[i].appendChild(choosedarr[i]);
}
}
}
三、运行结果展示
整体样式:
消除展示:
失败演示:
四、完整代码
1、文件设置格式
把ylgy.html文件和10张图片都放到一个文件夹下面,注意图片的格式修改为数字.png;这样才能保证正常运行;
如果你想修改图片的话,可以自行下载后放在该文件夹下面即可。
源码以及图片素材获取地址github:羊了个羊仿写页面;
源代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>羊了个羊</title>
<style>
body {
background-color: rgb(31, 146, 199);
}
.scene {
width: 500px;
height: 500px;
margin: 0 auto;
}
.block {
width: 25px;
height: 25px;
float: left;
position: relative;
}
.choose {
width: 357px;
height: 51px;
border-top: 1px solid red;
border-left: 1px solid red;
margin: 30px auto;
}
.item {
width: 50px;
height: 50px;
border-right: 1px solid red;
border-bottom: 1px solid red;
float: left;
position: relative;
}
.card {
width: 50px;
height: 50px;
background-color: rgb(23, 228, 43);
position: absolute;
left: 0;
top: 0;
border-bottom: 3px solid #1cd241;
box-shadow: 0 0 3px #000;
background-size: 70%;
background-position: center;
background-repeat: no-repeat;
cursor: pointer;
}
.mask {
width: 50px;
height: 50px;
background-color: #000000ae;
position: absolute;
left: 0;
top: 0;
}
</style>
</head>
<body>
<div class="scene">
</div>
<div class="choose">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<script>
// 坐标系的创建
let scene = document.querySelector(".scene");
let obj = {};
for (let i = 0; i < 20; i++) {
for (let j = 0; j < 20; j++) {
let block = document.createElement("div");
block.className = "block";
scene.appendChild(block);
obj[j + "-" + i] = block;
}
}
// 创建卡片
let cardarr = []; //放置所有卡片的数组
function draw(level = 1) {
let posarr = [];
for (let i = 0; i < 20; i++) {
posarr.push([]);
for (let j = 0; j < 20; j++) {
posarr[i][j] = 0;
}
}
for (let i = level; i < 19 - level; i++) {
for (let j = 1; j < 10; j++) {
if (Math.random() < 0.2 && check(i, j, posarr)) {
posarr[i][j] = 1;
posarr[i][18 - j] = 1;
}
}
}
for (let i = 0; i < 20; i++) {
for (let j = 0; j < 20; j++) {
if (posarr[i][j] === 1) {
let card = document.createElement("div");
card.className = "card";
card.style.zIndex = 10 - level;
obj[j + "-" + i].appendChild(card);
cardarr.push(card);
// if (level > 1) {
// let mask = document.createElement("div");
// mask.className = "mask";
// mask.style.zIndex = 10 - level;
// obj[j + "-" + i].appendChild(mask);
// }
}
}
}
}
for (let i = 7; i > 0; i--) {
draw(i);
}
// 把多余的卡片删除
let length = cardarr.length;
for (let i = 0; i < length % 3; i++) {
let card = cardarr.pop();
card.parentNode.removeChild(card);
}
function check(i, j, posarr) {
if (posarr[i][j - 1] || posarr[i - 1][j - 1] || posarr[i - 1][j] || posarr[i - 1][j + 1]) {
return false;
}
else {
return true;
}
}
// scene.getboundingClientRect;
// scene.isSameElement;
// 渲染遮罩
function renderMask() {
let masks = document.querySelectorAll(".mask");
for (let i = 0; i < masks.length; i++)
masks[i].parentNode.removeChild(masks[i]);
for (let i = 0; i < cardarr.length; i++) {
let item = cardarr[i];
let rect = item.getBoundingClientRect();
let { x, y } = rect;
let one = document.elementFromPoint(x, y);
let two = document.elementFromPoint(x + 49, y);
let three = document.elementFromPoint(x, y + 49);
let four = document.elementFromPoint(x + 49, y + 49);
if (!(item.isSameNode(one) && item.isSameNode(two) && item.isSameNode(three) && item.isSameNode(four))) {
let mask = document.createElement("div");
mask.className = "mask";
mask.style.zIndex = getComputedStyle(cardarr[i]).zIndex;
cardarr[i].parentNode.appendChild(mask);
}
cardarr[i].index = i;
}
}
renderMask()
// 图片渲染
let imgarr = [];
for (let i = 0; i < cardarr.length / 3; i++) {
let n = Math.floor(Math.random() * 10);
imgarr.push(n);
}
let allimg = [...imgarr, ...imgarr, ...imgarr];
allimg.sort(function () {
if (Math.random() > 0.5) {
return 1;
}
else {
return -1;
}
});
for (let i = 0; i < cardarr.length; i++) {
cardarr[i].style.backgroundImage = "url(" + allimg[i] + ".png)";
cardarr[i].n=allimg[i];
}
// 点击事件
let choosedarr = [];
let items = document.querySelectorAll(".item");
scene.onclick = function (e) {
if (e.target.className === "card") {
let item = e.target;
// 删除页面的卡片
item.parentNode.removeChild(item);
// 从cardarr当中也去进行删除
cardarr.splice(item.index, 1);
if(cardarr.length===0){
alert("游戏成功");
location.reload();
}
// 重新绘制所有的遮罩
renderMask();
// 将当前被删除的卡片对象添加到choosedarr中
if(choosedarr.length===7){
alert("游戏失败");
location.reload();
}
choosedarr.push(item);
choosedarr.sort((a,b)=>a.n-b.n);
let count={};
for(let i=0;i<choosedarr.length;i++){
if(!count[choosedarr[i].n]){
count[choosedarr[i].n]=1;
}else{
count[choosedarr[i].n]+=1;
}
}
for(let i in count){
if(count[i]===3){
let length=choosedarr.length;
for(let j=0;j<choosedarr.length;j++){
if(choosedarr[j].n==i){
choosedarr.splice(j,1);
j--;
}
}
}
}
// 向item中添加卡片标签
for(let i=0;i<items.length;i++){
items[i].innerHTML="";
}
for (let i = 0; i < choosedarr.length; i++) {
items[i].appendChild(choosedarr[i]);
}
}
}
</script>
</body>
</html>
🏖🏖OK,那么今天的前端知识分享就到这里啦,原来前端这么有意思,后续会持续更新,感谢关注;最近也是在做测开+Java方向的面试真题+投递链接,感兴趣的小伙伴可参考->
📑本专栏:大厂直通车!有任何问题可以下方VX联系到博主喔!!