《小猪快跑》小游戏

发布时间:2026/10/8 22:54:12
《小猪快跑》小游戏
游戏代码# -*- coding: utf-8 -*-《小猪快跑》桌面版启动器用系统 WebView2(Edge) 内核加载游戏页面。import osimport sysimport webviewdef resource_path(name):base getattr(sys, _MEIPASS, None) or os.path.dirname(os.path.abspath(__file__))return os.path.join(base, name)def main():html resource_path(index.html)webview.create_window(小猪快跑 · 100关大冒险,html,width980, height640,min_size(900, 600),text_selectFalse,)# private_modeFalse 让 localStorage关卡进度/装扮/最高分持久保存webview.start(private_modeFalse, storage_pathos.path.join(os.environ.get(APPDATA, os.path.expanduser(~)), PigRunGame))if __name__ __main__:main()游戏音乐代码# -*- coding: utf-8 -*- 生成《小猪快跑》背景音乐 WAV 文件原创 chiptune《小猪波尔卡》 与游戏内 Web Audio 播放的是同一首曲子C大调、132bpm、8小节循环。 import math import wave import struct import random SR 44100 BPM 132 STEP 60 / BPM / 2 # 八分音符时长 NOTE_OFFSETS {C: 0, C#: 1, D: 2, D#: 3, E: 4, F: 5, F#: 6, G: 7, G#: 8, A: 9, A#: 10, B: 11} def freq(name): octv int(name[-1]) semi NOTE_OFFSETS[name[:-1]] return 440.0 * 2 ** ((octv - 4) * 12 semi - 9) / 4 MELODY [ E5,G5,C6,None,G5,None,E5,C5, A4,C5,E5,None,C5,None,A4,None, F5,A5,C6,A5,F5,A5,C6,A5, D5,G5,B5,G5,D5,G5,B5,G5, E5,G5,C6,None,B5,A5,G5,E5, A5,None,C6,B5,A5,G5,E5,D5, F5,G5,A5,None,C6,None,A5,G5, G5,A5,B5,None,D6,None,B5,G5, ] BASSROOT [C3,A2,F2,G2,C3,A2,F2,G2] random.seed(20260915) def osc_tri(p): # 三角波 return 2 * abs(2 * ((p % 1.0) - 0.5)) - 1 def osc_sq(p): # 方波 return 1.0 if (p % 1.0) 0.5 else -1.0 def osc_sin(p): return math.sin(2 * math.pi * p) def render(): total_steps len(MELODY) * 2 # 循环两遍 ≈ 29 秒 total int(total_steps * STEP * SR) SR // 4 buf [0.0] * total def add(start_t, samples, gain): i0 int(start_t * SR) for i, v in enumerate(samples): j i0 i if j total: buf[j] v * gain def note_wave(f, dur, kind, env.95): n int(dur * SR) out [] for i in range(n): p i / SR * f v osc_tri(p) if kind tri else osc_sq(p) e max(0.0, 1.0 - i / n * env) out.append(v * e) return out def oink(start_t): # 小猪哼哧快速下滑锯齿音 dur .2 n int(dur * SR) out [] for i in range(n): t i / SR f 700 * math.exp(-t * 9) 180 v osc_sin(f * t) e max(0.0, 1.0 - t / dur) out.append(v * e) add(start_t, out, .30) def kick(start_t): dur .15 n int(dur * SR) out [] for i in range(n): t i / SR f 110 * math.exp(-t * 22) 38 out.append(osc_sin(f * t) * max(0.0, 1 - t / dur)) add(start_t, out, .5) def snare(start_t): dur .09 n int(dur * SR) out [] for i in range(n): t i / SR out.append((random.random() * 2 - 1) * max(0.0, 1 - t / dur)) add(start_t, out, .18) def hat(start_t): dur .03 n int(dur * SR) out [] for i in range(n): t i / SR out.append((random.random() * 2 - 1) * max(0.0, 1 - t / dur)) add(start_t, out, .05) for step in range(total_steps): t step * STEP s step % 64 m MELODY[s] if m: add(t, note_wave(freq(m), STEP * .95, tri), .34) root freq(BASSROOT[s // 8]) bf root if s % 2 0 else root * 2 add(t, note_wave(bf, STEP * .85, sq), .13) if s % 8 in (0, 4): kick(t) if s % 8 in (2, 6): snare(t) hat(t) if s % 32 24: oink(t) # 轻限幅 淡出结尾 fade SR for i in range(total): v buf[i] v math.tanh(v * .9) if i total - fade: v * (total - i) / fade buf[i] v return buf def main(): data render() out 小猪快跑主题曲_小猪波尔卡.wav with wave.open(out, w) as w: w.setnchannels(1) w.setsampwidth(2) w.setframerate(SR) frames b.join(struct.pack(h, int(max(-1, min(1, v)) * 32767)) for v in data) w.writeframes(frames) print(OK -, out, f{len(data)/SR:.1f}s) if __name__ __main__: main()