Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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: 14 additions & 4 deletions docs/tutorial/progress.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
| Phase 1 — Mesh 再分類 | [#678](https://github.com/smalruby/smalruby3-editor/issues/678) | ✅ マージ済み (PR #683) | 1 PR | 不要 |
| 基盤 — `setup` プロパティ | (Phase 2 sub-issue 内) | ✅ マージ済み (PR #684) | 1 PR | 不要 |
| Phase 2 — Ruby 拡充 | [#679](https://github.com/smalruby/smalruby3-editor/issues/679) | 🟢 7/7 deck 実装済み (`ruby-basics-1-numbers` 〜 `-7-next`。deck 7 は TryRuby 導線) | 2〜3 PR | ~50 枚 |
| Phase 3 — Block 4 シリーズ | [#680](https://github.com/smalruby/smalruby3-editor/issues/680) | ⚪️ 未着手 (書誌情報待ち) | 4 PR | ~76 枚 |
| Phase 3 — Block シリーズ (2 章) | [#680](https://github.com/smalruby/smalruby3-editor/issues/680) | 🟡 第1章 `blockBasics` 4 deck 実装済み (#957)。第4章 `blockGames` は別 PR。書誌・引用は #962 で確定 | 2 PR | ~40 枚 |
| Phase 4 — DNCL | [#681](https://github.com/smalruby/smalruby3-editor/issues/681) | ⚪️ 未着手 | 3〜4 PR | ~70 枚 |

凡例: ⚪️ 未着手 / 🟡 進行中 / 🟢 完了 (PR レビュー待ち含む) / ✅ マージ済み / ❌ 中断
Expand Down Expand Up @@ -60,10 +60,20 @@
- [x] ふりがなフラグも考慮した rubyMode の動作 (`smalruby:furiganaEnabled` localStorage の同期)
- [x] `test/unit/lib/deck-setup.test.js` で 13 ケースの単体テスト (全 pass)

### Phase 3 着手前に必要 (外部要因)
### Phase 3 着手前に必要 (外部要因) — 解決済み

- [ ] 書籍「キラキラRuby」(仮称) の正式タイトル・出版社・ISBN・購入リンク確定
- [ ] 著者 (藤村健吾氏) からの書籍引用許諾
- [x] 書誌情報・購入リンク確定 → `book-promo.jsx` の `BOOK` 定数 (プレースホルダ) + `docs/tutorial/book-kirakira-ruby-source.md` (#962) に集約
- [x] 書籍引用許諾 (共著者 takaokouji 本人が引用の範囲での利用に同意・#962)

### Phase 3 第1章 `blockBasics` (#957)

「ネコからにげるゲーム冒頭」を基本 3 deck + 発展 1 deck で実装:

- [x] `block-basics-lv0` (コード挿入体験) / `block-basics-lv2` (ブロック手組み) / `block-basics-lv3` (Ruby・`setup: {tab:'ruby', rubyMode:'ruby'}`) / `block-basics-advanced` (Lv0 のみ・完成デモ)
- [x] 各 deck 冒頭に書誌 step、末尾に「続きは書籍で」+ 購入リンク step (`book-promo.jsx` の共通ファクトリを利用)
- [x] locale 3 ファイル (`block-series.locale.js` の `ja`/`jaHira`/`en`)
- [x] step 画像 20 枚 (**プレースホルダ** — 本番スクリーンショットは headful キャプチャ待ち) + サムネイル 4 枚
- [x] `npm run lint` 緑 / `build:dev` 成功 / pw-check で 4 deck 起動確認

## 削除タイミング

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,342 @@
// 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 owns the Block-axis book-excerpt decks
// so they can be developed without touching index.jsx or the other tutorial
// categories (issue #932).
//
// blockBasics 第1章「ネコからにげるゲーム」 (issue #957). The chapter has a
// basic 3-deck ladder (Lv0 code-insert / Lv2 build-blocks / Lv3 Ruby) plus a
// single "発展" demo deck (Lv0 only). Every deck opens with the book's
// bibliographic info and closes with a purchase link; those shared steps come
// from book-promo.jsx (issue #956). Source snippets:
// docs/tutorial/book-kirakira-ruby-source.md 第1章.
import React from 'react';
import {FormattedMessage} from 'react-intl';

const decks = {};
import libraryBlockBasicsLv0 from '../thumbnails/block-basics-lv0.png';
import libraryBlockBasicsLv2 from '../thumbnails/block-basics-lv2.png';
import libraryBlockBasicsLv3 from '../thumbnails/block-basics-lv3.png';
import libraryBlockBasicsAdvanced from '../thumbnails/block-basics-advanced.png';
import {CATEGORIES} from '../../tutorial-tags';
import GreenFlagIcon from '../green-flag-icon.jsx';
import {bookOpeningStep, bookClosingStep, bookAdvancedClosingStep} from './book-promo.jsx';

// The book chapter this series excerpts from (used by the book-promo steps).
const CHAPTER = 1;

// The completed "ネコからにげるゲーム" program. Lv0 / Lv3 / advanced all insert
// this same program; Lv2 has the user assemble the equivalent blocks by hand.
// (docs/tutorial/book-kirakira-ruby-source.md 第1章 の完成プログラム)
const FULL_PROGRAM = `when_flag_clicked do
loop do
point_towards("_mouse_")
move(10)
if touching?("_mouse_")
say("こんにちは!", 2)
end
end
end`;

// Blocks surfaced in the palette while these decks are active. Kept to the
// blocks the ネコからにげるゲーム program uses so the palette stays focused.
const allowedBlocks = {
motion: ['motion_movesteps', 'motion_pointtowards'],
looks: ['looks_sayforsecs', 'looks_say'],
sound: [],
event: ['event_whenflagclicked'],
control: ['control_forever', 'control_if'],
sensing: ['sensing_touchingobject'],
operators: [],
};

const decks = {
// ─── Lv0: 完成プログラムを挿入して動かす(コード挿入体験) ───────────────
'block-basics-lv0': {
name: (
<FormattedMessage
defaultMessage="【Lv0】ネコからにげるゲームを動かそう"
description="Name for blockBasics Lv0: run the finished cat-chase game by inserting code"
id="gui.howtos.block-basics-lv0.name"
/>
),
tags: [],
category: CATEGORIES.blockBasics,
img: libraryBlockBasicsLv0,
nameMessageId: 'gui.howtos.block-basics-lv0.name',
allowedBlocks,
steps: [
bookOpeningStep(CHAPTER, 'blockBasicsBookOpening'),
{
title: (
<FormattedMessage
defaultMessage="【Lv0】ネコからにげるゲームを作るよ。ネコがマウスのポインターを追いかけてくるよ!"
description="blockBasics Lv0 intro step"
id="gui.howtos.block-basics-lv0.intro"
/>
),
image: 'blockBasicsLv0Intro',
startTutorial: true,
animationTarget: 'startTutorialButton',
},
{
title: (
<FormattedMessage
defaultMessage="「コードを挿入」ボタンを押して、完成プログラムを入れてみよう"
description="blockBasics Lv0 insert-code step"
id="gui.howtos.block-basics-lv0.insert"
/>
),
image: 'blockBasicsLv0Insert',
code: FULL_PROGRAM,
codeType: 'blocks',
animationTarget: 'insertCodeButton',
},
{
title: (
<FormattedMessage
defaultMessage="{greenFlag}を押すと、ネコがマウスポインターを追いかけるよ。マウスを動かしてにげよう!"
description="blockBasics Lv0 run step"
id="gui.howtos.block-basics-lv0.run"
values={{greenFlag: <GreenFlagIcon />}}
/>
),
image: 'blockBasicsLv0Run',
animationTarget: 'nextButton',
},
{
title: (
<FormattedMessage
defaultMessage="「こんにちは!」の言葉や、「10歩動かす」の歩数を変えて、動きを変えてみよう"
description="blockBasics Lv0 modify step"
id="gui.howtos.block-basics-lv0.modify"
/>
),
image: 'blockBasicsLv0Modify',
animationTarget: 'nextButton',
},
bookClosingStep(CHAPTER, 'blockBasicsBookClosing'),
],
urlId: 'blockBasicsLv0',
},

// ─── Lv2: ブロックを自分で組み立てる ────────────────────────────────────
'block-basics-lv2': {
name: (
<FormattedMessage
defaultMessage="【Lv2】ブロックを組み立てよう"
description="Name for blockBasics Lv2: assemble the cat-chase game with blocks"
id="gui.howtos.block-basics-lv2.name"
/>
),
tags: [],
category: CATEGORIES.blockBasics,
img: libraryBlockBasicsLv2,
nameMessageId: 'gui.howtos.block-basics-lv2.name',
allowedBlocks,
steps: [
bookOpeningStep(CHAPTER, 'blockBasicsBookOpening'),
{
title: (
<FormattedMessage
defaultMessage="【Lv2】同じゲームを、ブロックを自分で組み立てて作ってみよう"
description="blockBasics Lv2 intro step"
id="gui.howtos.block-basics-lv2.intro"
/>
),
image: 'blockBasicsLv2Intro',
startTutorial: true,
animationTarget: 'startTutorialButton',
},
{
title: (
<FormattedMessage
defaultMessage="「🏁が押されたとき」の中に「ずっと」を入れて、「マウスのポインターへ向ける」を置こう"
description="blockBasics Lv2 first blocks step"
id="gui.howtos.block-basics-lv2.block1"
/>
),
image: 'blockBasicsLv2Block1',
animationTarget: 'nextButton',
},
{
title: (
<FormattedMessage
defaultMessage="「10歩動かす」を追加しよう。これでネコがマウスに向かって進むよ"
description="blockBasics Lv2 move block step"
id="gui.howtos.block-basics-lv2.block2"
/>
),
image: 'blockBasicsLv2Block2',
animationTarget: 'nextButton',
},
{
title: (
<FormattedMessage
defaultMessage="「もし〈マウスのポインターに触れた〉なら」の中に「こんにちは!と2秒言う」を入れよう"
description="blockBasics Lv2 if-touching block step"
id="gui.howtos.block-basics-lv2.block3"
/>
),
image: 'blockBasicsLv2Block3',
animationTarget: 'nextButton',
},
{
title: (
<FormattedMessage
defaultMessage="{greenFlag}を押して、自分で組み立てたゲームを動かそう"
description="blockBasics Lv2 run step"
id="gui.howtos.block-basics-lv2.run"
values={{greenFlag: <GreenFlagIcon />}}
/>
),
image: 'blockBasicsLv2Run',
animationTarget: 'nextButton',
},
bookClosingStep(CHAPTER, 'blockBasicsBookClosing'),
],
urlId: 'blockBasicsLv2',
},

// ─── Lv3: 同じゲームを Ruby で書く ──────────────────────────────────────
'block-basics-lv3': {
name: (
<FormattedMessage
defaultMessage="【Lv3】Rubyで書こう"
description="Name for blockBasics Lv3: write the cat-chase game in Ruby"
id="gui.howtos.block-basics-lv3.name"
/>
),
tags: ['ruby'],
category: CATEGORIES.blockBasics,
img: libraryBlockBasicsLv3,
nameMessageId: 'gui.howtos.block-basics-lv3.name',
// Open the Ruby tab in Ruby (not DNCL/furigana) mode.
setup: {
tab: 'ruby',
rubyMode: 'ruby',
},
allowedBlocks,
steps: [
bookOpeningStep(CHAPTER, 'blockBasicsBookOpening'),
{
title: (
<FormattedMessage
defaultMessage="【Lv3】同じゲームを、Rubyのプログラムで書いてみよう"
description="blockBasics Lv3 intro step"
id="gui.howtos.block-basics-lv3.intro"
/>
),
image: 'blockBasicsLv3Intro',
startTutorial: true,
animationTarget: 'startTutorialButton',
},
{
title: (
<FormattedMessage
defaultMessage="ルビー(Ruby)タブが開いていることを確認しよう"
description="blockBasics Lv3 ruby-tab step"
id="gui.howtos.block-basics-lv3.rubyTab"
/>
),
image: 'blockBasicsLv3RubyTab',
animationTarget: 'nextButton',
},
{
title: (
<FormattedMessage
defaultMessage="「コードを挿入」ボタンを押して、Rubyのプログラムを入れてみよう"
description="blockBasics Lv3 insert-code step"
id="gui.howtos.block-basics-lv3.insert"
/>
),
image: 'blockBasicsLv3Insert',
code: FULL_PROGRAM,
animationTarget: 'insertCodeButton',
},
{
title: (
<FormattedMessage
defaultMessage={'say("こんにちは!", 2) の言葉や秒数を変えて、自分だけのゲームにしよう'}
description="blockBasics Lv3 modify step"
id="gui.howtos.block-basics-lv3.modify"
/>
),
image: 'blockBasicsLv3Modify',
animationTarget: 'nextButton',
},
{
title: (
<FormattedMessage
defaultMessage="{greenFlag}を押すと、Rubyで書いたゲームが動くよ"
description="blockBasics Lv3 run step"
id="gui.howtos.block-basics-lv3.run"
values={{greenFlag: <GreenFlagIcon />}}
/>
),
image: 'blockBasicsLv3Run',
animationTarget: 'nextButton',
},
bookClosingStep(CHAPTER, 'blockBasicsBookClosing'),
],
urlId: 'blockBasicsLv3',
},

// ─── 発展: 完成デモを動かして見せるだけ(Lv0 相当) ─────────────────────
'block-basics-advanced': {
name: (
<FormattedMessage
defaultMessage="【発展】完成デモを動かそう"
description="Name for blockBasics advanced: run the finished demo only"
id="gui.howtos.block-basics-advanced.name"
/>
),
tags: [],
category: CATEGORIES.blockBasics,
img: libraryBlockBasicsAdvanced,
nameMessageId: 'gui.howtos.block-basics-advanced.name',
allowedBlocks,
steps: [
bookOpeningStep(CHAPTER, 'blockBasicsBookOpening'),
{
title: (
<FormattedMessage
defaultMessage="【発展】本書 第1章では、このあとゲームをもっと楽しくしていきます。ここでは完成デモを動かして見てみよう"
description="blockBasics advanced intro step"
id="gui.howtos.block-basics-advanced.intro"
/>
),
image: 'blockBasicsAdvIntro',
startTutorial: true,
animationTarget: 'startTutorialButton',
},
{
title: (
<FormattedMessage
defaultMessage="「コードを挿入」ボタンで、完成した「ネコからにげるゲーム」を入れよう"
description="blockBasics advanced insert-code step"
id="gui.howtos.block-basics-advanced.insert"
/>
),
image: 'blockBasicsAdvInsert',
code: FULL_PROGRAM,
codeType: 'blocks',
animationTarget: 'insertCodeButton',
},
{
title: (
<FormattedMessage
defaultMessage="{greenFlag}を押して、完成デモを動かそう。マウスを動かしてネコからにげよう!"
description="blockBasics advanced run step"
id="gui.howtos.block-basics-advanced.run"
values={{greenFlag: <GreenFlagIcon />}}
/>
),
image: 'blockBasicsAdvRun',
animationTarget: 'nextButton',
},
bookAdvancedClosingStep(CHAPTER, 'blockBasicsBookAdvancedClosing'),
],
urlId: 'blockBasicsAdvanced',
},
};

export default decks;
Loading
Loading