Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions docs/tutorial/improvement-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ Welcome モーダルの `cardBlocks` / `cardRuby` / `cardMesh` が提示する 3

ユーザーが Welcome → チュートリアル一覧 → カテゴリで学習軸を選ぶ → 同じ題材を Lv1 (コード挿入) → Lv2 (ブロック手組み) → Lv3 (Ruby) と難度別に進めるという既存パターンを、全軸で踏襲する。

ただし **`gettingStarted` (「さあ、始めましょう」) は例外**で、Lv 分けをせず 1 本完結の単機能チュートリアルを並べる (→「方針分岐: `gettingStarted` は単機能・Lv 分けなし」)。

## 現状サマリー (2026-05 時点)

### 既存 deck 一覧 (`packages/scratch-gui/src/lib/libraries/decks/index.jsx`)
Expand Down Expand Up @@ -83,6 +85,22 @@ export const CATEGORIES = {

実装時、`library.jsx` で `withCategories` 表示の順序が `CATEGORIES` オブジェクトのキー順に依存しないなら、明示的な順序配列を導入する。

### 方針分岐: `gettingStarted` は単機能・Lv 分けなし

上の「ゴール」で述べた **Lv1 / Lv2 / Lv3 の難度別 3 本立て**は、`meshStep1-3` や Block 軸 (Lv0/Lv2/Lv3) のように **同じ題材を段階的に深める軸**にだけ適用する。**`gettingStarted` はこの体系から明示的に外す**:

| 観点 | Lv 別の軸 (mesh / block / ruby) | `gettingStarted` |
|---|---|---|
| 1 deck の役割 | 同じ題材を難度別に 3 本 | **1 チュートリアル = 1 機能**で完結 |
| ステップ数 | 5〜8 | **3〜6** |
| 順番 | Lv1 → Lv2 → Lv3 の前提あり | **順番に依存しない**(どれから始めてもよい) |
| 最終ステップ | `deckIds` で次の Lv へ誘導 | **`deckIds` を持たない**(他 deck に依存させない) |
| deck id | `chat-1-basic-1` のように Lv 番号入り | `getting-started-<機能スラッグ>`(**番号を付けない**) |

理由は授業運用にある。中学校技術科「双方向性のあるコンテンツ」の単元では、ワークシートから **「『さあ、始めましょう』から好きなものを 3 つやってみよう」**と指示したい。Lv 分けや通し番号があると「順番にやるもの」に見えてしまい、この指示が成立しない。

`gettingStarted` の単機能 deck の命名規約 (deck id / locale キー / step 画像 / 画像キー / `urlId`) は `packages/scratch-gui/src/lib/libraries/decks/categories/getting-started.jsx` の冒頭コメントに定義してあり、後続の deck 追加もそれに従う。

## Phase 1: Mesh 再カテゴリ化

**目標**: 既存 9 deck を 3 カテゴリ × 3 lv に再分類。新規 deck・画像は無し。
Expand Down
Binary file modified docs/tutorial/screenshots/0201-tips-library-1280x800.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,20 @@ import React from 'react';
import {FormattedMessage} from 'react-intl';

import libraryIntro from '../thumbnails/getting-started.jpg';
import libraryGettingStartedCostume from '../thumbnails/getting-started-costume.jpg';
import libraryGettingStartedSprites from '../thumbnails/getting-started-sprites.jpg';
import {CATEGORIES} from '../../tutorial-tags';
import GreenFlagIcon from '../green-flag-icon.jsx';

// 単機能チュートリアルの規約 (issue #1179 で確定。後続 leaf もこれに従う):
// - deck id : `getting-started-<機能スラッグ>` — Lv 番号も通し番号も付けない。
// このカテゴリの deck は 1 本完結・順番に依存しない
// (「好きなものを3つ」が成立する)ため、順序を示す番号は付けない
// - locale キー : `gui.howtos.getting-started-<スラッグ>.{name,stepN.title}`
// - step 画像 : `getting-started-<スラッグ>-<N>-<説明>.<ext>`。
// 複数 deck で共有する素材は `getting-started-shared-<説明>.<ext>`
// - 画像キー : `gettingStarted<スラッグPascal>StepN`(ja-steps.js / en-steps.js)
// - urlId : `gettingStarted<スラッグPascal>`
const decks = {
'intro-getting-started': {
name: (
Expand Down Expand Up @@ -71,6 +83,165 @@ end`,
],
urlId: 'getStarted'
},

// ─── コスチュームをかえてみよう(単機能・見た目) ───────────────────────
'getting-started-costume': {
name: (
<FormattedMessage
defaultMessage="コスチュームをかえてみよう"
description="Name for the single-feature 'switch costume' tutorial"
id="gui.howtos.getting-started-costume.name"
/>
),
tags: ['ブロック', 'はじめて'],
category: CATEGORIES.gettingStarted,
img: libraryGettingStartedCostume,
nameMessageId: 'gui.howtos.getting-started-costume.name',
// setup.tab は指定しない。step1 の「チュートリアルをはじめる」が新規プロジェクトを
// 作り直してコードタブに戻すため、ここで costumes を指定しても学習者が最初の
// ボタンを押した瞬間に打ち消され、一瞬だけタブが切り替わる不自然な動きになる
// (レビュー指摘 #1179)。コスチュームタブへは step2 の説明で誘導する。
allowedBlocks: {
motion: [],
looks: ['looks_nextcostume', 'looks_switchcostumeto', 'looks_costume'],
sound: [],
event: ['event_whenflagclicked'],
control: ['control_repeat', 'control_wait'],
sensing: [],
operators: [],
},
steps: [
{
title: (
<FormattedMessage
defaultMessage="スプライトの見た目(コスチューム)をかえてみよう!"
description="Getting Started Costume Step 1: Intro"
id="gui.howtos.getting-started-costume.step1.title"
/>
),
image: 'gettingStartedCostumeStep1',
startTutorial: true,
animationTarget: 'startTutorialButton',
},
{
title: (
<FormattedMessage
defaultMessage="「コスチューム」タブで、コスチュームをふやしてみよう"
description="Getting Started Costume Step 2: Add a costume in the costume tab"
id="gui.howtos.getting-started-costume.step2.title"
/>
),
image: 'gettingStartedCostumeStep2',
animationTarget: 'nextButton',
},
{
title: (
<FormattedMessage
defaultMessage="「コード」タブでこのプログラムを入れて、{greenFlag}を押してみよう"
description="Getting Started Costume Step 3: Insert the next-costume blocks and run"
id="gui.howtos.getting-started-costume.step3.title"
values={{greenFlag: <GreenFlagIcon />}}
/>
),
image: 'gettingStartedCostumeStep3',
code: `when_flag_clicked do
3.times do
next_costume
sleep(1)
end
end`,
codeType: 'blocks',
animationTarget: 'insertCodeButton',
},
],
urlId: 'gettingStartedCostume',
},

// ─── スプライトを2つ使ってみよう(単機能・スプライト操作) ───────────────
'getting-started-sprites': {
name: (
<FormattedMessage
defaultMessage="スプライトを2つ使ってみよう"
description="Name for the single-feature 'use two sprites' tutorial"
id="gui.howtos.getting-started-sprites.name"
/>
),
tags: ['ブロック', 'はじめて'],
category: CATEGORIES.gettingStarted,
img: libraryGettingStartedSprites,
nameMessageId: 'gui.howtos.getting-started-sprites.name',
// スプライトの追加・選択が主題なので、コードタブから始める。
setup: {
tab: 'code',
},
allowedBlocks: {
motion: [],
looks: ['looks_sayforsecs', 'looks_say'],
sound: [],
event: ['event_whenflagclicked'],
control: ['control_wait'],
sensing: [],
operators: [],
},
steps: [
{
title: (
<FormattedMessage
defaultMessage="スプライトをふやして、2つのキャラクターを動かそう!"
description="Getting Started Sprites Step 1: Intro - add a second sprite"
id="gui.howtos.getting-started-sprites.step1.title"
/>
),
image: 'gettingStartedSpritesStep1',
startTutorial: true,
animationTarget: 'startTutorialButton',
},
{
title: (
<FormattedMessage
defaultMessage="スプライトリストの右下のボタンから、ペンギンをふやしてみよう"
description="Getting Started Sprites Step 2: Add the penguin sprite"
id="gui.howtos.getting-started-sprites.step2.title"
/>
),
image: 'gettingStartedSpritesStep2',
animationTarget: 'nextButton',
},
{
title: (
<FormattedMessage
defaultMessage="ネコ(スプライト1)をえらんでから、このプログラムを入れよう"
description="Getting Started Sprites Step 3: Insert the cat's program"
id="gui.howtos.getting-started-sprites.step3.title"
/>
),
image: 'gettingStartedSpritesStep3',
code: `when_flag_clicked do
say("こんにちは!", 2)
end`,
codeType: 'blocks',
animationTarget: 'insertCodeButton',
},
{
title: (
<FormattedMessage
defaultMessage="ペンギンをえらぶとプログラムが切りかわるよ。入れたら{greenFlag}を押してみよう"
description="Getting Started Sprites Step 4: Selecting the penguin switches the program; insert it and run"
id="gui.howtos.getting-started-sprites.step4.title"
values={{greenFlag: <GreenFlagIcon />}}
/>
),
image: 'gettingStartedSpritesStep4',
code: `when_flag_clicked do
sleep(2)
say("やあ!", 2)
end`,
codeType: 'blocks',
animationTarget: 'insertCodeButton',
},
],
urlId: 'gettingStartedSprites',
},
};

export default decks;
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,40 @@ export const ja = {
'gui.howtos.getting-started.step.bounceCode': 'ルビーを表示してプログラムを入力してみよう',
'gui.howtos.getting-started.step.runRuby': '実行ボタンを押してプログラムを実行しよう',
'gui.howtos.getting-started.step.firstProgram': 'ネコが行ったり来たりするプログラムができました🎉',
// 単機能チュートリアル (#1179)
'gui.howtos.getting-started-costume.name': 'コスチュームをかえてみよう',
'gui.howtos.getting-started-costume.step1.title': 'スプライトの見た目(コスチューム)をかえてみよう!',
'gui.howtos.getting-started-costume.step2.title': '「コスチューム」タブで、コスチュームをふやしてみよう',
'gui.howtos.getting-started-costume.step3.title':
'「コード」タブでこのプログラムを入れて、{greenFlag}を押してみよう',
'gui.howtos.getting-started-sprites.name': 'スプライトを2つ使ってみよう',
'gui.howtos.getting-started-sprites.step1.title': 'スプライトをふやして、2つのキャラクターを動かそう!',
'gui.howtos.getting-started-sprites.step2.title':
'スプライトリストの右下のボタンから、ペンギンをふやしてみよう',
'gui.howtos.getting-started-sprites.step3.title': 'ネコ(スプライト1)をえらんでから、このプログラムを入れよう',
'gui.howtos.getting-started-sprites.step4.title':
'ペンギンをえらぶとプログラムが切りかわるよ。入れたら{greenFlag}を押してみよう',
};

export const jaHira = {
'gui.howtos.getting-started.step.rubyTab': 'ブロックのつぎはルビー(Ruby)にチャレンジしてみよう!',
'gui.howtos.getting-started.step.bounceCode': 'ルビーをひょうじしてプログラムをにゅうりょくしてみよう',
'gui.howtos.getting-started.step.runRuby': 'じっこうボタンをおしてプログラムをじっこうしよう',
'gui.howtos.getting-started.step.firstProgram': 'ネコがいったりきたりするプログラムができました🎉',
// 単機能チュートリアル (#1179)
'gui.howtos.getting-started-costume.name': 'コスチュームをかえてみよう',
'gui.howtos.getting-started-costume.step1.title': 'スプライトのみため(コスチューム)をかえてみよう!',
'gui.howtos.getting-started-costume.step2.title': '「コスチューム」タブで、コスチュームをふやしてみよう',
'gui.howtos.getting-started-costume.step3.title':
'「コード」タブでこのプログラムをいれて、{greenFlag}をおしてみよう',
'gui.howtos.getting-started-sprites.name': 'スプライトを2つつかってみよう',
'gui.howtos.getting-started-sprites.step1.title': 'スプライトをふやして、2つのキャラクターをうごかそう!',
'gui.howtos.getting-started-sprites.step2.title':
'スプライトリストのみぎしたのボタンから、ペンギンをふやしてみよう',
'gui.howtos.getting-started-sprites.step3.title':
'ネコ(スプライト1)をえらんでから、このプログラムをいれよう',
'gui.howtos.getting-started-sprites.step4.title':
'ペンギンをえらぶとプログラムがきりかわるよ。いれたら{greenFlag}をおしてみよう',
};

export const en = {
Expand All @@ -29,4 +56,16 @@ export const en = {
'gui.howtos.getting-started.step.bounceCode': 'Show Ruby and enter your program',
'gui.howtos.getting-started.step.runRuby': 'Press the run button to execute the program',
'gui.howtos.getting-started.step.firstProgram': "You've made a program where the cat moves back and forth! 🎉",
// Single-feature tutorials (#1179)
'gui.howtos.getting-started-costume.name': 'Switch costumes',
'gui.howtos.getting-started-costume.step1.title': "Let's change how your sprite looks (its costume)!",
'gui.howtos.getting-started-costume.step2.title': 'Add another costume in the Costumes tab',
'gui.howtos.getting-started-costume.step3.title': 'In the Code tab, insert this program and press {greenFlag}',
'gui.howtos.getting-started-sprites.name': 'Use two sprites',
'gui.howtos.getting-started-sprites.step1.title': "Add a sprite and let's move two characters!",
'gui.howtos.getting-started-sprites.step2.title':
'Add a penguin with the button at the bottom right of the sprite list',
'gui.howtos.getting-started-sprites.step3.title': 'Select the cat (Sprite1) first, then insert this program',
'gui.howtos.getting-started-sprites.step4.title':
'Selecting the penguin switches the program. Insert it and press {greenFlag}',
};
16 changes: 16 additions & 0 deletions packages/scratch-gui/src/lib/libraries/decks/en-steps.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ import introBounceCode from './steps/intro-2-bounce-code.ja.gif';
import introRunRuby from './steps/intro-3-run-ruby.ja.gif';
import introFirstProgram from './steps/intro-4-first-program.gif';

// Getting Started 単機能チュートリアル (issue #1179)。ja と同じ素材を使う
// (UI 操作の GIF は言語非依存)。
import gettingStartedCostumeList from './steps/getting-started-costume-1-costume-list.png';
import gettingStartedCostumeProgram from './steps/getting-started-costume-3-program.png';
import gettingStartedSpritesCatProgram from './steps/getting-started-sprites-3-cat-program.png';
import gettingStartedSpritesPenguinProgram from './steps/getting-started-sprites-4-penguin-program.png';

// Chat Tutorial 1 Basic 1: メッセージを送ってみよう
import chat1Basic1Step1 from './steps/chat1-basic1-1-intro.gif';
import chat1Basic1Step2 from './steps/chat1-basic1-2-run-code.gif';
Expand Down Expand Up @@ -121,6 +128,15 @@ const enImages = {
introBounceCode: introBounceCode,
introRunRuby: introRunRuby,
introFirstProgram: introFirstProgram,
// Getting Started: コスチュームをかえてみよう (#1179)
gettingStartedCostumeStep1: gettingStartedCostumeList,
gettingStartedCostumeStep2: chat3Mesh1Step4,
gettingStartedCostumeStep3: gettingStartedCostumeProgram,
// Getting Started: スプライトを2つ使ってみよう (#1179)
gettingStartedSpritesStep1: chat2Sprites1Step1,
gettingStartedSpritesStep2: chat2Sprites1Step5,
gettingStartedSpritesStep3: gettingStartedSpritesCatProgram,
gettingStartedSpritesStep4: gettingStartedSpritesPenguinProgram,
// Chat Tutorial 1 Basic 1
chat1Basic1Step1: chat1Basic1Step1,
chat1Basic1Step2: chat1Basic1Step2,
Expand Down
20 changes: 20 additions & 0 deletions packages/scratch-gui/src/lib/libraries/decks/ja-steps.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ import introBounceCode from './steps/intro-2-bounce-code.ja.gif';
import introRunRuby from './steps/intro-3-run-ruby.ja.gif';
import introFirstProgram from './steps/intro-4-first-program.gif';

// Getting Started 単機能チュートリアル (issue #1179)。UI 操作は既存 GIF を流用し
// (.claude/rules/scratch-gui/tutorial.md「画像の流用ルール」)、静止画は既存 GIF の
// フレームから生成した派生 PNG を使う。挿入するプログラムのステップは、実際に
// 生成されるブロックを「命令ブロックを画像として保存」で書き出したものを使う。
import gettingStartedCostumeList from './steps/getting-started-costume-1-costume-list.png';
import gettingStartedCostumeProgram from './steps/getting-started-costume-3-program.png';
import gettingStartedSpritesCatProgram from './steps/getting-started-sprites-3-cat-program.png';
import gettingStartedSpritesPenguinProgram from './steps/getting-started-sprites-4-penguin-program.png';

// Chat Tutorial 1 Basic 1: メッセージを送ってみよう
import chat1Basic1Step1 from './steps/chat1-basic1-1-intro.gif';
import chat1Basic1Step2 from './steps/chat1-basic1-2-run-code.gif';
Expand Down Expand Up @@ -122,6 +131,17 @@ const jaImages = {
introBounceCode: introBounceCode,
introRunRuby: introRunRuby,
introFirstProgram: introFirstProgram,
// Getting Started: コスチュームをかえてみよう (#1179)
// step1 はできあがりのコスチューム一覧、step2 はコスチュームを追加する操作 GIF、
// step3 は挿入されるプログラムそのもの。各画像が step の説明と一致すること。
gettingStartedCostumeStep1: gettingStartedCostumeList,
gettingStartedCostumeStep2: chat3Mesh1Step4,
gettingStartedCostumeStep3: gettingStartedCostumeProgram,
// Getting Started: スプライトを2つ使ってみよう (#1179)
gettingStartedSpritesStep1: chat2Sprites1Step1,
gettingStartedSpritesStep2: chat2Sprites1Step5,
gettingStartedSpritesStep3: gettingStartedSpritesCatProgram,
gettingStartedSpritesStep4: gettingStartedSpritesPenguinProgram,
// Chat Tutorial 1 Basic 1
chat1Basic1Step1: chat1Basic1Step1,
chat1Basic1Step2: chat1Basic1Step2,
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading