【Godot4.2】随机数应用案例 - 制作骰子组件

news2024/11/15 7:56:12

概述

在学习随机数之后,我们就来用随机数实现骰子。

初期:不要拘泥于形式只要表现了随机,骰子可以不必做成骰子的样子。刚开始因为技术力的原因,可能无法实现比较真实和动态的骰子效果,但是这并不意为着不可以做出一个“表意”的骰子,比如一个纯数字版本的骰子也是完全可以的,因为骰子在游戏里只是提供的随机的一种工具。

设计思路

我们可以用图片来实现骰子。最简单的骰子组件如下:
骰子模拟

  • 它有初始的骰子图片和具体的数字图片两种状态。点一下就出现一个1-6随机对应的图片。
  • 但是这种一点就出现结果的体验与现实中掷骰子的体验是不一样的。现实中,投出的骰子总是需要等待它的旋转结束,然后我们才能看到结果。
  • 所以提升真实度的好办法就是点击后也加入一个过渡和等待的效果。

一个中间过渡,让电子骰子拥有更真实的效果

  • 至于这个中间过渡如何做,仁者见仁智者见智,完全可以自由发挥,这也是编程和设计的乐趣。
  • 可行的办法之一是做一个类似技能冷却的效果。

冷却式的中间过渡

  • 另一个可行的办法是点击后显示随机的数,直到达到冷却时间才停止。

创建纯数字版6面骰子

在实现图片版之前,我们不妨先尝试一下实现纯数字的版本。
创建如下场景:

image.png

一个PanelContainer包起来一个Label,设定Label的文本水平和垂直都居中:

image.png

设定Label在容器中水平居中收缩。

image.png

设定PanelContainer的最小尺寸为30×30px。

image.png

此时的效果:

image.png

PanelContainer添加覆盖的样式盒:

image.png

Label的文本颜色设为黑色。

image.png

此时的效果:

image.png

为根节点添加如下代码:

extends PanelContainer

@onready var num_lab = $numLab


func _ready():
	randomize()
	# gui_input信号处理
	connect("gui_input",func(event):
		# 鼠标左键点击
		if event is InputEventMouseButton:
			if event.button_index == MOUSE_BUTTON_LEFT:
				if event.is_pressed():
					# 显示16之间任意数字
					num_lab.text = str(randi_range(1,6))
	)

这样我们就实现了一个简单的可以交互的6面骰子:

简单骰子效果

骰子组件化

为了更好的解耦,可以将摇骰子的功能,单独写成一个函数。

extends PanelContainer

@onready var num_lab = $numLab


func _ready():
	randomize()
	# gui_input信号处理
	connect("gui_input",func(event):
		# 鼠标左键点击
		if event is InputEventMouseButton:
			if event.button_index == MOUSE_BUTTON_LEFT:
				if event.is_pressed():
					shook_dice(6)  # 摇骰子
	)
	
# 摇骰子
func shook_dice(max_num:int) -> void:
	num_lab.text = str(randi_range(1,max_num))

此时我们就可以在其他场景中实例化我们的骰子组件也就是dice场景,并调用其shook_dice方法来掷骰子。

而且因为我们将骰子的面数设定为了max_num参数,这意为着我们可以实现6面或其他面的骰子效果。

测试

创建如下的测试场景:

image.pngimage.png
根节点代码如下:

extends Control

@onready var dice = $dice

# 按钮点击
func _on_button_pressed():
	dice.shook_dice(6)  # 掷6面骰子

我们设定按钮点击时掷6面骰子,效果如下:

用按钮摇骰子

引入间隔时间

上面的骰子是即时显示出结果的,这与现实的骰子不符。现实中投出骰子之后,都会间隔一段时间,才出现结果。

因此这里我们引入间隔时间参数Interval_time这里默认值为3.0,也就是调用shook_dice掷骰子后,3s后才出现结果。

extends PanelContainer

@onready var num_lab = $numLab

## 骰子显示数字的间隔时间
@export var Interval_time:float = 3.0

func _ready():
	randomize()
	# gui_input信号处理
	connect("gui_input",func(event):
		# 鼠标左键点击
		if event is InputEventMouseButton:
			if event.button_index == MOUSE_BUTTON_LEFT:
				if event.is_pressed():
					shook_dice(6)  # 摇骰子
	)
	
# 摇骰子
func shook_dice(max_num:int) -> void:
	num_lab.text = "-"         # 结果出现之前显示无意义的"-"字符
	await get_tree().create_timer(Interval_time).timeout  # 创建Timer
	num_lab.text = str(randi_range(1,max_num))

间隔3秒,无冷却(可连续点击)

间隔+冷却(基于Timer)

上面为骰子添加了显示结果的间隔时间,但是我们可以在结果出现之前,不停的重新摇骰子,这与现实中的骰子也是不符合的。因此我们还需要设定在一次摇骰子结束之前,不允许再次摇骰子。

我们修改代码如下:

extends PanelContainer

@onready var num_lab = $numLab

## 骰子显示数字的间隔时间
@export var Interval_time:float = 3.0

var can_shook = true   # 能否摇骰子

func _ready():
	randomize()
	# gui_input信号处理
	connect("gui_input",func(event):
		# 鼠标左键点击
		if event is InputEventMouseButton:
			if event.button_index == MOUSE_BUTTON_LEFT:
				if event.is_pressed():
					if can_shook:
						shook_dice(6)  # 摇骰子
	)
	
# 摇骰子
func shook_dice(max_num:int) -> void:
	can_shook = false
	num_lab.text = "-"         # 结果出现之前显示无意义的"-"字符
	await get_tree().create_timer(Interval_time).timeout  # 创建Timer
	num_lab.text = str(randi_range(1,max_num))
	can_shook = true

可以看到:

  • 我们设定一个变量can_shook来存储是否可以摇骰子,初始为true,当我们第一次摇骰子以后,立马标记can_shookfalse,直到间隔时间结束,结果显示,才再次将can_shook设为true
  • 这样我们就实现了在摇骰子期间无法再次摇骰子

创建图片版拟真骰子

上面已经通过数字版本实现了骰子的基本特性,那么实现图片版本,主要就是将图片与随机数对应了。

下图是我用PS做的一个6面骰子的序列图,其中还加入了摇骰子等待期间的问号图片。

all.png

我们有两种思路处理图片,一种是一个面一张图,导出为7张图片,利用数组,获取对应的图片。

image.png

另一种是将6个面整体导出为一个图片,然后用矩形截取和显示单个面的图片。

两种方法各有千秋,前者更直观简便,后者减少图片资源数目,更容易管理。

这里我首先采用前一种形式。创建如下场景:

image.png

我们用一个TextureRect显示骰子的某个面:

extends TextureRect

## 骰子显示数字的间隔时间
@export var Interval_time:float = 3.0

var can_shook = true   # 能否摇骰子

func _ready():
	randomize()
	# gui_input信号处理
	connect("gui_input",func(event):
		# 鼠标左键点击
		if event is InputEventMouseButton:
			if event.button_index == MOUSE_BUTTON_LEFT:
				if event.is_pressed():
					if can_shook:
						shook_dice(6)  # 摇骰子
	)
	
# 摇骰子
func shook_dice(max_num:int) -> void:
	can_shook = false
	texture = load("res://imgs/%d.png" % 0)  # 显示问号
	await get_tree().create_timer(Interval_time).timeout  # 创建Timer
	var i = randi_range(1,max_num)
	texture = load("res://imgs/%d.png" % i)
	can_shook = true

运行后的效果如下:

图片版6面骰子.gif

加入音效

我们可以在一些素材网站找到摇骰子的音效。

img_dice场景添加一个AudioStreamPlayer节点。

image.png

将骰子音效文件拖到AudioStreamPlayer节点的stream节点:

image.png

修改代码如下:

extends TextureRect

## 骰子显示数字的间隔时间
@export var Interval_time:float = 3.0

var can_shook = true   # 能否摇骰子


@onready var audio_stream_player = $AudioStreamPlayer

func _ready():
	randomize()
	# gui_input信号处理
	connect("gui_input",func(event):
		# 鼠标左键点击
		if event is InputEventMouseButton:
			if event.button_index == MOUSE_BUTTON_LEFT:
				if event.is_pressed():
					if can_shook:
						shook_dice(6)  # 摇骰子
	)
	
# 摇骰子
func shook_dice(max_num:int) -> void:
	can_shook = false
	texture = load("res://imgs/%d.png" % 0)  # 显示问号
	audio_stream_player.play() # 播放音效
	await get_tree().create_timer(Interval_time).timeout  # 创建Timer
	var i = randi_range(1,max_num)
	texture = load("res://imgs/%d.png" % i)
	audio_stream_player.stop() # 停止播放音效
	can_shook = true

此时就可以在摇骰子时听到音效了。

总结

本篇主要是随机数应用的一个简单实例。讲解如何手搓简单的纯数字骰子和图片版骰子。

同样只是抛砖引玉,讲解基础的原理,代码其实可以优化的更简洁,也可以使用Timer节点取代get_tree().create_timer(),以及实现摇骰子过程中显示随机的面等等。

这里就不过度拓展了,感兴趣的可以自己尝试一下。

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

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

相关文章

MATLAB | R2024a更新了哪些好玩的东西?

Hey 好久不见,大家一看三月中下旬这个时间节点也应该能猜到这篇更新什么内容,没错MATLAB R2024a正式版发布啦啦拉拉,直接来看看有啥我认为比较有意思的更新点吧: 1 极坐标表达式绘制 将会使用使用fpolarplot函数来替换ezpolar&a…

探索数据结构:顺序栈与链式栈的原理、实现与应用

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:数据结构与算法 贝蒂的主页:Betty’s blog 1. 栈的定义 栈简单来说就是一种只允许在一端进行操作(插入与删除&…

将OpenCV与gdb驱动的IDE结合使用

返回:OpenCV系列文章目录(持续更新中......) 上一篇:OpenCV4.9.0开源计算机视觉库在 Linux 中安装 下一篇:将OpenCV与gcc和CMake结合使用 ​ 能力 这个漂亮的打印机可以显示元素类型、、标志is_continuous和is_subm…

【论文阅读】基于多特征融合的智能合约缺陷检测方法

摘要: 1、预处理:颜色标记、词汇提取、字符转换、合约之间的继承关系的提取 2、 使用融合模型进行特征提取(BERT、CNN、BiLSTM) 3、使用node2vec随机游走算法,将合约之间的继承关系作为输入得到合约关系的特征向量。 4…

通过 Socket 手动实现 HTTP 协议

你好,我是 shengjk1,多年大厂经验,努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注!你会有如下收益: 了解大厂经验拥有和大厂相匹配的技术等 希望看什么,评论或者私信告诉我! 文章目录 一…

如何让uni-app开发的H5页面顶部原生标题和小程序的顶部标题不一致?

如何让标题1和标题2不一样&#xff1f; 修改根目录下的App.vue&#xff08;核心代码如下&#xff09; <script>export default {onLaunch() {// 监听各种跳转----------------------------------------[navigateTo, redirectTo, reLaunch, switchTab, navigateBack, ].…

[论文笔记] ChatDev:Communicative Agents for Software Development

Communicative Agents for Software Development&#xff08;大模型驱动的全流程自动化软件开发框架&#xff09; 会议arxiv 2023作者Chen Qian Xin Cong Wei Liu Cheng Yang团队Tsinghua University论文地址https://arxiv.org/pdf/2307.07924.pdf代码地址https://github.com/O…

HTML_CSS学习:表格、表单、框架标签

一、表格_跨行与跨列 1.相关代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>表格_跨行与跨列</title> </head> <body><table border"1" cellspacing"0&qu…

(一)基于IDEA的JAVA基础4

注释文本&#xff0c;注释模版 单行注释://开头放在代码前面&#xff0c;对少部分。 多行注释:快捷方式ctrlshift/,对段落代码注 释。 文档注释:/**……**/&#xff0c;用于声明作者或创作时 间。 文档注释如何设置&#xff0c;首先找到File中…

【前端Vue】Vue3+Pinia小兔鲜电商项目第2篇:什么是pinia,1. 创建空Vue项目【附代码文档】

全套笔记资料代码移步&#xff1a; 前往gitee仓库查看 感兴趣的小伙伴可以自取哦&#xff0c;欢迎大家点赞转发~ 全套教程部分目录&#xff1a; 部分文件图片&#xff1a; 什么是pinia Pinia 是 Vue 的专属状态管理库&#xff0c;可以实现跨组件或页面共享状态&#xff0c;是…

html5cssjs代码 033 SVG元素示例

html5&css&js代码 033 SVG元素示例 一、代码二、解释 一个SVG图形&#xff0c;该图形由一个椭圆、一个圆形和一个矩形组成。 一、代码 <!DOCTYPE html> <html lang"zh-cn"> <head><title>编程笔记 html5&css&js SVG元素示例…

公司系统中了.rmallox勒索病毒如何恢复数据?

早晨上班时刻&#xff1a; 当阳光逐渐洒满大地&#xff0c;城市的喧嚣开始涌动&#xff0c;某公司的员工们纷纷踏入办公大楼&#xff0c;准备开始新的一天的工作。他们像往常一样打开电脑&#xff0c;准备接收邮件、查看日程、浏览项目进展。 病毒悄然发作&#xff1a; 就在员…

Databend x CubeFS:面向未来的企业级云原生数据存储与分析

用场景的丰富&#xff0c;企业面临着前所未有的数据存储挑战。大规模数据存储变得日常化&#xff0c;伴随着超大容量和快速变化的I/O需求&#xff0c;传统的存储解决方案已经难以满足企业对弹性、运维效率及总体拥有成本&#xff08;TCO&#xff09;的更高要求。这些挑战促使基…

三角形重心坐标插值法 Interpolation Across Triangles: Barycentric Coordinates

本专栏内容整理了GAMES101的计算机图形学课程的主要内容&#xff0c;作为我学习计算机图形学的一份复习备份或叫做笔记。内容中如有错误&#xff0c;或有其他建议&#xff0c;欢迎大家指出。 附上GAMES101计算机图形学课程&#xff1a;GAMES101: 现代计算机图形学入门正在上传…

Django日志(二)

一、Handler Handler决定如何处理logger中的每条消息。它表示一个特定的日志行为,例如 将消息写入屏幕、文件或网络Socket handler对应的是个字典,每一个键都是一个handler的名字,每个值又一个字典,描述了如何配置对应的handler实例 2.1、内置Handler class(必需):处理…

【每日八股】Java基础经典面试题4

前言&#xff1a;哈喽大家好&#xff0c;我是黑洞晓威&#xff0c;25届毕业生&#xff0c;正在为即将到来的秋招做准备。本篇将记录学习过程中经常出现的知识点以及自己学习薄弱的地方进行总结&#x1f970;。 本篇文章记录的Java基础面试题&#xff0c;如果你也在复习的话不妨…

Scikit-Learn逻辑回归(二)

Scikit-Learn逻辑回归二&#xff1a;多项式与正则化 1、多项式回归回顾1.1、逻辑回归为什么要使用多项式1.2、多项式回归及原理 2、逻辑回归与多项式 1、多项式回归回顾 本文接上篇&#xff1a;Scikit-Learn逻辑回归(一) 上篇中&#xff0c;我们详细介绍了逻辑回归的概念、原理…

第六十一回 放冷箭燕青救主 劫法场石秀跳楼-编译安装飞桨paddlepaddle@openKylin+RISCV

卢俊义在水里被张顺抓住&#xff0c;用轿子抬到了梁山。宋江等人下马跪在地上迎接&#xff0c;请他坐第一把交椅。卢俊义宁死不从&#xff0c;大家只好说留他在山寨几天&#xff0c;先让李固带着马车货物回去。吴用对李固说&#xff0c;你的主人已经答应坐第二把交椅了&#xf…

matlab实现Logistic回归

一、目的和要求 1.编程实现Logistic Regression并应用于数据集&#xff1b; 2.绘制二元分类函数、sigmoid函数和代价函数&#xff1b; 3.正则化logistic回归代价。 二、算法介绍 步骤&#xff1a; 选择一个合适的分类函数来实现分类&#xff08;Sigmoid函数&#xff09; …

OpenHarmony开发之图形UI组件解析

简介 图形UI组件实现了一套系统级的图形引擎。 该组件为应用开发提供UIKit接口&#xff0c;包括了动画、布局、图形转换、事件处理&#xff0c;以及丰富的UI组件。 组件内部直接调用HAL接口&#xff0c;或者使用WMS(Window Manager Service)提供的客户端与硬件交互&#xff…