diff --git a/packages/scratch-gui/src/lib/libraries/decks/categories/block-series.jsx b/packages/scratch-gui/src/lib/libraries/decks/categories/block-series.jsx index cd9c97dd676..ede808e24aa 100644 --- a/packages/scratch-gui/src/lib/libraries/decks/categories/block-series.jsx +++ b/packages/scratch-gui/src/lib/libraries/decks/categories/block-series.jsx @@ -1,8 +1,392 @@ // Deck definitions for the blockBasics/blockGames tutorial categories -// (Phase 3, issue #680). Stub — populated by #680 so -// that category can be developed without touching index.jsx or the -// other tutorial categories (issue #932). +// (Phase 3, issue #680). This module holds the blockGames (第4章 +// シューティング) decks (issue #958). +// +// These decks are book-excerpt "試食" tutorials: each opens with the book's +// bibliographic info and closes with a "続きは書籍で" purchase link. The +// shared opening/closing steps and book constant live in book-promo.jsx +// (issue #956). The excerpted programs come from +// docs/tutorial/book-kirakira-ruby-source.md 第4章 (chapter 4), converted to +// Ruby v2 syntax so they convert cleanly into blocks. -const decks = {}; +import React from 'react'; +import {FormattedMessage} from 'react-intl'; + +import {CATEGORIES} from '../../tutorial-tags'; +import GreenFlagIcon from '../green-flag-icon.jsx'; +import {bookOpeningStep, bookClosingStep, bookAdvancedClosingStep} from './book-promo.jsx'; + +import libraryBlockShootingLv0 from '../thumbnails/block-shooting-lv0.jpg'; +import libraryBlockShootingLv2 from '../thumbnails/block-shooting-lv2.jpg'; +import libraryBlockShootingLv3 from '../thumbnails/block-shooting-lv3.jpg'; +import libraryBlockShootingAdvanced from '../thumbnails/block-shooting-advanced.jpg'; + +// Chapter this series excerpts from (see book-kirakira-ruby-source.md). +const CHAPTER = 4; + +// ネコ(スプライト1)を上下に動かすプログラム。Lv0/Lv2/Lv3 で共通の題材。 +const CAT_MOVE_CODE = `when_key_pressed("up arrow") do + self.y += 10 +end +when_key_pressed("down arrow") do + self.y += -10 +end`; + +// タマ(Arrow1)を発射して右へ飛ばし、端で消すプログラム。 +const BULLET_CODE = `when_flag_clicked do + hide +end +when_key_pressed("space") do + go_to("スプライト1") + show + until touching?("_edge_") + self.x += 10 + end + hide +end`; + +// 発展:クローンでタマをたくさん出すプログラム(見せるだけ)。 +const CLONE_CODE = `when_flag_clicked do + hide +end +when_key_pressed("space") do + create_clone("_myself_") +end +when_start_as_a_clone do + go_to("スプライト1") + show + until touching?("_edge_") + self.x += 10 + end + delete_this_clone +end`; + +const decks = { + // ─── blockGames 第4章 Lv0:コードを挿入して動かしてみる ─── + 'block-shooting-lv0': { + name: ( + + ), + tags: [], + category: CATEGORIES.blockGames, + img: libraryBlockShootingLv0, + nameMessageId: 'gui.howtos.block-shooting-lv0.name', + allowedBlocks: { + motion: ['motion_changeyby'], + looks: [], + sound: [], + event: ['event_whenkeypressed'], + control: [], + sensing: [], + operators: [], + }, + steps: [ + bookOpeningStep(CHAPTER, 'blockShootingOpening'), + { + title: ( + + ), + image: 'blockShootingLv0Intro', + startTutorial: true, + animationTarget: 'startTutorialButton', + }, + { + title: ( + + ), + image: 'blockShootingLv0Move', + code: CAT_MOVE_CODE, + codeType: 'blocks', + animationTarget: 'insertCodeButton', + }, + { + title: ( + + ), + image: 'blockShootingRun', + animationTarget: 'nextButton', + }, + { + title: ( + + ), + image: 'blockShootingLv0Customize', + animationTarget: 'nextButton', + }, + bookClosingStep(CHAPTER, 'blockShootingClosing'), + ], + urlId: 'blockShootingLv0', + }, + + // ─── blockGames 第4章 Lv2:ブロックを自分で組み立てる ─── + 'block-shooting-lv2': { + name: ( + + ), + tags: [], + category: CATEGORIES.blockGames, + img: libraryBlockShootingLv2, + nameMessageId: 'gui.howtos.block-shooting-lv2.name', + allowedBlocks: { + motion: ['motion_changeyby', 'motion_changexby', 'motion_goto'], + looks: ['looks_show', 'looks_hide'], + sound: [], + event: ['event_whenflagclicked', 'event_whenkeypressed'], + control: ['control_repeat_until'], + sensing: ['sensing_touchingobject'], + operators: [], + }, + steps: [ + bookOpeningStep(CHAPTER, 'blockShootingOpening'), + { + title: ( + + ), + image: 'blockShootingLv2Intro', + startTutorial: true, + animationTarget: 'startTutorialButton', + }, + { + title: ( + + ), + image: 'blockShootingLv2CatBlocks', + animationTarget: 'nextButton', + }, + { + title: ( + + ), + image: 'blockShootingAddArrow', + animationTarget: 'nextButton', + }, + { + title: ( + + ), + image: 'blockShootingLv2BulletBlocks', + animationTarget: 'nextButton', + }, + { + title: ( + }} + /> + ), + image: 'blockShootingRun', + animationTarget: 'nextButton', + }, + bookClosingStep(CHAPTER, 'blockShootingClosing'), + ], + urlId: 'blockShootingLv2', + }, + + // ─── blockGames 第4章 Lv3:Ruby で書く ─── + 'block-shooting-lv3': { + name: ( + + ), + tags: ['ruby'], + category: CATEGORIES.blockGames, + img: libraryBlockShootingLv3, + nameMessageId: 'gui.howtos.block-shooting-lv3.name', + // Lv3 は Ruby タブ・Ruby モードで開く(improvement-plan.md 参照)。 + setup: { + tab: 'ruby', + rubyMode: 'ruby', + }, + allowedBlocks: { + motion: ['motion_changeyby', 'motion_changexby', 'motion_goto'], + looks: ['looks_show', 'looks_hide'], + sound: [], + event: ['event_whenflagclicked', 'event_whenkeypressed'], + control: ['control_repeat_until'], + sensing: ['sensing_touchingobject'], + operators: [], + }, + steps: [ + bookOpeningStep(CHAPTER, 'blockShootingOpening'), + { + title: ( + + ), + image: 'blockShootingLv3RubyTab', + startTutorial: true, + animationTarget: 'startTutorialButton', + }, + { + title: ( + + ), + image: 'blockShootingLv3CatCode', + code: CAT_MOVE_CODE, + animationTarget: 'insertCodeButton', + }, + { + title: ( + + ), + image: 'blockShootingAddArrow', + animationTarget: 'nextButton', + }, + { + title: ( + + ), + image: 'blockShootingLv3BulletCode', + code: BULLET_CODE, + animationTarget: 'insertCodeButton', + }, + { + title: ( + }} + /> + ), + image: 'blockShootingRun', + animationTarget: 'nextButton', + }, + bookClosingStep(CHAPTER, 'blockShootingClosing'), + ], + urlId: 'blockShootingLv3', + }, + + // ─── blockGames 第4章【発展】:クローンでタマを増やす(見せるだけ・Lv0) ─── + 'block-shooting-advanced': { + name: ( + + ), + tags: [], + category: CATEGORIES.blockGames, + img: libraryBlockShootingAdvanced, + nameMessageId: 'gui.howtos.block-shooting-advanced.name', + allowedBlocks: { + motion: ['motion_changexby', 'motion_goto'], + looks: ['looks_show', 'looks_hide'], + sound: [], + event: ['event_whenflagclicked', 'event_whenkeypressed'], + control: [ + 'control_create_clone_of', + 'control_start_as_clone', + 'control_delete_this_clone', + 'control_repeat_until', + ], + sensing: ['sensing_touchingobject'], + operators: [], + }, + steps: [ + bookOpeningStep(CHAPTER, 'blockShootingOpening'), + { + title: ( + + ), + image: 'blockShootingAdvIntro', + startTutorial: true, + animationTarget: 'startTutorialButton', + }, + { + title: ( + + ), + image: 'blockShootingAdvClone', + code: CLONE_CODE, + codeType: 'blocks', + animationTarget: 'insertCodeButton', + }, + { + title: ( + }} + /> + ), + image: 'blockShootingRun', + animationTarget: 'nextButton', + }, + bookAdvancedClosingStep(CHAPTER, 'blockShootingAdvClosing'), + ], + urlId: 'blockShootingAdvanced', + }, +}; export default decks; diff --git a/packages/scratch-gui/src/lib/libraries/decks/categories/block-series.locale.js b/packages/scratch-gui/src/lib/libraries/decks/categories/block-series.locale.js index b46326f9dfc..3b7239f38fc 100644 --- a/packages/scratch-gui/src/lib/libraries/decks/categories/block-series.locale.js +++ b/packages/scratch-gui/src/lib/libraries/decks/categories/block-series.locale.js @@ -44,14 +44,138 @@ const bookPromoEn = { 'gui.howtos.book-promo.purchase': '📖 Buy the book', }; +// blockGames 第4章(シューティング)の deck 名・ステップ文言(issue #958)。 +const blockGames = { + 'gui.howtos.block-shooting-lv0.name': 'シューティングゲームを作ろう Lv0', + 'gui.howtos.block-shooting-lv0.step.intro': + 'この章ではネコが上下に動いてタマをうつシューティングゲームを作るよ。まずは動かしてみよう!', + 'gui.howtos.block-shooting-lv0.step.move': + '「コードを挿入」ボタンを押して、ネコを上下に動かすプログラムを入れてみよう', + 'gui.howtos.block-shooting-lv0.step.run': 'キーボードの上・下の矢印キーを押すと、ネコが上下に動くよ', + 'gui.howtos.block-shooting-lv0.step.customize': + '「10」の数を変えると、動く速さが変わるよ。好きな数に変えて試してみよう', + 'gui.howtos.block-shooting-lv2.name': 'シューティングゲームを作ろう Lv2', + 'gui.howtos.block-shooting-lv2.step.intro': '今度はブロックを自分で組み立ててみよう!', + 'gui.howtos.block-shooting-lv2.step.catBlocks': + 'ネコ:「上向き矢印キーが押されたとき」に「y座標を10ずつ変える」、下向きには「-10ずつ変える」を組み立てよう。y座標は上下の位置だよ', + 'gui.howtos.block-shooting-lv2.step.addArrow': + 'タマになるスプライト「Arrow1」を追加しよう(スプライト一覧の+ボタンから選べるよ)', + 'gui.howtos.block-shooting-lv2.step.bulletBlocks': + 'タマ:スペースキーで「スプライト1へ行く」「表示する」、そして「端に触れるまでx座標を10ずつ変える」を繰り返し、最後に「隠す」。' + + '『〜まで繰り返す』は条件が成り立つまで続けるブロックだよ', + 'gui.howtos.block-shooting-lv2.step.run': + '{greenFlag}を押して、矢印キーで動かしスペースキーでタマをうってみよう!', + 'gui.howtos.block-shooting-lv3.name': 'シューティングゲームを作ろう Lv3', + 'gui.howtos.block-shooting-lv3.step.intro': + '同じゲームを Ruby で書いてみよう。ルビータブが開いているのを確認してね', + 'gui.howtos.block-shooting-lv3.step.catCode': + 'ネコ:「コードを挿入」で上下移動のプログラムを入れよう。self.y は上下の位置だよ', + 'gui.howtos.block-shooting-lv3.step.addArrow': + 'タマになるスプライト「Arrow1」を追加して、そのスプライトを選ぼう', + 'gui.howtos.block-shooting-lv3.step.bulletCode': + 'タマ:スペースキーで発射して右へ飛ばすプログラムを入れよう。until は条件が成り立つまで繰り返すよ', + 'gui.howtos.block-shooting-lv3.step.run': + '{greenFlag}を押して、矢印キーとスペースキーで遊んでみよう!', + 'gui.howtos.block-shooting-advanced.name': 'シューティングゲーム【発展】クローンでタマを増やそう', + 'gui.howtos.block-shooting-advanced.step.intro': + 'タマを一度にたくさん出すには「クローン」を使うよ。まずは動くところを見てみよう!', + 'gui.howtos.block-shooting-advanced.step.clone': + 'タマ(Arrow1)を選んで「コードを挿入」しよう。スペースキーを押すたびに自分のクローンを作ってタマを増やすよ', + 'gui.howtos.block-shooting-advanced.step.run': + '{greenFlag}を押して、スペースキーを連打してみよう。タマがどんどん増えるよ!', +}; + +const blockGamesHira = { + 'gui.howtos.block-shooting-lv0.name': 'シューティングゲームをつくろう Lv0', + 'gui.howtos.block-shooting-lv0.step.intro': + 'このしょうではネコがじょうげにうごいてタマをうつシューティングゲームをつくるよ。まずはうごかしてみよう!', + 'gui.howtos.block-shooting-lv0.step.move': + '「コードをそうにゅう」ボタンをおして、ネコをじょうげにうごかすプログラムをいれてみよう', + 'gui.howtos.block-shooting-lv0.step.run': + 'キーボードのうえ・したのやじるしキーをおすと、ネコがじょうげにうごくよ', + 'gui.howtos.block-shooting-lv0.step.customize': + '「10」のかずをかえると、うごくはやさがかわるよ。すきなかずにかえてためしてみよう', + 'gui.howtos.block-shooting-lv2.name': 'シューティングゲームをつくろう Lv2', + 'gui.howtos.block-shooting-lv2.step.intro': 'こんどはブロックをじぶんでくみたててみよう!', + 'gui.howtos.block-shooting-lv2.step.catBlocks': + 'ネコ:「うわむきやじるしキーがおされたとき」に「yざひょうを10ずつかえる」、したむきには「-10ずつかえる」をくみたてよう。yざひょうはじょうげのいちだよ', + 'gui.howtos.block-shooting-lv2.step.addArrow': + 'タマになるスプライト「Arrow1」をついかしよう(スプライトいちらんの+ボタンからえらべるよ)', + 'gui.howtos.block-shooting-lv2.step.bulletBlocks': + 'タマ:スペースキーで「スプライト1へいく」「ひょうじする」、そして「はしにふれるまでxざひょうを10ずつかえる」をくりかえし、さいごに「かくす」。' + + '『〜までくりかえす』はじょうけんがなりたつまでつづけるブロックだよ', + 'gui.howtos.block-shooting-lv2.step.run': + '{greenFlag}をおして、やじるしキーでうごかしスペースキーでタマをうってみよう!', + 'gui.howtos.block-shooting-lv3.name': 'シューティングゲームをつくろう Lv3', + 'gui.howtos.block-shooting-lv3.step.intro': + 'おなじゲームを Ruby でかいてみよう。ルビータブがひらいているのをかくにんしてね', + 'gui.howtos.block-shooting-lv3.step.catCode': + 'ネコ:「コードをそうにゅう」でじょうげいどうのプログラムをいれよう。self.y はじょうげのいちだよ', + 'gui.howtos.block-shooting-lv3.step.addArrow': + 'タマになるスプライト「Arrow1」をついかして、そのスプライトをえらぼう', + 'gui.howtos.block-shooting-lv3.step.bulletCode': + 'タマ:スペースキーではっしゃしてみぎへとばすプログラムをいれよう。until はじょうけんがなりたつまでくりかえすよ', + 'gui.howtos.block-shooting-lv3.step.run': + '{greenFlag}をおして、やじるしキーとスペースキーであそんでみよう!', + 'gui.howtos.block-shooting-advanced.name': 'シューティングゲーム【はってん】クローンでタマをふやそう', + 'gui.howtos.block-shooting-advanced.step.intro': + 'タマをいちどにたくさんだすには「クローン」をつかうよ。まずはうごくところをみてみよう!', + 'gui.howtos.block-shooting-advanced.step.clone': + 'タマ(Arrow1)をえらんで「コードをそうにゅう」しよう。スペースキーをおすたびにじぶんのクローンをつくってタマをふやすよ', + 'gui.howtos.block-shooting-advanced.step.run': + '{greenFlag}をおして、スペースキーをれんだしてみよう。タマがどんどんふえるよ!', +}; + +const blockGamesEn = { + 'gui.howtos.block-shooting-lv0.name': 'Make a Shooting Game Lv0', + 'gui.howtos.block-shooting-lv0.step.intro': + 'In this chapter we make a shooting game where the cat moves up and down and shoots. First, try running it!', + 'gui.howtos.block-shooting-lv0.step.move': + 'Press "Insert code" to add the program that moves the cat up and down', + 'gui.howtos.block-shooting-lv0.step.run': 'Press the up/down arrow keys and the cat moves up and down', + 'gui.howtos.block-shooting-lv0.step.customize': + 'Changing the "10" changes how fast it moves. Try your own number!', + 'gui.howtos.block-shooting-lv2.name': 'Make a Shooting Game Lv2', + 'gui.howtos.block-shooting-lv2.step.intro': 'Now build the blocks yourself!', + 'gui.howtos.block-shooting-lv2.step.catBlocks': + 'Cat: on "when up arrow key pressed", "change y by 10"; for down, "change y by -10". y is the up/down position.', + 'gui.howtos.block-shooting-lv2.step.addArrow': + 'Add the sprite "Arrow1" for the bullet (pick it with the + button in the sprite list)', + 'gui.howtos.block-shooting-lv2.step.bulletBlocks': + 'Bullet: on space, "go to スプライト1", "show", then "repeat until touching edge: change x by 10", finally "hide". ' + + '"Repeat until" keeps going until the condition becomes true.', + 'gui.howtos.block-shooting-lv2.step.run': + 'Press {greenFlag}, move with the arrow keys and shoot with the space key!', + 'gui.howtos.block-shooting-lv3.name': 'Make a Shooting Game Lv3', + 'gui.howtos.block-shooting-lv3.step.intro': + "Let's write the same game in Ruby. Make sure the Ruby tab is open.", + 'gui.howtos.block-shooting-lv3.step.catCode': + 'Cat: use "Insert code" to add the up/down movement. self.y is the up/down position.', + 'gui.howtos.block-shooting-lv3.step.addArrow': 'Add the sprite "Arrow1" for the bullet and select it', + 'gui.howtos.block-shooting-lv3.step.bulletCode': + 'Bullet: add the program that fires on space and flies right. "until" repeats until the condition is true.', + 'gui.howtos.block-shooting-lv3.step.run': + 'Press {greenFlag} and play with the arrow keys and the space key!', + 'gui.howtos.block-shooting-advanced.name': 'Shooting Game (Advanced): Multiply bullets with clones', + 'gui.howtos.block-shooting-advanced.step.intro': + 'To fire many bullets at once, use "clones". First, watch it run!', + 'gui.howtos.block-shooting-advanced.step.clone': + 'Select the bullet (Arrow1) and "Insert code". Each space press makes a clone of itself to add bullets.', + 'gui.howtos.block-shooting-advanced.step.run': + 'Press {greenFlag} and mash the space key. The bullets keep multiplying!', +}; + export const ja = { ...bookPromo, + ...blockGames, }; export const jaHira = { ...bookPromoHira, + ...blockGamesHira, }; export const en = { ...bookPromoEn, + ...blockGamesEn, }; diff --git a/packages/scratch-gui/src/lib/libraries/decks/en-steps.js b/packages/scratch-gui/src/lib/libraries/decks/en-steps.js index e09179c26e7..74d251ecb95 100644 --- a/packages/scratch-gui/src/lib/libraries/decks/en-steps.js +++ b/packages/scratch-gui/src/lib/libraries/decks/en-steps.js @@ -115,6 +115,24 @@ import rubyBasics6Step5 from './steps/ruby-basics-6-5-modify.png'; // only the final step shows the TryRuby screenshot (see tutorial.md image reuse rule). import rubyBasics7TryRuby from './thumbnails/ruby-basics-1-tryruby.png'; +// blockGames 第4章 シューティング (issue #958) +import blockShootingOpening from './steps/blockShootingOpening.png'; +import blockShootingLv0Intro from './steps/blockShootingLv0Intro.png'; +import blockShootingLv0Move from './steps/blockShootingLv0Move.png'; +import blockShootingRun from './steps/blockShootingRun.png'; +import blockShootingLv0Customize from './steps/blockShootingLv0Customize.png'; +import blockShootingClosing from './steps/blockShootingClosing.png'; +import blockShootingLv2Intro from './steps/blockShootingLv2Intro.png'; +import blockShootingLv2CatBlocks from './steps/blockShootingLv2CatBlocks.png'; +import blockShootingAddArrow from './steps/blockShootingAddArrow.png'; +import blockShootingLv2BulletBlocks from './steps/blockShootingLv2BulletBlocks.png'; +import blockShootingLv3RubyTab from './steps/blockShootingLv3RubyTab.png'; +import blockShootingLv3CatCode from './steps/blockShootingLv3CatCode.png'; +import blockShootingLv3BulletCode from './steps/blockShootingLv3BulletCode.png'; +import blockShootingAdvIntro from './steps/blockShootingAdvIntro.png'; +import blockShootingAdvClone from './steps/blockShootingAdvClone.png'; +import blockShootingAdvClosing from './steps/blockShootingAdvClosing.png'; + const enImages = { // Getting Started introRubyTab: introRubyTab, @@ -214,7 +232,24 @@ const enImages = { rubyBasics6Step4: rubyBasics6Step4, rubyBasics6Step5: rubyBasics6Step5, - rubyBasics7TryRuby: rubyBasics7TryRuby + rubyBasics7TryRuby: rubyBasics7TryRuby, + // blockGames 第4章 シューティング (issue #958) + blockShootingOpening: blockShootingOpening, + blockShootingLv0Intro: blockShootingLv0Intro, + blockShootingLv0Move: blockShootingLv0Move, + blockShootingRun: blockShootingRun, + blockShootingLv0Customize: blockShootingLv0Customize, + blockShootingClosing: blockShootingClosing, + blockShootingLv2Intro: blockShootingLv2Intro, + blockShootingLv2CatBlocks: blockShootingLv2CatBlocks, + blockShootingAddArrow: blockShootingAddArrow, + blockShootingLv2BulletBlocks: blockShootingLv2BulletBlocks, + blockShootingLv3RubyTab: blockShootingLv3RubyTab, + blockShootingLv3CatCode: blockShootingLv3CatCode, + blockShootingLv3BulletCode: blockShootingLv3BulletCode, + blockShootingAdvIntro: blockShootingAdvIntro, + blockShootingAdvClone: blockShootingAdvClone, + blockShootingAdvClosing: blockShootingAdvClosing }; export {enImages}; diff --git a/packages/scratch-gui/src/lib/libraries/decks/ja-steps.js b/packages/scratch-gui/src/lib/libraries/decks/ja-steps.js index 6f8c65d90fc..2d6a86f8461 100644 --- a/packages/scratch-gui/src/lib/libraries/decks/ja-steps.js +++ b/packages/scratch-gui/src/lib/libraries/decks/ja-steps.js @@ -116,6 +116,24 @@ import rubyBasics6Step5 from './steps/ruby-basics-6-5-modify.png'; // (docs/tutorial/improvement-plan.md Phase 2 / tutorial.md「画像の流用ルール」)。 import rubyBasics7TryRuby from './thumbnails/ruby-basics-1-tryruby.png'; +// blockGames 第4章 シューティング (issue #958) +import blockShootingOpening from './steps/blockShootingOpening.png'; +import blockShootingLv0Intro from './steps/blockShootingLv0Intro.png'; +import blockShootingLv0Move from './steps/blockShootingLv0Move.png'; +import blockShootingRun from './steps/blockShootingRun.png'; +import blockShootingLv0Customize from './steps/blockShootingLv0Customize.png'; +import blockShootingClosing from './steps/blockShootingClosing.png'; +import blockShootingLv2Intro from './steps/blockShootingLv2Intro.png'; +import blockShootingLv2CatBlocks from './steps/blockShootingLv2CatBlocks.png'; +import blockShootingAddArrow from './steps/blockShootingAddArrow.png'; +import blockShootingLv2BulletBlocks from './steps/blockShootingLv2BulletBlocks.png'; +import blockShootingLv3RubyTab from './steps/blockShootingLv3RubyTab.png'; +import blockShootingLv3CatCode from './steps/blockShootingLv3CatCode.png'; +import blockShootingLv3BulletCode from './steps/blockShootingLv3BulletCode.png'; +import blockShootingAdvIntro from './steps/blockShootingAdvIntro.png'; +import blockShootingAdvClone from './steps/blockShootingAdvClone.png'; +import blockShootingAdvClosing from './steps/blockShootingAdvClosing.png'; + const jaImages = { // Getting Started introRubyTab: introRubyTab, @@ -215,7 +233,24 @@ const jaImages = { rubyBasics6Step4: rubyBasics6Step4, rubyBasics6Step5: rubyBasics6Step5, - rubyBasics7TryRuby: rubyBasics7TryRuby + rubyBasics7TryRuby: rubyBasics7TryRuby, + // blockGames 第4章 シューティング (issue #958) + blockShootingOpening: blockShootingOpening, + blockShootingLv0Intro: blockShootingLv0Intro, + blockShootingLv0Move: blockShootingLv0Move, + blockShootingRun: blockShootingRun, + blockShootingLv0Customize: blockShootingLv0Customize, + blockShootingClosing: blockShootingClosing, + blockShootingLv2Intro: blockShootingLv2Intro, + blockShootingLv2CatBlocks: blockShootingLv2CatBlocks, + blockShootingAddArrow: blockShootingAddArrow, + blockShootingLv2BulletBlocks: blockShootingLv2BulletBlocks, + blockShootingLv3RubyTab: blockShootingLv3RubyTab, + blockShootingLv3CatCode: blockShootingLv3CatCode, + blockShootingLv3BulletCode: blockShootingLv3BulletCode, + blockShootingAdvIntro: blockShootingAdvIntro, + blockShootingAdvClone: blockShootingAdvClone, + blockShootingAdvClosing: blockShootingAdvClosing }; export {jaImages}; diff --git a/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingAddArrow.png b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingAddArrow.png new file mode 100644 index 00000000000..187c483c366 Binary files /dev/null and b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingAddArrow.png differ diff --git a/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingAdvClone.png b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingAdvClone.png new file mode 100644 index 00000000000..9bd9aea3aa9 Binary files /dev/null and b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingAdvClone.png differ diff --git a/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingAdvClosing.png b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingAdvClosing.png new file mode 100644 index 00000000000..187c483c366 Binary files /dev/null and b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingAdvClosing.png differ diff --git a/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingAdvIntro.png b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingAdvIntro.png new file mode 100644 index 00000000000..187c483c366 Binary files /dev/null and b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingAdvIntro.png differ diff --git a/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingClosing.png b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingClosing.png new file mode 100644 index 00000000000..187c483c366 Binary files /dev/null and b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingClosing.png differ diff --git a/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingLv0Customize.png b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingLv0Customize.png new file mode 100644 index 00000000000..187c483c366 Binary files /dev/null and b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingLv0Customize.png differ diff --git a/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingLv0Intro.png b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingLv0Intro.png new file mode 100644 index 00000000000..187c483c366 Binary files /dev/null and b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingLv0Intro.png differ diff --git a/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingLv0Move.png b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingLv0Move.png new file mode 100644 index 00000000000..bd85cdb9efb Binary files /dev/null and b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingLv0Move.png differ diff --git a/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingLv2BulletBlocks.png b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingLv2BulletBlocks.png new file mode 100644 index 00000000000..ac44ace9418 Binary files /dev/null and b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingLv2BulletBlocks.png differ diff --git a/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingLv2CatBlocks.png b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingLv2CatBlocks.png new file mode 100644 index 00000000000..bd85cdb9efb Binary files /dev/null and b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingLv2CatBlocks.png differ diff --git a/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingLv2Intro.png b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingLv2Intro.png new file mode 100644 index 00000000000..187c483c366 Binary files /dev/null and b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingLv2Intro.png differ diff --git a/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingLv3BulletCode.png b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingLv3BulletCode.png new file mode 100644 index 00000000000..e959de64de1 Binary files /dev/null and b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingLv3BulletCode.png differ diff --git a/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingLv3CatCode.png b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingLv3CatCode.png new file mode 100644 index 00000000000..881028bf0b7 Binary files /dev/null and b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingLv3CatCode.png differ diff --git a/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingLv3RubyTab.png b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingLv3RubyTab.png new file mode 100644 index 00000000000..881028bf0b7 Binary files /dev/null and b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingLv3RubyTab.png differ diff --git a/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingOpening.png b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingOpening.png new file mode 100644 index 00000000000..187c483c366 Binary files /dev/null and b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingOpening.png differ diff --git a/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingRun.png b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingRun.png new file mode 100644 index 00000000000..187c483c366 Binary files /dev/null and b/packages/scratch-gui/src/lib/libraries/decks/steps/blockShootingRun.png differ diff --git a/packages/scratch-gui/src/lib/libraries/decks/thumbnails/block-shooting-advanced.jpg b/packages/scratch-gui/src/lib/libraries/decks/thumbnails/block-shooting-advanced.jpg new file mode 100644 index 00000000000..9666c37bd30 Binary files /dev/null and b/packages/scratch-gui/src/lib/libraries/decks/thumbnails/block-shooting-advanced.jpg differ diff --git a/packages/scratch-gui/src/lib/libraries/decks/thumbnails/block-shooting-lv0.jpg b/packages/scratch-gui/src/lib/libraries/decks/thumbnails/block-shooting-lv0.jpg new file mode 100644 index 00000000000..66b4575d027 Binary files /dev/null and b/packages/scratch-gui/src/lib/libraries/decks/thumbnails/block-shooting-lv0.jpg differ diff --git a/packages/scratch-gui/src/lib/libraries/decks/thumbnails/block-shooting-lv2.jpg b/packages/scratch-gui/src/lib/libraries/decks/thumbnails/block-shooting-lv2.jpg new file mode 100644 index 00000000000..e854f33c27e Binary files /dev/null and b/packages/scratch-gui/src/lib/libraries/decks/thumbnails/block-shooting-lv2.jpg differ diff --git a/packages/scratch-gui/src/lib/libraries/decks/thumbnails/block-shooting-lv3.jpg b/packages/scratch-gui/src/lib/libraries/decks/thumbnails/block-shooting-lv3.jpg new file mode 100644 index 00000000000..4b7f9eda756 Binary files /dev/null and b/packages/scratch-gui/src/lib/libraries/decks/thumbnails/block-shooting-lv3.jpg differ diff --git a/packages/scratch-gui/test/unit/lib/libraries/decks/tutorial-categories-refactor.test.js b/packages/scratch-gui/test/unit/lib/libraries/decks/tutorial-categories-refactor.test.js index 1513ca0875d..b4cd8151cb6 100644 --- a/packages/scratch-gui/test/unit/lib/libraries/decks/tutorial-categories-refactor.test.js +++ b/packages/scratch-gui/test/unit/lib/libraries/decks/tutorial-categories-refactor.test.js @@ -1,8 +1,9 @@ /** * Guards the decks/index.jsx + locale-file split into per-category modules - * (issue #932): deck order/content must stay identical, and the Phase 3 - * (#680) / Phase 4 (#681) stub categories must be independent, empty, and - * not collide with the existing categories. + * (issue #932): deck order/content must stay identical across the split. + * block-series has since been populated by Phase 4 (#681 / #958); dncl is + * still an empty stub for Phase 3 (#680). Each category module must remain + * independent and not collide with the others. */ import decks from '../../../../../src/lib/libraries/decks/index.jsx'; import gettingStartedDecks from '../../../../../src/lib/libraries/decks/categories/getting-started.jsx'; @@ -42,7 +43,19 @@ const EXPECTED_DECK_ID_ORDER = [ 'ruby-basics-4-arrays', 'ruby-basics-5-blocks', 'ruby-basics-6-methods', - 'ruby-basics-7-next' + 'ruby-basics-7-next', + // block-series decks (Phase 4 / #681, #958) — appended after ruby-basics + 'block-shooting-lv0', + 'block-shooting-lv2', + 'block-shooting-lv3', + 'block-shooting-advanced' +]; + +const BLOCK_SERIES_DECK_IDS = [ + 'block-shooting-lv0', + 'block-shooting-lv2', + 'block-shooting-lv3', + 'block-shooting-advanced' ]; describe('Tutorial deck category split (issue #932)', () => { @@ -50,7 +63,7 @@ describe('Tutorial deck category split (issue #932)', () => { expect(Object.keys(decks)).toEqual(EXPECTED_DECK_ID_ORDER); }); - test('getting-started and ruby-basics decks are composed from their category modules', () => { + test('getting-started, ruby-basics and block-series decks are composed from their category modules', () => { expect(decks['intro-getting-started']).toBe(gettingStartedDecks['intro-getting-started']); expect(decks['ruby-basics-1-numbers']).toBe(rubyBasicsDecks['ruby-basics-1-numbers']); expect(decks['ruby-basics-2-strings']).toBe(rubyBasicsDecks['ruby-basics-2-strings']); @@ -58,13 +71,15 @@ describe('Tutorial deck category split (issue #932)', () => { expect(decks['ruby-basics-4-arrays']).toBe(rubyBasicsDecks['ruby-basics-4-arrays']); expect(decks['ruby-basics-5-blocks']).toBe(rubyBasicsDecks['ruby-basics-5-blocks']); expect(decks['ruby-basics-6-methods']).toBe(rubyBasicsDecks['ruby-basics-6-methods']); + BLOCK_SERIES_DECK_IDS.forEach(id => { + expect(decks[id]).toBe(blockSeriesDecks[id]); + }); }); - test('block-series and dncl are empty stub categories that add no deck ids', () => { - expect(blockSeriesDecks).toEqual({}); + test('block-series exposes exactly its Phase 4 decks; dncl is still an empty stub', () => { + expect(Object.keys(blockSeriesDecks)).toEqual(BLOCK_SERIES_DECK_IDS); expect(dnclDecks).toEqual({}); EXPECTED_DECK_ID_ORDER.forEach(id => { - expect(Object.prototype.hasOwnProperty.call(blockSeriesDecks, id)).toBe(false); expect(Object.prototype.hasOwnProperty.call(dnclDecks, id)).toBe(false); }); }); @@ -75,15 +90,23 @@ describe('Tutorial deck category split (issue #932)', () => { expect(dnclLocale.en).toEqual({}); }); - test('block-series locale holds only the shared book-promo foundation (issue #956), no deck-id howtos', () => { - // #956 populates the Block-axis common book-promotion strings; the - // per-deck howto strings still come later (#680). + test('block-series locale holds the shared book-promo foundation (#956) plus Phase 4 deck howtos (#681)', () => { + // #956 added the Block-axis common book-promotion strings; #681/#958 + // added the per-deck howto strings for the block-shooting decks. [blockSeriesLocale.ja, blockSeriesLocale.jaHira, blockSeriesLocale.en].forEach(table => { const keys = Object.keys(table); expect(keys.length).toBeGreaterThan(0); + // every key is either the shared book-promo foundation or a + // block-shooting deck howto — no strays from other categories. keys.forEach(id => { - expect(id.startsWith('gui.howtos.book-promo.')).toBe(true); + const isBookPromo = id.startsWith('gui.howtos.book-promo.'); + const isBlockShooting = BLOCK_SERIES_DECK_IDS.some( + deckId => id.startsWith(`gui.howtos.${deckId}.`) + ); + expect(isBookPromo || isBlockShooting).toBe(true); }); + // the shared book-promo foundation must still be present. + expect(keys.some(id => id.startsWith('gui.howtos.book-promo.'))).toBe(true); }); });