diff -ruN a/project.godot b/project.godot --- a/project.godot 2026-11-06 23:45:39.935400473 -0300 +++ b/project.godot 2026-11-06 23:45:39.967371359 -0300 @@ -4,7 +4,7 @@ config/icon="res://assets/icon.png" boot_splash/image="res://assets/splash.png" boot_splash/bg_color=Color(0.027,0.082,0.13,1) -config/name="VECTOR RUSH · 反重力竞速" +config/name="Vector Rush" run/main_scene="res://main.tscn" config/features=PackedStringArray("4.7", "GL Compatibility") [display] diff -ruN a/scripts/content.gd b/scripts/content.gd --- a/scripts/content.gd 2026-11-06 23:45:39.922534643 -0300 +++ b/scripts/content.gd 2026-11-06 23:45:39.967081564 -0300 @@ -1,12 +1,12 @@ class_name RushContent extends RefCounted const TRACKS = [ - {'name':'霓虹海港','en':'NEON HARBOR','tag':'港区穿梭 · 高墙磁轨','length':'3.17 km','description':'沿港区上升,贴着高楼掠过云端。','gold':82.0,'silver':98.0,'bronze':128.0}, - {'name':'天穹回旋','en':'SKYLINE SPIRAL','tag':'高空盘旋 · 连续反向弯','length':'高空技术赛道','description':'在不断变化的倾角中保持漂移节奏。','gold':89.0,'silver':110.0,'bronze':145.0}, - {'name':'暮光疾驰','en':'TWILIGHT RUN','tag':'高速长直道 · 夜色冲刺','length':'高速耐力赛道','description':'收集赛道能量,在长直道用尽氮气。','gold':95.0,'silver':118.0,'bronze':155.0} + {'name':'Neon Harbor','en':'NEON HARBOR','tag':'Harbor run · high-wall magnetic track','length':'3.17 km','description':'Climb through the harbor and skim past the towers into the clouds.','gold':82.0,'silver':98.0,'bronze':128.0}, + {'name':'Skyline Spiral','en':'SKYLINE SPIRAL','tag':'High spirals · reversing bends','length':'High-altitude technical track','description':'Keep your drift rhythm as the banking keeps changing.','gold':89.0,'silver':110.0,'bronze':145.0}, + {'name':'Twilight Run','en':'TWILIGHT RUN','tag':'Long fast straights · night sprint','length':'High-speed endurance track','description':'Collect track energy and burn it all on the long straights.','gold':95.0,'silver':118.0,'bronze':155.0} ] const SHIPS = [ - {'name':'ARC–01','role':'均衡型','detail':'稳定的操控与充足的动力,适合所有赛道。','speed':104.0,'accel':20.0,'steer':42.0,'armor':1.0,'color':Color(.05,.75,1),'model':'res://assets/arc01.glb','stars':0}, - {'name':'KITE–02','role':'敏捷型','detail':'更轻巧的横向响应,适合连续弯道与漂移。','speed':101.0,'accel':25.0,'steer':53.0,'armor':1.16,'color':Color(1,.32,.075),'model':'res://assets/kite02.glb','stars':2}, - {'name':'ONYX–03','role':'高速型','detail':'更高的尾速和更强护盾,需要提前规划线路。','speed':114.0,'accel':17.0,'steer':36.0,'armor':.73,'color':Color(.62,.32,1),'model':'res://assets/onyx03.glb','stars':4} + {'name':'ARC–01','role':'Balanced','detail':'Stable handling and plenty of power, good on every track.','speed':104.0,'accel':20.0,'steer':42.0,'armor':1.0,'color':Color(.05,.75,1),'model':'res://assets/arc01.glb','stars':0}, + {'name':'KITE–02','role':'Agile','detail':'Lighter sideways response, great for linked corners and drifting.','speed':101.0,'accel':25.0,'steer':53.0,'armor':1.16,'color':Color(1,.32,.075),'model':'res://assets/kite02.glb','stars':2}, + {'name':'ONYX–03','role':'Fast','detail':'Higher top speed and a stronger shield; plan your line early.','speed':114.0,'accel':17.0,'steer':36.0,'armor':.73,'color':Color(.62,.32,1),'model':'res://assets/onyx03.glb','stars':4} ] diff -ruN a/scripts/hud.gd b/scripts/hud.gd --- a/scripts/hud.gd 2026-11-06 23:45:39.897603407 -0300 +++ b/scripts/hud.gd 2026-11-06 23:45:39.964187371 -0300 @@ -42,34 +42,34 @@ func menu(mode: String): for c in panel.get_children():panel.remove_child(c);c.queue_free() if mode=='menu': - button('开始比赛 / ENTER',Vector2(64,527),Vector2(410,63),game.start_race,true) - button('新手练习 / 一圈掌握驾驶',Vector2(64,605),Vector2(410,52),game.start_practice) - button('赛道',Vector2(64,682),Vector2(127,49),func():game.open_panel('tracks')) - button('机库',Vector2(205,682),Vector2(127,49),func():game.open_panel('garage')) - button('设置',Vector2(346,682),Vector2(128,49),func():game.open_panel('settings')) + button('Start Race / ENTER',Vector2(64,527),Vector2(410,63),game.start_race,true) + button('Practice Lap',Vector2(64,605),Vector2(410,52),game.start_practice) + button('Tracks',Vector2(64,682),Vector2(127,49),func():game.open_panel('tracks')) + button('Hangar',Vector2(205,682),Vector2(127,49),func():game.open_panel('garage')) + button('Settings',Vector2(346,682),Vector2(128,49),func():game.open_panel('settings')) elif mode in ['garage','tracks']: - button('返回主界面 / ESC',Vector2(64,790),Vector2(300,54),game.main_menu) + button('Main Menu / ESC',Vector2(64,790),Vector2(300,54),game.main_menu) for i in range(3): var unlocked=game.track_unlocked(i) if mode=='tracks' else game.vehicle_unlocked(i) var selected=(game.selected_track if mode=='tracks' else game.selected_vehicle)==i - button('已选择' if selected else '选择赛道' if mode=='tracks' and unlocked else '驾驶这架飞行器' if unlocked else '尚未解锁',Vector2(86+i*438,661),Vector2(358,56),(func():game.select_track(i)) if mode=='tracks' else (func():game.select_vehicle(i)),unlocked,not unlocked) + button('Selected' if selected else 'Select Track' if mode=='tracks' and unlocked else 'Fly This Craft' if unlocked else 'Locked',Vector2(86+i*438,661),Vector2(358,56),(func():game.select_track(i)) if mode=='tracks' else (func():game.select_vehicle(i)),unlocked,not unlocked) elif mode=='settings': - button('返回主界面 / ESC',Vector2(64,790),Vector2(300,54),game.main_menu) - check('辅助油门',Vector2(115,249),game.auto_throttle,game.set_auto) - check('声音',Vector2(115,325),game.sound_on,func(v):game.sound_on=v;game.apply_sound();game.save_settings()) + button('Main Menu / ESC',Vector2(64,790),Vector2(300,54),game.main_menu) + check('Auto Throttle',Vector2(115,249),game.auto_throttle,game.set_auto) + check('Sound',Vector2(115,325),game.sound_on,func(v):game.sound_on=v;game.apply_sound();game.save_settings()) var slider=HSlider.new();panel.add_child(slider);slider.position=Vector2(120,436);slider.size=Vector2(360,30);slider.min_value=0;slider.max_value=1;slider.step=.01;slider.value=game.volume;slider.value_changed.connect(game.set_volume) - choice(['休闲 · 从容熟悉线路','标准 · 旗鼓相当的对手','专家 · 每个弯道都算数'],Vector2(120,519),game.difficulty,game.set_difficulty) - choice(['流畅 · 无多重采样','均衡 · 2× 抗锯齿','精细 · 4× 抗锯齿'],Vector2(120,635),game.quality,game.set_quality) + choice(['Casual · learn the lines','Standard · fair rivals','Expert · every corner counts'],Vector2(120,519),game.difficulty,game.set_difficulty) + choice(['Smooth · no MSAA','Balanced · 2x MSAA','Fine · 4x MSAA'],Vector2(120,635),game.quality,game.set_quality) elif mode=='paused': - button('继续比赛',Vector2(520,380),Vector2(400,60),game.resume_race,true) - button('重新开始',Vector2(520,455),Vector2(400,60),game.restart_race) - button('返回主界面',Vector2(520,530),Vector2(400,60),game.main_menu) + button('Resume Race',Vector2(520,380),Vector2(400,60),game.resume_race,true) + button('Restart',Vector2(520,455),Vector2(400,60),game.restart_race) + button('Main Menu',Vector2(520,530),Vector2(400,60),game.main_menu) elif mode=='finished': - button('开始正式比赛' if game.practice else '再跑一次 / ENTER',Vector2(520,619),Vector2(400,60),game.start_race,true) - button('返回主界面',Vector2(520,694),Vector2(400,55),game.main_menu) + button('Start Real Race' if game.practice else 'Race Again / ENTER',Vector2(520,619),Vector2(400,60),game.start_race,true) + button('Main Menu',Vector2(520,694),Vector2(400,55),game.main_menu) func _process(_delta):queue_redraw() -func medal_name(value: int) -> String:return ['未获奖牌','铜牌','银牌','金牌'][clampi(value,0,3)] +func medal_name(value: int) -> String:return ['No medal','Bronze','Silver','Gold'][clampi(value,0,3)] func miniature(route: RushTrack,center: Vector2,scale_value: float,color: Color): var previous=Vector2.ZERO for i in range(0,route.points.size(),10): @@ -84,21 +84,21 @@ draw_rect(Rect2(0,0,570,h),Color(.015,.035,.065,.93)) draw_line(Vector2(64,73),Vector2(118,73),nitro_color,3);write('A N T I G R A V I T Y L E A G U E',Vector2(135,80),15,muted) write('VECTOR',Vector2(60,222),91,white,true);write('RUSH',Vector2(60,322),105,nitro_color,true) - write('反重力竞速',Vector2(66,372),27,white) - write('离开地面。追上极限。',Vector2(66,444),25,white) - write('贴墙过弯 / 漂移蓄能 / 氮气超车',Vector2(66,483),18,muted) - write('WASD 驾驶 SPACE 漂移 SHIFT 氮气',Vector2(66,780),17,muted) - write('3 条赛道 · 3 架飞行器 · 奖牌解锁生涯',Vector2(66,817),17,muted) - card(Rect2(974,48,406,137),.8);write(Content.TRACKS[game.selected_track].en,Vector2(999,83),20,nitro_color,true) + write('ANTI-GRAVITY RACING',Vector2(66,372),27,white) + write('Leave the ground. Chase the limit.',Vector2(66,444),25,white) + write('Wall-ride / charge drifts / nitro overtakes',Vector2(66,483),18,muted) + write('WASD drive SPACE drift SHIFT nitro',Vector2(66,780),17,muted) + write('3 tracks · 3 craft · medal-unlock career',Vector2(66,817),17,muted) + card(Rect2(974,48,406,137),.8);write('TRACK 0%d'%(game.selected_track+1),Vector2(999,83),20,nitro_color,true) write(Content.TRACKS[game.selected_track].name+' / '+Content.SHIPS[game.selected_vehicle].name,Vector2(999,122),23,white,true) - write('奖牌点 %d / 9 · %s'%[game.career_points,Content.SHIPS[game.selected_vehicle].role],Vector2(999,158),16,muted) - if game.best_time>0:write('个人最佳 '+game.format_time(game.best_time),Vector2(1030,840),21,white) + write('Medal points %d / 9 · %s'%[game.career_points,Content.SHIPS[game.selected_vehicle].role],Vector2(999,158),16,muted) + if game.best_time>0:write('Best '+game.format_time(game.best_time),Vector2(1030,840),21,white) return if game.state in ['garage','tracks','settings']: draw_rect(Rect2(0,0,w,h),Color(.013,.03,.05,.96)) write('VECTOR RUSH / '+{'garage':'HANGAR','tracks':'CIRCUITS','settings':'PREFERENCES'}[game.state],Vector2(65,74),17,nitro_color) - write({'garage':'选择你的飞行器','tracks':'下一条极限在哪里','settings':'找到自己的驾驶节奏'}[game.state],Vector2(64,140),40,white,true) - write('奖牌点 %d / 9'%game.career_points,Vector2(1170,135),22,gold) + write({'garage':'Choose your craft','tracks':'Where is the next limit?','settings':'Find your own rhythm'}[game.state],Vector2(64,140),40,white,true) + write('Medals %d / 9'%game.career_points,Vector2(1170,135),22,gold) if game.state=='settings':draw_settings() else: for i in range(3):draw_selection_card(i,game.state=='tracks') @@ -106,20 +106,20 @@ return # Race instruments occupy the edges, keeping the road clear. card(Rect2(26,24,278,89),.86);write('VECTOR RUSH',Vector2(44,55),20,white,true) - write('练习圈 / 1' if game.practice else 'LAP %d / 3'%mini(3,int(game.distance/game.track.length)+1),Vector2(44,94),23,nitro_color,true) - card(Rect2(w-292,24,266,89),.86);write(game.format_time(game.race_time),Vector2(w-274,71),34,white,true);write('比赛用时',Vector2(w-270,97),13,muted) + write('PRACTICE / 1' if game.practice else 'LAP %d / 3'%mini(3,int(game.distance/game.track.length)+1),Vector2(44,94),23,nitro_color,true) + card(Rect2(w-292,24,266,89),.86);write(game.format_time(game.race_time),Vector2(w-274,71),34,white,true);write('RACE TIME',Vector2(w-270,97),13,muted) if not game.practice:write('%d'%game.rank,Vector2(w*.5-36,73),49,white,true);write('/ 4',Vector2(w*.5+14,71),20,muted) var p=Vector2(145,h-133) draw_arc(p,88,PI*.8,PI*2.2,70,Color(.15,.24,.30,.8),7,true) draw_arc(p,88,PI*.8,PI*.8+PI*1.4*clampf(game.speed/170,0,1),70,nitro_color if not game.boosting else Color(1,.35,.13),7,true) write('%03d'%int(game.speed*3.6),p+Vector2(-58,13),54,white,true);write('KM/H',p+Vector2(-26,43),17,muted) write(Content.SHIPS[game.selected_vehicle].name,Vector2(85,h-30),16,muted) - write('氮气冷却中' if game.exhausted else '氮气 / SHIFT',Vector2(w-280,h-151),18,nitro_color) + write('NITRO COOLING' if game.exhausted else 'NITRO / SHIFT',Vector2(w-280,h-151),18,nitro_color) draw_rect(Rect2(w-280,h-129,236,8),Color(.14,.23,.29));draw_rect(Rect2(w-280,h-129,236*game.energy/100,8),nitro_color) - write('护盾',Vector2(w-280,h-90),16,muted);draw_rect(Rect2(w-220,h-102,176,5),Color(.14,.23,.29));draw_rect(Rect2(w-220,h-102,176*game.shield/100,5),Color(.9,.63,.36)) - write('SPACE 漂移 ESC 暂停 R 重赛',Vector2(w-337,h-30),15,muted) + write('Shield',Vector2(w-280,h-90),16,muted);draw_rect(Rect2(w-220,h-102,176,5),Color(.14,.23,.29));draw_rect(Rect2(w-220,h-102,176*game.shield/100,5),Color(.9,.63,.36)) + write('SPACE drift ESC pause R restart',Vector2(w-337,h-30),15,muted) if game.drifting: - centered('蓄能 II / 松开释放' if game.drift_charge>1.35 else '漂移蓄能 / 松开释放',h-150,23,gold if game.drift_charge>1.35 else nitro_color,true) + centered('CHARGE II / release' if game.drift_charge>1.35 else 'Charging drift / release',h-150,23,gold if game.drift_charge>1.35 else nitro_color,true) draw_rect(Rect2(610,h-128,220,5),Color(.14,.23,.29));draw_rect(Rect2(610,h-128,220*game.drift_charge/2.5,5),gold if game.drift_charge>1.35 else nitro_color) elif game.boosting: centered('OVERDRIVE',h-145,31,Color(1,.43,.18),true) @@ -136,11 +136,11 @@ var pos=game.track.pose(rival.s).origin;draw_circle(base+Vector2(pos.x,pos.z)*.126,3,Color(1,.42,.19)) if game.hit_flash>0:draw_rect(Rect2(0,0,w,h),Color(1,.16,.035,game.hit_flash*.19)) if game.state=='countdown': - centered(str(ceili(game.countdown)),h/2,112,white,true);centered('跟随青色磁轨 · 避开橙色障碍',h/2+55,22) + centered(str(ceili(game.countdown)),h/2,112,white,true);centered('Follow the cyan track · avoid the orange hazards',h/2+55,22) if game.state in ['paused','finished']: draw_rect(Rect2(0,0,w,h),Color(.008,.02,.035,.80));card(Rect2(465,182,510,600 if game.state=='finished' else 448),.98) if game.state=='paused': - centered('比赛已暂停',301,38,white,true);centered('呼吸一下,赛道会等你。',341,18,muted) + centered('Race Paused',301,38,white,true);centered('Take a breath. The track will wait.',341,18,muted) else:draw_finish() func draw_selection_card(index: int,is_track: bool): @@ -151,9 +151,9 @@ var spec=Content.TRACKS[index] miniature(game.menu_tracks[index],Vector2(x+205,359),.21,nitro_color if unlocked else muted) write(spec.name,Vector2(x+24,495),29,white,true);write(spec.tag,Vector2(x+24,530),17,muted) - write('金 %ds 银 %ds 铜 %ds'%[spec.gold,spec.silver,spec.bronze],Vector2(x+24,565),17,gold) + write('Gold %ds Silver %ds Bronze %ds'%[spec.gold,spec.silver,spec.bronze],Vector2(x+24,565),17,gold) var record=game.records.get(str(index),{}) - write(('最佳 '+game.format_time(float(record.get('time',0)))+' / '+medal_name(record.get('medal',0))) if record else '尚未挑战' if unlocked else '上一赛道获得铜牌后解锁',Vector2(x+24,609),17,muted) + write(('Best '+game.format_time(float(record.get('time',0)))+' / '+medal_name(record.get('medal',0))) if record else 'Not attempted' if unlocked else 'Needs bronze on the previous track',Vector2(x+24,609),17,muted) else: var spec=Content.SHIPS[index];var color=spec.color # A schematic makes geometry and role readable even before unlocking. @@ -161,34 +161,34 @@ var vertices=PackedVector2Array([Vector2(0,-75),Vector2(25,-17),Vector2(83,-8),Vector2(93,55),Vector2(40,33),Vector2(0,53),Vector2(-40,33),Vector2(-93,55),Vector2(-83,-8),Vector2(-25,-17)]) for j in range(vertices.size()):vertices[j]=center+vertices[j]*stretch draw_colored_polygon(vertices,Color(color,.14));vertices.append(vertices[0]);draw_polyline(vertices,color,2.5,true);draw_line(center+Vector2(0,-45),center+Vector2(0,17),color,5,true) - write(spec.name,Vector2(x+24,484),30,white,true);write(spec.role+' / '+str(int(spec.speed*3.6))+' KM/H 巡航',Vector2(x+24,520),18,color) + write(spec.name,Vector2(x+24,484),30,white,true);write(spec.role+' / '+str(int(spec.speed*3.6))+' KM/H cruise',Vector2(x+24,520),18,color) for k in range(3): var value=[spec.speed/120.0,spec.steer/60.0,(2.0-spec.armor)/1.4][k] - write(['极速','转向','护盾'][k],Vector2(x+24,558+k*26),15,muted);draw_rect(Rect2(x+86,548+k*26,263,5),Color(.13,.2,.26));draw_rect(Rect2(x+86,548+k*26,263*value,5),color) - write('已解锁' if unlocked else '需要 %d 奖牌点 · 金3 / 银2 / 铜1'%spec.stars,Vector2(x+24,643),15,muted) + write(['Speed','Steer','Shield'][k],Vector2(x+24,558+k*26),15,muted);draw_rect(Rect2(x+86,548+k*26,263,5),Color(.13,.2,.26));draw_rect(Rect2(x+86,548+k*26,263*value,5),color) + write('Unlocked' if unlocked else 'Needs %d medal points · G3 S2 B1'%spec.stars,Vector2(x+24,643),15,muted) func draw_settings(): card(Rect2(64,206,480,535));card(Rect2(581,206,795,535)) - write('音量 %d%%'%int(game.volume*100),Vector2(121,413),18,muted);write('对手难度',Vector2(121,505),18,muted);write('画面质量',Vector2(121,619),18,muted) - write('驾驶指南',Vector2(617,259),27,white,true) - var lines=['W / ↑ 加速(辅助油门开启时自动加速)','S / ↓ 刹车,急弯前降低入弯速度','A D / ← → 转向,贴近弯道内侧寻找线路','SPACE 弯中按住漂移,松开释放蓄能','SHIFT 消耗氮气,直道超车','ESC 暂停 R 重新比赛 F11 全屏'] + write('Volume %d%%'%int(game.volume*100),Vector2(121,413),18,muted);write('Rival difficulty',Vector2(121,505),18,muted);write('Graphics quality',Vector2(121,619),18,muted) + write('Driving guide',Vector2(617,259),27,white,true) + var lines=['W / ↑ accelerate (automatic with auto throttle)','S / ↓ brake; slow down before sharp corners','A D / ← → steer; hug the inside of the bend','SPACE hold in a corner to drift, release to cash in','SHIFT spend nitro to overtake on straights','ESC pause R restart F11 fullscreen'] for i in range(lines.size()):write(lines[i],Vector2(617,310+i*42),19,white) - write('手柄:左摇杆转向 · A 漂移 · RB 氮气',Vector2(617,601),18,nitro_color) - write('青色加速带补充氮气。橙色障碍会损伤护盾。',Vector2(617,647),18,muted) - write('护盾归零会返回检查点,计时增加 3 秒。',Vector2(617,683),18,muted) + write('Gamepad: left stick steers · A drifts · RB nitro',Vector2(617,601),18,nitro_color) + write('Cyan boost pads refill nitro. Orange hazards damage your shield.',Vector2(617,647),18,muted) + write('An empty shield sends you back to a checkpoint: +3 seconds.',Vector2(617,683),18,muted) func draw_finish(): - centered('练习完成' if game.practice else 'FINISH',262,47,nitro_color,true) + centered('PRACTICE DONE' if game.practice else 'FINISH',262,47,nitro_color,true) if game.practice: - centered('你已经完成第一次反重力飞行',315,21) - centered('试试正式比赛,赢取第一枚奖牌。',474,21,muted) - if game.practice_step<4:centered('还可以重练:转向 → 漂移释放 → 氮气',523,18,muted) + centered('You have flown your first anti-gravity lap',315,21) + centered('Try a real race and win your first medal.',474,21,muted) + if game.practice_step<4:centered('You can practise again: steering → drift release → nitro',523,18,muted) else: - centered('第 %d 名 / 4 · %s'%[game.rank,medal_name(game.medal)],315,25,gold,true) - centered('个人最佳 '+game.format_time(game.best_time),454,21,muted) - var message='奖牌点 %d / 9 · 继续刷新你的最佳成绩'%game.career_points - if game.medal>game.last_medal:message='奖牌进步!机库与下一条赛道等待挑战' - if game.medal==0:message='铜牌目标 %d 秒 · 提前刹车,减少碰撞'%Content.TRACKS[game.selected_track].bronze + centered('Position %d / 4 · %s'%[game.rank,medal_name(game.medal)],315,25,gold,true) + centered('Best '+game.format_time(game.best_time),454,21,muted) + var message='Medal points %d / 9 · keep improving your best time'%game.career_points + if game.medal>game.last_medal:message='Medal upgrade! The hangar and the next track await' + if game.medal==0:message='Bronze target %d s · brake early, hit fewer walls'%Content.TRACKS[game.selected_track].bronze centered(message,548,18,gold) centered(game.format_time(game.race_time),400,49,white,true) - centered('碰撞 %d 次 · 氮气使用 %.1f 秒'%[game.collisions,game.boost_seconds],590,18,muted) + centered('Collisions %d · nitro used %.1f s'%[game.collisions,game.boost_seconds],590,18,muted) diff -ruN a/scripts/main.gd b/scripts/main.gd --- a/scripts/main.gd 2026-11-06 23:45:39.910492154 -0300 +++ b/scripts/main.gd 2026-11-06 23:45:39.966466559 -0300 @@ -113,7 +113,7 @@ previous_boost=false;count_sound=4;practice=is_practice;practice_step=0;practice_steer=0;drift_charge=0;drift_flash=0;just_drifted=false;medal=0;lap_start=0;last_lap_time=0;exhausted=false state='countdown';distance=0;speed=0;lateral=0;lateral_velocity=0;energy=100;shield=100;race_time=0;countdown=3;rank=1;hit_flash=0;hit_cooldown=0;collisions=0;boost_seconds=0;previous_lap=0;pad_cooldown=0;boosting=false;drifting=false;captured.clear() for i in range(rivals.size()):rivals[i].s=-12.0-i*12;rivals[i].finish=0.0 - hud.menu(state);notify(Content.TRACKS[selected_track].name+(' / 引导练习' if practice else ' / 3 圈冲刺')) + hud.menu(state);notify(Content.TRACKS[selected_track].name+(' / guided practice' if practice else ' / 3-lap sprint')) var pose=track.pose(0);camera.transform=Transform3D(pose.basis,pose*Vector3(0,5.2,13)) print('RACE RESET') @@ -150,7 +150,7 @@ countdown-=dt if ceili(countdown)!=count_sound: count_sound=ceili(countdown);cue('count' if count_sound>0 else 'go') - if countdown<=0:state='racing';notify('GO / 用漂移积攒氮气') + if countdown<=0:state='racing';notify('GO / drift to build nitro') elif state=='racing': step_race(dt) update_visuals(dt) @@ -199,7 +199,7 @@ elif just_drifted: if drift_charge>.55: var reward=10.0 if drift_charge<1.35 else 23.0 - energy=minf(100,energy+reward);speed=minf(craft.speed*1.48,speed+reward*.55);drift_flash=1.3;cue('drift');notify('漂移释放 / +%d 氮气'%int(reward)) + energy=minf(100,energy+reward);speed=minf(craft.speed*1.48,speed+reward*.55);drift_flash=1.3;cue('drift');notify('Drift release / +%d nitro'%int(reward)) just_drifted=false;drift_charge=0 elif not boosting:energy=minf(100,energy+dt*2.0) if boosting: @@ -207,17 +207,17 @@ if energy<=2:exhausted=true if abs(lateral)>7.7: lateral=clampf(lateral,-7.7,7.7);lateral_velocity*=-.32 - if hit_cooldown<=0:hit(10,.74,'护栏碰撞 / 降低速度再入弯') + if hit_cooldown<=0:hit(10,.74,'Wall hit / slow down before the corner') distance+=speed*dt var wrapped=fposmod(distance,track.length) for pad in world.pads: if abs(wrapped-pad.s)<5 and abs(lateral-pad.lane)<2.1 and pad_cooldown<=0: - speed=minf(160,speed+24);energy=minf(100,energy+16);pad_cooldown=1.0;notify('加速带 / +16 氮气') + speed=minf(160,speed+24);energy=minf(100,energy+16);pad_cooldown=1.0;notify('Boost pad / +16 nitro') for obstacle in world.obstacles: - if abs(wrapped-obstacle.s)<3.6 and abs(lateral-obstacle.lane)<2.9 and hit_cooldown<=0:hit(19,.56,'障碍碰撞 / 注意橙色警示') + if abs(wrapped-obstacle.s)<3.6 and abs(lateral-obstacle.lane)<2.9 and hit_cooldown<=0:hit(19,.56,'Hazard hit / watch for orange warnings') if shield<=0: var checkpoint=track.length/12.0 - distance=floor(distance/checkpoint)*checkpoint;lateral=0;lateral_velocity=0;speed=20;shield=100;energy=35;race_time+=3;hit_cooldown=2;notify('已返回检查点 / +3 秒罚时') + distance=floor(distance/checkpoint)*checkpoint;lateral=0;lateral_velocity=0;speed=20;shield=100;energy=35;race_time+=3;hit_cooldown=2;notify('Back at the checkpoint / +3 s penalty') else:shield=minf(100,shield+dt*.65) for i in range(rivals.size()): var r=rivals[i] @@ -229,7 +229,7 @@ for obstacle in world.obstacles: var delta=fposmod(obstacle.s-fposmod(r.s,track.length),track.length) if delta<65 and abs(r.lane-obstacle.lane)<3.0:r.lane=lerpf(r.lane,-5.3 if obstacle.lane>=0 else 5.3,.13) - if abs(r.s-distance)<4.6 and abs(r.lane-lateral)<3.1 and hit_cooldown<=0:hit(7,.9,'擦碰 / 寻找超车空间') + if abs(r.s-distance)<4.6 and abs(r.lane-lateral)<3.1 and hit_cooldown<=0:hit(7,.9,'Contact / look for room to pass') if r.s>=track.length*3:r.finish=race_time rank=1 for r in rivals: @@ -243,7 +243,7 @@ if practice_step==2 and drift_flash>0:practice_step=3 if practice_step==3 and boost_seconds>1:practice_step=4 if lap>previous_lap and lap<3: - last_lap_time=race_time-lap_start;lap_start=race_time;previous_lap=lap;energy=minf(100,energy+30);notify('第 %d 圈 / 上圈 %s'%[lap+1,format_time(last_lap_time)]) + last_lap_time=race_time-lap_start;lap_start=race_time;previous_lap=lap;energy=minf(100,energy+30);notify('Lap %d / last lap %s'%[lap+1,format_time(last_lap_time)]) if distance>=track.length*(1 if practice else 3):finish_race() func hit(damage: float,multiplier: float,message: String): @@ -328,10 +328,10 @@ func track_unlocked(index: int) -> bool:return index==0 or int(records.get(str(index-1),{}).get('medal',0))>0 func vehicle_unlocked(index: int) -> bool:return career_points>=Content.SHIPS[index].stars func select_track(index: int): - if not track_unlocked(index):notify('在上一条赛道获得铜牌,即可解锁');return + if not track_unlocked(index):notify('Win a bronze on the previous track to unlock');return selected_track=index;refresh_records();build_world();save_settings();main_menu() func select_vehicle(index: int): - if not vehicle_unlocked(index):notify('需要 %d 奖牌点解锁'%Content.SHIPS[index].stars);return + if not vehicle_unlocked(index):notify('Needs %d medal points'%Content.SHIPS[index].stars);return selected_vehicle=index;build_world();save_settings();main_menu() func open_panel(mode: String):state=mode;hud.menu(mode) func start_practice():start_race(true) @@ -344,7 +344,7 @@ func set_volume(value: float):volume=value;apply_sound();save_settings() func set_difficulty(value: int):difficulty=value;save_settings() func practice_hint() -> String: - return ['起步 / 按 W 加速,或使用辅助油门','转向 / 按 A、D,感受飞行器的横向惯性','漂移 / 过弯时按住 SPACE,蓄能后松开','加速 / 按住 SHIFT,消耗氮气冲刺','完成练习 / 沿青色磁轨跑完这一圈'][practice_step] + return ['Start / press W, or use auto throttle','Steer / press A and D, feel the sideways inertia','Drift / hold SPACE in a corner, release when charged','Boost / hold SHIFT to spend nitro','Finish / follow the cyan track to complete the lap'][practice_step] func _exit_tree(): for player in [engine_audio,music_audio,effects,cue_audio]: