love 2d Lua 俄罗斯方块超详细教程

源码已经更新在CSDN的码库里:
git clone https://gitcode.com/funsion/love2d-game.git

一直在找Lua 能快速便捷实现图形界面的软件,找了一堆,终于发现love2d是小而美的原生lua图形界面实现的方式。

并参考相关教程做了一个更详细的,以便入门。

功能如上图,

开发过程用了love2d, 不大哦,直接Win下解压可以用的。这是跑程序用的。需要改一下Win的环境变量。

另外用了一个Love2D Editor,写代码用的,也很小,直接Win下解压可以用的。自己发个快捷方式到桌面即可。

已更新安装教程。请关注,love 2d win 下超简单安装方式,学习Lua 中文编程 刚需!!

再结合我们之前的Lua 中文入门教程,我相信,写起来,用起来。真的其实代码就像注释一样明了。

七个方块集合

-- 定义一个块的集合,每个块由多个二维数组表示

方块组={{{0,1,1},{1,1,0}},{{1,1,0},{0,1,1}},{{1,1,1},{0,0,1}},{{1,1,1},{1,0,0}},{{1,1,1},{0,1,0}},{{1,1},{1,1}},{{1,1,1,1}}}
{{0,1,1},{1,1,0}}

{{1,1,0},{0,1,1}}

{{1,1,1},{0,0,1}}

{{1,1,1},{1,0,0}}

{{1,1,1},{0,1,0}

{{1,1},{1,1}}

{{1,1,1,1}}

10列22行的游戏地图

初始化一个空的字段数组,用于游戏地图。

像一个10列(10个格子),22行(22个格子)的空格子。如左下图。

主体格子={}
主体格子={}
for i=1,22 do主体格子[i]={0,0,0,0,0,0,0,0,0,0}
end

初始化当前方块

随机选择一个块,初始化块的位置,坐标系在左下角,4,19,分别为第4列,第19行。

math.random()是随机数,取值范围1到7。即对应上方介绍过的7种方块组的图案。为什么是19行,如右上图中所示。刚好是4个竖向方格出现时能全显。

同样的4列也是这个原因,并且显示居中。

当前方块,方块X坐标,方块Y坐标 = 方块组[math.random(7)],4,19 

检测方块是否与现有的游戏地图重叠

先检查是否超边界

@当前方块: 要检测的块,

@方块x坐标: 方块的起始x坐标,

@方块y坐标: 方块的起始y坐标

返回值: 如果有重叠返回true(真),否则返回false(假)。

如下图,我们用一个田字方块做检查,红色空框代表当前位置,黄色实心框代表返回的位置。

左边红色空框位置如果超界,就会横坐标+1格变成黄色实心框,如箭头方向回到游戏地图内。

右边红色空框位置如果超界,就会横坐标-1格变成黄色实心框,如箭头方向回到游戏地图内。

下边红色空框位置如果超界,就会纵坐标+1格变成黄色实心框,如箭头方向回到游戏地图内。

检查块是否放置在边界之外

“当前方块[1]” 是方块的宽度

如果 “方块x坐标” 超出边界(横向小于1个格或者大于11格),

或者 “方块y坐标” 超出边界,

则 返回 “true”(真)

下面是检查的代码:

	if 方块x坐标 < 1 or 方块x坐标+#当前方块[1] > 11 or 方块y坐标 < 1 then  --当前方块[1]是方块的宽度return truereturn trueend
检查是否与游戏地图 “主体格子” 现存的方块重叠。 

假如你的游戏地图如左下图,蓝色的是 “主体格子” 现存的方块。

遍历 “当前方块” 的每个元素,检查是否与 “主体格子” 现存的方块重叠

主体格子[方块y坐标+i-1] 即在游戏地图上 “主体格子”与对应“当前方块”y坐标的位置,是否现存的方块格子。

 当前方块[i][j]即 “当前方块” 的二唯表格位置里的数据,

如果大于0,则表示是“主体格子”在当前位置不是空位,即现存的方块与 “当前方块” 相交。

如右下图红框与蓝色的 “主体格子” 相交,“当前方块”就会按箭头位置复位成黄色块相应的位置。

代码如下:

	for i=1,#当前方块 do  			-- 遍历块的每一行,即高度for j=1,#当前方块[1] do 	-- 遍历块的每一列,即宽度if 主体格子[方块y坐标+i-1] and 当前方块[i][j] > 0 and 主体格子[方块y坐标+i-1][方块x坐标+j-1] > 0 thenreturn trueendendend

下落过程函数

此函数用于处理方块的下落过程,包括方块位置的更新、方块与底部或其它方块的碰撞检测、以及消除满行等逻辑。

1、尝试将当前方块下落一行
2、检测当前方块是否与底部或其它方块发生重叠

        2.1  如果发生重叠,则将 “当前方块” 位置回退到重叠之前

        2.2 如果没有重叠,将 “当前方块” 的形状数据复制到游戏场地即“主体格子”内   

                2.2.1 遍历“当前方块”的每一行

                2.2.2 遍历“当前方块”的每一列     

                2.2.3 如果“当前方块”的形状数据在这个位置不为空,则将其复制到游戏场地即“主体格子”内

3、检查并消除满行
4、生成新的随机方块,设置其初始位置

代码如下:

function drop()方块Y坐标 = 方块Y坐标 - 1  -- 尝试将当前方块下落一行-- 检测当前方块是否与底部或其它方块发生重叠if 检查重叠(当前方块, 方块X坐标, 方块Y坐标) then方块Y坐标 = 方块Y坐标 + 1  -- 如果发生重叠,则将方块位置回退到重叠之前-- 将当前方块的形状数据复制到游戏场地上for i = 1, #当前方块 do 				-- 遍历方块的每一行for j = 1, #当前方块[1] do			-- 遍历方块的每一列if 当前方块[i][j] ~= 0 then		-- 如果方块元素不为空,则将其复制到游戏场地上主体格子[方块Y坐标 + i - 1][方块X坐标 + j - 1] = 1endendend-- 检查并消除满行for i = 方块Y坐标 + #当前方块 - 1, 方块Y坐标, -1 dolocal ct = 0  -- 用于统计当前行是否全满的计数器for j = 1, 10 doct = ct + 主体格子[i][j]endif ct == 10 thentable.remove(主体格子, i)  -- 移除满行table.insert(主体格子, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0})  -- 在场地上方补充一行空行endend-- 生成新的随机方块,设置其初始位置当前方块, 方块X坐标, 方块Y坐标 = 方块组[math.random(7)], 4, 19end
end

按键事件处理函数

参数:  i: 用户按下的键名(例如"left", "right", "up", "down"等)
处理左键按下事件:方块向左移动一格,并检查重叠,如果不重叠,即会更新“当前方块”的位置。

处理右键按下事件:方块向右移动一格,并检查重叠,如果不重叠,即会更新“当前方块”的位置

处理上键按下事件:方块旋转,构建旋转矩阵,若无重叠,则使用旋转后的方块数组为 “当前方块”。

处理下键按下事件:方块加速下落,不断执行下落操作,直到 “当前方块” Y坐标 = 19。

-- 按键事件处理函数
-- 参数:
--   i: 用户按下的键名(例如"left", "right", "up", "down"等)
function love.keypressed(i)-- 处理左键按下事件:方块向左移动,并检查重叠,如果不重叠,即会更新“当前方块”的位置if i=="left" then  if not 检查重叠(当前方块,方块X坐标-1,方块Y坐标) then方块X坐标=方块X坐标-1end-- 处理右键按下事件:方块向右移动,并检查重叠,如果不重叠,即会更新“当前方块”的位置elseif i=="right" then  if not 检查重叠(当前方块,方块X坐标+1,方块Y坐标) then方块X坐标=方块X坐标+1end-- 处理上键按下事件:方块旋转,elseif i== "up" then  local m={}  -- 创建用于存储旋转后方块的新数组for i=1,#当前方块[1] do  -- 构建旋转矩阵m[i]={}for j=1,#当前方块 dom[i][j] = 当前方块[j][#当前方块[1]+1-i]endendif not 检查重叠(m,方块X坐标,方块Y坐标) then当前方块=m  -- 若无重叠,则使用旋转后的方块数组end-- 处理下键按下事件:方块加速下落elseif i=="down" thenrepeat drop()  -- 不断执行下落操作until 方块Y坐标==19  --这里执行效果不高,没做判断,应该有多余的循环次数。但结果是符合的。end
end

引擎主循环函数

在Love引擎启动的时候就会调用love.run,这里程序里需要一个非默认的,所以要自己写一个functionlove.run()-引擎工作函数,

love的run函数重写可以重用。重点哦。
1、初始化计时器
2、设置颜色为红色
3、返回一个游戏循环函数
        3.1、处理事件队列
        3.2、遍历并处理所有事件,name,a,b,c,d,e,f 是什么呢,要去查一下love.event.poll()的定义去。
        3.3、检查是否需要进行下落操作,.6是什么呢,要去查一下love.timer.getTime()的定义去。
        3.4、清空画布
        3.5、绘制场地
        3.6、绘制下落的方块
        3.7、更新屏幕显示
然后会再次循环3的步骤。

代码如下:

-- 引擎主循环函数
-- 在Love引擎启动的时候就会调用love.run,这里程序里需要一个非默认的,所以要自己写一个functionlove.run()-引擎工作函数,
-- 重写可以重用。重点哦。
function love.run()	-- 初始化计时器flag = love.timer.getTime()	-- 设置画笔颜色为红色love.graphics.setColor(255,0,0)	-- 返回一个游戏循环函数return function()		-- 处理事件队列love.event.pump()	-- 遍历并处理所有事件,name,a,b,c,d,e,f 是什么呢,要去查一下love.event.poll()的定义去。for name,a,b,c,d,e,f in love.event.poll() do-- 如果事件为退出,则终止游戏循环if name=="quit" then return 0 end-- 调用相应的事件处理函数love.handlers[name](a,b,c,d,e,f)end-- 检查是否需要进行下落操作,.6是什么呢,要去查一下love.timer.getTime()的定义去。if love.timer.getTime()-flag >.6 then -- 执行下落逻辑 drop()-- 重置计时器flag=love.timer.getTime()end-- 清空画布love.graphics.clear(255,255,255) 	-- 绘制场地for j=1,20 dofor i=1,10 doif 主体格子[j][i]==1 then--这里的40是相素值,-39是偏移量,因为坐标原点在左上角,而方块的左上角在左下角,所以要偏移。--这是一个方块的左上角坐标love.graphics.rectangle("fill",40*i-39,801-40*j,38,38)endendend	-- 绘制下落的方块for j=1,#当前方块 dofor i=1,#当前方块[1]doif 当前方块[j][i]==1 thenlove.graphics.rectangle("fill",40*(i+方块X坐标-1)-39,801-40*(j+方块Y坐标-1),38,38)endendend	-- 更新屏幕显示love.graphics.present() 	end
end

引用了这位大玩家MrZ_26的bili教程。
59行代码实现俄罗斯方块(lua&love2d)

<iframe src="//player.bilibili.com/player.html?aid=59385769&bvid=BV14t411G7uS&cid=103480280&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe>

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

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

相关文章

Https【Linux网络编程】

目录 一、为什么需要https 二、常见加密方法 1、对称加密 2、非对称加密 3、数据指纹 三、选择什么加密方案&#xff1f; 方案一&#xff1a;对称加密&#xff08;&#xff09; 方案二&#xff1a;双方使用非对称加密&#xff08;效率低&#xff09; 方案三&#xff1a…

通过cplusplus网站学习函数用法演示

在我们学习c语言或者c时&#xff0c;总会遇到一些我们熟悉的库函数&#xff0c;这时候就需要我们通过cplusplus网站搜索学习&#xff0c;下面就由我为大家演示一下如何通过这个网站的页面学习函数的使用方法吧&#xff01; atoi - C Reference (cplusplus.com) 我们今天要学习…

vue3全局控制Element plus所有组件的文字大小

项目框架vue-右上角有控制全文的文字大小 实现&#xff1a; 只能控制element组件的文字及输入框等大小变化&#xff0c;如果是自行添加div,text, span之类的控制不了。 配置流程 APP.vue 使用element的provide&#xff0c;包含app <el-config-provider :locale"loca…

Android MediaPlayer

MediaPlayer 类是媒体框架最重要的组成部分之一。此类的对象能够获取、解码以及播放音频和视频&#xff0c;而且只需极少量设置。它支持多种不同的媒体源&#xff0c;例如&#xff1a; • 本地资源 • 内部 URI&#xff0c;例如您可能从内容解析器那获取的 URI • 外部网址…

debian12,linux-image-6.6.13+bpo-amd64内核nvidia显卡驱动失效

问题 更新linux内核linux-image-6.6.13bpo-amd64和linux-headers-6.6.13bpo-common后无法进入图形化界面&#xff0c;nvidia驱动版本535.154.05&#xff0c;nvidia官方驱动 日志 /var/log/Xorg.1.log [ 3.834] (--) Log file renamed from "/var/log/Xorg.pid-11…

QA:ubuntu22.04.4桌面版虚拟机鼠标丢失的解决方法

前言 在Windows11中的VMWare Workstation17.5.1 Pro上安装了Ubuntu22.04.4&#xff0c;在使用过程中发现&#xff0c;VM虚拟机的鼠标的光标会突然消失&#xff0c;但鼠标其他正常&#xff0c;就是光标不见了&#xff0c;下面是解决办法。 内容 如下图&#xff0c;输入mouse&a…

【智能算法】天鹰优化算法(AO)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2021年&#xff0c;L Abualigah等人受到天鹰猎食过程启发&#xff0c;提出了天鹰优化算法&#xff08;Aquila Optimizer&#xff0c;AO&#xff09;。 2.算法原理 2.1算法思想 AO模拟天鹰 4 种不…

Vue系列——数据对象

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>el:挂载点</title> </head> <body&g…

表情生成器微信小程序版

1.纯前端输出&#xff0c;无需后台&#xff0c;无需域名&#xff0c;速度杠杠快&#xff01; 2.完美支持微信端和抖音端&#xff1b; 3.双端均支持配置开启流量主广告&#xff0c;包括&#xff1a;激励视频广告、插屏广告、banner广告、原生广告、封面广告等&#xff1b; 4.…

刷题日记——国家名称排序

7.国家名称排序 分析 一开始打算用二维的字符数组来操作&#xff0c;但是数组指针玩不太明白&#xff0c;于是改用结构体&#xff0c;结构体country里面仅一个成员name&#xff08;字符数组&#xff09;&#xff0c;这样就有两种解题方法&#xff1a; 方法一&#xff1a;使用…

SpringBoot 整合Redis第1篇

SpringBoot是一个开发框架&#xff0c;Redis是一个高性能的键值存储数据库&#xff0c; 常用于缓存、会话管理、消息队列等应用场景。 定义 Redis是什么&#xff1f; 它是一个存储层级&#xff0c; 在实际项目中&#xff0c;位于关系数据库之上&#xff0c; 类似Android分为5…

ubuntu2204配置zabbix6.4高可用

zabbix6.4-HA 配置keepalived配置haproxy数据库高可用配置zabbix-server配置proxy配置客户端agent 本实验VMware搭建zabbix6.4高可用集群&#xff0c;搭配haproxykeepalived。 master&#xff0c;node节点搭建haproxykeepalibed主备并配置vip地址 三台控制节点搭建数据库高可用…

Linux内核之Binder驱动container_of进阶用法(三十四)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

小小狠招:巧妙使用HANA数据库的jdbc driver

SAP旗下的HANA数据库&#xff0c;实际上是分为两个系列进行发布&#xff0c;一种是基于本地部署的称之为HANA Platform。另一种是面向Cloud平台的&#xff0c;称之为HANA Cloud。 在实际使用当用&#xff0c;因为两者基本上共用同一代码库&#xff0c;除个别地方略有差异以外&…

车载电子电器架构 —— 电气架构释放检查

车载电子电器架构 —— 电气架构释放检查 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明…

Sql注入---基础

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 一.Sql注入概述 攻击者通过构造恶意的SQL查询语句&#xff0c;将其注入到应用程序的数据库查询中&#xff0c;以执行未经授权的操作或者获取敏感信息。 假设如下场景&#xff0c;当你想要知道对…

【c++】简单的日期计算器

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;c笔记仓 朋友们大家好啊&#xff0c;在我们学习了默认成员函数后&#xff0c;我们本节内容来完成知识的实践&#xff0c;来实现一个简易的日期计算器 目录 头文件声明函数函数的实现1.全缺省默认构…

每日一博 - 关于日志记录的最佳实践

文章目录 概述选择合适的日志等级打印函数的入参、出参打印日志对象要做判空处理&#xff0c;避免阻断流程推荐使用 Slf4j不用e.printStackTrace()打印日志低级别的日志输出&#xff0c;必须进行日志级别开关判断不打印重复日志打印全部的异常信息&#xff0c;方便定位问题核心…

cocos2.x => node 属性修改

简介 与节点属性相关的几个核心变量_trs、_matrix、_worldMatrix、_localMatDirty、_worldMatDirty。 _trs&#xff1a;存储节点的position、rotation、scale _matrix&#xff1a;存储节点的缩放、位移、旋转三者合一的变化矩陈&#xff08;仿射矩陈&#xff09; _worldMat…

python多方式操作elasticsearch介绍

python多方式操作elasticsearch介绍 1. requests模块操作ES ​ requests 是一个 Python HTTP 库&#xff0c;它简化了发送 HTTP 请求和处理响应的过程。通过 requests 模块&#xff0c;开发人员可以轻松地与 Web 服务进行通信&#xff0c;包括获取网页内容、执行 API 请求等。…