1
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: add more caps

+53 -21
+53 -21
physics_engine.vhd
··· 130 130 variable bounce_wall : std_logic; 131 131 variable bounce_speed : std_logic_vector(9 downto 0); 132 132 variable grounded : std_logic; 133 - variable c_left, c_right, c_top, c_bot : std_logic_vector(10 downto 0); 134 - variable overlap_x, overlap_y : std_logic_vector(10 downto 0); 135 - variable tcx, tcy, dcx, dcy : std_logic_vector(10 downto 0); 133 + variable c_left, c_right, c_top, c_bot : std_logic_vector(10 downto 0); 134 + variable c_prev_top, c_prev_bot, c_prev_left, c_prev_right : std_logic_vector(10 downto 0); 135 + variable tcx, tcy, dcx, dcy : std_logic_vector(10 downto 0); 136 136 begin 137 137 wait until vert_sync'event and vert_sync = '1'; 138 138 ··· 151 151 end if; 152 152 153 153 if key_w = '1' and jump_pressed = '1' and on_ground = '1' then 154 - vy := vy - 4; 154 + vy := vy - JUMP_FORCE; 155 155 end if; 156 156 157 157 if key_s = '1' and on_ground = '0' then vy := vy + SLAM_FORCE; end if; ··· 182 182 -- == CLAMP velocities == 183 183 if vx(9) = '0' and vx > MAX_VEL_X then vx := MAX_VEL_X; end if; 184 184 if vx(9) = '1' and vx < (not MAX_VEL_X) + 1 then vx := (not MAX_VEL_X) + 1; end if; 185 - if vy(9) = '0' and vy > 127 then vy := CONV_STD_LOGIC_VECTOR(127, 10); end if; 186 - if vy(9) = '1' and vy < CONV_STD_LOGIC_VECTOR(896, 10) then 187 - vy := CONV_STD_LOGIC_VECTOR(896, 10); 185 + if vy(9) = '0' and vy > 80 then vy := CONV_STD_LOGIC_VECTOR(80, 10); end if; 186 + if vy(9) = '1' and vy < CONV_STD_LOGIC_VECTOR(924, 10) then -- 924 = -100 187 + vy := CONV_STD_LOGIC_VECTOR(924, 10); 188 188 end if; 189 189 190 190 -- == MOVE: sign-extend 10-bit velocity to 11-bit before adding == ··· 244 244 end if; 245 245 end if; 246 246 247 - -- == OBSTACLE COLLISIONS (loop over level_pkg arrays) == 247 + -- == OBSTACLE COLLISIONS == 248 + -- Use previous-frame bounds to detect which face was entered. 249 + -- This avoids the overlap-axis bug where a fast horizontal move into 250 + -- a thin platform's side gets incorrectly resolved as a vertical hit. 251 + c_prev_top := pos_y - SIZE11; 252 + c_prev_bot := pos_y + SIZE11; 253 + c_prev_left := pos_x - SIZE11; 254 + c_prev_right := pos_x + SIZE11; 255 + 248 256 for obs_i in 0 to OBS_COUNT-1 loop 249 257 c_left := px - SIZE11; 250 258 c_right := px + SIZE11; ··· 254 262 if c_right >= OBS_L(obs_i) and c_left <= OBS_R(obs_i) and 255 263 c_bot >= OBS_T(obs_i) and c_top <= OBS_B(obs_i) then 256 264 257 - if vy(9) = '0' then overlap_y := c_bot - OBS_T(obs_i); 258 - else overlap_y := OBS_B(obs_i) - c_top; end if; 259 - if vx(9) = '0' then overlap_x := c_right - OBS_L(obs_i); 260 - else overlap_x := OBS_R(obs_i) - c_left; end if; 261 - 262 - if overlap_y <= overlap_x then 263 - -- Vertical resolution 264 - if vy(9) = '0' then py := OBS_T(obs_i) - SIZE11; grounded := '1'; 265 - else py := OBS_B(obs_i) + SIZE11; end if; 265 + if c_prev_bot <= OBS_T(obs_i) then 266 + -- Entered from top → land on surface 267 + py := OBS_T(obs_i) - SIZE11; grounded := '1'; 266 268 bounced := '1'; 267 269 vy := (not vy) + 1; 268 270 if vy(9) = '0' and vy > 1 then ··· 274 276 if vy(9) = '1' and vy >= CONV_STD_LOGIC_VECTOR(1022, 10) then 275 277 vy := (others => '0'); 276 278 end if; 277 - else 278 - -- Horizontal resolution 279 - if vx(9) = '0' then px := OBS_L(obs_i) - SIZE11; 280 - else px := OBS_R(obs_i) + SIZE11; end if; 279 + 280 + elsif c_prev_top >= OBS_B(obs_i) then 281 + -- Entered from bottom → bump head on underside 282 + py := OBS_B(obs_i) + SIZE11; 283 + bounced := '1'; 284 + vy := (not vy) + 1; 285 + if vy(9) = '0' and vy > 1 then 286 + vy := vy - ("000" & vy(9 downto 3)); 287 + end if; 288 + 289 + elsif c_prev_right <= OBS_L(obs_i) then 290 + -- Entered from left → bounce off left face 291 + px := OBS_L(obs_i) - SIZE11; 292 + bounced := '1'; bounce_wall := '1'; 293 + vx := (not vx) + 1; 294 + if vx(9) = '0' and vx > 1 then 295 + vx := vx - ("000" & vx(9 downto 3)); 296 + elsif vx(9) = '1' and vx < CONV_STD_LOGIC_VECTOR(1022, 10) then 297 + vx := vx + ("000" & ((not vx(9 downto 3)) + 1)); 298 + end if; 299 + 300 + elsif c_prev_left >= OBS_R(obs_i) then 301 + -- Entered from right → bounce off right face 302 + px := OBS_R(obs_i) + SIZE11; 281 303 bounced := '1'; bounce_wall := '1'; 282 304 vx := (not vx) + 1; 283 305 if vx(9) = '0' and vx > 1 then 284 306 vx := vx - ("000" & vx(9 downto 3)); 285 307 elsif vx(9) = '1' and vx < CONV_STD_LOGIC_VECTOR(1022, 10) then 286 308 vx := vx + ("000" & ((not vx(9 downto 3)) + 1)); 309 + end if; 310 + 311 + else 312 + -- Corner / spawn-inside fallback: resolve by velocity direction 313 + if vy(9) = '0' then py := OBS_T(obs_i) - SIZE11; grounded := '1'; 314 + else py := OBS_B(obs_i) + SIZE11; end if; 315 + bounced := '1'; 316 + vy := (not vy) + 1; 317 + if vy(9) = '0' and vy > 1 then 318 + vy := vy - ("000" & vy(9 downto 3)); 287 319 end if; 288 320 end if; 289 321 end if;