Simulating a custom reporter block in Scratch?

限于喜欢 提交于 2019-12-13 15:02:52

问题


In Scratch 2.0, support for custom stack blocks (procedures) was added. But is there any way to use this to "abstract away" logic that returns a value?

For example, i have here a script to naively calculate exponents: (view graphic representation)

set [base v] to [2]
set [index v] to [3]
... // above is for initializing
set [result v] to (base)
repeat until <(index) = [1]>
  set [result v] to ((result) * (base))
  change [index v] by (-1)

How could i export this logic to a "custom reporter" to reuse?


回答1:


Here's an example (rendered):

define split [text] by [splitter]
delete (all v) of [output list v]
set [parse v] to [0]
set [cur string v] to []
repeat until ((parse) > (length of (splitter))
   if <(letter (parse) of (text)) = (splitter)> then
      add (cur string) to [output list v]
      set [cur string v] to []
   else
      set [cur string v] to (join (cur string) (letter (parse) of (text)))
   end
end

when GF clicked
split [Hello, world! Do you like this?] by [ ] // That's a space.

// That should output a list: ["Hello,", "world!", "Do", "you", "like", "this?"]

define the answer to life
set [output var v] to (42)

when GF clicked
the answer to life
say (output var)

It shows off how to use both a list output and a variable output.




回答2:


There is a second, more complicated way to do this. It allows for recursive blocks, and you can run a block multiple times. I call it the stacking method, because i use a list as a stack. For an example, see this project that i made.

This method also doesn't clutter up the variables palette.

define (base) ^ (index) recursive
if <(index) = [1]>
  add (base) to [stack v]
else
  (base) ^ ((index) - (1)) recursive // adds the previous item to the stack
  add ((base) * (item (last v) of [stack v])) to [stack v]
  delete ((length of [stack v]) - (1)) of [stack v] // clean up

It can then be accessed using essentially the same method as i explained in the other answer:

when gf clicked
(4) ^ (3) recursive // the stack block
say (join [4 ^ 3 = ] (item (last v) of [stack v])) // get the item from the end of the stack
delete [last v] of [stack v] // optional, if you want to clean up

See this in rendered ScratchBlocks.




回答3:


The easiest way to do this is by creating a custom command block, and storing the return value in a variable. This has some drawbacks, such as not allowing recursive calls, but works in most cases. I also recommend setting the block to run without screen refresh.

Simply define it like this, with the return value available as result:

define (base) ^ (exp)
set [index v] to (exp) // need a variable, as arguments are immutable
set [result v] to (base)
repeat until <(index) = [1]>
  set [result v] to ((result) * (base))
  change [index v] by (-1)

It can then be called like:

when gf clicked
(4) ^ (3) // the stack block
say (join [4 ^ 3 = ] (result)) // result is set by the [()^()] block

See this in rendered ScratchBlocks.



来源:https://stackoverflow.com/questions/27948249/simulating-a-custom-reporter-block-in-scratch

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!