···5252 -- Physics tuning
5353 constant GRAVITY : std_logic_vector(9 downto 0) := CONV_STD_LOGIC_VECTOR(1, 10);
5454 constant IMPULSE : std_logic_vector(9 downto 0) := CONV_STD_LOGIC_VECTOR(3, 10);
5555- constant SLAM_FORCE : std_logic_vector(9 downto 0) := CONV_STD_LOGIC_VECTOR(4, 10);
5656- -- Jump: base force at zero velocity, tapers off as |vel_y| rises.
5555+ constant SLAM_FORCE : std_logic_vector(9 downto 0) := CONV_STD_LOGIC_VECTOR(4, 10);
5656+ -- Initial jump: full force at zero velocity, tapers off as |vel_y| rises.
5757 -- Piecewise lookup approximates: max(JUMP_MIN, JUMP_BASE*JUMP_SCALE/(JUMP_SCALE+|vy|))
5858- constant JUMP_BASE : integer := 6; -- force at zero velocity
5959- constant JUMP_VEL_THR1 : integer := 3; -- |vy| <= 3 → force 6
6060- constant JUMP_VEL_THR2 : integer := 8; -- |vy| <= 8 → force 4
6161- constant JUMP_VEL_THR3 : integer := 16; -- |vy| <= 16 → force 3
6262- constant JUMP_MIN_FORCE : integer := 2; -- floor at high velocity
5858+ constant JUMP_BASE : integer := 14; -- force at zero velocity
5959+ constant JUMP_VEL_THR1 : integer := 3; -- |vy| <= 3 → force 14
6060+ constant JUMP_VEL_THR2 : integer := 10; -- |vy| <= 10 → force 8
6161+ constant JUMP_VEL_THR3 : integer := 20; -- |vy| <= 20 → force 6
6262+ constant JUMP_MIN_FORCE : integer := 4; -- floor at high velocity
6363+ -- Trampoline: fixed additive boost on each ground contact while W held.
6464+ -- No inverse scaling so energy accumulates each bounce.
6565+ constant JUMP_BOUNCE : std_logic_vector(9 downto 0) := CONV_STD_LOGIC_VECTOR(6, 10);
6366 constant MAX_VEL_X : std_logic_vector(9 downto 0) := CONV_STD_LOGIC_VECTOR(32, 10);
64676568 -- World bounds (11-bit)
···157160 -- == INPUT ==
158161 if key_w = '0' then jump_pressed <= '0'; end if;
159162160160- -- Scaled jump: full force at low velocity, tapers as |vy| increases
163163+ -- Initial jump: force tapers as |vy| increases (inverse scaling)
161164 if vy(9) = '1' then abs_vy_int := CONV_INTEGER((not vy) + 1);
162165 else abs_vy_int := CONV_INTEGER(vy); end if;
163166 if abs_vy_int <= JUMP_VEL_THR1 then jforce_int := JUMP_BASE;
164164- elsif abs_vy_int <= JUMP_VEL_THR2 then jforce_int := 4;
165165- elsif abs_vy_int <= JUMP_VEL_THR3 then jforce_int := 3;
167167+ elsif abs_vy_int <= JUMP_VEL_THR2 then jforce_int := 8;
168168+ elsif abs_vy_int <= JUMP_VEL_THR3 then jforce_int := 6;
166169 else jforce_int := JUMP_MIN_FORCE;
167170 end if;
168171 jforce_slv := CONV_STD_LOGIC_VECTOR(jforce_int, 10);
···173176 jump_pressed <= '1';
174177 end if;
175178179179+ -- Trampoline: fixed boost (no inverse scaling) so energy accumulates each bounce
176180 if key_w = '1' and jump_pressed = '1' and on_ground = '1' then
177177- vy := vy - jforce_slv;
181181+ vy := vy - JUMP_BOUNCE;
178182 end if;
179183180184 if key_s = '1' and on_ground = '0' then vy := vy + SLAM_FORCE; end if;
+6-5
visualizer.py
···2525IMPULSE = 3
2626SLAM_FORCE = 4
2727AIR_CONTROL = 2
2828-JUMP_FORCE = 6 # base jump force at zero velocity
2929-JUMP_VEL_SCALE = 12 # velocity magnitude at which jump force is halved
3030-JUMP_MIN_FORCE = 2 # floor: minimum jump force regardless of velocity
2828+JUMP_FORCE = 14 # initial jump force at zero velocity (scales down with |vel_y|)
2929+JUMP_VEL_SCALE = 12 # velocity magnitude at which initial jump force is halved
3030+JUMP_MIN_FORCE = 4 # floor for inverse-scaled initial jump
3131+JUMP_BOUNCE = 6 # fixed additive boost on each ground contact while W held (trampoline)
3132MAX_VEL_X = 32
3233SIZE = 7
3334BOUNCE_SHIFT = 3 # energy loss = vel >> 3 (keep 87.5%)
···140141 vy = (vy - scaled_jump()) & MASK
141142 jump_pressed = True
142143 elif keys_held['w'] and jump_pressed and on_ground:
143143- # Holding W while bouncing: boost each ground contact
144144- vy = (vy - scaled_jump()) & MASK
144144+ # Holding W while bouncing: fixed boost so trampoline accumulates each contact
145145+ vy = (vy - JUMP_BOUNCE) & MASK
145146146147 # S: slam (air only)
147148 if keys_held['s'] and not on_ground: