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 true
		return true
	end
检查是否与游戏地图 “主体格子” 现存的方块重叠。 

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

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

主体格子[方块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 then
				return true
			end
		end
	end

下落过程函数

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

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] = 1
                end
            end
        end
        
        -- 检查并消除满行
        for i = 方块Y坐标 + #当前方块 - 1, 方块Y坐标, -1 do
            local ct = 0  -- 用于统计当前行是否全满的计数器
            for j = 1, 10 do
                ct = ct + 主体格子[i][j]
            end
            if ct == 10 then
                table.remove(主体格子, i)  -- 移除满行
                table.insert(主体格子, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0})  -- 在场地上方补充一行空行
            end
        end
        
        -- 生成新的随机方块,设置其初始位置
        当前方块, 方块X坐标, 方块Y坐标 = 方块组[math.random(7)], 4, 19
    end
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坐标-1
    end
  -- 处理右键按下事件:方块向右移动,并检查重叠,如果不重叠,即会更新“当前方块”的位置
  elseif i=="right" then  
    if not 检查重叠(当前方块,方块X坐标+1,方块Y坐标) then
      方块X坐标=方块X坐标+1
    end
  -- 处理上键按下事件:方块旋转,
  elseif i== "up" then  
    local m={}  -- 创建用于存储旋转后方块的新数组
    for i=1,#当前方块[1] do  -- 构建旋转矩阵
      m[i]={}
      for j=1,#当前方块 do
        m[i][j] = 当前方块[j][#当前方块[1]+1-i]
      end
    end
    if not 检查重叠(m,方块X坐标,方块Y坐标) then
      当前方块=m  -- 若无重叠,则使用旋转后的方块数组
    end
  -- 处理下键按下事件:方块加速下落
  elseif i=="down" then
    repeat 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 do
			for i=1,10 do
				if 主体格子[j][i]==1 then
					--这里的40是相素值,-39是偏移量,因为坐标原点在左上角,而方块的左上角在左下角,所以要偏移。
					--这是一个方块的左上角坐标
					love.graphics.rectangle("fill",40*i-39,801-40*j,38,38)
				end
			end
		end	
		-- 绘制下落的方块
		for j=1,#当前方块 do
			for i=1,#当前方块[1]do
				if 当前方块[j][i]==1 then
					love.graphics.rectangle("fill",40*(i+方块X坐标-1)-39,801-40*(j+方块Y坐标-1),38,38)
				end
			end
		end	
		-- 更新屏幕显示
		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>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

javaWeb项目-学生考勤管理系统功能介绍

项目关键技术 开发工具&#xff1a;IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7 框架&#xff1a;ssm、Springboot 前端&#xff1a;Vue、ElementUI 关键技术&#xff1a;springboot、SSM、vue、MYSQL、MAVEN 数据库工具&#xff1a;Navicat、SQLyog 1、JAVA技术 JavaSc…

百度轨迹验证码识别代码分享

百度出了如图所示的验证码&#xff0c;需要拖动滑块&#xff0c;与如图所示的曲线轨迹进行重合。经过不断研究&#xff0c;终于解决了这个问题。我把识别代码分享给大家。 下面是使用selenium进行验证的&#xff0c;这样可以看到轨迹滑动的过程&#xff0c;如果需要使用js逆向…

MySQL Server 8.3.0 重要变更解析

MySQL Server 8.3.0 Innovation 版本是 MySQL 8.x 系列最后一个创新版本&#xff0c;下个月即将迎来 MySQL 8.4.0 LTS 长期支持版本。 关于发版模型变更&#xff0c;在之前的文章 重磅&#xff01;MySQL 8.1.0 已来&#xff01; 中已有所介绍。 这里补充一点&#xff0c;对于 M…

国家发改委特许经营方案对公共数据运营的思考

数据交易所自贵州大数据交易所成立以来&#xff0c;已经有无数数据交易所像春笋一样在中华大地冒出来。随着国家数据局的成立、数据要素二十条的发布&#xff0c;各地数据交易所开启了竞赛机制&#xff0c;在数据体量、数商数量、交易规模等指标展开博弈。 公共数据运营是否会马…

Spring6-代理模式 / AOP切面编程

目录 1. 场景模拟 1.1. 声明接口 1.2. 创建实现类 1.3. 创建带日志功能的实现类 1.4. 提出问题 2. 代理模式 2.1. 概述 2.2. 静态代理 2.3. 动态代理 3. AOP切面编程 3.1. 概述 3.2. 相关术语 3.2.1. 横切关注点 3.2.2. 通知&#xff08;增强&#xff09; 3.2.3…

【JavaSE】java刷题--数组练习

前言 本篇讲解了一些数组相关题目&#xff08;主要以代码的形式呈现&#xff09;&#xff0c;主要目的在于巩固数组相关知识。 上一篇 数组 讲解了一维数组和二维数组的基础知识~ 欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗~ 如有错误&#xff0c;欢迎…

大创项目推荐 深度学习 opencv python 实现中国交通标志识别_1

文章目录 0 前言1 yolov5实现中国交通标志检测2.算法原理2.1 算法简介2.2网络架构2.3 关键代码 3 数据集处理3.1 VOC格式介绍3.2 将中国交通标志检测数据集CCTSDB数据转换成VOC数据格式3.3 手动标注数据集 4 模型训练5 实现效果5.1 视频效果 6 最后 0 前言 &#x1f525; 优质…

HTX Ventures:为什么BounceBit可能成为新的BTC生态解决方案?

随着BTC现货ETF的通过&#xff0c;全球各大机构和个人都在不断加码对BTC的持仓&#xff0c;BTC价格也随之上升&#xff0c;目前已上升至全球市值排名前十的资产。在本轮市场周期中&#xff0c;BTC铭文和BTC扩容是两个被市场高度关注的细分赛道。BTC生态资产的多元化收益探索正在…

TypseScript再学习之类型别名和接口(10)

先看类型别名&#xff1a;使用关键字 type 声明,注意有等于号额 // 类型别名 使用关键字 type 声明,注意有等于号额 type Cat {name: string; }; let huahua: Cat {name: "花花", };type和interface不同之处在于&#xff1a;interface 是可以自动合并类型的&#…

Linux shell编程学习笔记43:cut命令

0 前言 在 Linux shell编程学习笔记42&#xff1a;md5sum 中&#xff0c;md5sum命令计算md5校验值后返回信息的格式是&#xff1a; md5校验值 文件名 包括两项内容&#xff0c;前一项是md5校验值 &#xff0c;后一项是文件名。 如果我们只想要前面的md5 校验值&#xff0c…

计算机网络—UDP协议详解:特性、应用

​ &#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;マリンブルーの庭園—ずっと真夜中でいいのに。 0:34━━━━━━️&#x1f49f;──────── 3:34 &#x1f504; ◀…

Rust 02.控制、引用、切片Slice、智能指针

1.控制流 //rust通过所有权机制来管理内存&#xff0c;编译器在编译就会根据所有权规则对内存的使用进行 //堆和栈 //编译的时候数据的类型大小是固定的&#xff0c;就是分配在栈上的 //编译的时候数据类型大小不固定&#xff0c;就是分配堆上的 fn main() {let x: i32 1;{le…

美术馆设计方案优化布局与设施提升观众体验!

如今&#xff0c;美术馆不仅仅是作为展示艺术作品的平台&#xff0c;也是吸引公众参与和创造独特体验的数字艺术体验空间&#xff0c;因此许多传统美术馆在进行翻修改造时&#xff0c;都会更加注重用户体验&#xff0c;并在其中使用大量的多媒体互动&#xff0c;让参观者能够在…

基于 YOLO V8 Fine-Tuning 训练自定义的目标检测模型

一、YOLO V8 YOLO V8 是由 2023 年 ultralytics 公司开源的发布&#xff0c;是结合了前几代 YOLO 的融合改进版。YOLO V8 支持全方位的视觉 AI 任务&#xff0c;包括检测、分割、姿态估计、跟踪和分类。并且在速度和准确性方面具有无与伦比的性能。能够应用在各种对速度和精度…

【重制版】在Android手机上安装kali Linux

前言 由于kali官方的Nethunter2的安装代码因为…无法访问&#xff0c;手头又没有一些受支持的机器3&#xff0c;所以做了这个脚本&#xff0c;供大家使用。 工具 搭载基于Android的手机TermuxVNC Viewer 安装必备软件(如已安装请忽略) 请到 https://www.hestudio.net/post…

制造出海,灵途科技助力割草机器人、泳池清洁机器人全方位感知

近年来&#xff0c;越来越多的中国企业开始对外开拓&#xff0c;走向海外市场、挖掘和满足全球消费者的需求。在消费机器人领域&#xff0c;中国企业出海成绩亮眼&#xff01;在2024 ces 和上海AWE展会上&#xff0c;多家机器人公司展示了家用智能割草机器人、泳池清洁机器人的…

C#基础知识总结

C语言、C和C#的区别 ✔ 面向对象编程&#xff08;OOP&#xff09;&#xff1a; C 是一种过程化的编程语言&#xff0c;它不直接支持面向对象编程。然而&#xff0c;C 是一种支持 OOP 的 C 的超集&#xff0c;它引入了类、对象、继承、多态等概念。C# 是完全面向对象的&#xff…

【C++】string类(常用接口)

&#x1f308;个人主页&#xff1a;秦jh__https://blog.csdn.net/qinjh_?spm1010.2135.3001.5343&#x1f525; 系列专栏&#xff1a;http://t.csdnimg.cn/eCa5z 目录 修改操作 push_back append operator assign insert erase replace c_str find string类非成…

淘宝商品详情数据(商品分析,竞品分析,代购商城建站与跨境电商,ERP系统商品数据选品)

淘宝商品详情数据在多个业务场景中发挥着关键作用&#xff0c;以下是一些主要的应用场景&#xff1a; 请求示例&#xff0c;API接口接入Anzexi58 商品分析&#xff1a;通过对淘宝商品详情的全面分析&#xff0c;商家可以深入了解商品的属性、价格、销售量、评价等信息。这些数…

手写简易操作系统(十八)--实现用户进程

一、TSS TSS是Task State Segment的缩写&#xff0c;即任务状态段&#xff0c;早在简述特权级的时候我们就讲过了一点 手写简易操作系统(八)&#xff0c;现在我们讲一下这些保存的寄存器是干嘛的。 这一部分需要讲点历史&#xff0c;硬件与软件的关系是相互促进的&#xff0c…