手撸俄罗斯方块——游戏设计

手撸俄罗斯方块——游戏设计

概述

上一章我们介绍俄罗斯方块的基本信息,包括坐标点和方块的基本概念,这一章节我们继续介绍如何完成后续的游戏设计。

组成游戏的基本要素

俄罗斯方块作为一个 2D 的平面游戏,我们可以将整个参与元素做如下抽象,如下图:

在这里插入图片描述

  • 游戏(Game):游戏的核心,负责控制游戏的开始、暂停、结束等。

  • 舞台(Stage):游戏的舞台,是一个矩形的游戏区域,方块在舞台中移动和旋转。

    • 方块(Block):游戏的基本元素,包括各种形状的方块,每个方块由 4 个小方块组成。

    • 工厂(Factory):方块的生成器,负责生成不同形状的方块。

  • 控制器(Controller): 游戏控制器,用于注册事件,如键盘事件、鼠标事件等;

  • 渲染(Render):游戏的渲染器,负责将游戏的状态渲染到屏幕上。

    • 主题(Theme):游戏的主题,包括游戏的背景、方块的颜色等。

简单描述为:

  1. 通过工厂(Factory)产生方块(Block)

  2. 方块(Block)舞台(Stage)中移动和旋转。

  3. 控制器(Controller)监听用户输入,方块的移动和旋转是通过游戏(Game)实例做总体控制。

  4. 游戏的状态通过渲染(Render)渲染到屏幕上,输出样式由主题(Theme)进行控制。

Factory

工厂的目标是为了产生方块,因此它只需要提供产生方块的能力即可。可以抽象如下:

export abstract class AbstractFactory {abstract randomBlock(): Block;
}

没错,AbstractFactory只需要提供一个randomBlock,其随机产生一个方块。

Stage

Stage 作为整个游戏的舞台,它将方块进行组合,同时对外暴露一些能力,如:

  • tick,步进能力,包含三个操作: 生产新的方块、方块向下移动和方块结算。
  • rotate,旋转能力。
  • move,移动能力
  • reset,重置能力

除此之外,还需要提供几个状态的判断能力:

  • isOver,是否结束,tick无法继续。

为了完成上述能力,我们需要对一些信息进行存储,也是封装在Stage中。

  • current: Block,当前正在移动的方块。其要么是空,要么是一个固定的方块。
  • next: Block,下一个方块。
  • score: number,得分。
  • points: Point[][],一个二位数组,坐标轴的填充情况。
  • dimension: Dimension,定义坐标轴的可操作区域,所有的方块不能操作该区域。
  • factory: 方块生成器。
type Direction = "up" | "left" | "down" | "right";
class Dimension {xSize: number; // x坐标轴的最大值ySize: number; // y坐标轴的最大值
}class Stage {current: null | Block;next: null | Block;score: number;points: Point[][];dimension: Demension;tick() {}rotate() {}move(direction: Direction) {}reset() {}
}

Game

Game 作为程序的主入口,将多个元素进行聚合,并控制游戏的开始和结束。

我们首先来分析它的属性,它至少要包括如下属性:

  • status,游戏的状态,分别是 Ready、Running、Pause、Stop、Over。
  • stage,游戏的舞台。
  • render,渲染器
  • controller,控制器

它的目标是通过定时器来控制 Stage 的步进(tick),通过 contoller 监听用户输入,控制移动和旋转。

逻辑如下:

export interface GameOptions {dimension: Dimension;canvas: AbstractCanvas;factory?: AbstractFactory;controller?: AbstractController;
}export enum GameStatus {UNREADY = 0,READY = 1,RUNNING = 2,PAUSE = 3,STOP = 4,OVER = 5
}export class Game {controller?: AbstractController;canvas: AbstractCanvas;options: GameOptions;dimension: Dimension;stage: Stage;status: GameStatus;// 开始start() {}// 暂停pause() {}// 停止stop() {}// 旋转rotate() {}// 移动move(direction: Direction) {}toggle() {}destroy() {}
}

Render

对舞台进行渲染。一般对于游戏渲染,主要包括两个阶段:

  • 首次渲染,渲染基本场景;
  • 更新渲染,舞台发生变化时进行更新渲染。处于性能考量,更新时最好使用局部渲染。

定义如下:

class AbstractRender {theme: Theme;render(): void; // 首次渲染update(): void; // 更新渲染
}

Theme

为了确定游戏的背景,我们需要将游戏区域进行划分。划分如下图:

在这里插入图片描述

从上到下,我们可以将整个操作界面分为如下区域:

  • 外框区域: 包括外框的颜色和整体的背景,以及外框的样式;

  • 分数区域: 用于显示分数;

  • 当前图形: 显示当前正在移动的方块;

  • 下一图形: 显示接下来要出现的方块;

  • 游戏状态: 显示当前游戏的状态,如: 游戏暂停;

  • 已填充图形: 显示已填充的图形;

按照上述划分,我们可以将theme抽象为如下:

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;
}

小结

本章主要描述了俄罗斯方块的几个控制元素,也仅仅是几个相关的骨架。后续章节将进一步介绍方块的设计。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

简过网:工程专业最吃香的6个证书,你考了几个了?

工程专业最吃香的6个证书,你考了几个了?我们一起来看看吧! 1、二级建造师 报考条件:工程类大专及以上学历/从事相关职业 考试时间:3月报名、6月考试 就业前景:建筑设计院、房产开发公司、施工单位 2、一…

如何管理一百个ai专家智能体——ai调度系统设计

前言 如果你用过openai的chatgpt服务,你肯定知道一个叫做GPTs的智能体商店,里面提供了大量的来自官方和个人制作的专门针对某个领域的gpt助手。比如,你想让gpt帮忙写文章,并且要能够写得好,你就可以在商店中搜索相关的…

Smail语句如何使用判断语句跳过验证卡密界面?谈谈思路

🏆本文收录于《CSDN问答解惑》专栏,主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&…

数据融合工具(5)面中心线提取

这是一个重磅工具,建议先看视频。 提取中心线 一、需求背景 说真的,当小编第一次使用ArcGIS中的Polygon To Centerline工具提取面要素中心线时,激动得无以言表,毕竟,以前要提取面中心线,是一件非常麻烦的事…

[CTF]-PWN:House of Cat堆题型综合解析

原理: 调用顺序: exit->_IO_wfile_jumps->_IO_wfile_seekoff->_IO_switch_to_wget_mode _IO_wfile_seekoff源码: off64_t _IO_wfile_seekoff (FILE *fp, off64_t offset, int dir, int mode) {off64_t result;off64_t delta, new…

AI绘画小白必备!Stable Diffusion常用插件合集,好用推荐!(附插件下载)

前言 宝子们,早上好啊~Stable Diffusion 常用插件,月月已经给大家整理好了,自取就好。 拥有这些SD常用插件,让您的图像生成和编辑过程更加强大、直观、多样化。以下插件集成了一系列增强功能,覆盖从自动补全提示词到…

无法访问。你可能没有权限使用网络资源。请与这台服务器的管理员联系以查明你是否有访问权限。【解决办法】

问题描述 新建好一台windows虚拟机,两台设备网络是互通的,但是物理机在访问虚拟机的网络共享文件资源时,出现图下所示的报错:XXX无法访问。你可能没有权限使用网络资源。请与这台服务器的管理员联系以查明你是否有访问权限。用户…

echarts无法加载Map地图的问题

项目场景: echarts无法加载Map地图的问题 详情 查阅相关资料讲,echarts4.9以上版本已经移除了map,那么我们就得重新打包echarts文件了。打包echarts.min.js的链接:https://echarts.apache.org/zh/builder.html 在这个链接页面可…

考完软考之后,如何评职称?是否有有效期?

一、软考和职称之间的关系 软考和职称之间的关系可以这样理解:拿到软考证书并不意味着就能获得职称。软考证书是技术等级证书,而职称则是一种资格。如果单位聘用你做工程师,那么你的软考证书就可以发挥作用,相当于获得了职称证。…

MES:连接计划与执行的桥梁

想象一下,你的企业拥有一份完美的生产计划,但如何将这份计划准确无误地转化为实际生产中的每一步操作?这就是MES大展身手的地方。MES作为ERP(企业资源计划)与车间自动化控制之间的桥梁,确保生产计划能够顺畅…

hf-mirror (huggingface 的国内镜像)

官网: https://hf-mirror.com/ 网站域名 hf-mirror.com,用于镜像 huggingface.co 域名。作为一个公益项目,致力于帮助国内AI开发者快速、稳定的下载模型、数据集。 如何使用HF-Mirror 方法一:网页下载 在https://hf-mirror.com/…

边框插画:成都亚恒丰创教育科技有限公司

边框插画:艺术与生活的精致边界 在视觉艺术的广阔天地里,边框插画以其独特的魅力和细腻的表达方式,成为连接艺术与生活的一道精致边界。成都亚恒丰创教育科技有限公司它不仅仅是图像的外框装饰,更是情感、故事与创意的延伸&#…

看到指针就头疼?这篇文章让你对指针有更全面的了解!

文章目录 1.什么是指针2.指针和指针类型2.1 指针-整数2.2 指针的解引用 3.野指针3.1为什么会有野指针3.2 如何规避野指针 4.指针运算4.1 指针-整数4.2 指针减指针4.3 指针的关系运算 5.指针与数组6.二级指针7.指针数组 1.什么是指针 指针的两个要点 1.指针是内存中的一个最小单…

MVC 返回集合方法,以及分页

返回一个数据集方法 返回多个数据集方法 》》定义一个Model public class IndexMoel {public List<UserGroup> UserGroup{get;set;}public List<User> User{get;set;}}》》》控制器 //db 是 EF 中的上下文 var listnew IndexModel(); list.UserGroupdb.UserGro…

微信小程序中wx.navigateBack()页面栈返回上一页时执行上一页的方法或修改上一页的data属性值

let pages getCurrentPages();let prevPage pages[pages.length - 2]; // 获取上一个页面实例对象console.log(prevPage) //打印信息// 在 wx.navigateBack 的 success 回调中执行需要的方法wx.navigateBack({delta: 1, // 返回上一页success: function() {//修改上一页的属性…

秒懂设计模式--学习笔记(8)【结构型-组合模式】

目录 7、组合模式7.1 组合模式&#xff08;Composite&#xff09;7.2 叉树结构7.3 文件系统7.4 目录树展示7.5 自相似性的涌现7.6 组合模式的各角色定义7.7 组合 7、组合模式 7.1 组合模式&#xff08;Composite&#xff09; 是针对由多个节点对象&#xff08;部分&#xff0…

关于string的‘\0‘与string,vector构造特点,反迭代器与迭代器类等的讨论

目录 问题一&#xff1a;关于string的\0问题讨论 问题二&#xff1a;C标准库中的string内存是分配在堆上面吗&#xff1f; 问题三&#xff1a;string与vector的capacity大小设计的特点 问题四&#xff1a;string的流提取问题 问题五&#xff1a;迭代器失效 问题六&#xf…

个人开发实现AI套壳网站快速搭建(Vue+elementUI+SpringBoot)

目录 一、效果展示 二、项目概述 三、手把手快速搭建实现本项目 3.1 前端实现 3.2 后端方向 五、后续开发计划 一、效果展示 默认展示 一般对话展示&#xff1a; 代码对话展示&#xff1a; 二、项目概述 本项目是一个基于Web的智能对话服务平台&#xff0c;通过后端与第…

【C语言】指针(4):深入理解指针

目录 ​编辑 一、回调函数 二、qsort使用举例 2.1 使用qsort排序整型数据 2.2 使用qsort排序结构体数据 三、qsort的模拟实现 四、NULL、\0、0、0、null、NUL的区别 五、C99中的变长数组 一、回调函数 函数指针是将函数的地址取出来&#xff0c;再通过函数地址去调用&a…

untiy 在菜单栏添加自定义按钮 点击按钮弹出一个Unity窗口,并在窗口里添加属性

using System.Collections.Generic; using UnityEditor; using UnityEngine; using UnityEngine.Rendering.PostProcessing;public class AutoGenerateWindow : EditorWindow //这是定义一个窗口 {public string subjecttName "科目名字";//科目的名字public GameOb…