define AUDIO = False
define mc = Character("我", color="#d8b0c0") define l = Character("林砚", color="#8fa8d8", who_outlines=[(2, "#00000080")]) define shen = Character("沈亦舟", color="#a8d8a8", who_outlines=[(2, "#00000080")]) define n = Character("同桌", color="#999999") define v = Character(None, what_color="#b8b8c8", what_italic=True)
default aff = 0 default danger = 0 default aff_shen = 0 default flag_phone = False default show_aff = False default bad_end_triggered = False default danger_warn = 10 default danger_break = 16 default danger_lock = 22 default chat_log = []
default persistent.cg_unlocked = [] default persistent.endings_unlocked = [] default persistent.shen_unlocked = False default persistent.playthrough = 0 default persistent.unlocked_memories = []
define shake_s = Shake((0, 0, 0, 0), 0.4, dist=12) define shake_h = Shake((0, 0, 0, 0), 0.6, dist=28)
transform stand: xalign 0.5 yalign 1.0
transform stand_left: xalign 0.22 yalign 1.0
transform stand_right: xalign 0.78 yalign 1.0
transform stand_center: xalign 0.5 yalign 1.0
image bg black = Solid("#000000") image bg rain = Solid("#141a26") image bg door = Solid("#1a1a22") image bg school = Solid("#22242e") image bg roof = Solid("#2a1e28")
image lin normal = Solid("#3d4a63", xsize=340, ysize=700) image lin close = Solid("#5a3d4a", xsize=700, ysize=700) image lin smile = Solid("#4a5d7a", xsize=340, ysize=700) image lin dark = Solid("#241a24", xsize=340, ysize=700)
image shen normal = Solid("#3a4a3a", xsize=340, ysize=700) image shen close = Solid("#4a5a4a", xsize=700, ysize=700) image shen dark = Solid("#1a2a1a", xsize=340, ysize=700)
init python: # ---------- 音轨 ---------- renpy.music.register_channel("heartbeat", mixer="sfx", loop=True)
# ---------- CG 数据 ----------
CG_LIST = [
("cg_rain", "雨夜·伞下", "images/cg/cg_rain.png", "#1e2638"),
("cg_hand", "指尖·冰凉", "images/cg/cg_hand.png", "#2a1e28"),
("cg_roof", "天台·失控", "images/cg/cg_roof.png", "#3a1e1e"),
("cg_shen", "书库·靠近", "images/cg/cg_shen.png", "#1e2a1e"),
("cg_lock", "笼·门后", "images/cg/cg_lock.png", "#0a0a0a"),
("cg_rain2", "共犯·雨里", "images/cg/cg_rain2.png", "#141a26"),
("cg_after", "续章·清晨", "images/cg/cg_after.png", "#2a2218"),
]
# ---------- 结局数据 ----------
ENDING_LIST = [
("end_cage", "笼", "囚禁结局", "#666666"),
("end_co", "共犯", "真结局", "#d8a0a0"),
("end_heal", "松手", "救赎结局", "#8fa8d8"),
("end_escape", "未读", "逃离结局", "#888888"),
("end_shen_a", "书页", "沈亦舟线·停留", "#a8d8a8"),
("end_shen_b", "空白", "沈亦舟线·决裂", "#d8d8a8"),
("end_after", "还早", "续章结局·软", "#e0c8a0"),
("end_hard", "门外", "续章结局·硬", "#666666"),
("end_dark", "同归", "续章结局·黑", "#3a1e1e"),
("be_break", "崩", "BAD END · 崩坏", "#8a1e1e"),
("be_lock", "锁", "BAD END · 囚禁", "#3a0a0a"),
]
# ---------- 记忆碎片 ----------
MEMORY_LIST = [
("mem_1", "第一次见面", "他第一次看见你,不是在天台。"),
("mem_2", "那把伞", "他买了七把一模一样的伞。只为了给你一把。"),
("mem_3", "后排的椅子", "他曾经在你教室后排,坐了一整个学期。"),
("mem_4", "沈亦舟的日记", "他写你的名字,写了三年。"),
("mem_5", "通讯录", "他手机里,只有你一个人。"),
("mem_6", "凌晨四点", "他每天凌晨四点醒来,确认你还在。"),
]
# ---------- 解锁工具 ----------
def unlock_cg(cid):
if cid not in persistent.cg_unlocked:
persistent.cg_unlocked.append(cid)
def unlock_ending(eid):
if eid not in persistent.endings_unlocked:
persistent.endings_unlocked.append(eid)
def cg_unlocked(cid):
return cid in persistent.cg_unlocked
def ending_unlocked(eid):
return eid in persistent.endings_unlocked
def unlock_memory(mid):
if mid not in persistent.unlocked_memories:
persistent.unlocked_memories.append(mid)
def memory_unlocked(mid):
return mid in persistent.unlocked_memories
# ---------- 周目 ----------
def is_ngplus():
return persistent.playthrough >= 1
def ng_plus_count():
return persistent.playthrough
def clear_playthrough():
persistent.playthrough += 1
store.bad_end_triggered = False
# ---------- HUD 开关 ----------
def toggle_show_aff():
store.show_aff = not store.show_aff
config.keymap["toggle_aff"] = ["h"]
config.underlay.append(renpy.Keymap(toggle_aff=toggle_show_aff))
# ---------- Bad End 检查 ----------
def check_danger(warn=None, brk=None, lock=None):
if store.bad_end_triggered:
return
w = warn if warn is not None else store.danger_warn
b = brk if brk is not None else store.danger_break
k = lock if lock is not None else store.danger_lock
if store.danger >= k:
store.bad_end_triggered = True
renpy.jump("be_lock")
elif store.danger >= b:
store.bad_end_triggered = True
renpy.jump("be_break")
elif store.danger >= w:
renpy.show_screen("danger_edge")
def danger_rank():
d = store.danger
if d >= 22: return ("临界", "#ff2244")
if d >= 16: return ("危险", "#ff5577")
if d >= 10: return ("警告", "#ffaa44")
if d >= 5: return ("微感", "#cccc66")
return ("平静", "#888888")
# ---------- 手机聊天工具 ----------
def chat_clear():
store.chat_log = []
renpy.restart_interaction()
def chat_add(who, text):
store.chat_log.append((who, text))
renpy.restart_interaction()
def chat_typing(delay=1.0, who="him"):
store.chat_log.append((who, "……"))
renpy.restart_interaction()
renpy.pause(delay, hard=False)
store.chat_log.pop()
renpy.restart_interaction()
def chat_pop():
if store.chat_log:
store.chat_log.pop()
renpy.restart_interaction()
# ---------- 挂载 overlay ----------
config.overlay_screens.append("aff_hud")
config.overlay_screens.append("main_menu_extra")
config.overlay_screens.append("main_menu_ngplus")
screen timed_choice(question, choices, timeout=5.0): modal True zorder 100
bar:
value AnimatedValue(0.0, 1.0, delay=timeout)
xsize 640
ysize 4
xalign 0.5
ypos 0.68
left_bar Solid("#ff3355")
right_bar Solid("#ffffff20")
thumb None
bar_invert True
timer timeout action Return("__timeout__")
vbox:
xalign 0.5
ypos 0.74
spacing 14
text question:
size 26
color "#ffffff"
xalign 0.5
outlines [(2, "#000000")]
for label_text, val in choices:
textbutton label_text:
action Return(val)
xsize 560
text_size 22
text_xalign 0.5
screen danger_edge(): zorder 80 add Solid("#ff000022") timer 1.6 action Hide("danger_edge")
screen aff_hud(): zorder 90 if show_aff: frame: xalign 0.99 yalign 0.02 background "#0a0a0acc" padding (20, 16) vbox: spacing 10
text "── 状态 ──":
size 16
color "#888888"
hbox:
spacing 6
text "♥" size 22 color "#8fa8d8"
text " 林砚好感":
size 20
color "#c8d8f0"
text "[aff]":
size 20
color "#8fa8d8"
hbox:
spacing 6
text "☠" size 22 color "#ff5577"
text " 危险值":
size 20
color "#f0c8c8"
text "[danger]":
size 20
color "#ff5577"
if aff_shen > 0 or persistent.shen_unlocked:
hbox:
spacing 6
text "♠" size 22 color "#d8a0a0"
text " 亦舟好感":
size 20
color "#f0c8d8"
text "[aff_shen]":
size 20
color "#d8a0a0"
text "按 H 键收起":
size 14
color "#666666"
screen phone_chat(contact="林砚", avatar_color="#3d4a63"): modal True zorder 100
add Solid("#00000099")
frame:
xalign 0.5
yalign 0.5
xsize 520
ysize 760
background "#0a0a0a"
padding (0, 0)
vbox:
spacing 0
frame:
xsize 520
ysize 42
background "#1a1a1a"
hbox:
text "9:41":
size 16
color "#ffffff"
xpos 24
yalign 0.5
text "5G ▮▮▮":
size 13
color "#ffffff"
xpos 400
yalign 0.5
frame:
xsize 520
ysize 64
background "#262626"
hbox:
xpos 16
yalign 0.5
spacing 12
frame:
xsize 40
ysize 40
background avatar_color
text contact:
size 22
color "#ffffff"
yalign 0.5
frame:
xsize 520
ysize 540
background "#101010"
padding (14, 14)
viewport:
yinitial 1.0
mousewheel True
draggable True
scrollbars None
vbox:
spacing 12
for who, text in chat_log:
$ is_me = (who == "me")
hbox:
if is_me:
null width 110
frame:
background "#3d6b3d"
padding (14, 10)
text text:
size 18
color "#ffffff"
else:
frame:
background "#2a2a2a"
padding (14, 10)
text text:
size 18
color "#ffffff"
null width 110
frame:
xsize 520
ysize 114
background "#1a1a1a"
text "—— 选择你的回复 ——":
size 13
color "#555555"
xalign 0.5
yalign 0.5
screen phone_choice(items): zorder 110 vbox: xalign 0.5 ypos 0.78 spacing 8 for i in items: textbutton i.caption: action i.action xsize 460 background "#1f3f1f" hover_background "#2f5f2f" padding (12, 10) text_size 18 text_color "#ffffff" text_xalign 0.5
screen cg_gallery(): tag menu add Solid("#0a0a0a")
vbox:
xalign 0.5
ypos 0.05
spacing 20
text "CG 图鉴":
size 40
color "#ffffff"
xalign 0.5
grid 4 2:
xalign 0.5
ypos 0.22
spacing 16
for cid, name, path, color in CG_LIST:
if cg_unlocked(cid):
button:
action Show("cg_viewer", cid=cid, name=name, path=path, color=color)
xsize 240
ysize 135
background color
hover_background "#ffffff40"
text name:
size 16
color "#ffffff"
xalign 0.5
yalign 0.9
else:
frame:
xsize 240
ysize 135
background "#1a1a1a"
text "???":
size 24
color "#333333"
xalign 0.5
yalign 0.5
textbutton "返回":
action Return()
xalign 0.5
yalign 0.95
text_size 24
screen cg_viewer(cid, name, path, color): modal True zorder 200 add Solid("#000000") add color text name: xalign 0.5 yalign 0.08 size 32 color "#ffffff" textbutton "关闭": action Hide("cg_viewer") xalign 0.95 yalign 0.05 text_size 22
screen ending_gallery(): tag menu add Solid("#0a0a0a")
vbox:
xalign 0.5
ypos 0.05
spacing 20
text "结局收集":
size 40
color "#ffffff"
xalign 0.5
text "已解锁 [len(persistent.endings_unlocked)] / [len(ENDING_LIST)]":
size 20
color "#888888"
xalign 0.5
vbox:
xalign 0.5
ypos 0.2
spacing 10
for eid, name, desc, color in ENDING_LIST:
if ending_unlocked(eid):
frame:
xsize 620
background "#151515"
padding (24, 12)
hbox:
spacing 20
text name size 24 color color
text desc size 18 color "#999999"
text "✓" size 22 color "#66cc66"
else:
frame:
xsize 620
background "#0e0e0e"
padding (24, 12)
hbox:
spacing 20
text "???" size 24 color "#333333"
text "未解锁" size 18 color "#333333"
textbutton "返回":
action Return()
xalign 0.5
yalign 0.95
text_size 24
screen memory_gallery(): tag menu add Solid("#0a0a0a")
vbox:
xalign 0.5
ypos 0.05
spacing 16
text "记忆碎片":
size 40
color "#ffffff"
xalign 0.5
text "已解锁 [len(persistent.unlocked_memories)] / [len(MEMORY_LIST)]":
size 18
color "#777777"
xalign 0.5
vbox:
xalign 0.5
ypos 0.22
spacing 12
for mid, name, desc in MEMORY_LIST:
if memory_unlocked(mid):
frame:
xsize 660
background "#141414"
padding (24, 14)
vbox:
spacing 4
text name size 22 color "#d8b0c0"
text desc size 16 color "#999999"
else:
frame:
xsize 660
background "#0e0e0e"
padding (24, 14)
vbox:
spacing 4
text "???" size 22 color "#2a2a2a"
text "—— 未解锁 ——" size 16 color "#222222"
textbutton "返回":
action Return()
xalign 0.5
yalign 0.95
text_size 24
screen main_menu_extra(): zorder 100 vbox: xalign 0.05 yalign 0.1 spacing 12 textbutton "CG 图鉴": action ShowMenu("cg_gallery") text_size 22 text_color "#cccccc" text_hover_color "#ffffff" textbutton "结局收集": action ShowMenu("ending_gallery") text_size 22 text_color "#cccccc" text_hover_color "#ffffff"
screen main_menu_ngplus(): zorder 100 vbox: xalign 0.05 yalign 0.22 spacing 12 textbutton "记忆碎片": action ShowMenu("memory_gallery") text_size 22 text_color "#cccccc" text_hover_color "#ffffff"
label start: scene bg black with fade
if is_ngplus():
$ renpy.notify("二周目 · 记忆碎片已激活")
$ unlock_memory("mem_1")
v "“又见面了。”"
v "“这一次,你会做同样的选择吗?”"
$ unlock_memory("mem_2")
if AUDIO:
play music "rain_loop.ogg" fadein 2.0
"雨下得很大。"
"我没带伞,也没人接我。"
"巷子很窄,路灯坏了一半,光一闪一闪的。"
"我加快脚步。"
"身后的脚步声,也快了。"
"——不,是我快了,他也快了。"
scene bg rain
with Dissolve(1.0)
if AUDIO:
stop music fadeout 1.0
play heartbeat "heartbeat.ogg" fadein 0.5
"我停下。"
"他也停下。"
"我回头。"
show lin normal at stand
with Dissolve(0.4)
$ unlock_cg("cg_rain")
with shake_s
"伞沿滴着水,落在我的鞋尖上。"
"他离我很近。"
"近到我能闻到他身上的味道——雨水、烟草,还有一点点血腥味。"
l "这么晚,去哪了?"
"他笑得很轻。"
"像在问一句无关紧要的话。"
label q1: $ r = renpy.call_screen("timed_choice", question = "他在等你回答。", choices = [("老实回答", "honest"), ("撒谎", "lie"), ("反问他", "ask")], timeout = 6.0)
if r == "__timeout__":
jump q1_timeout
elif r == "honest":
jump q1_honest
elif r == "lie":
jump q1_lie
else:
jump q1_ask
label q1_honest: mc "……图书馆。" $ aff += 1 l "嗯。" l "我知道。" $ danger += 1 "他说得很自然。" "可我没告诉过任何人。" jump q1_after
label q1_lie: mc "……便利店。" with shake_h if AUDIO: play sound "thunder.ogg" "他笑了。" l "便利店。" l "你身上一点关东煮的味道都没有。" $ danger += 3 $ flag_phone = True l "再想一次。" "他的手指擦过我的下巴。" "很凉。" jump q1_after
label q1_ask: mc "……你为什么在这里?" $ aff += 2 $ danger += 1 "他愣了一下。" "然后笑得像被戳中了什么。" l "因为你在这里。" l "这个理由,够不够?" jump q1_after
label q1_timeout: "我张了张嘴。" "什么都没说出来。" $ danger += 2 l "……不说话啊。" l "那我就当你默认了。" l "默认你今晚,是故意走这条路的。" jump q1_after
label q1_after: "他撑着伞,往我这边偏了偏。" "伞面很小。" "他半个肩膀,全湿了。"
menu:
"往他那边靠":
$ aff += 2
"我往他那边挪了半步。"
"他僵了一下。"
l "……别动。"
l "再近一点,我就不保证自己还是人了。"
"保持距离":
$ danger += 1
"我没有动。"
l "……怕我?"
"他低声笑。"
l "怕就对了。"
$ check_danger()
jump phone_demo
label phone_demo: $ chat_clear() show screen phone_chat("林砚", "#3d4a63")
$ chat_add("him", "在吗")
$ chat_typing(0.6, "him")
$ chat_add("him", "睡了吗")
$ chat_typing(0.9, "him")
$ chat_add("him", "我看到你房间的灯还亮着")
menu (screen="phone_choice"):
"睡了":
$ chat_add("me", "睡了")
$ chat_typing(0.5, "him")
$ chat_add("him", "骗人")
$ chat_add("him", "灯还亮着")
jump phone_demo_2
"你怎么知道":
$ chat_add("me", "你怎么知道")
$ chat_typing(0.8, "him")
$ chat_add("him", "我一直在楼下")
$ danger += 2
jump phone_demo_2
"(不回复)":
$ chat_add("me", "……")
$ chat_typing(1.2, "him")
$ chat_add("him", "不说话,我就当你默认了")
$ danger += 1
jump phone_demo_2
label phone_demo_2: $ chat_typing(0.8, "him") $ chat_add("him", "下来") $ chat_add("him", "给你三分钟")
menu (screen="phone_choice"):
"好":
$ chat_add("me", "好")
$ chat_typing(0.4, "him")
$ chat_add("him", "乖")
"不去":
$ chat_add("me", "不去")
$ chat_typing(0.6, "him")
$ chat_add("him", "那我上去")
$ danger += 2
"(关机)":
$ chat_add("me", "……")
$ chat_add("him", "你关机了。")
$ chat_add("him", "没关系。")
$ chat_add("him", "我有钥匙。")
$ danger += 4
hide screen phone_chat
with Dissolve(0.4)
"手机黑屏了。"
"雨还在下。"
$ check_danger()
jump ch1_door
label ch1_door: scene bg door with fade
if AUDIO:
stop heartbeat fadeout 1.0
play music "tense.ogg" fadein 1.5
show lin normal at stand
with Dissolve(0.4)
"到了楼下。"
"我伸手去掏钥匙。"
"他忽然按住我的手腕。"
$ unlock_cg("cg_hand")
with shake_s
l "手机,给我。"
label q2: $ r = renpy.call_screen("timed_choice", question = "他的手指没有松开。", choices = [("把手机给他", "give"), ("拒绝", "refuse"), ("问他为什么", "why")], timeout = 4.0)
if r == "__timeout__":
jump q2_timeout
elif r == "give":
jump q2_give
elif r == "refuse":
jump q2_refuse
else:
jump q2_why
label q2_give: $ danger += 2 $ aff -= 1 "我把手机递了过去。" "他接过去,当着我的面,划开屏幕。" "通讯录里,一个名字消失了。" l "好了。" l "干净了。" jump q2_after
label q2_refuse: $ aff += 2 $ danger += 2 mc "不给。" "他盯着我看了很久。" l "……好。" l "那你记住了。" l "从今天起,你的手机里,最好只有我一个人。" jump q2_after
label q2_why: $ danger += 1 $ aff += 1 mc "为什么?" l "因为我想知道,你的一天里,有多少是我不知道的。" l "全部。" l "我想知道全部。" jump q2_after
label q2_timeout: $ danger += 3 "我没有动。" "他也没有动。" "我们就这样僵持着。" "最后,是他先松了手。" l "……算了。" l "今天先放过你。" jump q2_after
label q2_after: if flag_phone: with shake_h l "对了。" l "你刚才说,你去便利店。" "他把手机塞回我手里。" l "下次撒谎,记得把味道也换了。" $ danger += 2
"他转身走进雨里。"
"走了两步,又停下。"
show lin smile at stand
with Dissolve(0.3)
l "明天,别迟到。"
"——我没告诉过他,我几点上课。"
hide lin
with Dissolve(0.4)
$ check_danger()
jump ch2
label ch2: scene bg school with fade
if AUDIO:
stop music fadeout 1.0
play music "school.ogg" fadein 1教室.5
"第二天。都"
"我的桌上,放着一份早餐。安静"
"还有一把伞。"
"——不是我昨天弄丢的那把,是新的。"
了 show shen normal at stand_right 。 with Dissolve(0.4)
shen "你的伞,昨天落在图书馆了。"
"他把一把伞放在我桌上。"
"和林砚送的那把,一模一样。"
n "喂,昨天有人来问过你的课表。"
n "就是三班那个林砚。"
n "他不是出了名的不理人吗……"
"话音未落。"
"教室门口安静了一瞬。"
hide shen
show lin dark at stand
with Dissolve(0.4)
"他站在那里。"
"目光落在我桌上。"
"两把一模一样的伞。"
with shake_s
l "……"
label q3: $ r = renpy.call_screen("timed_choice", question = "空气凝固了。", choices = [("解释", "explain"), ("沉默", "silent"), ("收下沈亦舟的伞", "take")], timeout = 5.0)
if r == "__timeout__":
jump q3_silent
elif r == "explain":
jump q3_explain
elif r == "take":
jump q3_take
else:
jump q3_silent
label q3_explain: mc "伞是沈亦舟还给我的。" mc "我昨天落在图书馆了。" $ aff += 2 $ danger += 1 "林砚看了沈亦舟一眼。" "那一眼很平。" "平得像一潭水,下面全是东西。" l "嗯。" l "知道了。" "他把自己的那把伞,收进了书包。" jump q3_menu
label q3_silent: "我什么都没说。" $ danger += 3 "他也没说。" "他只是走过来,把那两把伞,一起拿走了。" "一把扔进垃圾桶。" "一把放进我的桌肚。" l "以后,只准用我给的。" jump q3_menu
label q3_take: "我伸手,拿起了沈亦舟的那把。" with shake_h $ danger += 5 $ aff -= 2 "整个" "林砚笑了。" "那是我第一次见他笑得那么真。" l "……好。" l "真好。" "他转身走了。" "沈亦舟看了我一眼,欲言又止。" jump q3_menu
label q3_menu: $ check_danger()
menu:
"追出去,找林砚":
jump ch3_roof
"留下来,和沈亦舟说话":
$ aff_shen += 2
jump shen_route
label ch3_roof: scene bg roof with fade
if AUDIO:
stop music fadeout 1.0
play heartbeat "heartbeat.ogg" fadein 1.0
play music "dark.ogg" fadein 2.0
if is_ngplus():
$ unlock_memory("mem_3")
v "“他曾经在你教室后排,坐了一整个学期。”"
v "“你从来没回头。”"
"放学后,我在天台被他堵住。"
show lin close at stand
with Dissolve(0.5)
$ unlock_cg("cg_roof")
l "那把伞,你收了。"
"他的声音很轻。"
"轻得像在说一件和自己无关的事。"
l "我数过。"
l "从你收下那把伞,到现在,一共是四小时十七分钟。"
l "这四小时十七分钟里,我一直在想一件事。"
with shake_h
l "——要不要,把你锁起来。"
"风很大。"
"吹得我眼睛发酸。"
"我看着他。"
"他看着我。"
"然后我听见自己说——"
label ending_check: "[好感度 [aff] / 危险值 [danger]]" with Dissolve(0.5)
if danger >= 12 and aff < 8:
jump end_cage
elif danger >= 8 and aff >= 8:
jump end_co
elif aff >= 10 and danger < 8:
jump end_heal
else:
jump end_escape
label end_cage: scene bg black with fade if AUDIO: stop heartbeat fadeout 2.0
$ unlock_cg("cg_lock")
"他没让我回家。"
"我也没有反抗。"
"那扇门关上的时候,我听见自己心跳的声音。"
"很响。"
"响得像在鼓掌。"
$ unlock_ending("end_cage")
$ clear_playthrough()
"{color=#666666}—— END A · 笼{/color}"
return
label end_co: if AUDIO: stop heartbeat fadeout 1.5
$ unlock_cg("cg_rain2")
l "我们都有病。"
mc "我知道。"
l "那就一起病着。"
"他把我拉进怀里。"
"很用力。"
"用力到我几乎不能呼吸。"
if AUDIO:
play music "rain_loop.ogg" fadein 2.0
"雨又下起来了。"
"这一次,我没有躲。"
$ unlock_ending("end_co")
jump after_co
label end_heal: if AUDIO: stop heartbeat fadeout 2.0
mc "林砚。"
mc "你松手。"
l "……"
mc "然后我教你怎么好好爱人。"
"他愣住了。"
"很久很久。"
"久到我以为他不会回答了。"
"然后,他松开了手。"
if AUDIO:
play music "heal.ogg" fadein 2.0
"那天的风很轻。"
"他站在我面前,像一个终于学会呼吸的人。"
$ unlock_ending("end_heal")
$ clear_playthrough()
"{color=#8fa8d8}—— END C · 松手{/color}"
return
label end_escape: scene bg black with fade if AUDIO: stop heartbeat fadeout 2.0
"我转学了。"
"换了号码,换了城市。"
"半年后,我收到一封信。"
"没有署名。"
"只有一句话——"
"{color=#888888}“我还在找。”{/color}"
$ unlock_ending("end_escape")
$ clear_playthrough()
"{color=#666666}—— END D · 未读{/color}"
return
label shen_route: $ persistent.shen_unlocked = True
scene bg school
with fade
if AUDIO:
stop music fadeout 1.0
play music "shen.ogg" fadein 2.0
"林砚走了。"
"教室里的空气还没缓过来。"
show shen normal at stand_center
with Dissolve(0.4)
shen "……你还好吗?"
"沈亦舟的声音很轻。"
"轻得像怕惊动什么。"
mc "……嗯。"
shen "那把伞,是我多事了。"
shen "对不起。"
"他垂下眼睛。"
"睫毛很长,投下一小片阴影。"
menu:
"安慰他":
$ aff_shen += 2
mc "不是你的错。"
shen "……谢谢。"
"他抬起头,笑了一下。"
"很干净的笑。"
"干净得让人放心。"
"问他怎么知道我的课表":
$ aff_shen += 3
$ danger += 1
mc "你怎么知道我伞落在图书馆了?"
shen "……"
"他没有马上回答。"
shen "我经常看到你。"
shen "在各种地方。"
shen "你可能没注意到我。"
"他顿了顿。"
shen "不过没关系。"
shen "我记得就够了。"
$ check_danger()
jump shen_ch2
label shen_ch2: scene bg school with fade
if AUDIO:
stop music fadeout 1.0
play music "shen.ogg" fadein 2.0
"接下来的三天。"
"林砚没来上课。"
"沈亦舟开始出现在我身边。"
show shen normal at stand_center
with Dissolve(0.4)
shen "书库缺人整理,你要来吗?"
shen "只有我们两个人。"
shen "很安静。"
menu:
"答应":
$ aff_shen += 2
jump shen_library
"拒绝":
$ aff_shen -= 1
$ danger += 1
mc "不了,我还有事。"
"他笑了一下。"
shen "……好。"
shen "那明天呢?"
shen "后天?"
shen "总有一天你会有空的。"
"他语气温和。"
"温和得让人无法拒绝。"
$ aff_shen += 1
jump shen_library
label shen_library: scene bg door with fade
"书库在最顶层。"
"没有窗,只有一盏旧灯。"
"门关上时,声音很轻。"
show shen normal at stand_center
with Dissolve(0.5)
$ unlock_cg("cg_shen")
shen "给你。"
"他递给我一本书。"
"封面很旧。"
"《如何照顾一个人》。"
mc "……这是什么?"
shen "我看的书。"
shen "从很久以前就开始看了。"
shen "因为我想知道,怎么才能让别人不离开我。"
"他看着我。"
"眼神安静得可怕。"
shen "林砚那套方法,是错的。"
shen "锁住一个人,只会让她想逃。"
shen "我不会那样。"
shen "我会让你自己走回来。"
menu:
"问他为什么是我":
$ aff_shen += 2
mc "为什么是我?"
shen "因为你从来不看别人。"
shen "你只看着自己脚下。"
shen "所以我想成为,你抬头时看见的第一个人。"
"站起来想走":
$ danger += 2
"我站起来。"
"他没有拦我。"
"只是轻轻说了一句——"
shen "门锁了。"
shen "别急。"
shen "我们还有时间。"
"靠近他":
$ aff_shen += 3
$ danger += 1
"我往前走了一步。"
"他愣了一下。"
shen "……你不怕?"
mc "不怕。"
shen "那你很快就要怕了。"
"他伸手,指尖碰到我的发梢。"
shen "因为我会比林砚,更慢,更久。"
$ check_danger()
jump shen_ch3
label shen_ch3: scene bg roof with fade
if AUDIO:
stop music fadeout 1.0
play heartbeat "heartbeat.ogg" fadein 1.0
play music "tense.ogg" fadein 2.0
"第二天。"
"天台的门被人从外面推开。"
show shen normal at stand_right
with Dissolve(0.4)
shen "你来了。"
show lin dark at stand_left
with Dissolve(0.4)
l "……你们,在这里做什么。"
"两个人都没有看对方。"
"都在看我。"
with shake_s
l "过来。"
shen "别过去。"
"空气里像有电流。"
label shen_final_choice: $ r = renpy.call_screen("timed_choice", question = "只有 4 秒。", choices = [("走向林砚", "lin"), ("走向沈亦舟", "shen"), ("谁都不走", "none")], timeout = 4.0)
if r == "__timeout__":
jump shen_none
elif r == "lin":
jump shen_lin
elif r == "shen":
jump shen_shen
else:
jump shen_none
label shen_lin: $ danger += 2 $ aff += 2 "我走向林砚。" show shen dark at stand_right shen "……" "沈亦舟笑了。" shen "好。" shen "那我等。" shen "我最擅长的,就是等。" hide shen with Dissolve(0.4) l "……你选了我。" l "那就别后悔。" jump end_co
label shen_shen: $ aff_shen += 3 $ aff -= 1 "我走向沈亦舟。" show lin dark at stand_left "林砚没有动。" l "……嗯。" l "我知道了。" "他转身。" "背影很直。" hide lin with Dissolve(0.4) shen "谢谢。" shen "你放心。" shen "我不会像他那样。" shen "我会让你,慢慢地,再也走不掉。" jump end_shen_a
label shen_none: "我没有动。" "谁都没有走。" with shake_h l "……你想清楚了。" shen "我也一样。" "两个人几乎同时说话。" "然后同时沉默。" "风很大。" "我听见自己心跳的声音。"
if aff_shen >= 6:
jump end_shen_a
else:
jump end_shen_b
label end_shen_a: scene bg black with fade $ unlock_ending("end_shen_a") if AUDIO: stop heartbeat fadeout 2.0 play music "shen.ogg" fadein 2.0
"后来我搬进了沈亦舟住的那条街。"
"每天他都会在楼下等我。"
"风雨无阻。"
"他的伞,永远比我大一点。"
"他的步子,永远比我慢半步。"
"他说这样可以看着我。"
"我说好。"
"很久以后,我才意识到——"
"我已经想不起来,自己上次一个人出门,是什么时候了。"
$ clear_playthrough()
"{color=#a8d8a8}—— END E · 书页{/color}"
return
label end_shen_b: scene bg black with fade $ unlock_ending("end_shen_b") if AUDIO: stop heartbeat fadeout 2.0
"那天以后,沈亦舟再也没出现在我身边。"
"林砚也没有。"
"两个人都像从未存在过。"
"只有一件事变了。"
"我再也没有一个人走过夜路。"
"因为我总觉得——"
"身后还有脚步声。"
$ clear_playthrough()
"{color=#d8d8a8}—— END F · 空白{/color}"
return
label after_co: scene bg black with fade
if AUDIO:
stop heartbeat fadeout 2.0
play music "rain_loop.ogg" fadein 2.0
"从那天起,我和林砚住在了同一个屋檐下。"
"他没锁门。"
"但他没收了我的伞。"
scene bg door
with fade
show lin normal at stand_center
with Dissolve(0.5)
"第一周,一切正常。"
"他做饭,我洗碗。"
"他送我上学,接我回家。"
"像一对普通情侣。"
"第二周,我开始发现——"
"家里的窗帘,从来没有拉开过。"
l "外面太吵。"
l "你不觉得吗?"
menu:
"附和他":
$ aff += 1
$ danger += 1
mc "……嗯。"
"他笑了。"
l "乖。"
"拉开窗帘":
$ danger += 2
$ aff -= 1
"我走到窗边。"
"伸手。"
with shake_s
"他按住我的手。"
l "别。"
l "光太亮。"
l "你会看清楚很多东西。"
l "看了,就回不去了。"
jump after_ch2
label after_ch2: scene bg school with fade
if AUDIO:
stop music fadeout 1.0
play music "tense.ogg" fadein 2.0
"那天在学校,有人塞给我一封信。"
"没有署名。"
"里面只有一句话——"
v "“他还好吗?”"
"字迹很干净。"
"像刚洗过的手。"
show lin dark at stand_center
with Dissolve(0.4)
"放学的时候,林砚站在校门口。"
"手里拿着一把新伞。"
"和信纸一样的颜色。"
l "今天有人给你东西了吗。"
menu:
"说实话":
$ aff += 2
mc "……有。一封信。"
"他看了我很久。"
l "……很好。"
l "你学会不骗我了。"
l "这封信,我不追究。"
l "但有下一次——"
"他没说完。"
"说没有":
$ danger += 3
mc "没有。"
"他笑了。"
"笑得比雨还冷。"
l "……嗯。"
l "那就当没有。"
"他把伞递给我。"
"伞柄上,绕着一根头发。"
"是下午那封信上的,颜色。"
$ unlock_cg("cg_after")
$ check_danger()
jump after_ch3
label after_ch3: scene bg black with fade
if AUDIO:
stop heartbeat "heartbeat.ogg" fadein 1.0
"那天晚上,我做了一个梦。"
"梦里有人问我——"
v "“你为什么不走?”"
"我想了很久。"
"然后我听见自己说——"
menu:
"“因为我怕他一个人。”":
$ aff += 2
jump after_end_soft
"“因为我不知道还能去哪。”":
$ danger += 2
jump after_end_hard
"“因为我想看看,他到底能坏到什么程度。”":
$ danger += 4
$ aff += 1
jump after_end_dark
label after_end_soft: scene bg black with fade $ unlock_ending("end_after") if AUDIO: stop heartbeat fadeout 2.0 play music "heal.ogg" fadein 2.0
"我醒来的时候,他坐在床边。"
"眼睛是红的。"
"像一夜没睡。"
show lin normal at stand_center
with Dissolve(0.5)
l "……你说梦话了。"
mc "我说什么了?"
l "你说,你怕我一个人。"
"他低下头。"
l "……对不起。"
"那是他第一次道歉。"
"也许有些病,可以一起治好。"
"也许不行。"
"但至少今天早上——"
"窗帘,是拉开的。"
$ clear_playthrough()
"{color=#e0c8a0}—— END G · 还早{/color}"
return
label after_end_hard: scene bg black with fade $ unlock_ending("end_hard")
"我醒来的时候,房间是空的。"
"桌上放着一把钥匙,和一张纸。"
"纸上只有一行字——"
v "“去吧。”"
"我拿起钥匙。"
"走到门口。"
"门没有锁。"
"我推开门。"
"外面是雨。"
"很大。"
"我站了很久。"
"最后,我把门又关上了。"
$ clear_playthrough()
"{color=#666666}—— END H · 门外{/color}"
return
label after_end_dark: scene bg black with fade $ unlock_ending("end_dark") if AUDIO: stop heartbeat fadeout 1.0 play music "dark.ogg" fadein 2.0
"他在黑暗里笑出了声。"
"很轻。"
show lin dark at stand_center
with Dissolve(0.5)
l "……你终于,和我一样了。"
"他伸手,摸到我的脸。"
l "别怕。"
l "我不会让你出去的。"
l "但我也不会一个人出去。"
"那扇门,从那以后,再也没有打开过。"
$ clear_playthrough()
"{color=#3a1e1e}—— END I · 同归{/color}"
return
label be_break: scene bg black with fade if AUDIO: stop music fadeout 1.0 play music "dark.ogg" fadein 2.0
"我听见什么东西断了。"
"不是骨头。"
"是比骨头更里面的东西。"
"他站在门口,背对着光。"
"看不清表情。"
v "“你不该走到这一步的。”"
v "“但既然到了——”"
with shake_h
"门合上了。"
"声音很轻。"
$ unlock_ending("be_break")
$ clear_playthrough()
"{color=#8a1e1e}—— BAD END · 崩{/color}"
return
label be_lock: scene bg black with fade if AUDIO: stop music fadeout 1.0 play music "dark.ogg" fadein 2.0
"钥匙落进雨里的声音,很轻。"
"轻得像一句告白。"
"他没有回头。"
"我也没有喊。"
v "“从今天起,你不用再走出去了。”"
v "“外面太危险。”"
with shake_h
"窗帘再也没有拉开过。"
"日历停在那一天。"
"我们都没有提过‘以后’这两个字。"
$ unlock_ending("be_lock")
$ clear_playthrough()
"{color=#3a0a0a}—— BAD END · 锁{/color}"
return