Maybe for sprite masking, you could have a [set mask to [costume]] block.
Offline
ProgrammingFreak wrote:
I thought it was just BHarvey and Jens
That's pretty much true as far as the actual downloadable stuff goes. (Mostly Jens!) But many, many people have contributed ideas, examples, and debugging effort; some of them are contributors to this forum thread, some are faculty, staff, and students at Berkeley, and some are colleagues elsewhere. (Not to mention our huge debt to the giants on whose shoulders we stand, including the Scratch Team.)[1] BYOB wouldn't be half as good without you all!
[1] - I read recently that when Newton said that about standing on giants he was being sarcastic; in context it was an attack on a particular colleague who believed himself to be such a giant. But I really mean it!
Last edited by bharvey (2011-03-03 01:11:29)
Offline
floppy_gunk wrote:
Maybe for sprite masking, you could have a [set mask to [costume]] block.
We won't need a new block. In the new 3.1 world, we would just add MASK to the set of attributes, and then you could use the plain old SET block.
Way back when we started this project, and I found out about Panther, I thought "these are really cool features but there are too many blocks!" I think we have now solved that problem, at least for sprite-related things.
Offline
bharvey wrote:
IMHO what you really want is the ability to right-click an input name orange blob and have a "set type" option that opens the same dialog as the long form Block Editor input name/type one. Then you could just choose the multiple inputs option.
No. The "multiple inputs" option is simply syntactic sugar for calling the procedure with a LIST block in an argument (the exception is unevaluated inputs, which are also syntactic sugar for THE SCRIPT or THE BLOCK (which is syntactic sugar for THE SCRIPT and RETURN)). I want a closure which can be called with a variable number of arguments and which knows the amount of arguments it was called with. The solution: a list of the arguments. This is not the same thing as an argument which is a list, which could be checked with an IF statement at the beginning of the closure.
Last edited by nXIII (2011-03-03 16:41:44)
Offline
Feeling like the dumb kid again...
I'm rewriting the games of some of my kids in BYOB, to see if I can learn anything from it, and also if I can TEACH anything... I want to test whether a sprite has children. I've tried this three ways:
wait until ((attribute -> children) of spriteX) = 0
wait until (length of ((attribute -> children) of spriteX)) = 0
if (not (attribute(children) of spriteX))
The first two tests are always true. The third gives a syntax error, and the script gets highlighted in red. Clearly I don't really understand what the 'children' attribute is -- which I guess is one question. And a second is, how should I test for the existence of clones/children?
More questions on their way...
Offline
gardenhackers wrote:
Feeling like the dumb kid again...
I'm rewriting the games of some of my kids in BYOB, to see if I can learn anything from it, and also if I can TEACH anything... I want to test whether a sprite has children. I've tried this three ways:
wait until ((attribute -> children) of spriteX) = 0
wait until (length of ((attribute -> children) of spriteX)) = 0
if (not (attribute(children) of spriteX))
The first two tests are always true. The third gives a syntax error, and the script gets highlighted in red. Clearly I don't really understand what the 'children' attribute is -- which I guess is one question. And a second is, how should I test for the existence of clones/children?
More questions on their way...
Since the attribute 'children' is an list of objects you should use the 'length of block' to measure the amount of children, but to call the reporter of another sprite you need to put it in (the block('foo'))of(spriteX) it Wont work without the 'the block()' block.
BTW- that just gets you the other sprites block, then you need to call it.
Last edited by 14God (2011-03-03 18:12:12)
Offline
nXIII wrote:
bharvey wrote:
IMHO what you really want is the ability to right-click an input name orange blob and have a "set type" option that opens the same dialog as the long form Block Editor input name/type one. Then you could just choose the multiple inputs option.
No. The "multiple inputs" option is simply syntactic sugar for calling the procedure with a LIST block in an argument (the exception is unevaluated inputs, which are also syntactic sugar for THE SCRIPT or THE BLOCK (which is syntactic sugar for THE SCRIPT and RETURN)). I want a closure which can be called with a variable number of arguments and which knows the amount of arguments it was called with. The solution: a list of the arguments. This is not the same thing as an argument which is a list, which could be checked with an IF statement at the beginning of the closure.
This is a handy feature in similar closure-based languages...Javascript has the arguments object available from within every function, and in AS3 you can specify ...args instead of parameters in the method signature to obtain a list of arguments instead.
Offline
Another 3.1 alpha test bugfix release.
Jens wrote:
Aanother nightly bugfix build, this one fixes an exception that happened when exporting a sprite with certain custom blocks and another one that happened when invoking
CALL ((THE (CLONE) BLOCK) OF (OBJECT myself))
Enjoy!
--Jens
P.S. I'll be away and mostly offline over the weekend and travelling (and mostly offline) next Monday and Tuesday.
Offline
two more attribute questions:
- where does the 'heading' attribute in jens's breakout game come from? and
- what's the 'anchor' attribute?
sorry if this has all been covered, I've been busy for the last couple of weeks.
Offline
14God wrote:
Since the attribute 'children' is an list of objects you should use the 'length of block' to measure the amount of children, but to call the reporter of another sprite you need to put it in (the block('foo'))of(spriteX) it Wont work without the 'the block()' block.
BTW- that just gets you the other sprites block, then you need to call it.
I'm going to go take another look at the old BYOB 3 tutorials, since I clearly don't understand this very well. But I just tried:
wait until ((length of (the (attribute(children)) block) of SpriteX) =0)
Even when there are no clones left, this evaluates as false. I would have thought the list "attribute(children)" wasn't exactly a block, anyway, right?
Anyway, I've uploaded a version of the project to the web:
http://www.mercey.org/clinton/ant_byob.ypr
if anyone wants to look at it. Thanks as always!
Matt
Offline
Another simple game that's stumping me, this time online at:
http://www.mercey.org/clinton/matthews_devil.ypr
Here I have two issues, perhaps related, both involving the spawning of 'bullet' clones to enemy ships in a space battle game. I'm using Jens' "tell (ask OBJECT for CLONE) to ACTION [" trick to get a clone to execute certain steps when it's created. In my case it just says:
tell (ask EVIL BULLET for CLONE) to [
go to object MYSELF
show
] (do I have the caps all wrong? sorry if I do!)
This doesn't work, so I tried setting a script variable a first to object MYSELF and then to the (object MYSELF) block, and then
go to a
Neither of these was successful. I need the reference to "myself" so that I can clone the enemy spaceship later on in the game; and in any case, the 'go to' block doesn't permit 'go to SpriteX' unless you're in a non-spriteX sprite.
(2) I'm realizing how much I rely on "when green flag clicked" scripts for permanent behaviours of sprites. With clones this doesn't work, and I really miss it. I'm not sure what the best replacement is when clones are added at an arbitrary point in the game. In Jens' breakout game, the bricks are all cloned at once, so you can send a signal to them all once they've been created. In my very simple game, the bullets are created all the time, and they need to be run in a forever loop -- or anyway a repeat until loop -- which should probalby be spawned off from the script that created them. I guess I could define a brick that governed the bullet's movement, and put it in the "tell the clone to" c-shaped brick; but that would still stall the bullet-creation script until the current bullet had been extinguished. It would be great if there was a "when created" or "when I clone myself" brick, or, better I guess, if I could figure out how to create such a brick myself.
thanks agian!
matt
Offline
nXIII wrote:
I want a closure which can be called with a variable number of arguments and which knows the amount of arguments it was called with. The solution: a list of the arguments. This is not the same thing as an argument which is a list, which could be checked with an IF statement at the beginning of the closure.
I'm sorry, I'm short on sleep, maybe I'm being dense, but I don't see the distinction you're making. If the procedure can be called with a variable number of arguments, then either it has a variable number of formal parameters, which I can't envision at all, or else it has one formal parameter bound -- somehow -- to all the arguments. The easiest "somehow" I can see is to make a list of the arguments. You want to know how many there are? Call LENGTH on the list!
Also, are you using "closure" and "procedure" to mean two different things? I was brought up with the understanding that in a lexically scoped language a procedure is the closure of a lambda expression -- in other words, the procedure provides bindings for all the free variables in the lambda expression.
Offline
gardenhackers wrote:
wait until ((attribute -> children) of spriteX) = 0
Like most programming languages, excepting afaik only the purely functional ones such as ML and Haskell, BYOB uses applicative order evaluation, which means basically that expressions are evaluated from the inside out. For example, if you say
[2 + [3 * 4]]
the plus function gets 2 and 12 as inputs; it doesn't know how the 12 was computed. The only exceptions to this rule are the special forms; that's what's special about them.
So, in particular, when you use an OF block, its two inputs are evaluated before BYOB does the OF function itself. In even more particular, when you say
[[ATTRIBUTE <whatever>] OF <whatever>]
the very first thing that happens is the evaluation of the ATTRIBUTE call, which reports the value of the chosen attribute of this sprite! This isn't what you want; you want the OF block to know which attribute of some other sprite you're trying to find out.
I'm like the sort of academic who only ever has one idea in his or her entire career, and keeps writing slight variations of the same paper over and over -- except that in my case, the one idea isn't even mine. The idea is first class procedures and maybe an even better analogy is the one about the guy who only has a hammer; my instinctive solution to every problem is to encapsulate something in a procedure-as-data. So, the value of
ATTRIBUTE <CHILDREN>
is a list, but the value of
THE [ATTRIBUTE <CHILDREN>] BLOCK
is an encapsulated request for someone's children. That's why, as 14God says, you have to put the ATTRIBUTE block inside a THE BLOCK block.
But, notice that OF will report the other sprite's version of the ATTRIBUTE block. You then have to call that block. So what you want is the mouthful
[[LENGTH OF [CALL [[THE [ATTRIBUTE <CHILDREN>] BLOCK] OF [OBJECT <whatever>]]]] = 0]
Luckily all those nested brackets turn into colorful self-delimiting blocks in a graphical language. And the 3.1 version of the tools project will have a block
ASK <object> FOR <Reporter>
and since that slot is Reporter-type instead of a dropdown list, it has grey-border behavior and you don't need an explicit THE BLOCK nor an explicit call to CALL (the ASK block does the CALL and the OF for you). So it'll be
[[LENGTH OF [ASK [OBJECT <whatever>] FOR {ATTRIBUTE <CHILDREN>}] = 0]
where the {braces} indicate a grey border.
Offline
gardenhackers wrote:
tell (ask EVIL BULLET for CLONE) to [
go to object MYSELF
show
]
As I think you've worked out, the problem is about the scope of the "myself." Anything inside that script is going to be run in the target sprite, not in the originating sprite. Using a script variable inside the script, set inside the script to the result of a "myself" inside the script, doesn't help that.
It really helps if you understand that
TELL <obj> TO <script>
means
LAUNCH [[THE SCRIPT <script>] OF <obj>]
What you actually want (my version of TELL lets you do this; I haven't read Jens's project's code yet so I'm not sure about his) is
LAUNCH [[THE SCRIPT <script>] OF <obj>] WITH INPUTS [OBJECT <MYSELF>]
and then in your script, you say GO TO < > leaving an empty slot into which the argument value (a sprite, in this case) will go.
I'm realizing how much I rely on "when green flag clicked" scripts for permanent behaviours of sprites. With clones this doesn't work, and I really miss it.
Isn't this the purpose of the TELL [CLONE] TO ... idea?
Offline
fullmoon wrote:
and in AS3 you can specify ...args instead of parameters in the method signature to obtain a list of arguments instead.
Yeah, and in BYOB you can specify "args..." instead of parameters to do the same thing! What am I missing here?
Offline
bharvey wrote:
gardenhackers wrote:
tell (ask EVIL BULLET for CLONE) to [
go to object MYSELF
show
]It really helps if you understand that
TELL <obj> TO <script>
means
LAUNCH [[THE SCRIPT <script>] OF <obj>]
What you actually want (my version of TELL lets you do this; I haven't read Jens's project's code yet so I'm not sure about his) is
LAUNCH [[THE SCRIPT <script>] OF <obj>] WITH INPUTS [OBJECT <MYSELF>]
and then in your script, you say GO TO < > leaving an empty slot into which the argument value (a sprite, in this case) will go.
This is really helpful. I need to learn to think in terms of THE BLOCK and THE SCRIPT more fundamentally. Thank you. Having the pre-fab "ASK [sprite] FOR" block will make it much easier for me to use these features with the 10 & 11 year olds I'm working with; one of the downsides to a more sophisticated language is that there's so much more to explain when you try to use the new features.
I'm realizing how much I rely on "when green flag clicked" scripts for permanent behaviours of sprites. With clones this doesn't work, and I really miss it.
Isn't this the purpose of the TELL [CLONE] TO ... idea?
yes... but take the case of the bullet. After being created and given an initial position and direction, the bullet needs to travel across the screen; maybe inb some circumstances it keeps bouncing or scrolling around until it hits something. The TELL [CLONE] TO ... script can't exit till the bullet's done moving (I think?). I can't create a new bullet with that script (say, in a loop that waits 2 seconds between shots) unless the initial bullet dies or something. Some way to work around this issue would be good (an not just for bullets, but also given that bullets appear in about 40% of the games my kids make, even just for bullets is significant), but I don't immediately see the solution.
Offline
bharvey wrote:
gardenhackers wrote:
wait until ((attribute -> children) of spriteX) = 0
L
But, notice that OF will report the other sprite's version of the ATTRIBUTE block. You then have to call that block. So what you want is the mouthful
[[LENGTH OF [CALL [[THE [ATTRIBUTE <CHILDREN>] BLOCK] OF [OBJECT <whatever>]]]] = 0]
Luckily all those nested brackets turn into colorful self-delimiting blocks in a graphical language. And the 3.1 version of the tools project will have a block
ASK <object> FOR <Reporter>
and since that slot is Reporter-type instead of a dropdown list, it has grey-border behavior and you don't need an explicit THE BLOCK nor an explicit call to CALL (the ASK block does the CALL and the OF for you). So it'll be
[[LENGTH OF [ASK [OBJECT <whatever>] FOR {ATTRIBUTE <CHILDREN>}] = 0]
where the {braces} indicate a grey border.
OK, I think I get it now. I'll go give it a try. Thanks a bunch -- super helpful!
Offline
bharvey wrote:
gardenhackers wrote:
wait until ((attribute -> children) of spriteX) = 0
But, notice that OF will report the other sprite's version of the ATTRIBUTE block. You then have to call that block. So what you want is the mouthful
[[LENGTH OF [CALL [[THE [ATTRIBUTE <CHILDREN>] BLOCK] OF [OBJECT <whatever>]]]] = 0]
Luckily all those nested brackets turn into colorful self-delimiting blocks in a graphical language. And the 3.1 version of the tools project will have a block
ASK <object> FOR <Reporter>
and since that slot is Reporter-type instead of a dropdown list, it has grey-border behavior and you don't need an explicit THE BLOCK nor an explicit call to CALL (the ASK block does the CALL and the OF for you). So it'll be
[[LENGTH OF [ASK [OBJECT <whatever>] FOR {ATTRIBUTE <CHILDREN>}] = 0]
where the {braces} indicate a grey border.
hmm. tried that (I think) but it doesn't seem to be working.
an image is here:
http://www.mercey.org/clinton/length_of_script.gif
and the project is here:
http://www.mercey.org/clinton/ant_byob.ypr
if anyone has the time to tinker. Thanks!
Matt
Offline
bharvey wrote:
gardenhackers wrote:
tell (ask EVIL BULLET for CLONE) to [
go to object MYSELF
show
]As I think you've worked out, the problem is about the scope of the "myself." Anything inside that script is going to be run in the target sprite, not in the originating sprite. Using a script variable inside the script, set inside the script to the result of a "myself" inside the script, doesn't help that.
It really helps if you understand that
TELL <obj> TO <script>
means
LAUNCH [[THE SCRIPT <script>] OF <obj>]
What you actually want (my version of TELL lets you do this; I haven't read Jens's project's code yet so I'm not sure about his) is
LAUNCH [[THE SCRIPT <script>] OF <obj>] WITH INPUTS [OBJECT <MYSELF>]
and then in your script, you say GO TO < > leaving an empty slot into which the argument value (a sprite, in this case) will go.I'm realizing how much I rely on "when green flag clicked" scripts for permanent behaviours of sprites. With clones this doesn't work, and I really miss it.
Isn't this the purpose of the TELL [CLONE] TO ... idea?
Offline
gardenhackers wrote:
The TELL [CLONE] TO ... script can't exit till the bullet's done moving (I think?).
This is the purpose of the LAUNCH block, a variant of RUN that runs the script in a new thread. I don't know if Jens's version of TELL uses LAUNCH or RUN, but if it's RUN, change it to LAUNCH.
Offline
gardenhackers wrote:
it doesn't seem to be working.
Since we're talking about a list, not a text string, you have to use the red LENGTH block in the Variables palette, not the green one in Operators. I agree that this is an annoying confusion, but we inherited it from Scratch.
Offline
bharvey wrote:
gardenhackers wrote:
it doesn't seem to be working.
Since we're talking about a list, not a text string, you have to use the red LENGTH block in the Variables palette, not the green one in Operators. I agree that this is an annoying confusion, but we inherited it from Scratch.
ach! thank you. THAT worked.
Offline
bharvey wrote:
What you actually want (my version of TELL lets you do this; I haven't read Jens's project's code yet so I'm not sure about his) is
LAUNCH [[THE SCRIPT <script>] OF <obj>] WITH INPUTS [OBJECT <MYSELF>]
and then in your script, you say GO TO < > leaving an empty slot into which the argument value (a sprite, in this case) will go.
sorry, I screwed up the posting where I meant to respond to this. This works great, and thanks also for the clarification about launch vs. run. I don't see how, in the block creation interface, I would create the TELL [sprite] TO [action] c-shaped block in such a way as to enable the WITH INPUTS element for the included script. Jens's does not seem to permit inputs -- it's just:
TELL [object] TO [action] [
LAUNCH (action OF object)
where action is a c-shaped input. How do I translate an input to TELL into an input to the LAUNCH block it contains? I knowthis is remedial, but I'm still having trouble iwth it. Thanks again (and again, and again...).
Offline
gardenhackers wrote:
How do I translate an input to TELL into an input to the LAUNCH block it contains?
The "args" input slot has to have the "multiple inputs" option selected in the long input name dialog. (The other two inputs are type Object and type C-shaped respectively.)
Note that it's "with input list," not "with inputs," in the LAUNCH block.
Offline