From Test-Scratch-Wiki
Ask () and Wait | |
ask [] and wait
| |
Category | Sensing |
Type | Stack |
Introduced in | 1.4 |
The Ask () and Wait block is a Sensing block and a Stack block. The block will make the sprite using the block say the question and show an input box at the bottom of the screen. If the question is being asked by the stage or a hidden sprite, the question will appear above the input instead. Scratchers can input text into it and submit it, and the input is stored then in the Answer block. The Answer block automatically updates to most recent input.
This block and the answer block were added in Scratch 1.4.
Appearance
If this block is used in a sprite that is showing, the question asked will show similar to the Say () (block). When the sprite is hidden, the question pops up above the input box.
Example Uses
As this block allows users to input any text they want, it is widely used when a user must communicate with the project.
Some common uses for the Ask () and Wait block:
- Chatbots
— receiving information from the user
ask [What's your name?] and wait say (join [Hello, ] (join (answer) [.]))
- Setting preferences
— coordinates, color, and so on
ask [What is your favourite colour?] and wait set [color v] effect to (answer) say [I turned into your favourite colour!]
- Receiving input
— asking the user to give a command
ask [Move how many steps?] and wait move (answer) steps
Workarounds
- Main article: List of Block Workarounds
Sensing Method
This block can be somewhat replicated with the following code:
say (question) delete all of [answer v] set [count v] to [0] repeat until <key (join [enter]()) pressed?> if <key (a v) pressed?> then change [count v] by (1) insert [A] at (count) of [answer v] end if <key (b v) pressed?> then change [count v] by (1) insert [B] at (count) of [answer v] end if <key (c v) pressed?> then change [count v] by (1) insert [C] at (count) of [answer v] end if <key (d v) pressed?> then change [count v] by (1) insert [D] at (count) of [answer v] end if <key (e v) pressed?> then change [count v] by (1) insert [E] at (count) of [answer v] end if <key (f v) pressed?> then change [count v] by (1) insert [F] at (count) of [answer v] end if <key (g v) pressed?> then change [count v] by (1) insert [G] at (count) of [answer v] end if <key (h v) pressed?> then change [count v] by (1) insert [H] at (count) of [answer v] end if <key (i v) pressed?> then change [count v] by (1) insert [I] at (count) of [answer v] end if <key (j v) pressed?> then change [count v] by (1) insert [j] at (count) of [answer v] end if <key (k v) pressed?> then change [count v] by (1) insert [K] at (count) of [answer v] end if <key (l v) pressed?> then change [count v] by (1) insert [L] at (count) of [answer v] end if <key (m v) pressed?> then change [count v] by (1) insert [M] at (count) of [answer v] end if <key (n v) pressed?> then change [count v] by (1) insert [N] at (count) of [answer v] end if <key (o v) pressed?> then change [count v] by (1) insert [O] at (count) of [answer v] end if <key (p v) pressed?> then change [count v] by (1) insert [P] at (count) of [answer v] end if <key (q v) pressed?> then change [count v] by (1) insert [Q] at (count) of [answer v] end if <key (r v) pressed?> then change [count v] by (1) insert [R] at (count) of [answer v] end if <key (s v) pressed?> then change [count v] by (1) insert [S] at (count) of [answer v] end if <key (t v) pressed?> then change [count v] by (1) insert [T] at (count) of [answer v] end if <key (u v) pressed?> then change [count v] by (1) insert [U] at (count) of [answer v] end if <key (v v) pressed?> then change [count v] by (1) insert [V] at (count) of [answer v] end if <key (w v) pressed?> then change [count v] by (1) insert [W] at (count) of [answer v] end if <key (x v) pressed?> then change [count v] by (1) insert [X] at (count) of [answer v] end if <key (y v) pressed?> then change [count v] by (1) insert [Y] at (count) of [answer v] end if <key (z v) pressed?> then change [count v] by (1) insert [Z] at (count) of [answer v] end if <key (0 v) pressed?> then change [count v] by (1) insert [0] at (count) of [answer v] end if <key (1 v) pressed?> then change [count v] by (1) insert [1] at (count) of [answer v] end if <key (2 v) pressed?> then change [count v] by (1) insert [2] at (count) of [answer v] end if <key (3 v) pressed?> then change [count v] by (1) insert [3] at (count) of [answer v] end if <key (4 v) pressed?> then change [count v] by (1) insert [4] at (count) of [answer v] end if <key (5 v) pressed?> then change [count v] by (1) insert [5] at (count) of [answer v] end if <key (6 v) pressed?> then change [count v] by (1) insert [6] at (count) of [answer v] end if <key (7 v) pressed?> then change [count v] by (1) insert [7] at (count) of [answer v] end if <key (8 v) pressed?> then change [count v] by (1) insert [8] at (count) of [answer v] end if <key (9 v) pressed?> then change [count v] by (1) insert [9] at (count) of [answer v] end if <<key (right arrow v) pressed?> and <(count) < ((length of [answer v]) + (1))>> then change [count v] by (1) end if <<key (left arrow v) pressed?> and <(count) > [1]>> then change [count v] by (-1) end if <key (space v) pressed?> then change [count v] by (1) insert [ ] at (count) of [answer v] end if <<key (join [][~]) pressed?> and <(count) > [1]>> then // the tilde serves as the backspace key, since it is impossible to let Scratch detect if the backspace key has been pressed change [count v] by (-1) delete (count) of [answer v] end wait until <not <key (any v) pressed?>> end say []
Note: | This does not work perfectly. See this project for more information. |
The list "answer" will replace the answer block.
Hat Block Method
Text input can be retrieved in correct order and speed by using this method.
when [a v] key pressed add [a] to [queue v] when [b v] key pressed add [b] to [queue v] when [c v] key pressed add [c] to [queue v] //and so forth for each key when [left arrow v] key pressed delete (last v) of [queue v] // backspace function when gf clicked delete (all v) of [queue v] wait until <key [right arrow v] pressed?> // this will confirm the user is done inputting set [clump v] to [] // blank set [n v] to [1] repeat (length of [queue v]) // compile list into a single string set [clump v] to (join (clump) (item (n) of [queue v]) change [n v] by (1) end (clump) // will be the answer
Cancellation
To cancel the text box that appears once this block is activated, one must stop the script which ran this block. An example of when one might want to cancel the text box is if an answer is not received in a certain amount of time, or if a cancel button is pressed.
A few methods of cancellation are:
// broadcast method (message)::grey hat (cancel?)::grey cap define ask-calcellable [message] and wait set [message v] to (message) set [cancel v] to [0] broadcast [ask v] and wait//an alternative version of the custom block could not wait here define cancel ask set [cancel v] to [1] broadcast [ask v] and wait//wait for cancel to finish. optional when I receive [ask v] if < (cancel?) = [0] > :: control ask (message) and wait else say [] // in some scratches, the bubble would otherwise stay up end // clone method ((message)::grey) define ask-calcellable [message] and wait set [message v] to (message) create clone of [myself v] // this means that no other clones can be used broadcast [ask v] and wait // the wait part is the important part when I receive [ask v] ask (message) and wait define cancel ask broadcast [cancel v] and wait when I receive [cancel v] delete this clone // stop method // Stage ((message)::grey) // Sprite1 define ask-calcellable [message] and wait set [message v] to (message) broadcast [ask v] and wait define cancel ask broadcast [cancel v] and wait // Sprite2 when I receive [ask v] ask (message) and wait when I receive [cancel v] stop [other scripts in sprite v]
An example of this can be found here.