HTML&CSS:如何让 Flappy Bird 游戏在页面 “活” 起来

189 阅读3分钟

这段代码创建了一个动态的 Flappy Bird 游戏动画,通过 CSS 动画技术模拟了小鸟的飞行动作和背景的滚动,为页面添加了趣味性的视觉效果。

演示效果

HTML&CSS

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>公众号关注:前端Hardy</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            background: #e8e8e8;
            display: flex;
            align-items: center;
            justify-content: center;
            height: 100vh;
        }

        .loader {
            position: relative;
            width: 18rem;
            aspect-ratio: 1;
            overflow: hidden;
            background: linear-gradient(to bottom, #6ccee7 60%, white);
        }

        #bird {
            position: absolute;
            left: 50%;
            top: 50%;
            transform: translate(-80%, -50%);
            width: 3rem;
            height: auto;
            animation: flap 500ms linear infinite;
        }

        .flappyBirdScene,
        .flappyBirdSceneBottom {
            display: flex;
            width: 20rem;
            top: -23%;
            position: relative;
        }

        .sceneTop {
            display: flex;
            width: fit-content;
            animation: flow 5s linear infinite;
        }

        .sceneBottom {
            display: flex;
            width: fit-content;
            animation: flowBottom 5s linear infinite;
        }

        #birdObstacle {
            height: 8rem;
            width: 2rem;
            background: linear-gradient(to right,
                    #9de558 0px,
                    #9de558 3px,
                    #e7ff8d 3px,
                    #e7ff8d 5px,
                    #9de858 5px,
                    #9de858 10px,
                    #74c029 10px,
                    #74c029 13px,
                    #9de558 13px,
                    #9de558 15px,
                    #74c029 22px,
                    #74c029 28px,
                    #59811a 28px,
                    #59811a 100%);
            border: solid;
            position: relative;
        }

        .flappyBirdSceneBottom {
            bottom: -25%;
            left: 0;
        }

        #birdObstacle::after {
            content: "";
            position: absolute;
            width: 135%;
            height: 1.25rem;
            top: 100%;
            left: 50%;
            border: solid;
            transform: translate(-50%, 0);
            background: linear-gradient(to right,
                    #9de558 0px,
                    #9de558 3px,
                    #e7ff8d 3px,
                    #e7ff8d 5px,
                    #9de858 5px,
                    #9de858 10px,
                    #74c029 10px,
                    #74c029 13px,
                    #9de558 13px,
                    #9de558 15px,
                    #74c029 22px,
                    #74c029 28px,
                    #59811a 28px,
                    #59811a 100%);
        }

        .birdObs2 {
            transform: translate(0%, 15%);
            left: 15%;
        }

        .birdObs3 {
            transform: translate(0, 18%);
            left: 30%;
        }

        .birdObs4 {
            transform: translate(0, 15%);
            left: 45%;
        }

        @keyframes flap {
            from {
                transform: translate(-80%, -50%);
            }

            25% {
                transform: translate(-80%, -50%) rotate(-15deg);
            }

            50% {
                transform: translate(-80%, -12%) rotate(5deg);
            }

            100% {
                transform: translate(-80%, -50%);
            }
        }

        @keyframes flow {
            from {
                transform: translate(0, -43%);
            }

            to {
                transform: translate(-50%, -43%);
            }
        }

        @keyframes flowBottom {
            from {
                transform: translate(0, 75%) rotateX(180deg);
            }

            to {
                transform: translate(-50%, 75%) rotateX(180deg);
            }
        }
    </style>
</head>

<body>
    <div class="loader">
        <svg width="115" height="81" viewBox="0 0 115 81" fill="none" xmlns="http://www.w3.org/2000/svg" id="bird">
            <rect x="41" y="47" width="20" height="7" fill="#FFEB3B"></rect>
            <rect x="35" y="67" width="33" height="7" fill="#FFC107"></rect>
            <rect x="21" y="54" width="40" height="14" fill="#FFC107"></rect>
            <rect x="48" y="40" width="20" height="7" fill="#FFEB3B"></rect>
            <rect x="48" y="33" width="20" height="7" fill="#FFEB3B"></rect>
            <rect x="41" y="27" width="20" height="7" fill="#FFEB3B"></rect>
            <rect x="34" y="20" width="20" height="7" fill="#FFEB3B"></rect>
            <rect x="28" y="14" width="20" height="7" fill="#FFEB3B"></rect>
            <rect x="40" y="7" width="21" height="7" fill="#FFEB3B"></rect>
            <rect x="41" y="34" width="7" height="13" fill="black"></rect>
            <rect x="21" y="14" width="7" height="7" fill="black"></rect>
            <rect x="41" width="40" height="7" fill="black"></rect>
            <rect x="28" y="7" width="13" height="7" fill="black"></rect>
            <rect x="7" y="27" width="34" height="27" fill="#FFFFCC"></rect>
            <rect x="61" y="12" width="34" height="28" fill="white"></rect>
            <rect x="7" y="20" width="27" height="7" fill="black"></rect>
            <rect x="34" y="27" width="7" height="7" fill="black"></rect>
            <rect x="7" y="40" width="7" height="7" fill="#FFEB3B"></rect>
            <rect x="34" y="40" width="7" height="7" fill="#FFEB3B"></rect>
            <rect x="48" y="14" width="7" height="7" fill="#FFEB3B"></rect>
            <rect x="7" y="47" width="7" height="7" fill="black"></rect>
            <rect x="14" y="47" width="20" height="7" fill="#FFEB3B"></rect>
            <rect y="47" width="20" height="7" transform="rotate(-90 0 47)" fill="black"></rect>
            <rect x="34" y="47" width="7" height="7" fill="black"></rect>
            <rect x="88" y="13" width="7" height="7" fill="black"></rect>
            <rect x="81" y="6" width="7" height="7" fill="black"></rect>
            <rect x="95" y="40" width="20" height="7" transform="rotate(-90 95 40)" fill="black"></rect>
            <rect x="81" y="33" width="13" height="7" transform="rotate(-90 81 33)" fill="black"></rect>
            <rect x="81" y="13" width="13" height="7" transform="rotate(-180 81 13)" fill="white"></rect>
            <rect x="61" y="33" width="7" height="7" fill="black"></rect>
            <rect x="61" y="6" width="7" height="7" fill="black"></rect>
            <rect x="54" y="33" width="20" height="7" transform="rotate(-90 54 33)" fill="black"></rect>
            <rect x="14" y="60" width="7" height="7" fill="black"></rect>
            <rect x="21" y="67" width="14" height="7" fill="black"></rect>
            <rect x="35" y="74" width="33" height="7" fill="black"></rect>
            <rect x="14" y="54" width="20" height="7" fill="black"></rect>
            <rect x="108" y="47" width="7" height="7" fill="black"></rect>
            <rect x="68" y="53" width="33" height="7" fill="black"></rect>
            <rect x="68" y="46" width="40" height="7" fill="#F44336"></rect>
            <rect x="65" y="60" width="40" height="7" fill="#F44336"></rect>
            <rect x="101" y="67" width="14" height="7" transform="rotate(-90 101 67)" fill="black"></rect>
            <rect x="61" y="46" width="7" height="7" fill="black"></rect>
            <rect x="68" y="40" width="40" height="7" fill="black"></rect>
            <rect x="68" y="67" width="33" height="7" fill="black"></rect>
            <rect x="54" y="53" width="7" height="7" fill="black"></rect>
            <rect x="61" y="53" width="7" height="7" fill="#F44336"></rect>
            <rect x="61" y="60" width="7" height="7" fill="black"></rect>
        </svg>
        <div class="sceneTop">
            <div class="flappyBirdScene">
                <div class="birdObs1" id="birdObstacle"></div>
                <div class="birdObs2" id="birdObstacle"></div>
                <div class="birdObs3" id="birdObstacle"></div>
                <div class="birdObs4" id="birdObstacle"></div>
            </div>
            <div class="flappyBirdScene">
                <div class="birdObs1" id="birdObstacle"></div>
                <div class="birdObs2" id="birdObstacle"></div>
                <div class="birdObs3" id="birdObstacle"></div>
                <div class="birdObs4" id="birdObstacle"></div>
            </div>
        </div>
        <div class="sceneBottom">
            <div class="flappyBirdSceneBottom">
                <div class="birdObs1" id="birdObstacle"></div>
                <div class="birdObs2" id="birdObstacle"></div>
                <div class="birdObs3" id="birdObstacle"></div>
                <div class="birdObs4" id="birdObstacle"></div>
            </div>
            <div class="flappyBirdSceneBottom">
                <div class="birdObs1" id="birdObstacle"></div>
                <div class="birdObs2" id="birdObstacle"></div>
                <div class="birdObs3" id="birdObstacle"></div>
                <div class="birdObs4" id="birdObstacle"></div>
            </div>
        </div>
    </div>
</body>

</html>

HTML 结构

  • loader: 创建一个类名为“loader”的 div 元素,用于包含整个 Flappy Bird 动画场景。

CSS 样式

  • body: 设置页面的边距、填充、背景色、显示方式和高度。
  • .loader: 设置容器的样式,包括位置、尺寸、宽高比、溢出隐藏和背景渐变。
  • #bird: 设置小鸟的样式,包括位置、变换和动画。
  • .flappyBirdScene 和 .flappyBirdSceneBottom: 设置场景的布局和位置。
  • .sceneTop 和 .sceneBottom: 设置顶部和底部场景的布局和动画。
  • #birdObstacle: 设置障碍物的样式,包括尺寸、背景渐变和边框。
  • .birdObs2, .birdObs3, .birdObs4: 设置不同障碍物的位置。
  • @keyframes flap: 定义小鸟翅膀扇动的动画。
  • @keyframes flow 和 @keyframes flowBottom: 定义场景流动的动画。
  • svg: SVG容器,包含了多个rect元素,这些矩形元素- 组合起来形成了小鸟的形象。
  • 每个rect元素都有特定的位置、尺寸和颜色,用于构建小鸟的不同部分。
  • #bird: 通过animation属性应用了flap动画,使小鸟的翅膀能够上下扇动。
  • .sceneTop 和 .sceneBottom: 通过animation属性应用了flow和flowBottom动画,使场景能够左右移动,模拟游戏背景的滚动。