这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

打开游戏界面,看到一个画面简洁、却又富有挑战性的游戏。屏幕上,有一个白色的矩形框,里面不断下落着各种单词,而我需要迅速地输入这些单词。如果我输入的单词与屏幕上的单词匹配,那么我就可以获得得分;如果我输入的单词错误或者时间过长,那么我就会输掉游戏。游戏的节奏非常快,每当我输入一个单词,屏幕上就会有新的单词出现,让我不能有丝毫的懈怠。

在游戏中,我不断地挑战自己,不断地提高自己的打字速度和准确性。经过一段时间的练习,我发现我的打字速度和准确性都有了显著的提高,这让我非常开心。

一、游戏介绍

打字游戏使用Canvas和JavaScript实现。游戏的核心玩法是,玩家需要在字母下落到底部之前输入相应的单词。如果玩家输入正确,就会得到相应的分数。游戏中包含了许多有趣的功能,如随机生成单词、单词下落、单词匹配、得分计算等等。此外,游戏设计还考虑到了玩家的游戏体验,如游戏难度的调整、游戏音效的设置等等。如果你喜欢挑战和打字游戏,那么这款游戏一定不容错过!

二、效果预览

体验链接:打飞字游戏 - 码上掘金 (juejin.cn)

三、实现思路

在实现游戏时,主要包括以下几个部分:

  • 随机生成单词
  • 添加新的单词
  • 更新画面
  • 画出单词
  • 处理已输入单词
  • 处理未输入单词
  • 重置游戏

具体实现可以参考代码中的注释。

1. 搭建页面结构

使用Canvas和JavaScript实现的打字游戏的HTML模板。在这个HTML模板中,我们使用了canvas元素来显示游戏画面。此外,我们还添加了一个得分标签、一个文本输入框和一个重置游戏按钮。在游戏开始时,用户需要点击文本输入框并输入单词。如果输入的单词与下落的单词匹配,则会得到相应的分数。如果下落的单词没有被输入,则游戏结束。用户可以通过点击重置游戏按钮重新开始游戏。

<!DOCTYPE html>
<html>
<head>
<title>Canvas打字游戏</title>
<meta charset="UTF-8">
</head>
<body>
<canvas id="gameCanvas" width="500" height="400"></canvas>
<p>得分: <span id="score">0</span></p>
<input type="text" id="userInput" autofocus>
<button id="resetButton">重新开始</button>
</body>
</html>

2. 美化界面

canvas {
border: 1px solid black;
} body {
display: flex;
flex-direction: column;
align-items: center;
} #gameCanvas {
margin: 20px;
} input[type=text] {
margin: 20px;
font-size: 20px;
padding: 10px;
border: none;
border-bottom: 2px solid gray;
} #score {
font-size: 20px;
margin: 20px;
} #resetButton {
margin: 20px;
font-size: 20px;
padding: 10px;
border: none;
background-color: #4CAF50;
color: white;
border-radius: 5px;
} #resetButton:hover {
background-color: #3E8E41;
}

3. 编写JavaScript代码

对于js代码的编写,我用ES6的class语法来进行编写。使用ES6中的class语法来定义一个游戏类,能够利用class语法的面向对象特性来进行游戏逻辑的封装和组织。使用class语法可以更加清晰地表达游戏的结构和关系,将游戏的各个部分封装在一个类中,可以更加方便地管理和维护代码。

同时,使用class语法还可以更加方便地进行继承和多态的操作,方便扩展和重用代码。在实现游戏时,可能会有不同的游戏模式,或者需要对游戏进行一些特殊的调整。使用class语法可以更加便捷地扩展和修改游戏的逻辑,提高代码的可维护性和可扩展性。

还可以更加方便地进行代码的组织和管理。游戏逻辑封装在一个类中,可以更加清晰地表达游戏的结构和关系,方便代码的组织和管理。同时还可以更加方便地进行代码的测试和调试,提高代码的质量和可靠性。

class TypingGame {
constructor() {
this.canvas = document.getElementById("gameCanvas");
this.context = this.canvas.getContext("2d");
this.gameStatus = 'looping' // 游戏状态,初始值为 'looping'
this.blinkInterval = null;
this.score = 0 // 得分,初始值为 0
this.wordList = [];
this.SPEED = 1; // 字符下落速度
this.ANGLE = Math.PI / 2;
this.words = ['apple', 'orange', 'banana', 'pear', 'grape'];
this.userInput = document.getElementById("userInput");
this.resetButton = document.getElementById("resetButton");
this.addNewWord = this.addNewWord.bind(this);
this.handleKeyPress = this.handleKeyPress.bind(this);
this.resetGame = this.resetGame.bind(this);
this.update = this.update.bind(this);
this.drawWord = this.drawWord.bind(this);
this.handleWordMatch = this.handleWordMatch.bind(this);
this.handleWordMiss = this.handleWordMiss.bind(this);
this.init();
} /**
* 初始化游戏
*/
init() {
// 随机生成一些单词
this.generateRandomWords();
// 绑定键盘输入事件
this.userInput.addEventListener("keypress", this.handleKeyPress);
// 绑定重置游戏按钮点击事件
this.resetButton.addEventListener("click", this.resetGame);
// 添加第一个单词
this.addNewWord();
// 开始游戏循环
this.update();
} /**
* 随机生成一些单词
*/
generateRandomWords() {
for (let i = 0; i < 100; i++) {
// 随机生成一个指定长度的单词
const word = this.getRandomString(Math.floor(Math.random() * 7) + 3);
this.words.push(word);
}
} /**
* 随机生成一个字母
*/
getRandomLetter() {
const letters = "abcdefghijklmnopqrstuvwxyz";
const index = Math.floor(Math.random() * letters.length);
return letters[index];
} /**
* 随机生成一个指定长度的单词
*/
getRandomString(length) {
let result = "";
for (let i = 0; i < length; i++) {
result += this.getRandomLetter();
}
return result;
} /**
* 添加新的单词
*/
addNewWord() {
// 获取单词的宽度
const wordWidth = this.context.measureText(this.getRandomWord()).width;
const word = {
word: this.getRandomWord(),
x: Math.max(wordWidth, Math.random() * (this.canvas.width - wordWidth)),
y: 0,
angle: this.ANGLE,
};
this.wordList.push(word);
} /**
* 随机获取一个单词
*/
getRandomWord() {
const index = Math.floor(Math.random() * this.words.length);
return this.words[index];
} /**
* 更新画面
*/
update() {
if (this.gameStatus !== 'looping') return;
// 清空画布
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.wordList.forEach((word, i) => {
word.y += this.SPEED;
word.x += Math.sin(word.angle);
word.angle += Math.random() * 0.1 - 0.05;
const x = word.x - this.context.measureText(word.word).width / 2;
// 画出单词
this.drawWord(word.word, x, word.y); if (word.x < 0 || word.x > this.canvas.width) {
word.angle = -word.angle;
} if (word.y > this.canvas.height) {
// 处理未输入单词
this.handleWordMiss(word);
this.wordList.splice(i, 1);
// 添加新的单词
this.addNewWord();
}
});
// 请求下一帧动画
requestAnimationFrame(this.update);
} /**
* 画出单词
*/
drawWord(word, x, y) {
this.context.font = "30px Arial";
this.context.fillText(word, x, y);
} /**
* 处理已输入单词
*/
handleKeyPress(event) {
if (event.keyCode === 13) {
const userWord = this.userInput.value;
this.userInput.value = ""; this.wordList.forEach((word, idx) => {
if (word.word === userWord) {
// 处理已输入单词
this.handleWordMatch(word, idx);
}
});
}
} /**
* 处理已输入单词
*/
handleWordMatch(word, idx) {
// 增加得分
this.score++;
// 更新得分显示
document.getElementById("score").innerText = this.score;
const x = word.x - this.context.measureText(word.word).width / 2;
const y = word.y;
let isWhite = true;
let blinkCount = 0;
// 单词闪烁
this.blinkInterval = setInterval(() => {
if (isWhite) {
this.context.fillStyle = "white";
} else {
this.context.fillStyle = "black";
}
this.context.fillText(word.word, x, y);
isWhite = !isWhite;
blinkCount++;
if (blinkCount >= 10) {
this.context.fillStyle = "black";
this.context.fillText(word.word, x, y);
this.wordList.splice(idx, 1)
// 添加新的单词
this.addNewWord()
clearInterval(this.blinkInterval);
}
}, 100);
} /**
* 处理未输入单词
*/
handleWordMiss(word) {
if (word.y > this.canvas.height) {
clearInterval(this.blinkInterval);
this.gameStatus = 'pause';
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.context.font = "30px Arial";
let text =['你输了,你这个菜鸡,','恭喜你,虽败犹荣,','真棒,我的宝子厉害,']
let textSay=this.score>15?this.score>50?text[2]:text[1]:text[0];
this.context.fillText(`${textSay}分数${this.score}分`, this.canvas.width / 2 - 180, this.canvas.height / 2); }
} /**
* 重置游戏
*/
resetGame() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
// 开始游戏循环
requestAnimationFrame(this.update);
clearInterval(this.blinkInterval);
this.gameStatus='looping';
this.score = 0;
// 更新得分显示
document.getElementById("score").innerText = this.score;
this.wordList = [];
// 添加新的单词
this.addNewWord();
}
} const typingGame = new TypingGame();

TypingGame类是整个游戏的核心。在constructor方法中,首先初始化了一些游戏状态和相关的变量,然后调用了init方法,对游戏进行初始化。在init方法中,定义了一些事件处理方法,如键盘输入事件处理方法、重置游戏按钮点击事件处理方法等等。在init方法中,还调用了addNewWord方法,添加了第一个单词,并且开始游戏循环。在update方法中,主要是更新画面的逻辑,如清空画布、画出单词、处理已输入单词、处理未输入单词等等。在resetGame方法中,主要是重置游戏的状态,如清空画布、得分归零、添加新的单词等等。

整个游戏的实现比较简单,主要是依赖于Canvas和JavaScript。游戏中使用了一些Canvas的API,如context.fillText()方法、context.clearRect()方法等等,同时还使用了一些JavaScript的语言特性,如类、箭头函数等等。如果你对游戏的实现过程感兴趣,可以参考代码中的注释,了解游戏中每个方法的具体实现细节。

四、写在最后

Canvas和JavaScript看似平凡无奇,却能够创造出令人惊叹的数字世界。在这个数字化时代,掌握这些工具已经成为了一种竞争优势。本篇文章将带领读者一起探索Canvas和JavaScript的世界,通过实现一个打字游戏,领略这些工具的神奇之处。

游戏的实现并不复杂,但却需要运用许多Canvas的API和JavaScript的语言特性。通过随机生成单词、让单词下落、根据用户输入判断单词是否匹配等等,我们成功实现了一个简单而有趣的游戏。在实现游戏的过程中,我们也学习了一些Canvas的API和JavaScript的语言特性,例如类、箭头函数等等。

本文转载于:

https://juejin.cn/post/7217704608034193468

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

记录--Canvas实现打飞字游戏的更多相关文章

  1. HTML5+JS 《五子飞》游戏实现(六)鼠标响应与多重选择

    上一章我们提到了如果有多条线上的棋子可以被吃掉,那么游戏需要提示用户,让用户选择吃哪条线上的.另外因为是网页游戏,所以一定要实现鼠标单击棋子可以进行操作. 当鼠标移动棋子上面后,切换鼠标指针为手形,移 ...

  2. HTML5+JS 《五子飞》游戏实现(四)夹一个和挑一对

    在第一章我们已经说了怎么才能“夹一个”以及怎样才能挑一对,但那毕竟只是书面上的,对码农来讲,我们还是用代码讲解起来会更容易了解. 为了更容易对照分析,我们先把路线再次贴出来: // 可走的路线 thi ...

  3. HTML5+JS 《五子飞》游戏实现(三)页面和棋盘棋子

    前面两节,我们已经对<五子飞>有个初步的认识,对走棋路线也有了基本的了解,现在里沃特继续跟大家分享HTML页面,另外把棋盘棋子也画出来. 演示地址:http://www.lyout.com ...

  4. 记录一下八款开源 Android 游戏引擎

    记录一下八款开源 Android 游戏引擎 虽然android学了点点,然后现在又没学了(我为啥这么没有恒心呢大哭).以后有时间还是要继续学android的,一定要啊!虽然现在没学android游戏编 ...

  5. 怎样用HTML5 Canvas制作一个简单的游戏

    原文连接: How To Make A Simple HTML5 Canvas Game 自从我制作了一些HTML5游戏(例如Crypt Run)后,我收到了很多建议,要求我写一篇关于怎样利用HTML ...

  6. [译]怎样用HTML5 Canvas制作一个简单的游戏

    这是我翻译自LostDecadeGames主页的一篇文章,原文地址:How To Make A Simple HTML5 Canvas Game. 下面是正文: 自从我制作了一些HTML5游戏(例如C ...

  7. html5 canvas简易版捕鱼达人游戏源码

    插件描述:html5利用canvas写的一个js版本的捕鱼,有积分统计,鱼可以全方位移动,炮会跟着鼠标移动,第一次打开需要鼠标移出背景图,再移入的时候就可以控制炮的转动,因为是用的mouseover触 ...

  8. HTML5+JS 《五子飞》游戏实现(一)规则

    很久没写文章了,这个游戏其实已经写了有段时间了,一直没有完善,赶在新年之际,分享给大家. 该<五子飞>游戏,不是平常大家所说的<五子棋>,这个玩法简单,是我们老家儿时常玩的一种 ...

  9. HTML5+JS 《五子飞》游戏实现(八)人机对战

    要想实现人机对战,就必须让电脑自动下棋,而且要知道自动去查找对方的棋子,看看有没有可以挑一对的,有没有可以夹一个的,这样下起来才有意思. 当电脑用户下完棋后,电脑应立即搜索用户的棋子,然后如果没有被吃 ...

  10. HTML5+JS 《五子飞》游戏实现(七)游戏试玩

    前面第一至第六章我们已经把<五子飞>游戏的基本工作都已经讲得差不多了,这一章主要是把所有的代码分享给大家,然后小伙伴们也可以玩一玩. 至于人机对战的我们放到后面讲进行分析. 试玩地址:ht ...

随机推荐

  1. JavaFX的目录结构, 项目创建和发布, 基于JDK11+JavaFX SDK17

    JDK 和 JavaFX SDK 需要使用JDK11, 推荐使用 https://adoptium.net/releases.html JDK11 JavaFX 11 不再是JDK的一部分, 需要单独 ...

  2. 【Unity3D】地形Terrain

    1 前言 ​ Terrain 是 Unity3D 提供的用于绘制地形的游戏对象,可以在其上绘制山地.江海.池塘.草树等. ​ 用户可以通过[GameObject → 3D Object → Terra ...

  3. Swoole从入门到入土(28)——协程[核心API]

    本节专门介绍swoole提供的协程机制中核心的API 类方法: 1) set():协程设置,设置协程相关选项. Swoole\Coroutine::set(array $options); 2) ge ...

  4. SpringCloud OpenFeign服务接口调用

    介绍 OpenFeign是一种声明式.模板化的HTTP客户端.在Spring Cloud中使用OpenFeign,可以做到使用HTTP请求访问远程服务,就像调用本地方法一样的,开发者完全感知不到这是在 ...

  5. spring boot实现邮箱验证码注册

    最近在设计自己的博客系统,涉及到用户注册与登录验证. 注册这地方我先采用最传统的邮箱验证码方式.具体的实现方式如下: 1.有关如何配置spring boot发送邮件,请参考我的另一篇文章: https ...

  6. Spring rce CVE-2022-22965

    原理大致是这样:spring框架在传参的时候会与对应实体类自动参数绑定,通过"."还可以访问对应实体类的引用类型变量.使用getClass方法,通过反射机制最终获取tomcat的日 ...

  7. win32-创建一个屏幕准星(UpdateLayeredWindow)

    // Test_1.cpp : Defines the entry point for the application. // #include "framework.h" #in ...

  8. Xray安全评估工具使用

    xray 是一款功能强大的安全评估工具,主要特性有: 检测速度快.发包速度快; 漏洞检测算法高效. 支持范围广.大至 OWASP Top 10 通用漏洞检测,小至各种 CMS 框架 POC,均可以支持 ...

  9. OkHttp 拦截器的一些操作

    OkHttp 拦截器的一些操作  转自:  https://blog.csdn.net/songzi1228/article/details/116782794

  10. React 组件之状态

    没有什么是不可能的,只是需要找到正确的方法. 1. 什么是状态? 状态就是组件内部特有数据的载体(组件数据挂载方式),改变数据页面就会刷新,由组件自己设置和更改,也就是说由组件自己产生.维护,使用状态 ...