# -*- coding: utf-8 -*- """研究のスキル一覧(ショート専用・舞台型の試作1本目・2026-11-06) 奥のモニターに1つずつ出す。中身はエイイチが実際に使っている仕組みだけ(誇張しない)。 #6 のセリフはエイイチの言葉「今まで煩わしかったターミナルでの作業から解放されたこと」から。 """ import json, os from kabe_kit import shake_js NAME, VER = "研究のスキル一覧", 5 HEAD = "ひとりで
ロボット研究?" LEAD = 0.8 STAGE = "stage" BG_NAME = "stage_bg_noring" # 床の円を消した舞台(円は OVER で回しながら描く) T_ON = (0, 1.3) FOOT_L, FOOT_R, SIZE, SUB_MID = (390, 1525), (690, 1525), 0.88, 1590 SUB_ONE_LINE = True # 字幕は1行ずつにして、箱を足もとの下に収める # 円の奥寄りに、2人を寄せて立たせる(版2: エイイチ「距離感もっと近くて良さそう」) ORANGE = "#E2683A" # 暗い画面の上で読めるよう、#C4471F を明るくした。色の意味は「いま話している1つ」だけ FACE_C, DIM, INK = "#1B2433", "#8A93A3", "#F5F3EE" ITEMS = ["運用分析", "GPUで学習", "依頼箱", "課題地図", "事実確認", "声の単語帳", "記録→記事"] # 画面の決まり(900×600): 左上に「番号 / 07」と名前、真ん中に言いたいことを1つ、図は面(ベタ)で。線・枠・記号のアイコンは使わない CSS = f"""""" def win(t0, t1, inner): an = f"show .15s linear {t0:.3f}s forwards" + (f", hide .15s linear {t1:.3f}s forwards" if t1 else "") return f'
{inner}
' def no(n, name): return f'
{n:02d}/ 07{name}
' def rows(t_in, step, t_pick=None, pick="依頼箱"): out = [] for k, name in enumerate(ITEMS): an = f"rowIn .3s cubic-bezier(.2,1.3,.4,1) {t_in + k * step:.3f}s forwards" if t_pick is not None: an += f", hiR .35s ease-out {t_pick:.3f}s forwards" if name == pick else f", dimR .35s linear {t_pick:.3f}s forwards" out.append(f'
{k + 1:02d}{name}
') return '
' + "".join(out) + "
" def scene(T, S): h = CSS # 0: 問い(モニターがついたら ? が息をする) h += win(T(0, 1.3), T(1, 0.0), f'
?
') # 1: 仕組みは7つ(左に大きな 7、右に7行) h += win(T(1, 0.0), T(2, 0.0), f'
7つの仕組み
' + rows(T(1, 1.1), 0.14)) # 2: 01 運用分析(動きの帯を再生ヘッドが進み、止まりが橙に変わる) t2 = T(2, 0.3); d2 = S(2) - 0.5 segs = [(0.16, 0), (0.08, 1), (0.22, 0), (0.12, 1), (0.25, 0), (0.07, 1), (0.10, 0)] acc, tr, tg = 0.0, "", "" for w, stop in segs: ts = t2 + d2 * (acc + w) tr += f'' if stop: tg += f'
止まり
' acc += w h += win(T(2, 0.0), T(3, 0.0), no(1, "運用分析") + '
ロボットの動画から、
止まった所を読む
' + f'
{tr}
{tg}
') # 3: 02 GPUで学習(借りる → 学習 → 消す が順に橙になる) t3 = T(3, 0.0); s3 = S(3) st = "".join(f'
{k + 1}{nm}
' for k, (nm, tt) in enumerate([("借りる", t3 + 0.7), ("学習", t3 + 1.6), ("消す", t3 + s3 - 0.9)])) h += win(t3, T(4, 0.0), no(2, "GPUで学習") + '
借りて学習して、
終わったら消す
' + f'
{st}
') # 4: 05 事実確認(別のAIが1行ずつ確かめる。言い切りだけ ✗) t4 = T(4, 0.0) rr = "".join(f'
{"✕" if c == "ng" else "✓"}{tx}
' for k, (c, tx) in enumerate([("ok", "数字の出どころ"), ("ng", "根拠のない言い切り"), ("ok", "引用の原文")])) h += win(t4, T(5, 0.0), no(5, "事実確認") + '
別のAIに、疑わせる
' + rr) # 5: いちばん助かってるのは…(7行に戻り、依頼箱だけ橙で残る) h += win(T(5, 0.0), T(6, 0.0), '
いちばん
助かって
いるのは
' + rows(T(5, 0.0), 0.0, t_pick=T(5, 1.0)).replace('top:46px', 'top:46px')) # 6: 03 依頼箱(依頼が 新規→実行中→済み と進み、ターミナルの行に線が引かれる) t6 = T(6, 0.0); s6 = S(6) lanes = "".join(f'
{nm}
' for k, nm in enumerate(["新規", "実行中", "済み"])) h += win(t6, T(7, 0.0), no(3, "依頼箱") + '
Claude Code に、自動で渡す
' + lanes + f'
依頼
' + '
$ cd ~/Robotics_UX/ServiceSim
$ claude -p "……"
' f'
' f'
解放!
') # 7: 研究の記録は毎日サイトで t7 = T(7, 0.0) h += win(t7, None, f'
pixelstomotors.com
' f'
研究の記録を、毎日公開
') return h RING = json.load(open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "stage", "ring_lut.json"))) RING_SEC = 48.0 # 床の円が1周する秒数(ゆっくり回す・版3) def OVER(T): """モニターの外に重ねるもの(版3)。床の円を回す・紙吹雪(7つ!と解放!)・解放!で画面が揺れる。 円は Unity の舞台から消した床(stage_bg_noring.png)の上に、同じカメラの値で描き直す(stage_meta.json の camera)。""" bursts = [dict(t=T(1, 1.0), n=230), dict(t=T(6, 4.4), n=130)] js = f""" """ return js + shake_js([(T(6, 4.4), 0.6)], amp=7) FACE = [(-1, 0.0, 1.0, "joy"), (1, 0.0, 2.0, "joy"), (4, 0.0, 2.5, "wink"), (6, 3.5, 2.5, "joy"), ("end", 0.0, 3.0, "smile")] POSE = [(-1, 0.0, 1), (1, 0.6, 3), (2, 0.0, 2), (5, 0.0, 1), (6, 3.2, 4)] LEAN = [] MOVES = [(1, 0.6, "hop", 1.4), (3, 0.5, "tilt", 1.2), (5, 0.2, "turn", 2.0), (7, 0.2, "jump", 1.0)] INTRO = "rise" SE = [(-1, 0.0, "se_rise", -8), (0, 1.3, "se_boot", -12), (1, 1.0, "se_ding", -8), (1, 1.15, "se_jaran", -12), (2, 0.0, "se_whoosh", -12), (3, 0.0, "se_whoosh", -12), (4, 0.0, "se_whoosh", -12), (4, 1.0, "se_pop", -10), (5, 1.0, "se_tick", -10), (6, 0.0, "se_whoosh", -12), (6, 4.4, "se_pechin", -6), (7, 0.4, "se_pop", -9)] ENDING = dict(kind="jump", at=(6, 3.4))