当前位置: 首页 > news >正文

手撸俄罗斯方块(五)——游戏主题

手撸俄罗斯方块(五)——游戏主题

当确定游戏载体(如控制台)后,界面将呈现出来。但是游戏的背景色、方块的颜色、方框颜色都应该支持扩展。

当前游戏也是如此,引入了 Theme 的概念,支持主题的扩展。

AbstractTheme

系统抽象了一个AbstractTheme,它将一些渲染过程中的行为进行了抽象,抽象定义如下:

abstract class AbstractTheme {/*** 设置外框的样式,如外框的颜色、整体的背景等。* @param outer 指代外框对象的元素,通过修改其内容改变显示样式。*/abstract outStyle(outer: any): void;/*** 设置内框的样式,如内框的颜色、整体的背景等。* @param inner 指代内框对象的元素,通过修改其内容改变显示样式。*/abstract innerStyle(inner: any): void;/*** 设置分数的样式。* @param score 指代分数对象的元素,通过修改其内容改变显示样式。*/abstract scoreStyle(score: any): void;/*** 设置状态栏的样式* @param status 指代状态对象的元素。*/abstract statusStyle(status: any): void;/*** 分数的格式化字符串,输入一个分数的数字,将其转换为目标的样式;* @param score {number} 当前游戏的分数*/abstract scoreTemplate(score: number): string;abstract nextStyle(blocks: any): void;abstract currentStyle(current: any): void;/*** 设置方块区域的样式* @param block 指代当前方块区域*/abstract blockStyle(block: any): void;/*** 设置current区域和已填充区域的小方块的样式* @param blockItem 当前小方块,如一个IBlock会拆分成4各BlockItem。* @param point 当前小方块的位置信息,包括`x`轴和`y`轴的坐标等信息*/abstract blockPointStyle(blockItem: any, point: Point): void;/*** 设置next区域的小方块的样式* @param blockItem* @param point*/abstract nextPointStyle(blockItem: any, point: Point): void;
}

注释已经描述得比较清晰了,分别对外框、内框等进行了设定。

控制台如何实现主题

为了使主题生效,需要在AbstractCanvas子类中调用Theme提供的方法。这里以ConsoleCanvas为例,它的实现如下:

export class ConsoleCanvas extends AbstractCanvas {render(): void {const { game } = this;if (!game) {return;}const { stage, dimension } = game;const printArray: string[] = [];console.clear();const { score, current, next } = stage;const { xSize, ySize } = dimension;const outLength = 1 + 1 + xSize + 1 + this.rightWidth + 1;if (!this.isHideOuter) {// 1. 渲染外边框的上边框const outLine1 = this.getOutterLine(this.outerLeftTopChar +this.createChar(xSize + 2 + this.rightWidth, this.horizonalChar) +this.outerRightTopChar);printArray.push(outLine1);}// 2. 渲染scoreconst scoreText = this.theme.scoreTemplate(score);const scoreConsoleChar = ConsoleChar.create(scoreText);this.theme.scoreStyle(scoreConsoleChar);// 计算左侧需要补充的空格const leftSpace = this.rightWidth - scoreText.length - 3;// 右侧需要补充的空格const rightSpace = 3;let scoreLine =this.getOutterLine(this.outerLeftVerticalChar) +this.createChar(xSize + 2 + leftSpace) +scoreConsoleChar.ch +this.createChar(rightSpace) +this.getOutterLine(this.outerRightVerticalChar);printArray.push(scoreLine);// 3. 渲染内边框的上边框let line1 =this.getOutterLine(this.outerLeftVerticalChar) +this.getInnerLine(this.innerLeftTopChar);for (let x = 0; x < xSize; x++) {const oneBlockItem = current?.points.find((item) => item.x === x);if (oneBlockItem) {line1 += this.getInnerLine(bold(this.horizonalChar));} else {line1 += this.getInnerLine(this.horizonalChar);}}line1 +=this.getInnerLine(this.innerRightTopChar) +this.createChar(this.rightWidth) +this.getOutterLine(this.outerRightVerticalChar);printArray.push(line1);let line2 =this.getOutterLine(this.outerLeftVerticalChar) +this.getInnerLine(this.innerLeftBottomChar);for (let x = 0; x < xSize; x++) {const oneBlockItem = current?.points.find((item) => item.x === x);if (oneBlockItem) {line2 += this.getInnerLine(bold(this.horizonalChar));} else {line2 += this.getInnerLine(this.horizonalChar);}}line2 +=this.getInnerLine(this.innerRightBottomChar) +this.createChar(this.rightWidth) +this.getOutterLine(this.outerRightVerticalChar);printArray.push(line2);if (!this.isHideOuter) {const outLine2 = this.getOutterLine(this.outerLeftBottomChar +this.createChar(xSize + 2 + this.rightWidth, this.horizonalChar) +this.outerRightBottomChar);printArray.push(outLine2);}if (this.exitMessage) {printArray.push(this.exitMessage);} else {printArray.push("");}process.stdout.write(this.handleOutput(outLength, printArray).join("\n"));}
}

我们看到渲染上边框,调用了getOutterLine方法,这个方法是在AbstractCanvas中定义的,它的实现如下:

export class ConsoleCanvas extends AbstractCanvas {// ...getOutterLine(char: string): string {if (this.isHideOuter) {return "";}const consoleChar = new ConsoleChar(str || "|");this.theme.outStyle(consoleChar);return consoleChar.ch;}// ...
}

它内部调用了 theme.outStyle 方法,对应我们上述 theme 的定义。

类似的,对于内边框的渲染,也是调用了getInnerLine方法,它的实现如下:

export class ConsoleCanvas extends AbstractCanvas {// ...getInnerLine(char: string): string {const consoleChar = new ConsoleChar(str || "|");this.theme.innerStyle(consoleChar);return consoleChar.ch;}// ...
}

这样,我们就实现了主题的扩展。

主题的扩展

我们可以通过继承AbstractTheme,实现自己的主题,比如实现一个RedTheme

export class RedTheme extends DefaultTheme {outStyle(outer: any): void {outer.ch = color.red(outer.ch);}
}

它实现了outStyle方法,将外边框的颜色设置为红色。

我们使用该主题,效果如下

在这里插入图片描述

详细内容可以我的git项目: https://github.com/shushanfx/tetris
也可以关注我的git账号: https://github.com/shushanfx

自此手撸俄罗斯方块的代码部分就讲到这里,后续将依次为开始展开,从俄罗斯方块开始,我们能走多远。

相关文章:

手撸俄罗斯方块(五)——游戏主题

手撸俄罗斯方块&#xff08;五&#xff09;——游戏主题 当确定游戏载体&#xff08;如控制台&#xff09;后&#xff0c;界面将呈现出来。但是游戏的背景色、方块的颜色、方框颜色都应该支持扩展。 当前游戏也是如此&#xff0c;引入了 Theme 的概念&#xff0c;支持主题的扩…...

【测试开发】--安全渗透测试

1. 安全渗透 1.1 分类 web数据库安全web应用服务器安全&#xff08;文件上传漏洞、文件包含漏洞&#xff09;web客户端安全&#xff08;XSS跨站攻击&#xff09; 2. sql注入 2.1 sql注入介绍 sql注入在安全问题中排行榜首sql注入攻击是输入参数未经过滤&#xff0c;然后直…...

AMEYA360:类比半导体三款车规级新品介绍

类比半导体三款全新车规级智能驱动芯片——HD70504与HD70804四通道高边驱动、HD7004低导通电阻高边驱动以及DR8112直驱马达驱动芯片介绍&#xff0c;进一步扩展了其汽车智能驱动产品的深度与广度。 新品首发&#xff0c;诠释“芯”动未来 HD70504 & HD70804四通道高边驱动芯…...

内衣洗衣机哪个牌子好用?五大硬核宝藏内衣洗衣机推荐

在日常生活中&#xff0c;内衣洗衣机已成为现代家庭必备的重要家电之一。选择一款耐用、质量优秀的内衣洗衣机&#xff0c;不仅可以减少洗衣负担&#xff0c;还能提供高效的洗涤效果。然而&#xff0c;市场上众多内衣洗衣机品牌琳琅满目&#xff0c;让我们往往难以选择。那么&a…...

红酒与未来科技:传统与创新的碰撞

在岁月的长河中&#xff0c;红酒以其深邃的色泽、丰富的口感和不同的文化魅力&#xff0c;成为人类文明中的一颗璀璨明珠。而未来科技&#xff0c;则以其迅猛的发展速度和无限的可能性&#xff0c;领着人类走向一个崭新的时代。当红酒与未来科技相遇&#xff0c;一场传统与创新…...

php快速入门

前言 php是一门脚本语言&#xff0c;可以访问服务器&#xff0c;对数据库增删查改&#xff08;后台/后端语言&#xff09; 后台语言&#xff1a;php&#xff0c;java&#xff0c;c&#xff0c;c&#xff0c;python等等 注意&#xff1a;php是操作服务器&#xff0c;不能直接在…...

【排序 - 归并排序】

归并排序&#xff08;Merge Sort&#xff09;是一种高效的排序算法&#xff0c;基于分治&#xff08;Divide and Conquer&#xff09;策略。它将待排序数组分成两个较小的子数组&#xff0c;分别对它们进行排序&#xff0c;然后将排好序的子数组合并成一个整体有序的数组。归并…...

Appium元素定位(全网详细讲解)(二)

1.appium inspector&#xff08;定位元素的工具&#xff09;使用方法 详细介绍&#xff1a; 详细解释&#xff1a; 图标名称说明1Show Element Handles是否显示元素句柄2Select Elements选择元素定位3Tap/Swipe By Coordinates按坐标点击/滑动4Download Screenshot下载屏幕截…...

滑动窗口,最长子序列最好的选择 -> O(N)

最近在学校上短学期课程&#xff0c;做程序设计题&#xff0c;一下子回忆起了大一学数据结构与算法的日子&#xff01; 这十天我会记录一些做题的心得&#xff0c;今天带来的是对于最长子序列长度题型的解题框架&#xff1a;滑动窗口 本质就是双指针算法&#xff1a; 通过le…...

【Python】已解决:Python安装过程中的报错问题

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确解决方法五、注意事项 已解决&#xff1a;Python安装过程中的报错问题 一、分析问题背景 在安装Python 3.9.6&#xff08;64位&#xff09;版本时&#xff0c;用户可能会遇到一个报错信息&#xff0c;提…...

C++ STL IO流介绍

目录 一&#xff1a;IO流的继承关系&#xff1a; 二&#xff1a;输入输出功能 1. 基本用法 2. 格式化输入 3.非格式化输入 4. 格式化输出 三&#xff1a;流 1. 字符流 2. 向字符流中写入数据 3. 从字符流中读出数据 4. 清空字符流 5.完整的例子 四&#xff1a;文件…...

华为浏览器,Chrome的平替,插件无缝连接

文章目录 背景插件书签 背景 不知道各位小伙伴有没有这样的痛点&#xff0c;办公电脑、家里的电脑还有手机、平板等&#xff0c;收藏了一个网址或者在手机上浏览了某个网页&#xff0c;保存起来&#xff0c;可是一换平台或者换个电脑&#xff0c;在想要浏览之前收藏的东西&…...

SpringBoot新手快速入门系列教程:前述

我自己是一个SpringBoot新手&#xff0c;花了一天时间学了SpringBoot。大家不要惊讶&#xff0c;前提是我自己已经有了10几年的编程经验精通多门语言&#xff0c;并且在人间最强兵器Chat某T的AI助手帮助下&#xff0c;才能创造一天快速学会一个框架的神话。 当然中间遇到了很多…...

C语言9 指针

目录 指针的声明与初始化 指针运算 指针的加法和减法 指针的比较 指针与数组 通过指针访问数组元素 指针与多维数组 声明指向多维数组的指针 访问多维数组元素 指针数组和数组指针 指针数组 数组指针 字符指针 字符串的定义和字符指针 直接使用字符指针初始化字…...

Floyd判圈算法——寻找重复数(C++)

287. 寻找重复数 - 力扣&#xff08;LeetCode&#xff09; 题目描述 给定一个包含 n 1 个整数的数组 nums &#xff0c;其数字都在 [1, n] 范围内&#xff08;包括 1 和 n&#xff09;&#xff0c;可知至少存在一个重复的整数。假设 nums 只有 一个重复的整数 &#xff0c;返…...

面试题目分享

学习目标&#xff1a; 从面试了解自己的不足。 学习内容&#xff1a; 1.你会什么语言&#xff1f; 我该如何回答&#xff0c;我会java&#xff0c;c&#xff0c;c等&#xff0c;在工作中我会用到合适的语言。 牛逼吹的大话 尊敬的面试官&#xff0c;我精通Java和Python&…...

Solana开发之Anchor框架

文章目录 Solana开发之Anchor框架一、什么是Anchor二、安装和使用1. 安装rust2. 安装Solana下载预构建的二进制文件 3. 使用 Anchor 版本管理器 &#xff08;avm&#xff09; 进行安装&#xff08;推荐&#xff09; 四、Anchor 核心原理Anchor 程序由三部分组成程序的 ID 从哪里…...

界面组件Kendo UI for React 2024 Q2亮点 - 生成式AI集成、设计系统增强

随着最新的2024年第二季度发布&#xff0c;Kendo UI for React为应用程序开发设定了标准&#xff0c;包括生成式AI集成、增强的设计系统功能和可访问的数据可视化。新的2024年第二季度版本为应用程序界面提供了人工智能(AI)提示&#xff0c;从设计到代码的生产力增强、可访问性…...

python输出/sys/class/power_supply/BAT0/电池各项内容

读取 /sys/class/power_supply/BAT0/ 目录下的所有相关文件,并输出其内容: import os# 定义电池信息文件的路径 battery_path = "/sys/class/power_supply/BAT0/"# 读取文件内容的函数 def read_battery_info(file_name):try:with open(os.path.join(battery_path…...

HDFS体系架构文件写入/下载流程

HDFS体系架构 HDFS&#xff08;Hadoop Distributed File System&#xff0c;Hadoop分布式文件系统&#xff09;是Hadoop项目中的一个核心组件&#xff0c;旨在以高容错、高吞吐量来处理大规模数据集。它的体系架构由以下几个主要部分组成&#xff1a;Client&#xff0c;NameNo…...

跨平台兼容计算引擎:解锁非NVIDIA GPU的CUDA计算潜能

跨平台兼容计算引擎&#xff1a;解锁非NVIDIA GPU的CUDA计算潜能 【免费下载链接】ZLUDA CUDA on non-NVIDIA GPUs 项目地址: https://gitcode.com/GitHub_Trending/zl/ZLUDA 在高性能计算领域&#xff0c;硬件壁垒常常限制着开发者的创新空间——当你手中的Intel GPU无…...

别只训练了!聊聊LSTM翻译模型保存的那些事儿:.h5权重、字符字典与config.json

LSTM翻译模型工程化实战&#xff1a;从权重保存到完整资产包的深度解析 当你花了三天三夜训练出一个效果不错的LSTM翻译模型&#xff0c;看着验证集上的BLEU分数终于突破30&#xff0c;正准备松口气时——突然意识到这个模型可能永远走不出你的Jupyter Notebook。这不是危言耸听…...

从深海冷泉到实验室:原核生物抗病毒系统研究的5个前沿突破与未来方向

深海微生物的病毒防御战&#xff1a;5项颠覆性发现与跨学科研究路径 在南海1200米深的冷泉区&#xff0c;一簇簇贻贝群落正无声上演着微观世界的军备竞赛——这里的硫氧化细菌每20分钟就会遭遇一次噬菌体袭击&#xff0c;而它们携带的抗毒素蛋白和逆转录酶构成了独特的防御工事…...

NPS内网穿透实战:如何为本地站点快速配置HTTPS(含防火墙设置)

NPS内网穿透实战&#xff1a;如何为本地站点快速配置HTTPS&#xff08;含防火墙设置&#xff09; 在数字化转型浪潮中&#xff0c;远程访问内网资源的需求日益增长。想象一下这样的场景&#xff1a;你正在开发一个本地Web应用&#xff0c;需要让异地同事实时测试&#xff1b;或…...

Labelme标注完别急着训练!手把手教你批量把JSON转成YOLO能吃的TXT格式

Labelme标注数据转YOLO格式实战指南&#xff1a;从原理到批量处理 当你用Labelme完成数百张图片的标注&#xff0c;满心欢喜准备开始YOLO模型训练时&#xff0c;却发现训练脚本报错——原来YOLO无法直接读取Labelme生成的JSON文件。这不是代码问题&#xff0c;而是格式不匹配的…...

OpenClaw+千问3.5-9B:学术论文摘要生成与关键词提取

OpenClaw千问3.5-9B&#xff1a;学术论文摘要生成与关键词提取 1. 为什么需要自动化文献处理工具 作为一名经常需要阅读大量文献的研究人员&#xff0c;我深刻体会到手动处理论文的痛点。每次面对几十篇PDF文献时&#xff0c;光是阅读摘要和提取关键词就要耗费数小时。更糟糕…...

单电源运放差分放大电路实战:3.3V供电下的精确计算与仿真验证

单电源运放差分放大电路实战&#xff1a;3.3V供电下的精确计算与仿真验证 在嵌入式系统开发中&#xff0c;信号调理电路的设计往往面临低功耗与高精度的双重挑战。单电源运放差分放大电路因其结构简单、成本低廉&#xff0c;成为3.3V供电环境下小信号放大的首选方案。本文将深入…...

LRCGet:三步构建完美离线音乐歌词库的终极指南

LRCGet&#xff1a;三步构建完美离线音乐歌词库的终极指南 【免费下载链接】lrcget Utility for mass-downloading LRC synced lyrics for your offline music library. 项目地址: https://gitcode.com/gh_mirrors/lr/lrcget 你是否曾面对庞大的本地音乐收藏&#xff0c…...

效能倍增:ZenTimings的场景化内存性能优化指南

效能倍增&#xff1a;ZenTimings的场景化内存性能优化指南 【免费下载链接】ZenTimings 项目地址: https://gitcode.com/gh_mirrors/ze/ZenTimings ZenTimings是一款专为AMD Ryzen平台打造的内存时序监控与优化工具&#xff0c;通过精准的参数调校和实时监控功能&#…...

万象视界灵坛效果展示:同一图像下10组候选神谕的同步率热力图

万象视界灵坛效果展示&#xff1a;同一图像下10组候选神谕的同步率热力图 1. 平台概览 万象视界灵坛&#xff08;Omni-Vision Sanctuary&#xff09;是一款基于OpenAI CLIP技术的高级多模态智能感知平台。它将复杂的语义对齐过程转化为直观的视觉体验&#xff0c;采用独特的1…...