Discuss Scratch
- Discussion Forums
- » 日本語
- » Scratch 3.0 をハック(動作や構造を解析すること)しよう!
- bsahd
-
Scratcher
100+ posts
Scratch 3.0 をハック(動作や構造を解析すること)しよう!
特に決まってません。自動識別するか、決めておくのが良いでしょう。
Last edited by bsahd (Feb. 19, 2021 07:04:18)
- abee
-
Scratcher
1000+ posts
Scratch 3.0 をハック(動作や構造を解析すること)しよう!
#247
規約(RFC 8259)によりUTF-8にすることが決まっています。特別な場合を除き、勝手に変えてはいけません。
規約(RFC 8259)によりUTF-8にすることが決まっています。特別な場合を除き、勝手に変えてはいけません。
- BlueRayi
-
Scratcher
30 posts
Scratch 3.0 をハック(動作や構造を解析すること)しよう!
独自拡張機能によるカスタムブロックで, 引数のデフォルト値として空文字列を使用したいのですがうまくいきません。
のようにすると undefined となります(空文字列が undefined に化け, その後文字列 ‘undefined’ にキャストされている?)。
代替として抹消文字(U+007F)を使用すると見た目的にはそれっぽくなります。
しかし, 制御文字を使うのは予期せぬ動作を引き起こす心配が大きいので, できれば使いたくありません。
よりよい解決策があれば教えてください。
/* 前略 */ arguments: { arg1: { type: ArgumentType.STRING, defaultValue: '', }, }, /* 後略 */
のようにすると undefined となります(空文字列が undefined に化け, その後文字列 ‘undefined’ にキャストされている?)。
代替として抹消文字(U+007F)を使用すると見た目的にはそれっぽくなります。
/* 前略 */ arguments: { arg1: { type: ArgumentType.STRING, defaultValue: String.fromCodePoint(0x7F), }, }, /* 後略 */
しかし, 制御文字を使うのは予期せぬ動作を引き起こす心配が大きいので, できれば使いたくありません。
よりよい解決策があれば教えてください。
- jishiha
-
Scratcher
60 posts
Scratch 3.0 をハック(動作や構造を解析すること)しよう!
いくつか拡張機能を作っていますが、私もうまい解決方法がわかりません。
どうしてもデフォルト値なしにしたい場合は、
defaultValue: “ ” (半角スペース一つ)
を指定しています。
どうしてもデフォルト値なしにしたい場合は、
defaultValue: “ ” (半角スペース一つ)
を指定しています。
- Poteto143
-
Scratcher
1000+ posts
Scratch 3.0 をハック(動作や構造を解析すること)しよう!
Scratchのプロジェクトに含まれる音や画像は、sb3ファイルではどのようにして保存しているのでしょうか?
- apple502j
-
Scratcher
1000+ posts
Scratch 3.0 をハック(動作や構造を解析すること)しよう!
Scratchのプロジェクトに含まれる音や画像は、sb3ファイルではどのようにして保存しているのでしょうか?sb3ファイルはproject.jsonと画像等を含むzipです。ファイル名はファイルの内容のMD5+拡張子です。
- inoking
-
Scratcher
1000+ posts
Scratch 3.0 をハック(動作や構造を解析すること)しよう!
質問コーナー4 #4831, #4832 から:
A が偽の場合(多分これが元の質問に近い):
#4831 で説明されている短絡評価の効果により前者の方が速くなるようです(1.59秒 < 2.35秒)。
ただ、A の C型ブロック の中を読み飛ばす処理がどのようになっているかが気になります。
A も B も真の場合:
「処理」を常に実行することになりますが後者の方が若干速くなるようです(4.66秒 > 4.26秒)。
これは「もし」が2回呼ばれるためと考えられます。
結論としては
複数の条件式がある場合、短絡評価が見込めるなら「もし」の入れ子で書いたほうがよさそう。
というところでしょうか。
もし <A::operators> ならと
もし <B::operators> なら
処理
end
end
もし <<A::operators> かつ <B::operators>> ならの違いについて考えてみます。検証プロジェクト
処理
end
A が偽の場合(多分これが元の質問に近い):
#4831 で説明されている短絡評価の効果により前者の方が速くなるようです(1.59秒 < 2.35秒)。
ただ、A の C型ブロック の中を読み飛ばす処理がどのようになっているかが気になります。
A も B も真の場合:
「処理」を常に実行することになりますが後者の方が若干速くなるようです(4.66秒 > 4.26秒)。
これは「もし」が2回呼ばれるためと考えられます。
結論としては
複数の条件式がある場合、短絡評価が見込めるなら「もし」の入れ子で書いたほうがよさそう。
というところでしょうか。
- apple502j
-
Scratcher
1000+ posts
Scratch 3.0 をハック(動作や構造を解析すること)しよう!
シーケンサーにはC型ブロックの内側にあるブロックを実行する「stepToBranch」命令があります。
「もし」の実装は、この命令をif文で囲むだけというシンプルな実装です。
stepToBranch命令自体は、「指定された枝の最初のブロックのIDを、スタックに追加する」という感じだったはずです。
そのため、次の実行時にはスタックに追加されたブロックが実行され、そのスクリプトの終了後スタックからブロックが削除され、元のブロックの実行に戻る、という風になります。
「もし」の実装は、この命令をif文で囲むだけというシンプルな実装です。
stepToBranch命令自体は、「指定された枝の最初のブロックのIDを、スタックに追加する」という感じだったはずです。
そのため、次の実行時にはスタックに追加されたブロックが実行され、そのスクリプトの終了後スタックからブロックが削除され、元のブロックの実行に戻る、という風になります。
- inoking
-
Scratcher
1000+ posts
Scratch 3.0 をハック(動作や構造を解析すること)しよう!
#255 に追記します。
元の質問では
30fps となるようにそこで待ちが入ります。
よって、動きのブロックの場合は結果は同じです(あっても誤差の問題)。
元の質問では
処理のところが
(10) 歩動かすだったのですが、動きのブロックの場合は事情が全く異なります。
ずっとのように、動きのある(描画を引き起こす)ブロックをループ内に入れると
(10) 歩動かす
end
30fps となるようにそこで待ちが入ります。
よって、動きのブロックの場合は結果は同じです(あっても誤差の問題)。
- inoking
-
Scratcher
1000+ posts
Scratch 3.0 をハック(動作や構造を解析すること)しよう!
質問コーナー4 #6202 より:
タイマーは
https://github.com/LLK/scratch-vm/blob/develop/src/blocks/scratch3_sensing.js#L213
タイマーの実体は https://github.com/LLK/scratch-vm/blob/develop/src/util/timer.js にありそうです。
2000年からの日数は
https://github.com/LLK/scratch-vm/blob/develop/src/blocks/scratch3_sensing.js#L252
よく考えると、
2000年からの日数 はブロック実行時に直接時刻が取得されるのに対し、
タイマーは別途常時更新される値を取得しています。
別途常時更新されるタイミングは分かりませんがおそらく1フレーム(30ミリ秒: 0.03秒)単位でしょう。
それからすると「誤差は 0.025 秒まで広がる」のは納得できます。
つまり、タイマーより 2000年からの日数 のほうが正確と言えそうです。
タイマーは
https://github.com/LLK/scratch-vm/blob/develop/src/blocks/scratch3_sensing.js#L213
getTimer (args, util) { return util.ioQuery('clock', 'projectTimer'); }
2000年からの日数は
https://github.com/LLK/scratch-vm/blob/develop/src/blocks/scratch3_sensing.js#L252
daysSince2000 () { const msPerDay = 24 * 60 * 60 * 1000; const start = new Date(2000, 0, 1); // Months are 0-indexed. const today = new Date(); const dstAdjust = today.getTimezoneOffset() - start.getTimezoneOffset(); let mSecsSinceStart = today.valueOf() - start.valueOf(); mSecsSinceStart += ((today.getTimezoneOffset() - dstAdjust) * 60 * 1000); return mSecsSinceStart / msPerDay; }
よく考えると、
2000年からの日数 はブロック実行時に直接時刻が取得されるのに対し、
タイマーは別途常時更新される値を取得しています。
別途常時更新されるタイミングは分かりませんがおそらく1フレーム(30ミリ秒: 0.03秒)単位でしょう。
それからすると「誤差は 0.025 秒まで広がる」のは納得できます。
つまり、タイマーより 2000年からの日数 のほうが正確と言えそうです。
Last edited by inoking (April 19, 2021 15:27:54)
- apple502j
-
Scratcher
1000+ posts
Scratch 3.0 をハック(動作や構造を解析すること)しよう!
タイマーの更新は https://github.com/LLK/scratch-vm/blob/develop/src/engine/sequencer.js#L76 です。(これは、ブロックが実行される前の段階です。)
Last edited by apple502j (April 20, 2021 12:51:38)
- JirenGames
-
Scratcher
100+ posts
Scratch 3.0 をハック(動作や構造を解析すること)しよう!
(10) 歩動かすを10こ並べるのと、
(10) 回繰り返すってどっちの処理が早いんですか?
(10) 歩動かす
end
- ringoumai
-
Scratcher
1000+ posts
Scratch 3.0 をハック(動作や構造を解析すること)しよう!
#263
あと、何故そっちの方が速いのか、根拠を示してください。
ソースコードを解析し、その仕組みや仕様を研究します。と、#1に書いてあるので、ここで良い気がします。
あと、何故そっちの方が速いのか、根拠を示してください。
Last edited by ringoumai (May 9, 2021 03:27:59)











