I have an idea for a new mod. The mod will take advantage of the online Java applet and its ability to recognize Logo commands.
The mod will add blocks which are found in the .logo files in the applet. The functions in the files (along with most Logo commands), when used as a selector in a block, will run that function in the applet.
This applet will be 100% sharable and functional on the online Java applet.
As long as we directly modify the Scratch image instead of the source code, there's nothing (besides an updated license) that will keep us from keeping the sharing function in this mod.
To give you an idea of what might be in this mod, a list of Logo commands can be found here, and the .logo files from the applet are here:
Commands.logo
; This file defines non-primitive sprite commands except Control commands, which are defined in thread.logo.
; ******* Control *******
; Note: doForever, doIf, doIfElse, doRepeat, doWaitUntil, and doReturn are defined in thread.logo
define wait:elapsed:from: [secs] [timedCommand :secs [] []]
define mwait:elapsed:from: [secs] [timedCommand (:secs / 1000) [] []]
to timedCommand :secs :startAction :endAction
if thread-end-msecs = [] [
set-thread-end-msecs %timer + (1000 * :secs)
run :startAction
yield stop]
if %timer < thread-end-msecs [yield stop]
run :endAction
set-thread-end-msecs []
set-thread-tmp []
end
to broadcast: :msg
ignore startThreadsForBroadcast :msg
end
to doBroadcastAndWait :msg
if empty? thread-tmp [
let [thrds startThreadsForBroadcast :msg]
if empty? :thrds [stop]
set-thread-tmp :thrds
yield stop]
dolist [thrd thread-tmp] [if first :thrd [yield stop]] ; found a running thread
set-thread-tmp [] ; all threads have stopped; we're done
end
; start threads for the given broadcast and return the list of started threads
to startThreadsForBroadcast :msg
let [me who result []]
if (not string? :msg) [make "msg string :msg]
dolist [o fput stage sprites] [
talkto :o
dolist [scr scripts] [
let [hat first :scr]
if (first :hat) = "EventHatMorph [
if (strequ (last :hat) :msg) [
make "result (lput (start-script :o :scr false) :result)
]]]]
talkto :me
output :result
end
to stopAll
let [me who]
stopAllSounds
stop-all-threads
dolist [s sprites][if sprite? :s [talkto :s filterReset talkbubble "||]]
talkto stage filterReset
talkto :me
redrawall
end
define comment: [commentString isOpen] [] ; comments are no-ops
; ******* Motion *******
; Note: xpos, ypos, heading, and %scale are Logo reporters
; %left, %top, %w, and %h give the top, left, width, and height of the scaled & rotated sprite in screen coordinates
; (i.e. origin at top-left corner of window, y grows down
define forward: [n] [gotoX:y: (xpos + (:n * sin heading)) (ypos + (:n * cos heading))]
define turnRight: [n] [heading: heading + :n]
define turnLeft: [n] [heading: heading - :n]
; handy shortcuts for testing
define fd [n] [forward: :n]
define rt [n] [turnRight: :n]
define lt [n] [turnLeft: :n]
to heading: :n
if isStage? [stop]
if :n < 0 [make "n remainder (:n + 360000000) 360]
changed
setheading :n
changed
end
to pointTowards: :thing
let [p mouseOrSpritePosition :thing]
heading: arctan2 ((first :p) - xpos) ((last :p) - ypos)]
end
define screenLeft [] [output 1]
define screenRight [] [output screenLeft + 480]
define screenTop [] [output 26]
define screenBottom [] [output screenTop + 360]
to bounceOffEdge
if (not touching: "edge) [stop]
turnAwayFromEdge
if (%left < screenLeft) [%setleft screenLeft]
if (%top < screenTop) [%settop screenTop]
if (%right > screenRight) [%setleft screenRight - %w]
if (%bottom > screenBottom) [%settop screenBottom - %h]
end
to turnAwayFromEdge
let [
closest 10000
d 10000
e 0]
make "d (max 0 (%left - screenLeft)) if :d < :closest [make "e 1 make "closest :d]
make "d (max 0 (%top - screenTop)) if :d < :closest [make "e 2 make "closest :d]
make "d (max 0 (screenRight - %right)) if :d < :closest [make "e 3 make "closest :d]
make "d (max 0 (screenBottom - %bottom)) if :d < :closest [make "e 4 make "closest :d]
if :closest > 10 [stop]
let [dx sin heading dy cos heading]
if :e = 1 [make "dx (max abs :dx 0.2)]
if :e = 2 [make "dy 0 - (max abs :dy 0.2)]
if :e = 3 [make "dx 0 - (max abs :dx 0.2)]
if :e = 4 [make "dy (max abs :dy 0.2)]
heading: arctan2 :dx :dy
end
to keepOnStage
let [inset 1]
if %right < (screenLeft + :inset) [%setleft (screenLeft + :inset - %w)]
if %bottom < (screenTop + :inset) [%settop (screenTop + :inset - %h)]
if %left > (screenRight - :inset) [%setleft (screenRight - :inset)]
if %top > (screenBottom - :inset) [%settop (screenBottom - :inset)]
updateBubble
end
to gotoX:y: :x :y
if isStage? [stop]
changed
setx :x
sety :y
keepOnStage
changed
end
to gotoSpriteOrMouse: :thing
let [p mouseOrSpritePosition :thing]
gotoX:y: (first :p) (last :p)
end
to glideSecs:toX:y:elapsed:from: :secs :dstX :dstY
if thread-end-msecs = [] [
set-thread-end-msecs %timer + (1000 * :secs)
set-thread-tmp (se xpos ypos :dstX :dstY (1000 * :secs) %timer) ; record start and end position
yield stop]
let [
startX (item 1 thread-tmp)
startY (item 2 thread-tmp)
endX (item 3 thread-tmp)
endY (item 4 thread-tmp)
totalDur (item 5 thread-tmp)
frac (%timer - (item 6 thread-tmp)) / :totalDur]
if %timer < thread-end-msecs [
gotoX:y:
(:startX + (:frac * (:endX - :startX)))
(:startY + (:frac * (:endY - :startY)))
yield stop]
gotoX:y: :endX :endY
set-thread-tmp []
set-thread-end-msecs []
end
define changeXposBy: [n] [xpos: xpos + :n]
define changeYposBy: [n] [ypos: ypos + :n]
define xpos: [n] [if not isStage? [changed setx :n keepOnStage changed]]
define ypos: [n] [if not isStage? [changed sety :n keepOnStage changed]]
define isStage? [] [output who = stage]
to mouseOrSpritePosition :thing
if "mouse = :thing [output (se mouseX mouseY)]
let [me who result []]
talkto :thing
make "result (se xpos ypos)
talkto :me
output :result
end
; ******* Looks *******
; Note: show and hide are Logo commands
to lookLike: :costumeNameOrNum
if string? :costumeNameOrNum [
if (not hasCostumeNamed :costumeNameOrNum) [
ifelse (isNumberFormat :costumeNameOrNum)
[make "costumeNameOrNum round (0 + :costumeNameOrNum)]
[stop]]] ; neither a costume name nor a valid number
if number? :costumeNameOrNum [
let [i ((round :costumeNameOrNum - 1) % count costumes)]
if :i < 0 [make "i :i + count costumes]
make "costumeNameOrNum first (nth :i costumes)]
dotimes [i count costumes][
let [c nth :i costumes]
if (strequ (first :c) :costumeNameOrNum) [
setcindex :i
let [oldxpos xpos oldypos ypos]
changed
setcostume (item 2 :c) (item 3 :c) (item 4 :c)
gotoX:y: :oldxpos :oldypos
changed]]
end
to changeCostumeIndexBy: :n
let [i ((findcostumeIndex costume) + :n) % count costumes]
lookLike: (item 1 (nth :i costumes))
end
define nextBackground [] [nextCostume]
to nextCostume
let [index ((findcostumeIndex costume) + 1) % count costumes]
lookLike: (item 1 (nth :index costumes))
end
define costumeIndex [] [output (findcostumeIndex costume) + 1]
define backgroundIndex [] [output (findcostumeIndex costume) + 1]
to findcostumeIndex :img
if (not empty? cindex) [output cindex]
dotimes [i count costumes][
if :img = (item 2 (nth :i costumes)) [
setcindex :i
output :i]]
end
to hasCostumeNamed :costumeName
dotimes [i count costumes][
let [c nth :i costumes]
if (strequ (first :c) :costumeName) [output true]]
output false
end
to isNumberFormat :s
let [i 1]
if ((count :s) = 0) [output false]
if (:s = "-) [output false]
if (:s = ".) [output false]
if (:s = "-.) [output false]
if ((first :s) = "-) [make "i :i + 1]
skipDigits
if (:i > (count :s)) [output true]
if ((item :i :s) = ".) [make "i :i + 1]
skipDigits
output :i > (count :s)
end
to skipDigits ; uses s and i from isNumberFormat
let [ch 0]
loop [
if (:i > (count :s)) [stop]
make "ch ascii (item :i :s)
if (or (:ch < 48)(:ch > 57)) [stop]
make "i :i + 1]
end
define showBackground: [s] [lookLike: :s]
define showScene: [s] [lookLike: :s]
define changeBackgroundIndexBy: [n] [changeCostumeIndexBy: :n]
define changeSceneIndexBy: [n] [changeCostumeIndexBy: :n]
define say: [s] [talkbubble :s]
define think: [s] [thinkbubble :s]
define sayNothing [] [say: "||]
to say:duration:elapsed:from: :s :secs
timedCommand :secs
[talkbubble :s]
[talkbubble "||]
end
to think:duration:elapsed:from: :s :secs
timedCommand :secs
[thinkbubble :s]
[thinkbubble "||]
end
to changeGraphicEffect:by: :effect :delta
if "color = :effect [setcolor color + :delta]
if "brightness = :effect [setbrightness brightness + :delta]
if "fisheye = :effect [setfisheye fisheye + :delta]
if "whirl = :effect [setwhirl whirl + :delta]
if "mosaic = :effect [setmosaic mosaic + :delta]
if "pixelate = :effect [setpixelate pixelate + :delta]
if "ghost = :effect [setalpha alpha - (:delta / 100)]
changed
end
to setGraphicEffect:to: :effect :val
if "color = :effect [setcolor :val]
if "brightness = :effect [setbrightness :val]
if "fisheye = :effect [setfisheye :val]
if "whirl = :effect [setwhirl :val]
if "mosaic = :effect [setmosaic :val]
if "pixelate = :effect [setpixelate :val]
if "ghost = :effect [setalpha (100 - :val) / 100]
changed
end
to filterReset
setcolor 0
setbrightness 0
setfisheye 0
setwhirl 0
setmosaic 0
setpixelate 0
setalpha 1
changed
end
to changeSizeBy: :n
if isStage? [stop]
changed
setscale %scale + (:n / 100)
changed
end
to setSizeTo: :n
if isStage? [stop]
changed
setscale (:n / 100)
changed
end
define scale [] [output 100 * %scale]
define comeToFront [] [setsprites fput who (removeitem who sprites) changed]
to goBackByLayers: :n
let [
oldlist removeitem who sprites
newlist []
cnt (itempos who sprites) + :n - 1]
repeat (max 0 (min :cnt count :oldlist)) [
make "newlist lput first :oldlist :newlist
make "oldlist butfirst :oldlist]
make "newlist lput who :newlist
setsprites se :newlist :oldlist
changed
end
; ******* Math *******
; Note: arithmetic and logical operations are implemented thread.logo
to randomFrom:to: :start :stop
let [
low (min :start :stop)
hi (max :start :stop)]
ifelse (and (:low = (int :low)) (:hi = (int :hi)))
[output (int (rand * ((:hi + 1) - :low))) + :low]
[output (rand * (:hi - :low)) + :low]
end
define rounded [n] [output round :n]
to computeFunction:of: :op :arg
if (strequ "abs :op) [output abs :arg]
if (strequ "sqrt :op) [output sqrt :arg]
if (strequ "sin :op) [output sin :arg]
if (strequ "cos :op) [output cos :arg]
if (strequ "tan :op) [output tan :arg]
if (strequ "asin :op) [output arcsin :arg]
if (strequ "acos :op) [output arccos :arg]
if (strequ "atan :op) [output arctan :arg]
if (strequ "ln :op) [output ln :arg]
if (strequ "log :op) [output (ln :arg) / (ln 10.0)]
if (strequ "|e ^| :op) [output exp :arg]
if (strequ "|10 ^| :op) [output power 10.0 :arg]
output 0
end
; ******* Sound *******
; Note: beep is a Logo command
to playSound: :soundName
let [snd soundNamed :soundName]
if list? :snd [stop]
ignore startSound :snd
end
to doPlaySoundAndWait :soundName
if thread-tmp = [] [
let [snd soundNamed :soundName]
if list? :snd [stop]
set-thread-tmp startSound :snd
yield stop]
if (isSoundPlaying? thread-tmp) [yield stop]
set-thread-tmp []
end
to soundNamed :soundName
if string? :soundName [
if (not hasSoundNamed :soundName) [
ifelse (isNumberFormat :soundName)
[make "soundName round (0 + :soundName)]
[output []]]] ; neither a sound name nor a valid number
if number? :soundName [
let [i ((:soundName - 1) % count sounds)]
if :i < 0 [make "i :i + count sounds]
make "soundName first (nth :i sounds)]
dolist [s sounds] [if (strequ (item 1 :s) :soundName) [output (item 2 :s)]]
output []
end
to hasSoundNamed :soundName
dotimes [i count sounds][
let [s nth :i sounds]
if (strequ (first :s) :soundName) [output true]]
output false
end
to drum:duration:elapsed:from: :drum :secs
timedCommand (:secs * 60) / tempo
[ set-thread-tmp round :drum
midinoteon 10 thread-tmp midiVolume]
[ midinoteoff 10 thread-tmp]
end
to noteOn:duration:elapsed:from: :key :secs
timedCommand (:secs * 60) / tempo
[ if midichan = [] [assign-midi-channel]
set-thread-tmp round :key
midinoteon midichan thread-tmp midiVolume]
[ midinoteoff midichan thread-tmp]
end
to rest:elapsed:from: :secs
timedCommand (:secs * 60) / tempo
[]
[]
end
to midiInstrument: :n
if midichan = [] [assign-midi-channel]
midisetinstrument midichan :n
end
to assign-midi-channel
let [
in-use makelist 16
ch 0
besti 0
bestcnt 1000]
setmidichan []
dotimes [i 16] [setnth :i :in-use 0]
setnth 9 :in-use 1000
dolist [spr (fput stage sprites)] [
make "ch (get :spr "midichan)
if number? :ch [setitem :ch :in-use (item :ch :in-use) + 1]]
dotimes [i 16] [
if (nth :i :in-use) < :bestcnt [
make "besti :i
make "bestcnt nth :i :in-use]]
setmidichan :besti + 1
end
define changeTempoBy: [n] [setTempoTo: tempo + :n]
define setTempoTo: [n] [make "<tempo> (max 20 (min 500 :n))]
define tempo [] [output :<tempo>]
define changeVolumeBy: [n] [setVolumeTo: volume + :n]
define setVolumeTo: [n] [setvolume (max 0 (min 100 :n))]
define midiVolume [] [output (max 0 (min 127 ((127 * volume) / 100)))]
; ******* Pen *******
; Note: setPenDown, setPenColor, setPenHue, setPenShade,setPenSize, penSize, clearPenTrails, and stampCostume are Logo commands
define putPenDown [] [setPenDown true]
define putPenUp [] [setPenDown false]
define penColor: [c] [setPenColor :c]
define changePenHueBy: [n] [setPenHue penHue + :n]
define changePenShadeBy: [n] [setPenShade penShade + :n]
define changePenSizeBy: [n] [penSize: penSize + :n]
define setPenHueTo: [n] [setPenHue :n]
define setPenShadeTo: [n] [setPenShade :n]
define penSize: [n] [setPenSize (max 1 (min 500 :n))]
; ******* Sensing *******
; mouseX, mouseY, mousePressed, and soundLevel are Logo reporters
define mousePressed [] [output mouseIsDown]
to handle-keystrokes
let [k keystroke]
if empty? :k [stop]
dolist [o fput stage sprites] [
talkto :o
dolist [scr scripts] [
if (first first :scr) = "KeyEventHatMorph [
if :k = (asciiForKeyname (item 2 first :scr)) [ignore start-script :o :scr true]
]]]
end
to keyPressed: :keyName
let [k asciiForKeyname :keyName]
if (and (:k > 64)(:k < 91)) [make "k (:k + 32)] ; convert letters to lower case
output keydown? :k
end
to asciiForKeyname :keyName
if (count :keyName) = 1 [output ascii :keyName]
if :keyName = "enter [output 10]
if :keyName = "|left arrow| [output 28]
if :keyName = "|right arrow| [output 29]
if :keyName = "|up arrow| [output 30]
if :keyName = "|down arrow| [output 31]
if :keyName = "space [output 32]
output -1
end
to handle-mouseclicks
let [p mouseClick]
if empty? :p [stop]
dolist [o lput stage sprites] [
talkto :o
if (isShowing :o) [
if (containsPoint? (item 1 :p)(item 2 :p)) [
dolist [scr scripts] [
if (first first :scr) = "MouseClickEventHatMorph [ignore start-script :o :scr false]]
stop
]]]
end
to touching: :thing
if "mouse = :thing [output containsPoint? mouseX mouseY]
if "edge = :thing [
if %left < screenLeft [output true]
if %top < screenTop [output true]
if %right > screenRight [output true]
if %bottom > screenBottom [output true]
output false]
if sprite? :thing [
if (and (isShowing who) (isShowing :thing)) [
if (touchingSprite? :thing) [output true]]]
output false
end
define touchingColor: [c] [output touchingColor? :c]
define color:sees: [c1 c2] [output colorTouchingColor? :c1 :c2]
to distanceTo: :thing
let [
p mouseOrSpritePosition :thing
dx xpos - (first :p)
dy ypos - (last :p)]
output sqrt (:dx * :dx) + (:dy * :dy)
end
define timerReset [] [make "<basetime> %timer]
define timer [] [output (%timer - :<basetime>) / 1000]
define isLoud [] [output soundLevel > 35]
define sensorPressed: [s] [output (sensor: :s) < 10]
to sensor: :s
if (number? :s) [output getSensorValue :s]
if (:s = "slider) [output getSensorValue 1]
if (:s = "light) [output getSensorValue 2]
if (:s = "sound) [output getSensorValue 3]
if (:s = "|button pressed|) [output getSensorValue 4]
if (or (strequ "A first :s) (strequ "A last :s)) [output getSensorValue 5]
if (or (strequ "B first :s) (strequ "B last :s)) [output getSensorValue 6]
if (or (strequ "C first :s) (strequ "C last :s)) [output getSensorValue 7]
if (or (strequ "D first :s) (strequ "D last :s)) [output getSensorValue 8]
output 0
end
to getAttribute:of: :attr :obj
if not (or (stage = :obj)(sprite? :obj)) [output 0]
let [
me who
result []
vdict []]
talkto :obj
if (stage = :obj) [
if (strequ :attr "|background #|) [make "result backgroundIndex]
if (strequ :attr "volume) [make "result volume]
]
if (sprite? :obj) [
if (strequ :attr "|x position|) [make "result xpos]
if (strequ :attr "|y position|) [make "result ypos]
if (strequ :attr "direction) [make "result heading]
if (strequ :attr "|costume #|) [make "result costumeIndex]
if (strequ :attr "size) [make "result scale]
if (strequ :attr "volume) [make "result volume]
]
talkto :me
if (not empty? :result) [output :result]
; look up :attr as a variable
make "vdict (get :obj "vars)
if not list? (get :vdict :attr) [output (get :vdict :attr)] ; local var
make "vdict (get stage "vars)]
if not list? (get :vdict :attr) [output (get :vdict :attr)] ; global var
output :result
end
; ******* Variables *******
define getVar: [n] [output readVariable :n]
define getUserVar: [n] [output readVariable :n]
to readVariable :vname
let [vdict vardictfor :vname]
output get :vdict :vname
end
to changeVariable :vname :op :val
let [vdict vardictfor :vname]
ifelse (or (:op = "set:to:)(:op = "setVar:to:))
[put :vdict :vname :val]
[put :vdict :vname (coerceToNumber (get :vdict :vname) + (coerceToNumber :val))]
end
; answer the vars object (for the current sprite or the stage) that defines the given variable
; if the variable is not found in either the spite's or stage's variables, define
; it as a stage variable (i.e. as a global)
to vardictfor :vname
let [vdict (get who "vars)]
if not list? (get :vdict :vname) [output :vdict]
make "vdict (get stage "vars)
if list? (get :vdict :vname) [put :vdict :vname 0] ; auto-define the variable as a global
output :vdict
end
to showVariable: :varName
let [wlist watchersFor: :varName]
if ((count :wlist) = 0) [make "wlist (list createWatcherFor :varName)]
dolist [w :wlist][showWatcher :w]
redrawall
end
to hideVariable: :varName
dolist [w watchersFor: :varName][hideWatcher :w]
redrawall
end
to watchersFor: :varName
let [result []]
dolist [w sprites] [
if (watcher? :w) [
if ((get :w "op) = "getVar:) [
if ((get :w "param) = :varName) [
make "result (lput :w :result)]]]]
output :result
end
to createWatcherFor :varName
if (string? :varName) [make "varName intern :varName]
let [w newVarWatcher :varName title string :varName]
if (localVar? :varName) [make "title (word (word name "| |) :title)]
setWatcherXY :w 10 findYForNewWatcher
setWatcherColorAndLabel :w (newcolor 243 118 29) :title
put :w "target who
put :w "op "getVar:
put :w "param :varName
setsprites (fput :w sprites)
output :w
end
to localVar? :varName
let [vdict (get who "vars)]
output not list? (get :vdict :varName) ; found varName in sprite's local variable dictionary
end
to findYForNewWatcher
let [newY 35]
dolist [w sprites] [
if (watcher? :w) [
if ((watcherY :w) + 25) > :newY [make "newY ((watcherY :w) + 25)]]]
if (:newY > 360) [make "newY 360]
output :newY
end
; ******* Lists *******
to contentsOfList: :listName
let [lists listvarsFor :listName]
output listContents (get (listvarsFor :listName) :listName)
end
to append:toList: :val :listName
let [
lists listvarsFor :listName
newList []]
make "newList (lput (asListElement: :val) (get :lists :listName))
put :lists :listName :newList
updateWatcher :listName :newList (count :newList)
end
to deleteLine:ofList: :index :listName
let [lists listvarsFor :listName
i 0
newList []]
if (:index = "all) [
put :lists :listName :newList
updateWatcher :listName :newList "none
stop]
if not (:i = (count (get :lists :listName))) [
make "i compute-index :index :listName]
if (:i = 0) [
updateWatcher :listName (get :lists :listName) :i
stop]
make "newList (removeitempos :i (get :lists :listName))
put :lists :listName :newList
if (:i < ((count :newList) + 1)) [updateWatcher :listName :newList :i]
if (:i > (count :newList)) [updateWatcher :listName :newList (:i - 1)]
end
to insert:at:ofList: :val :index :listName
let [lists listvarsFor :listName
len count (get :lists :listName)
i compute-index :index :listName
newList []]
if (:index = "last) [make "i :len + 1]
if (:index = "any) [make "i int(rand * (:len + 1)) + 1]
if (:i = 0) [make "i 1]
make "newList (insert (get :lists :listName) :i (asListElement: :val))
put :lists :listName :newList
updateWatcher :listName :newList :i
end
to setLine:ofList:to: :index :listName :val
let [lists listvarsFor :listName
i compute-index :index :listName]
if (:i = 0) [stop]
setitem :i (get :lists :listName) (asListElement: :val)
updateWatcher :listName (get :lists :listName) :i
end
to getLine:ofList: :index :listName
let [lists listvarsFor :listName
i compute-index :index :listName
w (get (get (listowner :listName) "listwatchers) :listName)]
if not (:w = []) [highlightListWatcherIndex :w :i]
if (:i = 0) [output "||]
output item :i (get :lists :listName)
end
to lineCountOfList: :listName
let [lists listvarsFor :listName]
output count (get :lists :listName)
end
; following gets the listvars object for either the current sprite or the stage
to listvarsFor :listName
if (hasKey listvars :listName) [output listvars]
output get stage "listvars]
end
to updateWatcher :listName :newList :i
let [w (get (get (listowner :listName) "listwatchers) :listName)]
if (:w = []) [stop]
setListWatcherList :w :newList
if not (:i = "none) [highlightListWatcherIndex :w :i]
end
to listowner :listName
if (hasKey listvars :listName) [output who]
output stage
end
to compute-index :index :listName
let [len count (get (listvarsFor :listName) :listName) i 0]
if (:index = "last) [output :len]
if (:index = "any) [output int(rand * :len) + 1]
make "i round :index
if (or (:i < 1)(:i > (:len + 1))) [output 0]
output :i
end
to list:contains: :listName :val
output member? :val (get (listvarsFor :listName) :listName)
end
to asListElement: :val
if (false = :val) [output "0]
if (true = :val) [output "1]
if (number? :val) [
if ((int :val) = :val) [output string :val]] ; use integer string
output :val
end
; ******* Strings *******
to concatenate:with: :s1 :s2
output word :s1 :s2
end
to letter:of: :i :s
if (not string? :s) [make "s string :s]
if (strequ :i "first) [make "i 1]
if (strequ :i "last) [make "i (count :s)]
if (strequ :i "any) [make "i int(rand * (count :s)) + 1]
if (string? :i) [make "i coerceToNumber :i]
if (not number? :i) [make "i 0]
make "i round :i
if (or (:i < 1)(:i > (count :s))) [output "||]
output item :i :s
end
to stringLength: :s
if (not string? :s) [make "s string :s]
output count :s
end
define answer [] [output lastAnswer]
; ******* Motor *******
define motorOnFor:elapsed:from: [secs] [timedCommand :secs [] []]
define allMotorsOn [] []
define allMotorsOff [] []
define startMotorPower: [power] []
define setMotorDirection: [direction] []Sprite.logo
; This file defines the structure of a sprite and how to read in a Scratch project.
; The entry points are sprite, open, and openurl.
to sprite-startup
; builtin sprite fields: xpos ypos costume
let [fields [name costumes sounds scripts vars listvars listwatchers midichan volume cindex]]
dolist [i (se :fields)] [
define :i [] (se [output get who] quote :i)
define (word "set :i) [val] (se [put who] quote :i [:val])]
make "<tempo> 60
end
; lookup a sprite by name
to sprite :name
if :name = get stage "name [output stage]
dolist [spr sprites] [if :name = get :spr "name [output :spr]]
error (se [no sprite named] :name)
end
to open :projname
install-objtable readprojfile (word :projname ".sb)
end
to openold :projname
install-objtable readprojfile (word :projname ".scratch)
end
to openurl
install-objtable readprojurl
end
to install-objtable :objtable
clearall
make "<tempo> 60
setsprites []
dolist [entry :objtable] [
if (or ((item 2 :entry) = 124) ((item 2 :entry) = 125)) [add-extracted-object :entry]
if ((item 2 :entry) = 155) [init-watcher :entry]
]
dolist [entry :objtable] [
if ((item 2 :entry) = 175) [init-list-watcher :entry]
]
redrawall
timerReset
end
; add a sprite/stage extracted from the given table entry
to add-extracted-object :o
let [
spr item 1 :o
id item 2 :o
version item 3 :o
pos item 4 :o
cost extract-costume (item 15 :o)
flags item 8 :o
sname item 10 :o
sscale item 1 item 17 :o
degrees item 18 :o
rstyle item 19 :o]
talkto :spr
setname :sname
setcostumes extract-costume-list :o
setsounds extract-sounds :o
setscripts extract-scripts :o
setvars extract-variables :o
setcostume (item 2 :cost) (item 3 :cost) (item 4 :cost)
setvolume 100
setDraggable false
setcindex []
setlistvars []
setlistwatchers makelist 0
if :id = 124 [ ; this object is a sprite
setscale :sscale
if (logand :flags 1) = 1 [hide]
setheading :degrees + 90
setrotationstyle stylenum :rstyle
setx (item 1 :pos) + (item 3 :cost) - 240
sety 180 - ((item 2 :pos) + (item 4 :cost))
if (:version > 1) [
setvolume (item 20 :o)
setDraggable (item 22 :o)]
if (:version > 2) [setlistvars extract-listvars (item 24 :o)]
]
if :id = 125 [ ; this object is the stage
setstage :spr
setsprites []
dolist [obj (item 6 :o)][
if sprite? :obj [setsprites (lput :obj sprites)]
if watcher? :obj [setsprites (lput :obj sprites)]]
if (:version > 3) [
setvolume (item 21 :o)
make "<tempo> (item 22 :o)]
if (:version > 4) [setlistvars extract-listvars (item 24 :o)]
]
end
; extract a list of costumes from a sprite/stage object table entry
to extract-costume-list :x
let [
medialist item 14 :x
result []]
dolist [m :medialist] [
if (item 2 :m) = 162 [make "result lput (extract-costume :m) :result]]
output :result
end
; extract a costume record from the given ImageMedia object table entry
; output a 4-typle: (<name><image><rotCenter x><rotCenter y>)
to extract-costume :m
let [
name item 4 :m
img item 5 :m
rotCenter item 6 :m]
if (item 3 :m) > 2 [ ; ImageMedia version 4 or later, use compositeForm if not nil
if (not list? (item 8 :m)) [ ; image was jpeg compressed; expand and save
make "img jpegDecode (item 8 :m)
setitem 5 :m :img
setitem 8 :m []]]
if (item 3 :m) > 3 [ ; ImageMedia version 4 or later, use compositeForm if not nil
if (not list? (item 9 :m)) [make "img (item 9 :m)]]
output (se :name :img (item 1 :rotCenter)(item 2 :rotCenter))
end
; extract a list of sounds from a sprite/stage object table entry
; each sound is a pair (<name><sound>)
to extract-sounds :o
let [
medialist item 14 :o
result []]
dolist [m :medialist] [
if (item 2 :m) = 164 [
let [
name item 4 :m
snd item 5 :m]
make "result lput (se :name :snd) :result]]
output :result
end
; extract a list of scripts from a sprite/stage object table entry
to extract-scripts :o
let [
slist item 12 :o
result []]
dolist [s :slist] [make "result lput (item 2 :s) :result]
output :result
end
to stylenum :styleName
if (:styleName = "normal) [output 0]
if (:styleName = "leftRight) [output 1]
if (:styleName = "none) [output 2]
output 0
end
; extract the variables for the given sprite/stage object table entry
; return an empty list whose property list contains the variable bindings.
to extract-variables :o
let [
varlist item 11 :o
i 1
result makelist 0]
repeat ((count :varlist) / 2) [
put :result (intern item :i :varlist) (item :i + 1 :varlist)
make "i :i + 2
]
output :result
end
; extract the list variables for the given array of (name, list) pairs
; return an empty list whose property list contains the list variable bindings.
to extract-listvars :pairs
let [
i 1
vname []
val []
result makelist 0]
repeat ((count :pairs) / 2) [
make "vname (intern item :i :pairs)
make "val (item 13 (item :i + 1 :pairs))
put :result :vname :val
make "i :i + 2
]
output :result
end
; initialize the Watcher for the given object table entry
to init-watcher :o
let [
w item 1 :o
version item 3 :o
box item 4 :o
title item 17 :o
readout item 18 :o
readoutFrame item 19 :o
readoutBox item 4 :readoutFrame
slider item 20 :o
target item 14 :readout
op item 15 :readout
param item 17 :readout]
if (string? :param) [make "param intern :param]
setWatcherXY :w ((item 1 :box) + 1) ((item 2 :box) + 26)
setWatcherColorAndLabel :w (item 7 :readoutFrame) (item 12 :title)
if (:version > 3) [setWatcherSliderMinMax :w (item 24 :o) (item 25 :o)]
ifelse ((count :slider) > 0)
[setWatcherMode :w 2]
[if ((item 4 :readoutBox) - (item 2 :readoutBox)) > 14 [setWatcherMode :w 3]]
put :w "target :target
put :w "op :op
put :w "param :param
end
; initialize the ListWatcher for the given object table entry
to init-list-watcher :o
if not (sprite? (item 5 :o)) [stop] ; do nothing if owner is nil (i.e. watcher is not showing)
let [
w newListWatcher
version item 3 :o
box item 4 :o
listName item 12 :o
listContents item 13 :o
listTarget item 14 :o]
put (get :listTarget "listwatchers) intern :listName :w
setListWatcherXY :w ((item 1 :box) + 1) ((item 2 :box) + 26)
setListWatcherWidthHeight :w ((item 3 :box) - (item 1 :box)) ((item 4 :box) - (item 2 :box))
if not (:listTarget = stage) [make "listName (word (get :listTarget "name) "| | :listName)]
setListWatcherLabel :w :listName
setListWatcherList :w :listContents
endStartup.logo
to startup
load "sprite
load "thread
load "commands
sprite-startup
thread-startup
make "cycle 0
ifelse applet?
[openurl]
[open "midiTest]
if autostart? [greenflag]
end
to greenflag
stopAll
dolist [o fput stage sprites] [
talkto :o
dolist [scr scripts] [
if (first :scr) = [EventHatMorph Scratch-StartClicked] [ignore start-script :o :scr false]
]
]
interact
end
to interact
redrawall
requestFocus
loop [runstep]
end
to runstep
let [t %timer]
handle-keystrokes
handle-mouseclicks
step-all-threads
updatePenTrails
updateWatchers
updateListWatchers
redraw
make "t %timer - :t
if :t < 30 [mwait 30 - :t] ; limit speed to 33 frames/sec
end
to updateWatchers
dolist [w sprites] [
if (watcher? :w) [
let [
op (get :w "op)
param (get :w "param)
val 0]
talkto (get :w "target)
ifelse empty? :param
[make "val run (list :op)]
[make "val run (list :op (quote :param))]
setWatcherText :w :val]]
end
to updateListWatchers
make "cycle ((:cycle + 1) % 5)
if (:cycle = 0) [
dolist [w sprites] [
if (listWatcher? :w) [clearListWatcherHighlights :w]]]
end
; for debugging; run a script to completion on the current sprite
to do :cmds
stopAll
ignore start-thread who :cmds
loop [
if (count :<threads>) = 0 [stop]
runstep]
endThread.logo
; A thread is a list:
;
; 1 running? becomes false when thread stops
; 2 owner script owner (a sprite or the stage)
; 3 oldstate state saved when a block runs a sublist of commands
; 4 cmds current command list
; 5 ip index of the current command in cmds
; 6 end-msecs used by timed commmads such as glide
; 7 tmp used by timed commmads and repeat
;
; <threads> is a global list of running threads
; <current-thread> is the thread currently being run by step-thread
; <yield?> is set to true when the current thread wishes to yield
; <stopall> is set to true when the stopall command is invoked
to thread-startup
stop-all-threads
let [ fields [running? owner oldstate cmds ip end-msecs tmp]
field "]
dotimes [i count :fields] [
make "field nth :i :fields
define word "thread- :field [] (se [output nth] :i [:<current-thread>])
define word "set-thread- :field [v] (se [setnth] :i [:<current-thread> :v])
]
end
to stop-all-threads
if (name? "<threads>) [
dolist [thrd :<threads>][abort-thread :thrd]]
make "<threads> []
make "<stopall> true
end
to abort-thread :<current-thread>
stop-thread
if thread-ip > count thread-cmds [stop]
let [
cmd item thread-ip thread-cmds
chan get thread-owner "midichan]
if list? thread-tmp [stop]
if list? :chan [stop]
if ((first :cmd) = "noteOn:duration:elapsed:from:) [midinoteoff :chan thread-tmp]
if ((first :cmd) = "drum:duration:elapsed:from:) [midinoteoff 10 thread-tmp]
if ((first :cmd) = "doPlaySoundAndWait) [stopSound thread-tmp]
end
to stop-thread
set-thread-running? false
let [topCmds item 4 (thread-top :<current-thread>)]
if not empty? :topCmds [put (first :topCmds) "thread []]
end
; return the thread for the top-level command list for this thread
to thread-top :thrd
loop [
if empty? (item 3 :thrd) [output :thrd]
make "thrd (item 3 :thrd)]
end
; start a thread for a hat block and return the thread object
to start-script :sprite :hat :isKeyEvent
let [cmdList butfirst :hat]
if empty? :cmdList [output [false]]
let [oldThrd get (first :cmdList) "thread]
if not empty? :oldThrd [
if (first :oldThrd) [ ; the thread for this hat is running
ifelse :isKeyEvent
[output [false]]
[abort-thread :oldThrd]]]
let [newThrd start-thread :sprite :cmdList]
put (first :cmdList) "thread :newThrd
output :newThrd
end
; start a thread and return the thread object
to start-thread :sprite :cmds
let [thrd (list true :sprite [] :cmds 1 [] [])]
make "<threads> lput :thrd :<threads>
output :thrd
end
; step each thread in <threads> and remove any threads that are no longer running
to step-all-threads
let [oldThreads :<threads>]
make "<threads> []
make "<stopall> false
dolist [thrd :oldThreads] [
carefully [step-thread :thrd][print "error abort-thread :thrd]
;;;xxx step-thread :thrd
if :<stopall> [
dolist [t :oldThreads][abort-thread :t]
stop]]
dolist [thrd :oldThreads] [if first :thrd [make "<threads> lput :thrd :<threads>]]
end
; step a thread until it yields
to step-thread :<current-thread>
if not thread-running? [stop]
talkto thread-owner
let [<yield?> false]
loop [
if thread-ip > count thread-cmds [end-list]
if :<yield?> [stop]
run eval-all-args (item thread-ip thread-cmds)
updatePenTrails
if :<yield?> [stop]
set-thread-ip thread-ip + 1]
end
; run the given list of commands (used by control structure commands)
to run-list :cmdList
set-thread-oldstate copylist :<current-thread>
set-thread-cmds :cmdList
set-thread-ip 0
set-thread-end-msecs []
set-thread-tmp []
end
to end-list
ifelse empty? thread-oldstate
[stop-thread yield]
[ let [oldstate thread-oldstate]
set-thread-oldstate (item 3 :oldstate)
set-thread-cmds (item 4 :oldstate)
set-thread-ip (item 5 :oldstate)
set-thread-end-msecs (item 6 :oldstate)
set-thread-tmp (item 7 :oldstate)
if thread-ip > count thread-cmds [end-list stop]
let [cmd first (item thread-ip thread-cmds)]
if (or (:cmd = "doForever)(:cmd = "doForeverIf)(:cmd = "doRepeat)(:cmd = "doUntil)) [yield]
]
end
; if the argument is a list, evaluate it. otherwise, return it
to eval-arg :arg
if number? :arg [output :arg]
if quoted? :arg [output :arg]
if string? :arg [output quote :arg]
if color? :arg [output :arg]
if sprite? :arg [output :arg]
if list? :arg [
if ((count :arg) = 1) [
if (list? first :arg) [make "arg first :arg]]
output eval-expression eval-all-args :arg]
if :arg = true [output :arg]
if :arg = false [output :arg]
output quote :arg
end
; evaluate an expression whose arguments have already been evaluted
to eval-expression :expr
if (count :expr) = 0 [output :expr]
let [op item 1 :expr]
if (count :expr) = 3 [
if (count first :expr) < 3 [
let [
op item 1 :expr
arg1 eval-arg item 2 :expr
arg2 eval-arg item 3 :expr]
if (member? :op [< = >]) [output eval-comparision :expr]
make "arg1 coerceToNumber :arg1
make "arg2 coerceToNumber :arg2
if "+ = :op [output :arg1 + :arg2]
if "- = :op [output :arg1 - :arg2]
if "* = :op [output :arg1 * :arg2]
if "/ = :op [output :arg1 / :arg2]
if "\\ = :op [
let [n :arg1 % :arg2]
if :n < 0 [make "n :n + abs :arg2]
output :n]
if "& = :op [output (and :arg1 :arg2)]
if (char 124) = :op [output (or :arg1 :arg2)]]] ; 124 is | (vertical bar)
let [v run :expr]
if (string? :v) [make "v quote :v]
output :v
end
to eval-comparision :expr
let [
op item 1 :expr
arg1 eval-arg item 2 :expr
arg2 eval-arg item 3 :expr]
if quoted? :arg1 [make "arg1 unquote :arg1]
if quoted? :arg2 [make "arg2 unquote :arg2]
if isNumberFormat :arg1 [make "arg1 coerceToNumber :arg1]
if isNumberFormat :arg2 [make "arg2 coerceToNumber :arg2]
if (and (string? :arg1)(string? :arg2)) [
if "< = :op [output (strcmp :arg1 :arg2) < 0]
if "= = :op [output (strcmp :arg1 :arg2) = 0]
if "> = :op [output (strcmp :arg1 :arg2) > 0]]
if (and (string? :arg1)(number? :arg2)) [
ifelse isNumberFormat :arg1
[make "arg1 coerceToNumber :arg1]
[output false]]
if (and (number? :arg1)(string? :arg2)) [
ifelse isNumberFormat :arg2
[make "arg2 coerceToNumber :arg2]
[output false]]
if "< = :op [output :arg1 < :arg2]
if "= = :op [output :arg1 = :arg2]
if "> = :op [output :arg1 > :arg2]
end
to coerceToNumber :o
if number? :o [output :o]
if quoted? :o [make "o unquote :o]
if string? :o [
if (count :o) = 0 [output 0]
ifelse isNumberFormat :o
[output 0 + :o]
[output 0]]
output :o
end
; return a copy of the given command with all of its arguments evaluated
; however, do not evalute the arguments if the command is a control structure
to eval-all-args :cmd
let [new-cmd copylist :cmd]
if is-control? :cmd [output :new-cmd]
dotimes [i (count :cmd) - 1] [
setitem :i + 2 :new-cmd (eval-arg item :i + 2 :cmd)]
if (count :new-cmd) > 0 [coerce-number-args :new-cmd]
output :new-cmd
end
; coerce selected arguments of the given command to numbers if necessary
to coerce-number-args :cmd
let [op first :cmd]
; coerce all arguments of these commands to numbers
if member? :op [
forward: turnRight: turnLeft: gotoX:y: glideSecs:toX:y:elapsed:from: changeXposBy: xpos: changeYposBy: ypos:
setSizeTo: goBackByLayers:
drum:duration:elapsed:from: rest:elapsed:from: noteOn:duration:elapsed:from:
midiInstrument: changeVolumeBy: setVolumeTo: changeTempoBy: setTempoTo:
changePenHueBy: setPenHueTo: changePenShadeBy: setPenShadeTo: changePenSizeBy: penSize: changeSizeBy:
wait:elapsed:from: randomFrom:to: rounded] [
dotimes [i count :cmd] [
if :i > 0 [setnth :i :cmd (coerceToNumber nth :i :cmd)]]]
; coerce the last argument of these commands to a number
if member? :op [
computeFunction:of:
say:duration:elapsed:from: think:duration:elapsed:from:
changeGraphicEffect:by: setGraphicEffect:to:] [
let [i count :cmd]
setitem :i :cmd (coerceToNumber item :i :cmd)]
end
define yield [] [make "<yield?> true]
; ******* control structures *******
; return true if the given command is a control structure
; (i.e. it decided when and how to evalutate it's arguments)
to is-control? :cmd
if (count :cmd) = 0 [output false]
output member? first :cmd [doForever doForeverIf doIf doIfElse doRepeat doUntil doWaitUntil]
end
to is-true? :expr
if :expr = "false [output false]
output eval-arg :expr
end
to doForever :cmdList
run-list :cmdList
end
to doForeverIf :expr :cmdList
ifelse is-true? :expr
[run-list :cmdList]
[yield]
end
to doIf :expr :cmdList
if is-true? :expr [
set-thread-ip thread-ip + 1
run-list :cmdList]
end
to doIfElse :expr :trueCmdList :falseCmdList
set-thread-ip thread-ip + 1
ifelse is-true? :expr
[run-list :trueCmdList]
[run-list :falseCmdList]
end
to doRepeat :count :cmdList
if empty? thread-tmp [set-thread-tmp coerceToNumber eval-arg :count]
if thread-tmp < 1 [set-thread-tmp [] stop] ; repeat finished
set-thread-tmp thread-tmp - 1
run-list :cmdList
end
to doUntil :expr :cmdList
if not is-true? :expr [run-list :cmdList]
end
define doWaitUntil [expr] [if not is-true? :expr [yield]]
define doReturn [] [stop-thread yield]
to doAsk :question
if list? thread-tmp [
if askPromptShowing? [yield stop]
ifelse (and (sprite? thread-owner) (not thread-owner = stage) (isVisible thread-owner))
[talkto thread-owner
askbubble :question
showAskPrompt "||]
[showAskPrompt :question]
set-thread-tmp "askInProgress
]
if askPromptShowing? [yield stop]
askbubble "||
set-thread-tmp []
endAren't you glad we have scrollbars in code boxes?
Development:
At some point: Decide a name for the mod. DONE (LogoBlox)
1. Make new categories for blocks DONE
2. Make list of blocks to be added. This should include a block which allows the user to type in Logo code. 1/2 DONE
3. Add these blocks. DONE
4. Make these blocks work. Most of the Logo commands do not have the colons needed to define inputs in Squeak. This will require the blocks to which this applies to be special form blocks, which makes them evaluated in ScratchProcess without needing direct inputs. DONE (Found another workaround)
5. Swat all remaining bugs DONE (I hope!)
Last edited by rubiks_cube_guy238 (2011-05-13 14:46:47)
Offline
veggieman001 wrote:
what's it called?
rubiks_cube_guy238 wrote:
Development:
At some point: Decide a name for the mod.
Last edited by scimonster (2011-05-11 10:35:18)
Offline
Beta is out!
You will find 2 new categories: Applet and Logo. Currently, only Applet has blocks in it. I have everything (I think) working, but let me know if you find any bugs!
At the moment, I am calling this 'LogoBlox', but I'm open to other name suggestions!
Download
Last edited by rubiks_cube_guy238 (2011-05-11 18:13:10)
Offline
Oops! I just noticed that the open project block doesn't work offline. Could anyone solve this problem for me? (You want to change the code in ScriptableScratchMorph other openProject: )
Offline
The keep on stage block is not needed, the selector is always ran whenever the sprite moves. Oh, it is for the applet online, I see, great!
Offline
Whoa! I need to test this! After they fix th upload glitch... or maybe it will work.
Offline
They haven't fixed it, I had only one block one costume with one pixel and it said that it might have been because of being higher than 10GB.
Offline
Oh yah the open project block doesn't work because the blockspec isn't right here is what it should be:
('open project from %s' #- #openProject: 'http://www.scratch.mit.edu/static/users/userName/projectID.sb?version=1')
Last edited by Pecola1 (2011-05-11 19:38:11)
Offline
The open project won't read anything, I entered:
http://www.scratch.mit.edu/static/users/appleman45/1744824.sb?version=1
into the insert.
Offline
I added LogoBlox to the wiki.
Offline
Pecola1 wrote:
Oh yah the open project block doesn't work because the blockspec isn't right here is what it should be:
('open project from %s' #- #openProject: 'http://www.scratch.mit.edu/static/users/userName/projectID.sb?version=1')
Then it won't work correctly online. I have a special way to handle blocks with selectors with no inputs.
Offline
rubiks_cube_guy238 wrote:
Pecola1 wrote:
Oh yah the open project block doesn't work because the blockspec isn't right here is what it should be:
('open project from %s' #- #openProject: 'http://www.scratch.mit.edu/static/users/userName/projectID.sb?version=1')
Then it won't work correctly online. I have a special way to handle blocks with selectors with no inputs.
Oh, you want to get it complicated,
, but I guess if the insert doesn't work then you'll have to.
but you need to make the method, depending on how you are making it read the insert, and stuff. Unless you make it so it replaces the selector.
Offline
Pecola1 wrote:
rubiks_cube_guy238 wrote:
Pecola1 wrote:
Oh yah the open project block doesn't work because the blockspec isn't right here is what it should be:
Then it won't work correctly online. I have a special way to handle blocks with selectors with no inputs.
Oh, you want to get it complicated,
, but I guess if the insert doesn't work then you'll have to.
but you need to make the method, depending on how you are making it read the insert, and stuff. Unless you make it so it replaces the selector.
The point is, it won't work correctly online if it doesn't use the special workaround.
Oh, yeah, and I've deleted the block. It would have been really cool if it worked online, but it didn't.
Last edited by rubiks_cube_guy238 (2011-05-12 20:34:01)
Offline
Another beta!
This update has blocks in the Logo category, and unwanted watcher toggles are removed.
Right now, the blocks might only work online (The evaluation of blocks offline is problematic), but that's why it's still beta.
Download
Offline
I don't get one of the blocks, yield, what does it do? Also the to the power block doesn't seem to have the right code offline, 2 ^ 10 = 1024? Memory space left is cool, but what measurement is that? Also, are you taking off the open project block? I also tested the clipboard block, it doesn't work, but in The New Flash Player it shows undefined and the watcher says unknown: clipboard.
Last edited by Pecola1 (2011-05-13 12:12:46)
Offline
Pecola1 wrote:
I don't get one of the blocks, yield, what does it do?
I actually don't entirely know myself, but it makes a pause.
Also the to the power block doesn't seem to have the right code offline, 2 ^ 10 = 1024?
Check your own math.
Memory space left is cool, but what measurement is that?
Bytes.
Also, are you taking off the open project block?
Yes. It didn't work online. If you really want it, I moved it to obsoleteBlockSpecs, so it's still recognized by the program.
I also tested the clipboard block, it doesn't work, but in The New Flash Player it shows undefined and the watcher says unknown: clipboard.
That's because its a watcher. It works otherwise.
Last edited by rubiks_cube_guy238 (2011-05-13 14:44:02)
Offline
I don't suppose this works for the Flash viewer, correct?
I guess we'll have to wait until they release the source code for it before making another mod recognized by the flash player
Offline
Another update!
I was going to add a block that would do some javascript, but it didn't work online, so I moved it to obsoleteBlockSpecs. There is also a block that makes the default beeping noise. Oh, and all the blocks finally work
Download
Offline
rubiks_cube_guy238 wrote:
Pecola1 wrote:
I don't get one of the blocks, yield, what does it do?
I actually don't entirely know myself, but it makes a pause.
Also the to the power block doesn't seem to have the right code offline, 2 ^ 10 = 1024?
Check your own math.
Memory space left is cool, but what measurement is that?
Bytes.
Also, are you taking off the open project block?
Yes. It didn't work online. If you really want it, I moved it to obsoleteBlockSpecs, so it's still recognized by the program.
I also tested the clipboard block, it doesn't work, but in The New Flash Player it shows undefined and the watcher says unknown: clipboard.
That's because its a watcher. It works otherwise.
LOL I know about the to the power, I was doing 10 ^ 2! LOL, my mistake. I figured out about bytes but thanks anyways. Thanks for telling me the open project block is obsolete, did you get it to work offline? For the clipboard block, it wont work if there is a watcher on it, correct? In that case I can take the watcher off. Thanks.
Offline
The clipboard still doesn't seem to work, I updated it.
Offline
Pecola1 wrote:
The clipboard still doesn't seem to work, I updated it.
I guess you're right...
Moved clipboard block to the graveyard (also known as obsoleteBlockSpecs).
Offline
I hate to do this, but...
The memory space left block doesn't work. So it gets removed.
Offline
rubiks_cube_guy238 wrote:
I hate to do this, but...
The memory space left block doesn't work. So it gets removed.
NO! THEN IT WON'T REPORT! AND I WILL FORGET EVERYTHING!!!!!!! *zap* Who are you? Are you my mommy?
Offline