js开发bird小鸟

15分钟上手前端小游戏开发

演示效果

在这里插入图片描述

代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        html,
        body {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            width: 100%;
            height: 100%;
            background-color: #00ff94;
        }
        
        .sky {
            width: 100%;
            height: 100%;
            border: 1px solid black;
            position: relative;
            background-image: url(./哦哦哦哦哦.png);
        }
        
        .bird {
            position: absolute;
            left: 20px;
            top: 35%;
            width: 30px;
            height: 30px;
            background-color: #f40;
        }
        
        .up,
        .down {
            background-color: yellowgreen;
            position: absolute;
        }
    </style>
</head>

<body>
    <div class="sky">
        <div class="bird"></div>
    </div>
    <script>
        var g = 1;
        var arr = [];
        var flag = true;
        var wuwuwu = document.getElementsByClassName("bird")[0];
        var wuli = document.getElementsByClassName("sky")[0];
        // 鸟
        var bird = {
                body: wuwuwu,
                width: 30,
                height: 30,
                x: wuwuwu.offsetLeft,
                y: wuwuwu.offsetTop,
                speedX: 2,
                speedY: 0
            }
            // 天空
        var sky = {
                x: 0,
                height: wuli.offsetHeight,
                body: wuli
            }
            // 混屏
        var timer = setInterval(() => {
            if (flag) {
                sky.x -= bird.speedX;
                sky.body.style.backgroundPositionX = sky.x + "px";
                // 背景以小鸟飞的速度往左移动
                bird.speedY += g;
                // 这是业务逻辑
                bird.y += bird.speedY;
                bird.body.style.top = bird.y + "px";
                if (bird.y < 0 || bird.y > sky.height - bird.height) {
                    stop();
                }
            }
        }, 40);
        // 按键
        document.onkeydown = function(e) {
                if (e.keyCode === 38) {
                    bird.speedY = -10;
                } else if (e.keyCode === 13) {
                    location.reload();
                }
            }
            // gg
        function stop() {
            flag = false;
            clearInterval(timer);
            for (var i = 0; i < arr.length; i++) {
                clearInterval(arr[i].timer);
            }
        }
        class 柱子 {
            constructor(x) {
                let div = document.createElement("div");
                let div2 = document.createElement("div");
                let h0 = sky.height;
                let h1 = Math.ceil(Math.random() * 150) + 200;
                let h2 = h0 - h1 - 200;
                this.up = h1;
                this.down = h1 + 200;
                this.width = 80;
                this.x = x;
                this.div = div;
                this.div2 = div2;
                div.style.height = h1 + "px";
                div.style.left = x + "px";
                div.style.width = this.width + "px";
                div.className = "up";
                div2.className = "down";
                div2.style.width = this.width + "px";
                div2.style.height = h2 + "px";
                div2.style.top = h1 + 200 + "px";
                div2.style.left = x + "px";
                sky.body.appendChild(div);
                sky.body.appendChild(div2);
                this.timer = setInterval(() => {
                    if (flag) {
                        if (this.x <= -80) {
                            this.div.parentNode.removeChild(this.div);
                            this.div2.parentNode.removeChild(this.div2);
                            arr.shift();
                            arr[arr.length] = new 柱子(1100);
                        }
                        this.x -= 1;
                        div.style.left = this.x + "px";
                        div2.style.left = this.x + "px";
                        //   判定结束游戏
                        if (bird.x + bird.width > this.x && bird.x < this.x + this.width) {
                            // 横坐标进来了
                            if (bird.y <= this.up || bird.y >= this.down) {
                                stop();
                            }
                        }
                    }
                }, 10);
            }
        }
        for (var i = 0; i < 6; i++) {
            arr[i] = new 柱子(i * 200 + 400);
        }
    </script>
</body>

</html>

解析

解析一下这一坨长长的代码,是一个面向对象编程的超级小游戏
有一个鸟,一个天空,几个管子
鸟有宽度高度,有飞行的速度,还有自己的x、y值,就是定位的left与top
天空有背景图,这玩意一直跑,一直跑
每个柱子都是一个对象,他们生出来就开始往左边跑,直到出屏幕后被回收
当小鸟的坐标(x,y)与一些障碍物的坐标(x,y)冲突时,调用stop结束定时器,游戏结束。
游戏开始后,背景往左边滚,小鸟往下掉,柱子往左滚,按键盘上键,小鸟的向上的速度增加很多,但是定时器里,每次执行都会把小鸟向下的速度增加,所以小鸟迟早会往下掉,就需要适时的按上键来维持。

语法上一个是定时器,对象来存数据,dom操作与内存中数据同步
先说对象,是一种以键值对形式存储数据的方式,然后还是对显示一类事物抽象后又具象的一个有特点的家伙。鸟在这里有宽高有颜色有速度有坐标。天空和树又何尝不是?
再说dom操作,相信现在dom已经拦不住大家了,如果还是不熟练,dom操作案例讲解
再说定时器:
1、setTimeout允许设置一个超时对象,超时后执行这个对象,但是只执行一次,无周期
2、setInternval允许设置一个超时对象,超时后执行这个对象,周期等于超时对象指定的时间,周期为无限循环

定时器是在指定时间, 将任务放入事件队列,等待js引擎空闲后被执行.
就是说,到了时间,我把线程给你放到事件队列,主线程要是很忙,那么它就在队列放着,没法确保它执行。
使用setInterval时,并不能保证两次执行之间间隔具体是多少,因为我只是按时间差放到队列的,一切都要看它怎么执行的,电脑卡写啥代码也不会好使!
定时器还可以拿来渲染页面,有些好看的页面,一下子渲染出来会显得比较卡,慢慢来比较快。
另外记得clearInterval或clearTimeout,不然可能会出奇奇怪怪的事情

下一篇讲
js运行原理与机制
里面详细讲了定时器存在的潜在问题

猜你喜欢

转载自blog.csdn.net/jvhbi/article/details/107127041
今日推荐