Open deader69 opened 9 years ago
The font / text is a bit hard to implement correctly...at least for anything beyond the basics (i.e. Multiline support and more than just stamping of text). Though the basics do still allow you to get fairly complex.
Under the examples category of projects, if you open the JS functions project, there is one which allows you to LABEL text (a la Logo and others). There is an older pull request which implements a more advanced (and complex) block for lots of font options which could be relatively easily turned into a custom block using JS Function.
Long term, there is a plan to have a sprite which has a "text" type costume that would be programmatically controllable I believe.
Another hidden (but fun!) trick is to use the pen
category blocks to draw something and then turn that into a new costume. It's an experimental feature that you can access by shift-right-clicking (shift-two-finger-clicking on a Mac trackpad) on the stage:
Oooh, that IS a cool feature!
How exactly does it work, though? Is it documented somewhere? I don't quite understand how/when the 'recording' starts/stops, where the bitmaps go. I see it's generated some costume frames, auto-named 1428939861416, etc.... but they're blank when I 'edit' them with the paint tool. (I've only spent 1 minute playing with it so far).
Also, when I shift+right-click in FireFox on the Stage, I get a FireFox popup menu with: View Image, Save Image As.., , Inspect Element, etc..
I can still "get around" the popup... but it's a UI collision, confusion for kids.
Hoping I can use this or some similar to develop tile-based games. I wanted to write something like the old Q*Bert arcade game, but want/need to draw stuff algorithmically.
I HAVE written snap stuff to render things algorithmically, then used the right-click 'pic' option to open a bitmap in a separate tab, then saved that bitmap...
Anyway, keep up the good work!
Also, I'd be happy with even a crude font/text feature for now. Even if it allowed only short words, no line wrap.
Say I want to make a simple calculator app, or a virtual keyboard. I'd like to be able to render the buttons somehow without creating and loading a bunch of little bitmaps.
BTW, there's a commercial product name 'Tynker' which is very much like Snap!
It has many many features I'd like to see, and a nice efficient architecture (generates javascript directly, rather than interpreting binary JSON data structures when executing blocks).
Worth a look, for ideas: www.tynker.com/ide/
Thanks! The "turn pen trails into new costume" feature just takes everything that's drawn onto the stage (sans stage background, sprites and watchers) and turns it into a costume.
Yes, I've also just now noticed the Firefox event collision. Sigh. I'll investigate. I hate browsers, they update each week, and each week some browser breaks something else... :-)
For text stamping Michael's LABEL block (in the JS example project) is actually pretty awesome, did you check that out?
I know Tynker and have been in contact with them. I agree they do have some nice features, but I'm afraid their evaluation model is not what you think it is ("generating JS directly", they're not doing that), neither is Snap's ("interpreting binary JSON structures")...
In their 'code view', they do something like the Snap! 'Codification' example...
Since it's right there, available for any/all scripts, I thought that's how they'd implemented... I thought I'd even read somewhere that they're working on the inverse, being able to parse javascript back into block form.
I've only spent like one hour in Tynker, so I'm no expert... but why NOT do it that way?
I know you need an internal binary block representation, to manipulate statements with the mouse... but why not just 'compile' and run on the fly when the program executes? It's how javascript runs anyway, right?
The code they generate looks complete and correct and I don't see why the technique wouldn't work... you could even export the code from a project, and it'd run stand-alone, if you provided the right .js library to provide the runtime environment.
I thought Tynker ran this way because it SEEMS to be faster (based on my very, very limited experimentation)... I've been wanting to test if Tynker apps run better than Snap on limited deviced (smart phones, iPad, tablets)...
I know you're super-busy, and I'm talking about theoretical, monumental architectural changes.. but it was the first thought that came to my mind as a sw engineer.
I really think these block-based programming environments can and SHOULD be the next generation of sw dev tools! :-)
BTW, I totally appreciate and respect the intellectual heritage that you're building upon. I majored in Cog Psych at Carnegie Mellon, so heavy Lisp/Scheme/Smalltalk influences in my own thinking!
I don't mean to be a 'back seat programmer', just asking these questions out of curiosity. :-)
Okay, looking at the 'label' custom block within the JSFunctions example... I can definitely steal some of that code! :-)
Ah, after a few days of vacation I actually love explaining some reasons behind Snap's architecture :-)
It's not just about the IDE. And it's not just about blocks.
Browser side JavaScript is running in a single thread. JS in the browser does currently not have mutlithreading capabilities, on the contrary, it needs to constantly surrender control to the browser, otherwise the browser will complain and kill the process. If you want parallelism in the browser you need to write your own evaluator, and you cannot call any JavaScript functions that take more than a single tick / display cycle to complete. That's why "translating" block scripts to "text code" is nothing but a nice cocktail party trick, it certainly is not "the code behind the blocks", and it certainly is not (ever!) runnable, or - if it is - it will produce different results. Codification in Snap is great for single scripts (so you can embed them in robots), but it does not ever capture the massively parallel runtime environment.
For example: Take these two scripts in Tynker:
If you run this project, the sprite moves in circles, right?
Now look at the "code behind the blocks". This is what Tynker shows you:
It's immediatly clear that this code is not the thing that's actually running, beause in JavaScript you cannot overload primitives like while
. Therefore these two scripts will never run at the same time. In fact, if you did actually try to run this, your browser would immediately crash because while (true)
doesn't ever surrender control.
See, I get all mad at this "progression from blocks to code" crap. What these commercial tools like Tynker show kids is some kind of equivalent, but you really have to squint both eyes. Let's be clear, this kind of "code" is all fake, it is lying to kids. I'm passionately against lying to kids. There is no such thing as "progression" from blocks to text, every programmer knows it's exactly the other way: Text gets parsed into an AST (blocks!), and that gets evaluated (or converted to something else).
So, of course you can convert blocks to "native" JavaScript, but it's going to look like nothing they would ever want to show you in this "code view" tab, and it might not even be faster, because, you know, it needs to be parsed (and compiled!) and - worse - carry the whole multithreading model along.
Yes, Tynker is fast. Speed is always a trade-off and comes out of a bunch of decisions about priorities. First of all, Scratch (and Snap) are designed to be slow. The whole point of Snap is not so much the blocks, but the interactive liveliness. You can change scripts as they are running, you can directly click on anything, even while other stuff is going on, you can tinker and it's always "live". So, I want kids to see what's going on, and that means it has to be slow enough. Otherwise, making a sprite move in circles could be so fast you wouldn't even see it move. It's really a decision of how often to update the display, and how to precise you want to be. At higher frame rates you can do less at each step, which makes it both appear faster and actually work slower than doing more at a lower framerate. Also, you can sometimes decide to be sloppy about certain things, for example about pixel perfect collision detection. That greatly speeds up everything which doesn't need pixel perfect collision detection at every instant. Or you might decide that it's okay if the user presses the red stop button that the project doesn't immediately fully stop, but might go on for a couple of frames. If you only check for such user interactions while a script is running at every other display cycle that also frees resources you can use for other operations (If you closely examine Tynker you'll notice many such decisions towards "sloppiness", btw.)
Snap tries to be as precise as possible, and I have yet to see a project that could not be sped up by choosing the right scheduling option. For example, if your project has several sprites all doing things in parallel, you want to change the scheduling preference to "prefer smooth animations" (which by default is turned off), and that will usually take care of any speed issues. However, to me, Snap is about live interaction with a computer, and not so much about a blocks based IDE. Blocks are great, but they are great because they are live.
So, don't get me wrong, I really like Tynker. They have done really nice work and I like many of their - original - design decisions. It's this obsession about "the code behind the blocks" that gets me all worked up, because it's just not true.
Awesome reply... I have much to learn.
Parallelism, yes... whew! My head is exploding already... turning every loop body into a lambda, with some sort of pollhost() to switch to another thread... yikes!
I could try to muster some intelligent counter-suggestions, but for now... I'm just going to pass on this message in an email to my instructors, so they better understand the architecture.
Great stuff. Wish I had the time to be a contributor, but I'm teaching 10-15 classes a week, and am the General Manager at my school. And I'd have to up my Firefox/Chrome debugging skills, I'm not really a javascript hacker.
Keep on doing whatever's best, I trust your judgement!
Wow, sounds busy but fun. Where do you teach? What level? Are you using BJC?
I teach at theCoderSchool in San Mateo (2nd location, our first school was in Palo Alto).
It's an after-school thing, here's our website. Mostly 8-14 years old, some older students, but they're mostly in python, javascript, etc... http://www.thecoderschool.com/
What is BJC?
The Beauty and Joy of Computing: http://bjc.berkeley.edu It's a college freshman non-CS-major breadth course, and (a year from now) an AP CS course for high schoolers. Combines programming with an exploration of the social implications of computing. Recursion and HOFs in Snap!.
Ahh, I've taken a look at it. And I read about how you transitioned from Scheme to Snap!
Our kids are quite a bit below college level (for the moment), but I we've talked about basing our curriculum for more advanced student on BJC.
I am/was pretty familiar with SICP, hacked many different Scheme/Lisp implementations in C (X-Lisp, X-Scheme, ELK, a couple others)... I learned how to program in C by learning how Scheme/Lisp are implemented in C! :-)
That's a good way to learn!
This is a feature request, not a bug report... (please let me know where I should have filed this idea).
Would love to have a nice set of{draw|fill}{Rect,Oval,Line...} primitives in it's own category/color of blocks. All this functionality already exists in the paint tool, it's a shame kids can't get to it programmatically.
And why are there no font/text tools inside paint? I'd also like to see a category of blocks for that (or fold them into the proposed paint blocks category).
It'd take very little screen real estate to add those categories, and presumably very little code to implement, since they already exist within paint.