added (very primitive) gravity and physics engine

This commit is contained in:
Alexandre 2024-07-22 23:21:43 +02:00
parent 8f4b74c171
commit 16977db2d6
5 changed files with 145 additions and 49 deletions

BIN
a.out

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -25,21 +25,37 @@ let chunk_size = 6 ;;
let chunk_size_f = float_of_int chunk_size ;; let chunk_size_f = float_of_int chunk_size ;;
(* between 0 (empty) and 100 (full) *) (* between 0 (empty) and 100 (full) *)
let density = 50 ;; let density = 35 ;;
let speed_multiplier = 0.15 ;; let speed_multiplier = 0.1 ;;
(* money money money *) (* money money money *)
let coins = ref 0 ;; let coins = ref 0 ;;
(* player has a cube hitbox with 2*this_value as length *) (* player has a cube hitbox with 2*this_value as length *)
let collison_leniency = (float_of_int cube_size) /. 10. ;; let collison_leniency = (float_of_int cube_size) /. 6. ;;
(* hitbox for coins *) (* hitbox for coins *)
let coin_magnet_dist = 1. ;; let coin_magnet_dist = 1. ;;
(* -------------------------------------------------------------------------------------------------------- *) (* -------------------------------------------------------------------------------------------------------- *)
(* m/sœ *)
let gravity = 0.98 ;;
(* should be bigger then collision_leniency *)
let gravity_leniency = (float_of_int cube_size) /. 6. ;;
let vx = ref 0.0
and vy = ref 0.0
and vz = ref 0.0 ;;
let ax = ref 0.0
and ay = ref 0.0
and az = ref 0.0 ;;
(* -------------------------------------------------------------------------------------------------------- *)
(* avg number of chunk generation required before encountering a structure of type 1 *) (* avg number of chunk generation required before encountering a structure of type 1 *)
let structure_1_frequency = 2500 ;; let structure_1_frequency = 2500 ;;
@ -1042,6 +1058,17 @@ let is_collision_cube_bis (cam_coords : pt_3d) (cuube : coloredCube) =
cuube.cube.(6).y +. collison_leniency >= (-. cam_coords.y) && cuube.cube.(6).y +. collison_leniency >= (-. cam_coords.y) &&
cuube.cube.(6).z +. collison_leniency >= cam_coords.z ;; cuube.cube.(6).z +. collison_leniency >= cam_coords.z ;;
let is_collision_cube_G (cam_coords : pt_3d) (cuube : coloredCube) =
if is_string_integer cuube.flag then
false
else
cuube.cube.(0).x -. gravity_leniency <= (-. cam_coords.x) &&
cuube.cube.(0).y -. gravity_leniency <= (-. cam_coords.y) &&
cuube.cube.(0).z -. gravity_leniency <= cam_coords.z &&
cuube.cube.(6).x +. gravity_leniency >= (-. cam_coords.x) &&
cuube.cube.(6).y +. gravity_leniency >= (-. cam_coords.y) &&
cuube.cube.(6).z +. gravity_leniency >= cam_coords.z ;;
let is_collision (cam_coords : pt_3d) (cubes : pt_3d array array) = let is_collision (cam_coords : pt_3d) (cubes : pt_3d array array) =
let res = ref false in let res = ref false in
let n = !n_walls in let n = !n_walls in
@ -1127,6 +1154,51 @@ let is_collision_hash_2 (cam_coords : pt_3d) (rcubes : (coloredCube dynamic) opt
!res !res
end ;; end ;;
let is_collision_hash_G (cam_coords : pt_3d) (rcubes : (coloredCube dynamic) option) = match rcubes with
| None -> false
| Some cubes -> begin
let res = ref false in
let n = cubes.len in
let distances = Array.make n 0. in
for i = 0 to n-1 do
distances.(i) <- cube_dist cubes.tab.(i).cube;
done ;
let to_be_removed = ref [] in
let rem_len = ref 0 in
for i = 0 to n-1 do
if is_string_integer cubes.tab.(i).flag then begin (* coin *)
if is_collision_coin cam_coords cubes.tab.(i).cube then begin
let valc = str_to_int cubes.tab.(i).flag in
coins := !coins + valc;
to_be_removed := (i - !rem_len)::(!to_be_removed);
incr rem_len;
(*Printf.printf "%d" valc;
Stdlib.print_endline " "*)
end
end
else if (String.length cubes.tab.(i).flag) = 1 then begin (* ore *)
if is_collision_coin cam_coords cubes.tab.(i).cube then begin
add_ore_to_inventory cubes.tab.(i).flag;
to_be_removed := (i - !rem_len)::(!to_be_removed);
incr rem_len;
(*Printf.printf "%d" valc;
Stdlib.print_endline " "*)
end
end
else if not !res && distances.(i) < chunk_size_f then
(*res := is_collision_cube cam_coords cubes.tab.(i).cube*)
res := is_collision_cube_G cam_coords cubes.tab.(i)
done;
indent_list cubes !to_be_removed;
!res
end ;;
let convert_laby laby = let convert_laby laby =
let width = Array.length laby let width = Array.length laby
and height = Array.length laby.(0) and height = Array.length laby.(0)
@ -1215,77 +1287,64 @@ let cheesify (laby : tile array array array) =
done done
done;; done;;
let is_collision_global_2 hash cx cy cz =
(* O() goes brrr *)
let boo = ref false in
for i = -1 to 1 do
for j = -1 to 1 do
for k = -1 to 1 do
boo := !boo || is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx+i,cy+j,cz+k))
done
done
done;
!boo ;;
let is_collision_global_G hash cx cy cz =
let boo = ref false in
for i = -1 to 1 do
for j = -1 to 1 do
for k = -1 to 1 do
boo := !boo || is_collision_hash_G camera_xyz (Hashtbl.find_opt hash (cx+i,cy+j,cz+k))
done
done
done;
!boo ;;
let rec move_cam_hash_2 hash cx cy cz b c =(* Printf.printf "[%b]" b; Stdlib.print_endline " " ; *)match c with let rec move_cam_hash_2 hash cx cy cz b c =(* Printf.printf "[%b]" b; Stdlib.print_endline " " ; *)match c with
| 'z' -> | 'z' ->
camera_xyz.z <- camera_xyz.z +. speed_multiplier *. Float.cos ((float_of_int !camera_angle_y) *. 3.1415926535 /. 180.); camera_xyz.z <- camera_xyz.z +. speed_multiplier *. Float.cos ((float_of_int !camera_angle_y) *. 3.1415926535 /. 180.);
camera_xyz.x <- camera_xyz.x +. speed_multiplier *. Float.sin ((float_of_int !camera_angle_y) *. 3.1415926535 /. 180.); camera_xyz.x <- camera_xyz.x +. speed_multiplier *. Float.sin ((float_of_int !camera_angle_y) *. 3.1415926535 /. 180.);
if b && ( if b && (
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy,cz))) || is_collision_global_2 hash cx cy cz
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx+1,cy,cz))) ||
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx-1,cy,cz))) ||
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy+1,cz))) ||
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy-1,cz))) ||
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy,cz+1))) ||
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy,cz-1)))
) then move_cam_hash_2 hash cx cy cz false 's' ) then move_cam_hash_2 hash cx cy cz false 's'
| 'q' -> | 'q' ->
camera_xyz.z <- camera_xyz.z +. speed_multiplier *. Float.cos (((float_of_int !camera_angle_y) +. 90.) *. 3.1415926535 /. 180.); camera_xyz.z <- camera_xyz.z +. speed_multiplier *. Float.cos (((float_of_int !camera_angle_y) +. 90.) *. 3.1415926535 /. 180.);
camera_xyz.x <- camera_xyz.x +. speed_multiplier *. Float.sin (((float_of_int !camera_angle_y) +. 90.) *. 3.1415926535 /. 180.); camera_xyz.x <- camera_xyz.x +. speed_multiplier *. Float.sin (((float_of_int !camera_angle_y) +. 90.) *. 3.1415926535 /. 180.);
if b && ( if b && (
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy,cz))) || is_collision_global_2 hash cx cy cz
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx+1,cy,cz))) ||
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx-1,cy,cz))) ||
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy+1,cz))) ||
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy-1,cz))) ||
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy,cz+1))) ||
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy,cz-1)))
) then move_cam_hash_2 hash cx cy cz false 'd' ) then move_cam_hash_2 hash cx cy cz false 'd'
| 's' -> | 's' ->
camera_xyz.z <- camera_xyz.z -. speed_multiplier *. Float.cos ((float_of_int !camera_angle_y) *. 3.1415926535 /. 180.); camera_xyz.z <- camera_xyz.z -. speed_multiplier *. Float.cos ((float_of_int !camera_angle_y) *. 3.1415926535 /. 180.);
camera_xyz.x <- camera_xyz.x -. speed_multiplier *. Float.sin ((float_of_int !camera_angle_y) *. 3.1415926535 /. 180.); camera_xyz.x <- camera_xyz.x -. speed_multiplier *. Float.sin ((float_of_int !camera_angle_y) *. 3.1415926535 /. 180.);
if b && ( if b && (
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy,cz))) || is_collision_global_2 hash cx cy cz
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx+1,cy,cz))) ||
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx-1,cy,cz))) ||
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy+1,cz))) ||
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy-1,cz))) ||
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy,cz+1))) ||
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy,cz-1)))
) then move_cam_hash_2 hash cx cy cz false 'z' ) then move_cam_hash_2 hash cx cy cz false 'z'
| 'd' -> | 'd' ->
camera_xyz.z <- camera_xyz.z +. speed_multiplier *. Float.cos (((float_of_int !camera_angle_y) -. 90.) *. 3.1415926535 /. 180.); camera_xyz.z <- camera_xyz.z +. speed_multiplier *. Float.cos (((float_of_int !camera_angle_y) -. 90.) *. 3.1415926535 /. 180.);
camera_xyz.x <- camera_xyz.x +. speed_multiplier *. Float.sin (((float_of_int !camera_angle_y) -. 90.) *. 3.1415926535 /. 180.); camera_xyz.x <- camera_xyz.x +. speed_multiplier *. Float.sin (((float_of_int !camera_angle_y) -. 90.) *. 3.1415926535 /. 180.);
if b && ( if b && (
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy,cz))) || is_collision_global_2 hash cx cy cz
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx+1,cy,cz))) ||
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx-1,cy,cz))) ||
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy+1,cz))) ||
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy-1,cz))) ||
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy,cz+1))) ||
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy,cz-1)))
) then move_cam_hash_2 hash cx cy cz false 'q' ) then move_cam_hash_2 hash cx cy cz false 'q'
| 'p' -> | 'p' ->
camera_xyz.y <- camera_xyz.y -. speed_multiplier ; camera_xyz.y <- camera_xyz.y -. speed_multiplier ;
if b && ( if b && (
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy,cz))) || is_collision_global_2 hash cx cy cz
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx+1,cy,cz))) || ) then begin Stdlib.print_endline "Nope (p)" ; move_cam_hash_2 hash cx cy cz false 'm' end
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx-1,cy,cz))) ||
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy+1,cz))) ||
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy-1,cz))) ||
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy,cz+1))) ||
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy,cz-1)))
) then move_cam_hash_2 hash cx cy cz false 'm'
| 'm' -> | 'm' ->
camera_xyz.y <- camera_xyz.y +. speed_multiplier ; camera_xyz.y <- camera_xyz.y +. speed_multiplier ;
if b && ( if b && (
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy,cz))) || is_collision_global_2 hash cx cy cz
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx+1,cy,cz))) || ) then begin Stdlib.print_endline "Nope (m)" ; move_cam_hash_2 hash cx cy cz false 'p' end
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx-1,cy,cz))) ||
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy+1,cz))) ||
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy-1,cz))) ||
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy,cz+1))) ||
(is_collision_hash_2 camera_xyz (Hashtbl.find_opt hash (cx,cy,cz-1)))
) then move_cam_hash_2 hash cx cy cz false 'p'
| 'a' -> camera_angle_y := !camera_angle_y + 1 | 'a' -> camera_angle_y := !camera_angle_y + 1
| 'e' -> camera_angle_y := !camera_angle_y - 1 | 'e' -> camera_angle_y := !camera_angle_y - 1
| _ -> () ;; | _ -> () ;;
@ -1617,6 +1676,34 @@ let draw_inventories () =
draw_integer_alignedleft 40 (__height__ - (240 + 50 * (Array.length playerOreInventory -1 -i))) playerOreInventory.(i) 20 draw_integer_alignedleft 40 (__height__ - (240 + 50 * (Array.length playerOreInventory -1 -i))) playerOreInventory.(i) 20
done ;; done ;;
exception CannotPass ;;
let move_auto_y hash redraw =
try
let (cx, cy, cz) = coords_to_chunk_f (-. camera_xyz.x) (-. camera_xyz.y) camera_xyz.z in
for i = 1 to 15 do
camera_xyz.y <- camera_xyz.y +. !vy /. 15.;
let new_cy = ctcf_one (-. camera_xyz.y) in
if is_collision_global_G hash cx new_cy cz then begin
if i <> 1 then
redraw := true;
camera_xyz.y <- camera_xyz.y -. !vy /. 15. ;
raise CannotPass
end
else
()
done ;
redraw := true;
()
with
| CannotPass -> vy := 0.; () ;;
let update_gravity dt hash redraw =
vy := !vy +. gravity *. dt ;
Printf.printf "{%f, %f, %f}" !vx !vy !vz;
Stdlib.print_endline " ";
move_auto_y hash redraw ;;
let play_dos laby = let play_dos laby =
try try
Stdlib.print_endline "Building terrain..."; Stdlib.print_endline "Building terrain...";
@ -1650,6 +1737,8 @@ let play_dos laby =
camera_xyz.z <- 2. ; camera_xyz.z <- 2. ;
while true do while true do
let time_s = Unix.gettimeofday() in
if !redraw then begin (* update the display *) if !redraw then begin (* update the display *)
auto_synchronize false; auto_synchronize false;
open_graph openstring; open_graph openstring;
@ -1670,11 +1759,18 @@ let play_dos laby =
let usr_input = get1char_plus () in let usr_input = get1char_plus () in
if usr_input <> '@' then begin if usr_input <> '@' then begin
for i = 0 to 9 do Stdlib.print_endline "EEEEE";
for i = 0 to 15 do
move_cam_hash_2 hash !ch_x !ch_y !ch_z true usr_input move_cam_hash_2 hash !ch_x !ch_y !ch_z true usr_input
done; done;
redraw := true redraw := true
end end;
Unix.sleepf 0.001;
let time_e = Unix.gettimeofday() in
(*Printf.printf "[%f]" (time_e -. time_s);
Stdlib.print_endline " ";*)
update_gravity (time_e -. time_s) hash redraw
done ; done ;
() ()
with with

BIN
display.o

Binary file not shown.