佛山自助建站软件,湖南seo优化推荐,现在网站都是拿什么软件做的,网页版微信登录二维码已失效手撸俄罗斯方块#xff08;五#xff09;——游戏主题
当确定游戏载体#xff08;如控制台#xff09;后#xff0c;界面将呈现出来。但是游戏的背景色、方块的颜色、方框颜色都应该支持扩展。
当前游戏也是如此#xff0c;引入了 Theme 的概念#xff0c;支持主题的扩…手撸俄罗斯方块五——游戏主题
当确定游戏载体如控制台后界面将呈现出来。但是游戏的背景色、方块的颜色、方框颜色都应该支持扩展。
当前游戏也是如此引入了 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
自此手撸俄罗斯方块的代码部分就讲到这里后续将依次为开始展开从俄罗斯方块开始我们能走多远。