Web前端开发实训 -- 弹球王小游戏

1. 作品展示

2. 代码(全)

链接:https://pan.baidu.com/s/1Mxdz8rR18uM_7yuY-eTwbQ 
提取码:6666

以下是项目目录及部分代码。

① 项目目录

② HTML 

<!-- page\PinballKing.html -->

<!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>
    <link rel="stylesheet" href="../css/index.css">
</head>

<body>
    <div class="game-zone">
        <div class="function-area">
            <div class="button continue-button keep">继续</div>
            <div class="button start-button play">开始游戏</div>
            <div class="button puse-button suspend">暂停</div>
        </div>
        <div class="blocks">

            <div class="ball"></div>
            <div class="skate"></div>
            <div class="message">
                <div class="info-txt">第&nbsp;1&nbsp;关</div>
                <div class="info-time">时间: 00:00</div>
                <div class="info-number">砖块: 0</div>
            </div>

        </div>

</body>

<script src="../js/index.js">
</script>
</html>

③ CSS

/* css\index.css */

/* 游戏区 */
.game-zone {
    background-color: pink;
    height: 600px;
    width: 900px;
    margin: 50px 300px;
    color: white;
    font-size: 25px;
    font: bold;
    font-family: cursive;
    user-select: none;
}
/* 功能区 */
.function-area {
    height: 36px;
    background-color: #ccc;
    display: flex;
}
/* 开始游戏按钮 */
.active {
    background-color: black;
}
.start-button {
    flex: 1;
    /* justify-content 用于设置或检索弹性盒子元素在主轴(横轴)方向上的对齐方式。 */
    justify-content: center;
    /* align-items 属性定义flex子项在flex容器的当前行的侧轴(纵轴)方向上的对齐方式。 */
    align-items: center;
    color: #fff;
    display: flex;
}
.start-button:hover {
    background-color: rgb(115, 115, 168);
}
/* 继续 */
.continue-button {
    flex: 1;
    justify-content: center;
    align-items: center;
    color: #fff;
    display: flex;
}
.continue-button:hover {
    background-color: rgb(187, 187, 247);
}
/* 暂停 */
.puse-button {
    flex: 1;
    justify-content: center;
    align-items: center;
    color: #fff;
    display: flex;
}
.puse-button:hover {
    background-color: rgb(160, 160, 212);
}
/* 堆块区 */
.blocks {
    height: calc(600px - 36px);
    background-color: rgb(220, 247, 255);
    position: relative;
    overflow: hidden;
}
.row {
    height: 20px;
    margin-top: 15px;
    /* margin-right: 5px;
    margin-left: 5px; */
    display: flex;
    justify-content: space-between;
}
.brick {
    width: 107px;
    height: 30px;
}
.brick:nth-child(1) {
    background-color: rgb(255, 106, 106);
    border-radius: 10px;
}
.brick:nth-child(2) {
    background-color: rgb(255, 161, 126);
    border-radius: 10px;
}
.brick:nth-child(3) {
    background-color: rgb(253, 255, 147);
    border-radius: 10px;
}
.brick:nth-child(4) {
    background-color: rgb(173, 248, 143);
    border-radius: 10px;
}
.brick:nth-child(5) {
    background-color: rgb(146, 190, 255);
    border-radius: 10px;
}
.brick:nth-child(6) {
    background-color: rgb(155, 214, 253);
    border-radius: 10px;
}
.brick:nth-child(7) {
    background-color: rgb(209, 152, 255);
    border-radius: 10px;
}
.brick:nth-child(8) {
    background-color: coral;
    border-radius: 10px;
}
/* 滑板 */
.skate {
    width: 100px;
    height: 20px;
    background-image: url("../images/skate.png");
    border-radius: 20px;
    position: absolute;
    left: 400px;
    bottom: 1px;
}
.ball {
    width: 20px;
    height: 20px;
    position: absolute;
    left: 440px;
    bottom: 22px;
    border-radius: 20px;
    background-image: url("../images/ball.png");
}
.message {
    font-size: 20px;
    position: absolute;
    right: 85px;
    bottom: 40px;
    line-height: 30px;
    color: pink;
}

④ JS

/* js\index.js */

// 封装一个添加类名的函数
function addClass(obj) {
    // classList 属性返回元素的类名,作为 DOMTokenList 对象
    var buttons = document.querySelectorAll(".button");
    for (var i = 0; i < buttons.length; i++) {
        buttons[i].classList.remove("active");
    }
    obj.classList.add("active");
};

// 循环创建div
var blocks = document.querySelector(".blocks");
function createBrick(n) {
    for (var i = 0; i < n; i++) {
        var row = document.createElement("div");
        row.classList.add("row");
        for (var j = 0; j < 8; j++) {
            var brick = document.createElement("div");
            brick.classList.add("brick");
            row.appendChild(brick);
        }
        blocks.appendChild(row);
    }
    var brick = document.querySelectorAll(".brick");
    for (var i = 0; i < brick.length; i++) {
        brick[i].style.left = brick[i].offsetLeft + "px";
        brick[i].style.top = brick[i].offsetTop + "px";
    }
    for (var j = 0; j < brick.length; j++) {
        brick[j].style.position = "absolute";
    }
};
createBrick(8);

// 封装定时器
function innerval() {
    timer = setInterval(function() {
        ball.style.top = ball.offsetTop + spendY + "px";
        ball.style.left = ball.offsetLeft + spendX + "px";
        //  是否出上边界
        if (ball.offsetTop < 0) {
            spendY *= -1
        }
        // 是否出左右边界
        if (ball.offsetLeft < 0 || ball.offsetLeft > blocksWidth - ballWidth) {
            spendX *= -1
        }

        // 是否出下边界
        if (ball.offsetTop > blocksHeight - ballHeight) {
            // 游戏结束,停止定时器
            clearInterval(timer)
                // 解绑事件
            skate.onmousedown = null;
            document.onmousemove = null;
            alert("游戏结束!");
        }

        if (collide(ball, skate)) {
            spendY *= -1;
        }

        var rows = document.querySelectorAll(".row");
        for (var i = 0; i < rows.length; i++) {
            var item = rows[i];
            for (var k = 0; k < item.children.length; k++) {
                if (collide(ball, item.children[k])) {
                    spendY *= -1;
                    item.children[k].style.display = "none";
                    score++;

                    var number = document.querySelector(".info-number");
                    number.innerText = "砖块:" + score;

                }
            }
        }

        time++;

        var infoTime = document.querySelector(".info-time");
        infoTime.innerText = "时间:" + resetTime(time * 20 / 1000)

    }, 20);
};

// 封装两个节点相撞的函数
function collide(node1, node2) {
    var left1 = node1.offsetLeft;
    var right1 = node1.offsetLeft + node1.offsetWidth;
    var top1 = node1.offsetTop;
    var bottom1 = node1.offsetTop + node1.offsetHeight;

    var left2 = node2.offsetLeft;
    var right2 = node2.offsetLeft + node2.offsetWidth;
    var top2 = node2.offsetTop;
    var bottom2 = node2.offsetTop + node2.offsetHeight;

    if (left1 > right2 || left2 > right1 || top1 > bottom2 || top2 > bottom1) {
        return 0;
    } else {
        return 1;
    }
}

// 重置时间 
function resetTime(setTime) {
    var f = Math.floor(setTime / 60);
    var s = Math.floor(setTime % 60);
    return (f < 10 ? "0" + f : f) + ":" + (s < 10 ? "0" + s : s);
}

// querySelector() 方法返回文档中匹配指定 CSS 选择器的一个元素
var skate = document.querySelector(".skate");
var gameZone = document.querySelector(".game-zone");
var ball = document.querySelector(".ball");
var blocks = document.querySelector(".blocks");

var skateWidth = skate.offsetWidth;
var skateHeight = skate.offsetHeight;

var gameZoneWidth = gameZone.offsetWidth;

var blocksWidth = blocks.offsetWidth;
var blocksHeight = blocks.offsetHeight;

var ballHeight = ball.offsetHeight;
var ballWidth = ball.offsetWidth;

var spendY;
var spendX;
var timer;

var score = 0;
var time = 1;

// 开始游戏
var play = document.querySelector(".play");
play.onclick = function() {
    // play.classList.add("active");
    addClass(play);

    // 滑板绑定鼠标按下事件
    skate.onmousedown = function() {
        document.onmousemove = function(e) {
            // js在事件处理兼容IE和非IE的写法
            var e = e || window.event;
            // e.pageX -> 触摸目标在页面中的x坐标。
            var moveX = e.pageX - gameZone.offsetLeft - skateWidth / 2;

            //  判断是否出了左边界
            if (moveX < 0) {
                moveX = 0;
            }
            // 判断是否出了右边界
            if (moveX > gameZoneWidth - skateWidth) {
                moveX = gameZoneWidth - skateWidth;
            }
            skate.style.left = moveX + "px";

        }
    };

    document.onmouseup = function() {
        // 鼠标弹起解绑鼠标移动事件
        document.onmousemove = null;
    };

    // 小球的垂直速度 -3 ~ -5
    spendY = Math.floor(Math.random() * (-3 - (-5) + 1) + -5);

    // 小球的水平速度 -5 ~ 5
    spendX = Math.floor(Math.random() * (5 - -5 + 1) + -5);

    while (spendY == 0) {
        // 重新生成一个随机数
        spendY = Math.floor(Math.random() * (5 - -5 + 1) + -5);
        if (spendX != 0) {
            break;
        }
    }

    innerval();

};

// 继续
var keep = document.querySelector(".keep")
keep.onclick = function() {
    addClass(keep);
    innerval();
};

// 暂停
var suspend = document.querySelector(".suspend")
suspend.onclick = function() {
    addClass(suspend);
    clearInterval(timer);
};

  • 2
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值