学习YouTube@brwxddev写的Godot项目(Slot Machine)

呕吐式学习

学习目的

前两天跟着Godot官方入门教程把“你的第一个2D游戏”做出来了(帖子
虽然还是云里雾里,但我觉得我可以开始通过模仿别人开源的项目学习并制作一点别的小游戏(某种我觉得对的学习曲线)

想做一个老虎机游戏 于是搜索到了YouTube@brwxddev写的这个教程
作者也把项目文件放在GitHub上了(链接

我的目的是最终在学习基础上做出一个5x5的老虎机游戏(类似弹丸V3里的那个),并且钱是会花完的(Game Over),赢的钱可以兑换物品(通往Ending?)

学习中……

不堪入目的试图看懂代码过程

研究这个老虎机https://youtu.be/AcvvarHo5T8?si=IV7gAKmsuszX4gwE

看reel.gd

  1. 原来脚本不用对应场景,哥们单独写了个signalbank脚本,里面放了开始roll和roll停止的信号,不过这个信号括号里的参数是怎么用的,增增哇嘎乃:bugcat_sweat:
1signal startRoll(slotID,duration)
2signal rollFinished(slotID,result)
  1. 然后在reel节点的脚本里ready函数就调用了开始roll的信号,遇到了没学过的名字就是这个callable
    reel1和reel2是代表白色和红色的卷轴,两个都会一起塞进一个滚筒里,有点不明白为什么要这么设计?这段代码应该是在说启动时的状态是显示红色卷轴,白色卷轴放到显示区域外?
1func _ready():
2    SigBank.startRoll.connect(Callable(self,"_startRoll"))
3    reel1.position.y = -1000
4    reel2.position.y = 0
  1. 上次学到process函数是运行时每一帧都会刷新的函数(大意)
 1func _process(delta):
 2    if Input.is_action_just_released("ui_accept"):
 3        _startRoll(reelID,5)
 4        print("rollMe")
 5    
 6    match state:
 7        ROLLBACK:
 8            _roll(reel1,-MS)
 9            _roll(reel2,-MS)
10            
11            rollBackDuration -= delta
12            if rollBackDuration <= 0:
13                state = ROLL
14        ROLL:
15            _roll(reel1,MS)
16            _roll(reel2,MS)
17            
18            rollDuration -= delta
19            if rollDuration <= 0:
20                state = STOP
21                _stopRoll()
22        STOP:
23            pass

这么看起来SigBank.startRoll.connect(Callable(self,"_startRoll"))这行是定义了开始的roll信号?结合signal startRoll(slotID,duration)来看,_startRoll(reelID,5)的意思是开始rollreelID(整数),每个转轴的roll时间间隔5(单位是帧吗?)
之前学过match可以给枚举的变量的值执行不同的代码,这里脚本顶部枚举了enum {ROLL,STOP,ROLLBACK}
但是没能理解前面有下划线的这个是什么意思:bugcat_sweat:
顶部也写了var state,但没看懂这里是什么意思……:zenzenwakannai:

  1. 看了后面的代码
 1func _startRoll(reelNumber,dur):
 2    if reelNumber!= reelID : return
 3    
 4    reel1.position.y = -1000
 5    reel2.position.y = 0
 6    state = ROLLBACK
 7    rollDuration = dur
 8    print(reelID,reelNumber,dur)
 9    rollBackDuration = 0.25
10    
11
12func _roll(slot:Sprite2D,MSpeed):
13    var newPOS2 = slot.position.y + MSpeed
14    if newPOS2 >= 1000:
15        newPOS2 =-1000
16    slot.position.y = newPOS2
17
18func _stopRoll():
19    TWN = create_tween().set_trans(Tween.TRANS_SPRING).set_ease(Tween.EASE_OUT).set_parallel()
20    var rng = randi_range(0,9)
21    var dur = 1.5
22
23    var finalPos = -100*rng
24    
25    var finalSlot
26    var anotherSlot
27    if reel1.position.y < reel2.position.y:
28        finalSlot = reel1
29        anotherSlot = reel2
30    else:
31        finalSlot = reel2
32        anotherSlot = reel1
33    
34    finalSlot.z_index = 1
35    anotherSlot.z_index = 0
36    TWN.tween_property(finalSlot,"position:y",finalPos,dur)
37    TWN.tween_property(anotherSlot,"position:y",finalPos+1000,dur)
38    await TWN.finished
39    print("Reeel ID",reelID," reel Image ", finalSlot.name ," POS : ",finalPos, " RNJESUS :",rng)
40    SigBank.rollFinished.emit(reelID,rng)

好像有点明了了,前面match的里面调用的是这里的函数

  • 看一下_startRoll
    没看懂,应该是在定义转轴初始状态??

  • 看一下_roll
    好像是在说如果图片往下转到屏幕下方显示区域外面,就把它刷新到屏幕上方显示区域外面(确保可持续

  • 看一下_stopRoll
    有必要去查一下tween的定义……这一行没看懂
    这个rng应该是指显示的图样0-9
    finalSlot取y值更小的卷轴?没看懂 不是有可能在屏幕外面吗:bugcat_sweat:还是说有部分代码确保最终显示的卷轴是在屏幕内且在另一个卷轴上方的
    tween相关的看不懂
    最后传回了一个roll结束的信号

看slot_machine_ui.gd

这是一个用户界面节点(?)包括三个滚轴和spin按钮 bet按钮 结果显示

1.顶部

1var reelResult1
2var reelResult2
3var reelResult3
4
5var receivedHowManyTimes = 0
6
7var betValue
8var betResult
9var winningMultiplier = 0
  1. ready函数看起来是启动时接收roll结束的信号并收集数据?
1func _ready():
2    
3    SigBank.rollFinished.connect(Callable(self,"_receiveNumber"))
4    pass # Replace with function body.
  1. 上面信号里用到了这个函数
 1func _receiveNumber(reelID,rngResult):
 2    receivedHowManyTimes +=1
 3    match reelID:
 4        1:
 5            reelResult1 = rngResult
 6        2:
 7            reelResult2 = rngResult
 8        3:
 9            reelResult3 = rngResult
10    if receivedHowManyTimes <3:
11        print(receivedHowManyTimes)
12        
13    else:
14        receivedHowManyTimes = 0
15        _calculateWinning()

应该是在说收集三个滚轴的结果,并只收集三次
4. 上面的函数最后一行用到了这个函数

 1func _calculateWinning():
 2    betValue = int($betAmount.value)
 3    
 4    
 5    if reelResult1 == reelResult2 || reelResult2 == reelResult3:
 6        winningMultiplier = 5
 7    elif  reelResult1 == reelResult2 && reelResult2 == reelResult3:
 8        winningMultiplier = 100
 9    else :
10        winningMultiplier = -1
11    betResult = betValue * winningMultiplier
12    if betResult>0:
13        $Result.text = "+ "+str(betResult)
14    else:
15        $Result.text = "LMAO !!!!  "+str(betResult)

这里定义了结果赢不赢钱
如果三个卷轴中有两个一样就赢5倍
三个结果都一样赢100倍
否则扣除下注的钱
(嗯?这个意思是,赢钱的情况不会扣下注的钱?)
如果赢钱,结果标签显示“+数字”,没有的话就嘲笑
5. 最后一个函数

1func _on_spin_button_button_up():
2    SigBank.startRoll.emit(1,2)
3    SigBank.startRoll.emit(2,2.5)
4    SigBank.startRoll.emit(3,3)
5    pass # Replace with function body.

这个应该传的是系统带的按钮抬起的信号
emit是什么意思(
括号内的参数左边是reelID,右边是duration(这个duration到底是指哪里的间隔

查资料补充知识中

信号

emit

emit:释放信号
signal_name.emit()

因此:

1func _on_spin_button_button_up():
2    SigBank.startRoll.emit(1,2)
3    SigBank.startRoll.emit(2,2.5)
4    SigBank.startRoll.emit(3,3)
5    pass # Replace with function body.

的意思是当接收到spin按钮抬起信号时,释放Sigbank.gd脚本中的startRoll信号,参数为(slotID, duration),即第一个滚轴开始滚动持续时间为2,第二个滚轴开始滚动持续时间为2.5,第三个滚轴开始滚动持续时间为3

问了AI如何理解这里的duration单位是帧还是秒:

  1. 有小数,所以不会是帧
  2. 有信号接收方要求duration的单位是秒(找了一下,应该是_startroll调用了startRoll信号,而func _process(delta):调用了_startroll,因此单位是秒)
*学不完了明天学*
本博客已稳定运行
发表了7篇文章 · 总计25.93k字
使用 Hugo 构建
主题 StackJimmy 设计