CSS实现经典打字小游戏《生死时速》

在这里插入图片描述

🌻 前言

CSS 中有这样一个模块:Motion Path 运动模块,它可以使元素按照自定义的路径进行移动。本文将为你讲解这个模块属性的使用,并且利用它实现我小时候电脑课经常玩的一个打字游戏:金山打字的《生死时速》。

🪴 Motion Path 使用教程

css中有这样一个模块:Motion Path ,它可以实现元素按不规则路径移动。

Motion Path模块包含 offset 的一系列属性,包括以下几个:

  • offset-path:设置元素运动路径;
  • offset-distance:控制当前元素基于 offset-path 运动的距离;
  • offset-anchor:定义元素在路径上移动时的锚点。 简单来说就是,运动元素可能不是一个点,那么就需要指定元素中的哪个点附着在路径上进行运动
  • offset-position:指定运动的初始位置;
  • offset-rotate:定义沿 offset-path 运动路径移动时元素的朝向;

1. offset-path

offset-path 属性可以取以下几个值来设置元素的运动路径:

  • ray()函数ray([<angle> && <size> && contain?]),设置以射线状路线偏移;
  • url()函数:用id选择器绑定页面内联SVG元素中任意图形元素的路径;
  • <basic-shape>:一些css的基本形状函数,例如:circle(), ellipse(), inset(), path(), polygon(), rect()等,对于可以设置position位置的circle(), ellipse(),如果没有设置position的话,就会应用offset-position的值;
  • box-edge:设置以相对的父元素的边缘为运动路径,例如设置content-box、border-box、fill-box等,可以设置按内容区的边缘还是边框边缘等;

看下面例子就懂了:

下面代码中ray射线运动是设置元素朝70度方向运动200px;
按svg路径运动是让电车以一个五角星的svg的路线运动;
shape图形是让电车以polygon()绘制的菱形运动;
box是在其父盒子边缘运动;
jcode

2. offset-distance

设置运动的距离,可以是值,也可以是百分比,例如设置0%处于初始位置,100%就是移动到路径的终点。所以一般实现元素按不规则路径移动,就是通过animation修改offset-distance实现的。

jcode

3. offset-anchor

设置元素的哪个点沿着路径运动,例如设置offset-anchor: center bottom为元素的底部中心点沿路径移动,其他就不多说了,使用方式和background-position一样。

jcode

4. offset-position

设置运动的起始位置,只能作用于可以设置position的路线.

例如 ray() 射线运动,可以设置起点位置,或者ellipse()、circle()等这些需要设置position的图形元素。而且如果在定义路径时已经写明了position的话,offset-position是不会生效的,例如circle(50% at 25% 25%)

5. offset-rotate

offset-rotate定义元素沿偏移路径定位时的方向,默认的话是元素角度会一直和运动路径的水平角度保持一致,当然你也可以自定义固定角度,或者反向显示元素(reverse)。

看下面例子就明白了:

jcode

🎯 游戏开发

1. 游戏简介

游戏开始后,警察在3秒后开始出动,如果警察抓到小偷(位置重合)即游戏失败。
你需要根据页面底部的对话正确输入单词,即可让小偷不断运动,拉开与警察的距离,如果在输入全部对话前没有被警察逮到,即闯关成功。

整个游戏其实实现起来很简单,只需要在设置offset路径动画的基础上加一点点细节就完成了。

2. 利用offset属性实现运动路径

找个svg在线编辑网站,设计一个用来当道路等路径path,然后将两个位置重合的元素设置相同的运动路径,即可实现警察和小偷的运动路线。

tutieshi_640x347_4s.gif

3. 实现警察追小偷

  1. 如何实现警察小偷你追我赶的情景呢?很简单,警察是一直在运动的,只要小偷不要一直运动,两者错开即可。

只需要利用animation-play-state: paused属性控制小偷运动暂停即可,如果你输入正确的字符,则设置为animation-play-state: running继续运动。

  1. 如何制作打字控制小偷移动的效果呢?

很简单,监听键盘输入即可,如果输入正确,则将此字符推入答案中,并设置小偷animation-play-state: running让他继续运动,延时一小段时间再设置为paused暂停。
答案和题目重合,并且答案设置为了蓝色,在答案尾部还利用step逐帧动画,方便体现打字的进度。因为输入时,输入空格也需要光标移动,所以一定要在答案元素上设置white-space: pre以保留空白符的所有空白。另外,为了使要输入的字符永远显示出来,我在推入答案时会使光标调用scrollIntoView()方法使其滚动到可视区。

document.addEventListener('keydown', function (event) {
    const myinput = answer.textContent
    if (event.key === words[myinput.length]) {
        timer && clearTimeout(timer)
        answer.textContent = myinput + event.key
        thief.style.setProperty('--paused', 'running');
        document.querySelector('.show').scrollIntoView(true)
        timer = setTimeout(() => {
            thief.style.setProperty('--paused', 'paused');
        }, 400);
    }
});
setTimeout(() => {
    checkCollision()
    police.style['animation-play-state'] = 'running'
}, 2000);

在这里插入图片描述

4. 判断结果

如果做碰撞检测呢并显示结果呢?

碰撞检测其实很简单,只需要利用getBoundingClientRect()方法获取警察和小偷的定位,判断是否几乎重合即可。判断输赢的方式为:如果你在打完所有文字之前不被逮捕则闯关成功,否则闯关失败。

// 碰撞检测
function checkCollision() {
    const policeRect = police.getBoundingClientRect()
    const thiefRect = thief.getBoundingClientRect()
    if (answer.textContent.length >= words.length) {
        showResult(true)
        return
    }
    if (Math.abs(policeRect.x - thiefRect.x) < 2 && Math.abs(policeRect.y - thiefRect.y) < 2) {
        showResult()
        return
    }
    requestAnimationFrame(checkCollision)
}
// 结局判断
function showResult(flag) {
    if (flag) {
        document.querySelector('.success').style.display = 'grid'
    } else {
        document.querySelector('.fail h1').textContent =
            `你被逮捕了!${document.querySelector(".timing").textContent}`
        document.querySelector('.fail').style.display = 'grid'
    }
}

在这里插入图片描述

🎮 玩游戏

《生死时速》游戏地址

更多游戏

🎁最后

学如逆水行舟,不进则退~
我是喜欢归纳总结前端相关知识的前端阿彬,欢迎点赞关注

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/710113.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【免费Web系列】大家好 ,今天是Web课程的第二一天点赞收藏关注,持续更新作品 !

这是Web第一天的课程大家可以传送过去学习 http://t.csdnimg.cn/K547r 员工管理 1. 条件分页查询 1.1 概述 在页面原型中&#xff0c;我们可以看到在查询员工信息列表时&#xff0c;既需要根据条件动态查询&#xff0c;还需要对查询的结果进行分页处理。 那要完成这个页面…

计算机组成原理历年考研真题对应知识点(计算机系统层次结构)

目录 1.2计算机系统层次结构 1.2.2计算机硬件 【命题追踪——冯诺依曼计算机的特点(2019)】 【命题追踪——MAR 和 MDR 位数的概念和计算(2010、2011)】 1.2.3计算机软件 【命题追踪——三种机器语言的特点(2015)】 【命题追踪——各种翻译程序的概念(2016)】 1.2.5计算…

四十五、openlayers官网示例Icon modification解析——在地图上添加标记图形并随意移动它的位置

官网demo地址&#xff1a; Icon modification 这篇讲了如何随意移动地图上的矢量点。 先在地图上添加一个矢量点&#xff0c;其中anchorXUnits 和 anchorYUnits: 指定锚点的单位。fraction 表示相对于图标的宽度&#xff08;0到1之间&#xff09;&#xff0c;pixels 表示以像素…

关于Unity四种合批技术详解

文章目录 一.静态合批(StaticBatching)1.启用静态合批2.举例说明3.静态合批的限制4.静态合批的优点缺点5.动态指定物品合批 二.动态合批(Dynamic Batching)1.启用动态合批2.合批规则3.举例说明4.使用限制 三.GPU Instancing1.启用GPU Instancing2.启用限制3.举例说明 四.SRP Ba…

【面试干货】ArrayList、Vector、LinkedList的存储性能和特性比较

【面试干货】ArrayList、Vector、LinkedList的存储性能和特性比较 1、ArrayList1.1 存储性能1.2 特性1.3 示例用法 2、Vector2.1 存储性能2.2 特性2.3 示例用法 3、LinkedList3.1 存储性能3.2 特性3.3 示例用法 4、ArrayList、Vector、LinkedList用法总结 &#x1f496;The Beg…

Java数据库编程

引言 在现代应用开发中&#xff0c;与数据库交互是不可或缺的一部分。Java提供了JDBC&#xff08;Java Database Connectivity&#xff09; API&#xff0c;允许开发者方便地连接到数据库并执行SQL操作。本文将详细介绍Java数据库编程的基础知识&#xff0c;包括JDBC的基本概念…

AI金融投资:批量下载深交所公募REITs公开说明书

打开深交所公募REITs公开说明书页面&#xff0c;F12查看网络&#xff0c;找到真实地址&#xff1a;https://reits.szse.cn/api/disc/announcement/annList?random0.3555675437003616 { "announceCount": 39, "data": [ { "id": "80bc9…

循环订单激励:打造企业增长新引擎

循环订单激励&#xff1a;打造企业增长新引擎 在当今竞争激烈的商业环境中&#xff0c;许多企业都在寻求独特而高效的营销策略以吸引并留住客户。今天&#xff0c;我要为您介绍的是一种名为“循环订单激励”的新颖模式&#xff0c;它不仅能提升客户参与度&#xff0c;还能为企…

《站在2024年的十字路口:计算机专业是否仍是高考生的明智之选?》

文章目录 每日一句正能量前言行业竞争现状行业饱和度和竞争激烈程度[^3^]新兴技术的影响[^3^]人才需求的变化[^3^]行业创新动态如何保持竞争力 专业与个人的匹配度判断专业所需的技术能力专业核心课程对学生的要求个人兴趣和性格特点专业对口的职业发展要求实践和经验个人价值观…

vivado HW_VIO

描述 虚拟输入/输出&#xff08;VIO&#xff09;调试核心hw_VIO可以监视和驱动内部 在编程的XilinxFPGA上实时显示信号。在没有物理访问的情况下 目标硬件&#xff0c;可以使用此调试功能来驱动和监视 存在于物理设备上。 VIO核心具有硬件探测器hw_probe对象&#xff0c;用于监…

VS2022,编译最新版obs30.1

VS2022&#xff0c;编译最新版obs30.1 VS2022&#xff0c;编译最新版obs30.1 VS2022&#xff0c;编译最新版obs30.1一、源码编译1.1 官方编译1.2 利用cmake软件进行编译 二、为二次开发做准备遇到问题&#xff0c;暂时无法解决 一、源码编译 编译环境Win11&#xff0c;VS2022&…

C++语法08 数据类型之间的强制转换

目录 强制类型转换 强制类型转换格式 整型转换成浮点型 整型转换成浮点型其他写法 训练&#xff1a;糖果奖励 糖果奖励参考代码 浮点型转换成整型 浮点型转换成整型其他写法 训练&#xff1a;分离小数 分离小数参考代码 强制类型转换 强制类型转换&#xff0c;就是把…

C++ static关键字详解

背景 前段时间初步整理了C中static的相关知识点&#xff0c;以此做个记录。 在C中&#xff0c;static关键字是常见的修饰符。从大方向上static分为两类&#xff1a; 1.类或结构体外的static 2.类或结构体内的static 因此&#xff0c;本文内容的划分如下&#xff1a; 接下来会…

Vue42-vc与vm的原型对象

一、普通函数与其对象的原型对象 显示原型属性&#xff0c;只有函数才有&#xff01;&#xff01;&#xff01; 实例对象只有隐式原型属性。 普通函数与其对象&#xff0c;指向同一个原型对象&#xff01;&#xff01;&#xff01; 这么写不推荐&#xff0c;建议直接如下格式&a…

k8s学习--helm的详细解释及安装和常用命令

文章目录 Helm简介什么是Helm主要组件核心概念chart结构总结 应用环境一、helm部署二、helm基础使用 Helm简介 什么是Helm Helm 是 Kubernetes 的一个包管理工具&#xff0c;它允许用户定义、安装和升级复杂的 Kubernetes 应用程序。Helm 通过使用 “Charts” 的概念来简化应…

byzer 笔记总结

1.总览&#xff08;简单了解&#xff09; 1.1 数据挖掘的定义 基于大数据技术&#xff0c;针对有价值是业务场景&#xff0c;对数据中台沉淀的大量数据进行探索&#xff0c;分析。寻找数据与数据之间潜藏的关系&#xff0c;转化为自动化的算法模型&#xff0c;从而获取有价值的…

【SpringBoot + Vue 尚庭公寓实战】地区信息管理接口实现(九)

【SpringBoot Vue 尚庭公寓实战】地区信息管理接口实现&#xff08;九&#xff09; 文章目录 【SpringBoot Vue 尚庭公寓实战】地区信息管理接口实现&#xff08;九&#xff09;1、业务说明2、数据逻辑模型3、接口实现3.1、查询省份信息列表3.2、根据省份ID查询城市信息列表3…

Hexapod C-887使用手册 -- 4,5,6

4 - 拆包 小心拆包C-887 根据合同和发货注意比较发货范围的内容&#xff1a; 检查危险符号的内容。如果任何零件损坏或缺失&#xff0c;立即联系客服部门。 保存所有包装材料&#xff0c;以防产品需要返厂。 5 - 安装 本章中 安装一般注意 安装PC软件 确保通风 接地C-…

增材制造引领模具创新之路

随着科技的快速发展和制造业的不断转型升级&#xff0c;增材制造&#xff08;也称为3D打印&#xff09;技术正逐渐展现出其在模具智造中的巨大潜力和优势。增材制造以其独特的加工方式和设计理念&#xff0c;为模具行业带来了革命性的变革&#xff0c;为传统制造业注入了新的活…