From 522e472c4d972c9a4d228e1bf24c35102c5032e4 Mon Sep 17 00:00:00 2001 From: Jakob Feldmann Date: Tue, 3 Oct 2023 19:21:59 +0200 Subject: [PATCH] feat: caterpillar sprite, vacuum sprite fix, level balance --- assets/enemy/Caterpilllar.aseprite | Bin 0 -> 1164 bytes assets/enemy/VacuumRobot.aseprite | Bin 1341 -> 1392 bytes assets/enemy/VacuumRobot.png | Bin 586 -> 604 bytes project.godot | 6 - src/Actors/Actor.gd | 34 +- src/Actors/Blobby/Blobby.gd | 818 +++++++++--------- src/Contraptions/Portal/Portal.gd | 38 +- src/Levels/Level 0.1.tscn | 5 - src/Levels/Level 0.3.tscn | 4 - src/Levels/Level 0.4.tscn | 6 +- src/Levels/Level 2.tscn | 3 + src/Levels/Level 3.tscn | 2 +- src/Levels/Level 4.tscn | 4 +- src/Levels/Level 5.tscn | 2 +- src/Levels/Templates/LevelTemplate.gd | 28 +- src/Sounds/default_bus_layout.tres | 2 +- .../Screens/InGameMenu/PauseScreen.gd | 78 +- .../Screens/MainMenu/MainScreen.gd | 4 +- .../Screens/MainMenu/MainScreen.tscn | 3 +- src/Utilities/LevelState.gd | 144 +-- src/Utilities/SceneAudio.gd | 100 +-- src/Utilities/SignalManager.gd | 2 +- 22 files changed, 633 insertions(+), 650 deletions(-) create mode 100644 assets/enemy/Caterpilllar.aseprite diff --git a/assets/enemy/Caterpilllar.aseprite b/assets/enemy/Caterpilllar.aseprite new file mode 100644 index 0000000000000000000000000000000000000000..6f12f58b4e54de2cd878a400d00a42830fd45611 GIT binary patch literal 1164 zcmcJNi%*SV9LJy11xpKECds=~u1$8NICZqdI#e>H4V7ESLK8cy46(V4#OAWHqSg_c z%wbqpp=E8z=2AngkZY2KBi+vNd74fCfal%&dCz&?v-kIYKi_lAMu^wNRzev(tb`C7 zIR7o3u#%g?iQ|7P2j=&7*$z&%Wq>QEy)rm*$hcZI#wohLJ7Gia2w`V8+#-at(^wef zHVN)@n*nbs(_w3{7wk3{JsI^H!XlG@A*ULLSN{ zXpFk(ilS(Vis(m{Lo@v$bV4DtK^62s2{eFy+#??AQn|%~Y)qpW#|XwQYVnFxjG_~l zh{Pfa@rOLjp$%sU!xpOWgd_~12RDep3QF*S3{0Q_2M8cN(aB9{5)+rK1SKUA$v08P zQ-%%sYm!^oi^z2u8+RybZ-Uz@@~)GxSj($i3g6Q6i(}P})@p~!Im+bP?ZbSwMlR|e z9#CDgC4FSok#h??qsKj5?6YiI;H^}T(wv*mPM@gP8m~S0c%{bmb4Byfm%&kAzUosB zX%aQA=Fy|vW4by!BcAP>`JwOqZ^KHpS5kZWx<^^s!(WPf*5)S8+uf0-^(}216_b*5 zJ@e9j{~depZ}Bj0d~x2+zkW@ZrZY1&KH|z)L*2Z~r8TMNzW06{=rG&Yi{o0gKoxHaw;tzAIs>A>Q literal 0 HcmV?d00001 diff --git a/assets/enemy/VacuumRobot.aseprite b/assets/enemy/VacuumRobot.aseprite index a2a00ef0a3d7ed691e7419fd0b62113cb7264b24..415d0442b192060e2e43031bb98a3a7f860a89b5 100644 GIT binary patch delta 422 zcmV;X0a^aN3h)X6aFGFj0qn7X=K=x*0h4M2NPjT-+|u6vULi?vnjDO52FzS!yFm2+ zBIUq4)jL&X#Ghu!v z6vnvBJ^TI9e-I#KFRrjA*S{cpL73kDB{rOK`IneHL`k~BmzM~IH8t`Oau~z%FRr{q ztxWO?JrCh3Ckf?eV(mmX551g3_BTijRCmDCBD0Cb==x#l2v>as1KQf!|3w6Z!5G9Q zq@Eo80H#*5Wds2L0Q&I(0Av6F009610Q8e;1U7$z%w%KZz-k{zoR%1uoi;W$|8q-w z|9gcb!D(_ZvKb&VvDryY`-rs{#HXfx*z85N6Xr);_D#C8i)cHrsfC$|>{k$t?k0R@ zfW(k7K6}y4M79%GxZ*PN?Dt3iL4c5*xWbnle}e1;VS4(L*s#UtPki}=k~D-bzu*gB zYUDl>_7(c0SD|3w6Z Q!5G9QMh~g_0jY5`Tw6}fwg3PC delta 371 zcmV-(0gV3e3cU&eJ&^%_0ok#E=K=!p0F!D1NPi$XuaG2~V366!c7f>s%X8pvqNTkc z46+N^&$#S7`~4BgcHq*3>}NuLrMA5=KjZW3wO=p5W`Jm9@kw`fpV(lHMbVZLc1KqE%{5ufk26{P3ZTpeUL@y_i z{W%R11JxZcwa9E@F}i+OI>J>S!GN~5_J0upVK4@<38^PXKL7-2w`1f0008>&0RUtG z00031007jJeFQdt!|cRnpN);pe_CQ(c6x;*(F9|&6Xq6L+KFy2F8j`Ye?+qRxbz^~ ziO-MJwi9MAF8i+idI8oCqLIZX-PwhLiP3}ZS3-88yBlN=NDKt1Z6~g9g4qee=yno{ z4@&IB6}F_+%5Ij{{jIpqIDQwhLEz3j?4!0HzKenN2K4*N@LG7|_<%{x2dR R48|ZfF?vYV4*-3?V_WCxtOWo7 diff --git a/assets/enemy/VacuumRobot.png b/assets/enemy/VacuumRobot.png index 76433dc67c4b39193b4907bc270af2950b3fb7d5..77d2e2353a9b403370bded9e2808597d84cd4f7d 100644 GIT binary patch delta 566 zcmV-60?GZ#1l$CWF@F|GL_t(&f$f*SOM*cd$G@+rLob9-LC_>GL~s!GZsO}A#Ou=F zR%>I~-k;zfP>n4Gx;3=q(xTC(AqXLeLj=u&5;(`B6BD_B;3cB6cSV)q0wk;K>(tj`P002nGVxh{PheH5B zrBX3u;#K)4l5reop;NS0t4-|y)&3{|e4nn+`1Qc}K3$>N=IF9*#Q zd1b96LF45fyeob^2<(hS`FX|(&{BbBu3kfvPfMbDwg=<*GH~`S+Rx5{i1#t9-XLr_ z0AF4Esl3l6LVtyyB?62_Kijk?3b5pgN77P0majA0v_VS+-&*%ZUxlCDXQF^NA~sex zw|!H_E08N5;qjt8Rl@#%yeRw1`051E`)mtmfl9wegsns*pGJCX2j|wo%s94AD@g+5 zmf?@c1_n|8dY>61+puN$qq2b_oIrH~K+WVg4-;wx53sOe8={1v;$W;INZHzuyM{n5H@YmW3^2nkF8sDq@)v z;T2ef>o2-AOuy_abPOSct|!*$dSZ1`zz&t0A^blv|1rx>;M1&07*qoM6N<$ Eg3*B!T>t<8 delta 548 zcmV+<0^9xE1j+=EF@FR}L_t(&f$f()NW(xFhTqhtU;`qkAUFyl1RT0HSqc&tcNJVZ zO5Gep5ClOS97{(R#k#xL#iex>$s`3Q5jq!IrKOyMTzYLT^-6Om;yqKipFEfEa^Kwn z8jVJy(P%UpjYgvo&-2K?_3MxSMTY%JUZbmp1u28P&SZqzsekly0{{S7(~MRA*zE!U zDwT>M(q5H6G#JNmr2e9{T5V(iRQreZZ9}wYkBN z=^rKm0I5>jAmswd`C@By5^{b9q+H;ByzJTMITG}tTfGFpkN)Y^$=D)ZANp?U;-SLN zk^lfzvrnOa0e@SjV)l711NhDXIX}aV(8bLeK6)KYPo;3Ma}<x9a(ORLylUKf4EM9A|07yuf< void: - if level_state.is_dead: - return - var snap = Vector2.DOWN * 128 - var center_floor_rot = 0 - var floor_rot = 0 - var onfloor = is_on_floor() + if level_state.is_dead: + return + var snap = Vector2.DOWN * 128 + var center_floor_rot = 0 + var floor_rot = 0 + var onfloor = is_on_floor() - # get rotation of floor, compare collided floor with floor under center - if onfloor: - # TODO: Problem when correctly rotating? - center_floor_rot = $SlopeRaycast.get_collision_normal().rotated(PI / 2).angle() - floor_rot = get_floor_normal().rotated(PI / 2).angle() - if abs(center_floor_rot) > PI / 4 + 0.1: - center_floor_rot = floor_rot - # snap when on slopes - if (abs(floor_rot) > 0.1 || abs(center_floor_rot) > 0.1) && snap_possible: - velocity = move_and_slide_with_snap(velocity.rotated(floor_rot), snap, FLOOR_NORMAL, true) - # normal slide on flat floor - else: - velocity = move_and_slide(velocity.rotated(floor_rot), FLOOR_NORMAL) - rotation = 0 - if ( - $SlopeRaycastLeft.is_colliding() - && $SlopeRaycastRight.is_colliding() - && $SlopeRaycast.is_colliding() - ): - rotation = calculate_slope_rotation(onfloor) - # rotate related to floor slope - # Convert velocity back to local space. - # TODO: Downward velocity should be increased by gravity - velocity = velocity.rotated(-floor_rot) if snap_possible else velocity + # get rotation of floor, compare collided floor with floor under center + if onfloor: + # TODO: Problem when correctly rotating? + center_floor_rot = $SlopeRaycast.get_collision_normal().rotated(PI / 2).angle() + floor_rot = get_floor_normal().rotated(PI / 2).angle() + if abs(center_floor_rot) > PI / 4 + 0.1: + center_floor_rot = floor_rot + # snap when on slopes + if (abs(floor_rot) > 0.1 || abs(center_floor_rot) > 0.1) && snap_possible: + velocity = move_and_slide_with_snap(velocity.rotated(floor_rot), snap, FLOOR_NORMAL, true) + # normal slide on flat floor + else: + velocity = move_and_slide(velocity.rotated(floor_rot), FLOOR_NORMAL) + rotation = 0 + if ( + $SlopeRaycastLeft.is_colliding() + && $SlopeRaycastRight.is_colliding() + && $SlopeRaycast.is_colliding() + ): + rotation = calculate_slope_rotation(onfloor) + # rotate related to floor slope + # Convert velocity back to local space. + # TODO: Downward velocity should be increased by gravity + velocity = velocity.rotated(-floor_rot) if snap_possible else velocity func calculate_duck_velocity(linear_velocity: Vector2, delta: float, direction: Vector2) -> Vector2: - var state = player_state_machine.state - var out_vel := linear_velocity - var velocity_direction = 1.0 - if velocity.x < 0: - velocity_direction = -1.0 + var state = player_state_machine.state + var out_vel := linear_velocity + var velocity_direction = 1.0 + if velocity.x < 0: + velocity_direction = -1.0 - # TODO Improve this to separate crawling(slow) and sliding - var deceleration_force = calculate_deceleration_force(_gravity, mass) * 0.333 + # TODO Improve this to separate crawling(slow) and sliding + var deceleration_force = calculate_deceleration_force(_gravity, mass) * 0.333 - # Slowing down movement when not controlling direction - if is_equal_approx(direction.x, 0): - # TODO Handle Deadzones - out_vel.x = PhysicsFunc.two_step_euler( - out_vel.x, deceleration_force * -1 * velocity_direction, mass, delta - ) - if abs(out_vel.x) > abs(velocity.x): - out_vel.x = 0 - else: - # Reversing movement - # When turning the opposite direction, friction is added to the opposite acceleration movement - var reverse_move = is_reversing_horizontal_movement(direction) - if reverse_move: - # TODO dont put constants in here - out_vel.x = PhysicsFunc.two_step_euler( - out_vel.x, deceleration_force * -3.42 * velocity_direction, mass, delta - ) - # Normal movement - if abs(velocity.x) < max_velocity[state]: - out_vel.x = PhysicsFunc.two_step_euler( - out_vel.x, (acceleration_force[state].x) * direction.x, mass, delta - ) - elif !reverse_move: - out_vel.x = max_velocity[state] * direction.x - # TODO is_on_dropThrough does the action, is that ok? yEs, MaAsTeR-ChAn - # TODO Drop Through coyote time? - if Input.is_action_just_pressed("jump") && is_on_dropThrough(): - return Vector2(out_vel.x, _gravity * delta) - # Jumping when grounded or jump is buffered - if Input.is_action_just_pressed("jump") || (jump_buffer_filled && is_on_floor()) || stomping: - snap_possible = false - return calculate_jump_velocity(velocity, delta, direction) + # Slowing down movement when not controlling direction + if is_equal_approx(direction.x, 0): + # TODO Handle Deadzones + out_vel.x = PhysicsFunc.two_step_euler( + out_vel.x, deceleration_force * -1 * velocity_direction, mass, delta + ) + if abs(out_vel.x) > abs(velocity.x): + out_vel.x = 0 + else: + # Reversing movement + # When turning the opposite direction, friction is added to the opposite acceleration movement + var reverse_move = is_reversing_horizontal_movement(direction) + if reverse_move: + # TODO dont put constants in here + out_vel.x = PhysicsFunc.two_step_euler( + out_vel.x, deceleration_force * -3.42 * velocity_direction, mass, delta + ) + # Normal movement + if abs(velocity.x) < max_velocity[state]: + out_vel.x = PhysicsFunc.two_step_euler( + out_vel.x, (acceleration_force[state].x) * direction.x, mass, delta + ) + elif !reverse_move: + out_vel.x = max_velocity[state] * direction.x + # TODO is_on_dropThrough does the action, is that ok? yEs, MaAsTeR-ChAn + # TODO Drop Through coyote time? + if Input.is_action_just_pressed("jump") && is_on_dropThrough(): + return Vector2(out_vel.x, _gravity * delta) + # Jumping when grounded or jump is buffered + if Input.is_action_just_pressed("jump") || (jump_buffer_filled && is_on_floor()) || stomping: + snap_possible = false + return calculate_jump_velocity(velocity, delta, direction) - elif player_state_machine.coyote_hanging: - out_vel.y = 0 + elif player_state_machine.coyote_hanging: + out_vel.y = 0 - else: - out_vel.y = _gravity * delta + else: + out_vel.y = _gravity * delta - return out_vel + return out_vel func is_on_dropThrough(): - var bodies: Array = $BlobbySkin.get_overlapping_bodies() - for i in range(0, bodies.size()): - if bodies[i].get_collision_mask_bit(7): - set_collision_mask_bit(7, false) - return true - return false + var bodies: Array = $BlobbySkin.get_overlapping_bodies() + for i in range(0, bodies.size()): + if bodies[i].get_collision_mask_bit(7): + set_collision_mask_bit(7, false) + return true + return false func calculate_grounded_velocity( - linear_velocity: Vector2, delta: float, direction: Vector2 + linear_velocity: Vector2, delta: float, direction: Vector2 ) -> Vector2: - var state = player_state_machine.state - var out_vel := linear_velocity - var velocity_direction = 1.0 - if velocity.x < 0: - velocity_direction = -1.0 + var state = player_state_machine.state + var out_vel := linear_velocity + var velocity_direction = 1.0 + if velocity.x < 0: + velocity_direction = -1.0 - var deceleration_force = calculate_deceleration_force(_gravity, mass) + var deceleration_force = calculate_deceleration_force(_gravity, mass) - # Slowing down movement when not controlling direction - if is_equal_approx(direction.x, 0): - # TODO Handle Deadzones - out_vel.x = PhysicsFunc.two_step_euler( - out_vel.x, deceleration_force * -1 * velocity_direction, mass, delta - ) - if abs(out_vel.x) > abs(velocity.x): - out_vel.x = 0 - else: - # Reversing movement - # When turning the opposite direction, friction is added to the opposite acceleration movement - var reverse_move = is_reversing_horizontal_movement(direction) - if reverse_move: - # TODO dont put constants in here - out_vel.x = PhysicsFunc.two_step_euler( - out_vel.x, deceleration_force * -3.42 * velocity_direction, mass, delta - ) - # Normal movement - if abs(velocity.x) < max_velocity[state]: - out_vel.x = PhysicsFunc.two_step_euler( - out_vel.x, - ( - ( - acceleration_force[state].x - + (init_acceleration_force[init_boost_type] * int(init_boost)) - ) - * direction.x - ), - mass, - delta - ) - elif !reverse_move: - out_vel.x = max_velocity[state] * direction.x - # Jumping when grounded or jump is buffered - if Input.is_action_just_pressed("jump") || (jump_buffer_filled && is_on_floor()) || stomping: - snap_possible = false - #velocity += get_floor_velocity() * 0.5 - return calculate_jump_velocity(velocity, delta, direction) + # Slowing down movement when not controlling direction + if is_equal_approx(direction.x, 0): + # TODO Handle Deadzones + out_vel.x = PhysicsFunc.two_step_euler( + out_vel.x, deceleration_force * -1 * velocity_direction, mass, delta + ) + if abs(out_vel.x) > abs(velocity.x): + out_vel.x = 0 + else: + # Reversing movement + # When turning the opposite direction, friction is added to the opposite acceleration movement + var reverse_move = is_reversing_horizontal_movement(direction) + if reverse_move: + # TODO dont put constants in here + out_vel.x = PhysicsFunc.two_step_euler( + out_vel.x, deceleration_force * -3.42 * velocity_direction, mass, delta + ) + # Normal movement + if abs(velocity.x) < max_velocity[state]: + out_vel.x = PhysicsFunc.two_step_euler( + out_vel.x, + ( + ( + acceleration_force[state].x + + (init_acceleration_force[init_boost_type] * int(init_boost)) + ) + * direction.x + ), + mass, + delta + ) + elif !reverse_move: + out_vel.x = max_velocity[state] * direction.x + # Jumping when grounded or jump is buffered + if Input.is_action_just_pressed("jump") || (jump_buffer_filled && is_on_floor()) || stomping: + snap_possible = false + #velocity += get_floor_velocity() * 0.5 + return calculate_jump_velocity(velocity, delta, direction) - elif player_state_machine.coyote_hanging: - out_vel.y = 0 + elif player_state_machine.coyote_hanging: + out_vel.y = 0 - else: - out_vel.y = _gravity * delta + else: + out_vel.y = _gravity * delta - return out_vel + return out_vel # Determines if the player has reversed the steering direction # in reference to the current movement direction func is_reversing_horizontal_movement(direction: Vector2) -> bool: - return (direction.x > 0 && velocity.x < 0) || (direction.x < 0 && velocity.x > 0) + return (direction.x > 0 && velocity.x < 0) || (direction.x < 0 && velocity.x > 0) # Returns if the character is touching a wall with its whole body # Being able to touch a vertical surface over this length also makes it a qualified "wall" # Also sets wall_touch_direction func is_touching_wall_completely() -> bool: - var value = true - for left_raycast in left_wall_raycasts.get_children(): - wall_touch_direction = -1 - if !left_raycast.is_colliding(): - value = false - continue - if value == true: - return value + var value = true + for left_raycast in left_wall_raycasts.get_children(): + wall_touch_direction = -1 + if !left_raycast.is_colliding(): + value = false + continue + if value == true: + return value - value = true - for right_raycast in right_wall_raycasts.get_children(): - wall_touch_direction = 1 - if !right_raycast.is_colliding(): - value = false - continue - return value + value = true + for right_raycast in right_wall_raycasts.get_children(): + wall_touch_direction = 1 + if !right_raycast.is_colliding(): + value = false + continue + return value func is_crushed() -> bool: - var touching_left = false - for left_raycast in left_wall_raycasts.get_children(): - if left_raycast.is_colliding(): - touching_left = true - var touching_right = false - for right_raycast in right_wall_raycasts.get_children(): - if right_raycast.is_colliding(): - touching_right = true - return touching_left && touching_right + var touching_left = false + for left_raycast in left_wall_raycasts.get_children(): + if left_raycast.is_colliding(): + touching_left = true + var touching_right = false + for right_raycast in right_wall_raycasts.get_children(): + if right_raycast.is_colliding(): + touching_right = true + return touching_left && touching_right # Attached to wall state is in the PlayerStateMachine func is_correct_walljump_input(direction: Vector2) -> bool: - if is_touching_wall_completely(): - return ( - Input.is_action_pressed("jump") - && abs(direction.x + wall_touch_direction) < 1 - && abs(direction.x + wall_touch_direction) >= 0 - ) - return false + if is_touching_wall_completely(): + return ( + Input.is_action_pressed("jump") + && abs(direction.x + wall_touch_direction) < 1 + && abs(direction.x + wall_touch_direction) >= 0 + ) + return false func is_correct_airstrafe_input() -> bool: - return ( - air_strafe_charges > 0 - && (Input.is_action_just_pressed("move_right") || Input.is_action_just_pressed("move_left")) - ) + return ( + air_strafe_charges > 0 + && (Input.is_action_just_pressed("move_right") || Input.is_action_just_pressed("move_left")) + ) # Calculates the force of the ground friction func calculate_deceleration_force(_gravity: float, mass: float) -> float: - return floor_friction * _gravity * mass + return floor_friction * _gravity * mass func calculate_stomp_velocity(delta: float) -> float: - var v = 0 - if Input.is_action_pressed("jump"): - v += stomp_feedback - # print(stomp_time) - stomp_time -= delta - # print(stomp_time) - if stomp_time <= 0: - # print("stomping over") - stomping = false - stomp_time = init_stomp_time - return v + var v = 0 + if Input.is_action_pressed("jump"): + v += stomp_feedback + # print(stomp_time) + stomp_time -= delta + # print(stomp_time) + if stomp_time <= 0: + # print("stomping over") + stomping = false + stomp_time = init_stomp_time + return v func calculate_jump_velocity(linear_velocity: Vector2, delta: float, direction: Vector2) -> Vector2: - var state = player_state_machine.state - var additive_jump_force = velocity_jump_boost_ratio * abs(velocity.x) * mass - #TODO Single out stomping and make betta - #TODO too much force intially and too high with frog jump - if stomping: - additive_jump_force += calculate_stomp_velocity(delta) + var state = player_state_machine.state + var additive_jump_force = velocity_jump_boost_ratio * abs(velocity.x) * mass + #TODO Single out stomping and make betta + #TODO too much force intially and too high with frog jump + if stomping: + additive_jump_force += calculate_stomp_velocity(delta) - var y_acceleration_force = acceleration_force[state].y - var x_acceleration_force = acceleration_force[state].x + var y_acceleration_force = acceleration_force[state].y + var x_acceleration_force = acceleration_force[state].x - if duck_jumping: - y_acceleration_force *= duck_boost.y - linear_velocity.x += duck_boost.x * direction.x + if duck_jumping: + y_acceleration_force *= duck_boost.y + linear_velocity.x += duck_boost.x * direction.x - if state != "jump": - linear_velocity.y = PhysicsFunc.two_step_euler( - linear_velocity.y, - (y_acceleration_force / delta + additive_jump_force) * -1, - mass, - delta - ) + if state != "jump": + linear_velocity.y = PhysicsFunc.two_step_euler( + linear_velocity.y, + (y_acceleration_force / delta + additive_jump_force) * -1, + mass, + delta + ) # print(acceleration_force[state].y) # print(linear_velocity.y) - var y_velocity = 0 - if !Input.is_action_pressed("jump") && !stomping: - # Smooth transition from jumping to falling - if velocity.y > _gravity * delta * 10: - y_velocity += _gravity * delta * 10 - else: - y_velocity += (max(abs(linear_velocity.y), _gravity * delta) / 2) + var y_velocity = 0 + if !Input.is_action_pressed("jump") && !stomping: + # Smooth transition from jumping to falling + if velocity.y > _gravity * delta * 10: + y_velocity += _gravity * delta * 10 + else: + y_velocity += (max(abs(linear_velocity.y), _gravity * delta) / 2) - else: - y_velocity += _gravity * delta - - #if linear_velocity.y < max_velocity["jump"].y: - linear_velocity.y += y_velocity + else: + y_velocity += _gravity * delta + + #if linear_velocity.y < max_velocity["jump"].y: + linear_velocity.y += y_velocity - # TODO This is poop too - if ( - -max_velocity["jump"].x < velocity.x and direction.x < 0 - || max_velocity["jump"].x > velocity.x and direction.x > 0 - ): - var absolut = 1 - initial_velocity_dependence - var divisor = 1 / max(0.1, initial_velocity_dependence) - var movement_factor = absolut + abs(velocity.x) / (max_velocity["fall"].x * divisor) - linear_velocity.x = PhysicsFunc.two_step_euler( - linear_velocity.x, x_acceleration_force * movement_factor * direction.x, mass, delta - ) + # TODO This is poop too + if ( + -max_velocity["jump"].x < velocity.x and direction.x < 0 + || max_velocity["jump"].x > velocity.x and direction.x > 0 + ): + var absolut = 1 - initial_velocity_dependence + var divisor = 1 / max(0.1, initial_velocity_dependence) + var movement_factor = absolut + abs(velocity.x) / (max_velocity["fall"].x * divisor) + linear_velocity.x = PhysicsFunc.two_step_euler( + linear_velocity.x, x_acceleration_force * movement_factor * direction.x, mass, delta + ) - if is_correct_airstrafe_input(): - linear_velocity = execute_airstrafe(linear_velocity, delta, direction) + if is_correct_airstrafe_input(): + linear_velocity = execute_airstrafe(linear_velocity, delta, direction) # print(linear_velocity.y) - return linear_velocity + return linear_velocity # Only applicable to downwards gravity # Can set the jump buffer func calculate_fall_velocity(linear_velocity: Vector2, delta: float, direction: Vector2) -> Vector2: - var state = player_state_machine.state - if velocity.y < max_velocity["fall"].y: - linear_velocity.y = PhysicsFunc.two_step_euler( - linear_velocity.y, _gravity * mass, mass, delta - ) - else: - linear_velocity.y = max_velocity["fall"].y - if ( - -max_velocity["fall"].x < velocity.x and direction.x < 0 - || max_velocity["fall"].x > velocity.x and direction.x > 0 - ): - # TODO This is poop - var absolut = 1 - initial_velocity_dependence - var divisor = 1 / max(0.1, initial_velocity_dependence) - var movementFactor = absolut + abs(velocity.x) / (max_velocity["fall"].x * divisor) - linear_velocity.x = PhysicsFunc.two_step_euler( - linear_velocity.x, - acceleration_force[state].x * movementFactor * direction.x, - mass, - delta - ) - if Input.is_action_just_pressed("jump"): - jump_buffer_filled = true - if is_correct_airstrafe_input(): - linear_velocity = execute_airstrafe(linear_velocity, delta, direction) - if stomping: - linear_velocity = calculate_jump_velocity(Vector2(linear_velocity.x, 0), delta, direction) - return linear_velocity + var state = player_state_machine.state + if velocity.y < max_velocity["fall"].y: + linear_velocity.y = PhysicsFunc.two_step_euler( + linear_velocity.y, _gravity * mass, mass, delta + ) + else: + linear_velocity.y = max_velocity["fall"].y + if ( + -max_velocity["fall"].x < velocity.x and direction.x < 0 + || max_velocity["fall"].x > velocity.x and direction.x > 0 + ): + # TODO This is poop + var absolut = 1 - initial_velocity_dependence + var divisor = 1 / max(0.1, initial_velocity_dependence) + var movementFactor = absolut + abs(velocity.x) / (max_velocity["fall"].x * divisor) + linear_velocity.x = PhysicsFunc.two_step_euler( + linear_velocity.x, + acceleration_force[state].x * movementFactor * direction.x, + mass, + delta + ) + if Input.is_action_just_pressed("jump"): + jump_buffer_filled = true + if is_correct_airstrafe_input(): + linear_velocity = execute_airstrafe(linear_velocity, delta, direction) + if stomping: + linear_velocity = calculate_jump_velocity(Vector2(linear_velocity.x, 0), delta, direction) + return linear_velocity func calculate_wallslide_velocity( - linear_velocity: Vector2, delta: float, direction: Vector2 + linear_velocity: Vector2, delta: float, direction: Vector2 ) -> Vector2: - # Walljump mechanics - if is_correct_walljump_input(direction): - linear_velocity.x = PhysicsFunc.two_step_euler( - 0, acceleration_force["walljump"].x / delta * direction.x, mass, delta - ) - linear_velocity.y = PhysicsFunc.two_step_euler( - 0, acceleration_force["walljump"].y / delta * -1, mass, delta - ) - elif is_correct_airstrafe_input(): - # var rev = 1 if !is_reversing_horizontal_movement(direction) else -1 - linear_velocity = execute_airstrafe(linear_velocity, delta, direction) - elif ( - abs(direction.x + wall_touch_direction) < 1 - && abs(direction.x + wall_touch_direction) >= 0 - ): - var absolut = 1 - initial_velocity_dependence - var divisor = 1 / max(0.1, initial_velocity_dependence) - var movementFactor = absolut + abs(velocity.x) / (max_velocity["fall"].x * divisor) - linear_velocity.x = PhysicsFunc.two_step_euler( - linear_velocity.x, - acceleration_force["fall"].x * movementFactor * direction.x, - mass, - delta - ) - else: - # TODO dont put constants in here - linear_velocity.y = PhysicsFunc.two_step_euler( - linear_velocity.y * 0.94, _gravity * mass, mass, delta - ) - # TODO single out to function - air_strafe_charges = ( - air_strafe_charges + 1 - if max_air_strafe_charges > air_strafe_charges - else 0 - ) - return linear_velocity.rotated(rotation) + # Walljump mechanics + if is_correct_walljump_input(direction): + linear_velocity.x = PhysicsFunc.two_step_euler( + 0, acceleration_force["walljump"].x / delta * direction.x, mass, delta + ) + linear_velocity.y = PhysicsFunc.two_step_euler( + 0, acceleration_force["walljump"].y / delta * -1, mass, delta + ) + elif is_correct_airstrafe_input(): + # var rev = 1 if !is_reversing_horizontal_movement(direction) else -1 + linear_velocity = execute_airstrafe(linear_velocity, delta, direction) + elif ( + abs(direction.x + wall_touch_direction) < 1 + && abs(direction.x + wall_touch_direction) >= 0 + ): + var absolut = 1 - initial_velocity_dependence + var divisor = 1 / max(0.1, initial_velocity_dependence) + var movementFactor = absolut + abs(velocity.x) / (max_velocity["fall"].x * divisor) + linear_velocity.x = PhysicsFunc.two_step_euler( + linear_velocity.x, + acceleration_force["fall"].x * movementFactor * direction.x, + mass, + delta + ) + else: + # TODO dont put constants in here + linear_velocity.y = PhysicsFunc.two_step_euler( + linear_velocity.y * 0.94, _gravity * mass, mass, delta + ) + # TODO single out to function + air_strafe_charges = ( + air_strafe_charges + 1 + if max_air_strafe_charges > air_strafe_charges + else 0 + ) + return linear_velocity.rotated(rotation) func execute_airstrafe(linear_velocity: Vector2, delta: float, direction: Vector2) -> Vector2: - # var rev = 1 if !is_reversing_horizontal_movement(direction) else -1 - # TODO Consider adding a extra state for airstrafing - # TODO Make airstrafing less instantaneous and moderate the impulse - if direction.x > 0: - effect_player.play("airstrafing") - else: - effect_player.play("airstrafingLeft") - if is_reversing_horizontal_movement(direction): - linear_velocity.x = 0 - linear_velocity.x = PhysicsFunc.two_step_euler( - linear_velocity.x, acceleration_force["air_strafe"].x / delta * direction.x, mass, delta - ) - if linear_velocity.y > 0: - # TODO Put constant elsewhere - linear_velocity.y = linear_velocity.y * 0.33 - air_strafe_charges -= 1 - return linear_velocity + # var rev = 1 if !is_reversing_horizontal_movement(direction) else -1 + # TODO Consider adding a extra state for airstrafing + # TODO Make airstrafing less instantaneous and moderate the impulse + if direction.x > 0: + effect_player.play("airstrafing") + else: + effect_player.play("airstrafingLeft") + if is_reversing_horizontal_movement(direction): + linear_velocity.x = 0 + linear_velocity.x = PhysicsFunc.two_step_euler( + linear_velocity.x, acceleration_force["air_strafe"].x / delta * direction.x, mass, delta + ) + if linear_velocity.y > 0: + # TODO Put constant elsewhere + linear_velocity.y = linear_velocity.y * 0.33 + air_strafe_charges -= 1 + return linear_velocity func calculate_slope_rotation(_onfloor: bool) -> float: - var angle = 0 - var slope_angle_left = $SlopeRaycastLeft.get_collision_normal().rotated(PI / 2).angle() - var slope_angle_right = $SlopeRaycastRight.get_collision_normal().rotated(PI / 2).angle() - # avoid invalid angles and stay in rotation when touching ground completely - if ( - !(-PI / 2 <= slope_angle_left && slope_angle_left <= PI / 2) - || !(-PI / 2 <= slope_angle_right && slope_angle_right <= PI / 2) - || (is_equal_approx(abs(slope_angle_left), abs(slope_angle_right))) - ): - return ( - previous_rotation - if abs(rad2deg(previous_rotation)) > 1 && !is_equal_approx(slope_angle_left, 0) - else 0.0 - ) - # downturn - if ( - abs(slope_angle_left) > abs(slope_angle_right) && velocity.x < -10 - || abs(slope_angle_right) > abs(slope_angle_left) && velocity.x > 10 - ): - var length_vector: Vector2 = ( - $SlopeRaycastRight.get_collision_point() - - $SlopeRaycastLeft.get_collision_point() - ) - angle = length_vector.angle() - # upturn - else: - var length_vector: Vector2 = ( - $SlopeRaycastLeft.get_collision_point() - - $SlopeRaycastRight.get_collision_point() - ) - angle = length_vector.angle() - PI - previous_rotation = angle - if is_equal_approx(deg2rad(angle), 0): - pass - return angle + var angle = 0 + var slope_angle_left = $SlopeRaycastLeft.get_collision_normal().rotated(PI / 2).angle() + var slope_angle_right = $SlopeRaycastRight.get_collision_normal().rotated(PI / 2).angle() + # avoid invalid angles and stay in rotation when touching ground completely + if ( + !(-PI / 2 <= slope_angle_left && slope_angle_left <= PI / 2) + || !(-PI / 2 <= slope_angle_right && slope_angle_right <= PI / 2) + || (is_equal_approx(abs(slope_angle_left), abs(slope_angle_right))) + ): + return ( + previous_rotation + if abs(rad2deg(previous_rotation)) > 1 && !is_equal_approx(slope_angle_left, 0) + else 0.0 + ) + # downturn + if ( + abs(slope_angle_left) > abs(slope_angle_right) && velocity.x < -10 + || abs(slope_angle_right) > abs(slope_angle_left) && velocity.x > 10 + ): + var length_vector: Vector2 = ( + $SlopeRaycastRight.get_collision_point() + - $SlopeRaycastLeft.get_collision_point() + ) + angle = length_vector.angle() + # upturn + else: + var length_vector: Vector2 = ( + $SlopeRaycastLeft.get_collision_point() + - $SlopeRaycastRight.get_collision_point() + ) + angle = length_vector.angle() - PI + previous_rotation = angle + if is_equal_approx(deg2rad(angle), 0): + pass + return angle # TODO could be expanded with a parameter about what got stomped func stomp() -> void: - #print("stomping") - #print(player_state_machine.state) - scene_audio.play_parallel_sound( - "res://assets/sounds/FABRIC_Flap_03_mono.wav", -15, false, 1.5, 0.2 - ) - scene_audio.play_parallel_sound("res://assets/sounds/CLASP_Plastic_Open_stereo.wav", -12) - stomping = true + #print("stomping") + #print(player_state_machine.state) + scene_audio.play_parallel_sound( + "res://assets/sounds/FABRIC_Flap_03_mono.wav", -15, false, 1.5, 0.2 + ) + scene_audio.play_parallel_sound("res://assets/sounds/CLASP_Plastic_Open_stereo.wav", -12) + stomping = true # TOD lose_power_up function func receive_power_up(kind: String) -> void: - if kind == "shield": - $BubbleShieldViewport/IridescenceBall.visible = true - shielded = true + if kind == "shield": + $BubbleShieldViewport/IridescenceBall.visible = true + shielded = true # TODO Maybe this should be a state in itself? func die(animation_number: int = 0) -> void: - if level_state.is_dead: - return - if shielded: - shielded = false - $BubbleShieldViewport/IridescenceBall.visible = false - $InvincibilityTimer.start() - $BlobbySprite.material = invincible_shader - return - elif !$InvincibilityTimer.is_stopped(): - return - z_index = 1 - $BlobbySprite.material = death_shader - signal_manager.emit_signal("player_died", animation_number) - $"%BlobbymationTree".active = false - $"%BlobbymationPlayer".play("dying3") - if animation_number == 0: - $"%BlobbymationPlayer".play("expandingDisolve") - if animation_number == -1: - respawn() - return - scene_audio.play_parallel_sound(death_sound_1, -15) - scene_audio.play_parallel_sound(death_sound_2, -16) + if level_state.is_dead: + return + if shielded: + shielded = false + $BubbleShieldViewport/IridescenceBall.visible = false + $InvincibilityTimer.start() + $BlobbySprite.material = invincible_shader + return + elif !$InvincibilityTimer.is_stopped(): + return + z_index = 1 + $BlobbySprite.material = death_shader + signal_manager.emit_signal("player_died", animation_number) + $"%BlobbymationTree".active = false + $"%BlobbymationPlayer".play("dying3") + if animation_number == 0: + $"%BlobbymationPlayer".play("expandingDisolve") + if animation_number == -1: + respawn() + return + scene_audio.play_parallel_sound(death_sound_1, -15) + scene_audio.play_parallel_sound(death_sound_2, -16) func die_for_real(animation_number: int = 0) -> void: - shielded = false - $BubbleShieldViewport/IridescenceBall.visible = false - die(animation_number) + shielded = false + $BubbleShieldViewport/IridescenceBall.visible = false + die(animation_number) # TODO Checkpoint system func respawn() -> void: - # Is tied to the death animation - get_tree().reload_current_scene() + # Is tied to the death animation + get_tree().reload_current_scene() # When the Enemy stomp AREA enters the enemy collision area -> stomp func _on_BlobbySkin_area_entered(area: Area2D) -> void: - if area.is_in_group("harmful"): - die() - if area.is_in_group("pit"): - #scene_audio.play_parallel_sound(death_sound_1, -15) - scene_audio.play_parallel_sound(death_sound_2, -16) - $PitfallTimer.start() + if area.is_in_group("harmful"): + die() + if area.is_in_group("pit"): + #scene_audio.play_parallel_sound(death_sound_1, -15) + scene_audio.play_parallel_sound(death_sound_2, -16) + $PitfallTimer.start() # This problem stems from trying to decelerate a walk @@ -518,54 +518,54 @@ func _on_BlobbySkin_area_entered(area: Area2D) -> void: # It is particularly usefull for moving floor physics # TODO Setting y velocity this way stopped is_on_floor() from working correctly func _on_Blobby_got_grounded() -> void: - velocity.x -= get_floor_velocity().x - snap_possible = true - var floor_object = get_last_slide_collision().collider.get_parent() - #TODO There is already a friction property in engine - if "slide_friction" in floor_object: - floor_friction = floor_object.slide_friction - else: - floor_friction = base_floor_friction - air_strafe_charges = ( - air_strafe_charges + 1 - if max_air_strafe_charges > air_strafe_charges - else 0 - ) + velocity.x -= get_floor_velocity().x + snap_possible = true + var floor_object = get_last_slide_collision().collider.get_parent() + #TODO There is already a friction property in engine + if "slide_friction" in floor_object: + floor_friction = floor_object.slide_friction + else: + floor_friction = base_floor_friction + air_strafe_charges = ( + air_strafe_charges + 1 + if max_air_strafe_charges > air_strafe_charges + else 0 + ) func _on_BlobbySkin_body_exited(body: Node) -> void: - # This is for drop through platforms - if body.get_collision_mask_bit(7): - set_collision_mask_bit(7, true) + # This is for drop through platforms + if body.get_collision_mask_bit(7): + set_collision_mask_bit(7, true) func _on_InvincibilityTimer_timeout() -> void: - $BlobbySprite.material = null - for area in $BlobbySkin.get_overlapping_areas(): - if area.is_in_group("harmful"): - die() + $BlobbySprite.material = null + for area in $BlobbySkin.get_overlapping_areas(): + if area.is_in_group("harmful"): + die() func _on_CrushTimer_timeout() -> void: - if is_crushed(): - die_for_real() + if is_crushed(): + die_for_real() func handle_grounded_movement(delta: float, direction: Vector2) -> Vector2: - return calculate_grounded_velocity(velocity, delta, direction) + return calculate_grounded_velocity(velocity, delta, direction) func handle_jump_movement(delta: float, direction: Vector2) -> Vector2: - return calculate_jump_velocity(velocity, delta, direction) + return calculate_jump_velocity(velocity, delta, direction) func handle_duck_movement(delta: float, direction: Vector2) -> Vector2: - return calculate_duck_velocity(velocity, delta, direction) + return calculate_duck_velocity(velocity, delta, direction) func handle_fall_movement(delta: float, direction: Vector2) -> Vector2: - return calculate_fall_velocity(velocity, delta, direction) + return calculate_fall_velocity(velocity, delta, direction) func handle_wallslide_movement(delta: float, direction: Vector2) -> Vector2: - return calculate_wallslide_velocity(velocity, delta, direction) + return calculate_wallslide_velocity(velocity, delta, direction) diff --git a/src/Contraptions/Portal/Portal.gd b/src/Contraptions/Portal/Portal.gd index 4b0d4db..d84c65a 100644 --- a/src/Contraptions/Portal/Portal.gd +++ b/src/Contraptions/Portal/Portal.gd @@ -10,33 +10,33 @@ export(String, FILE, "*.tscn") var next_scene export(bool) var is_active func _ready() -> void: - if(!is_active): - monitoring = false - signal_manager.connect("terminal_activated", self, "activate_portal") - else: - $portal.frame = 0 + if(!is_active): + monitoring = false + signal_manager.connect("terminal_activated", self, "activate_portal") + else: + $portal.frame = 0 func _get_configuration_warning() -> String: - return "The next scene property can't be empty" if not next_scene else "" + return "The next scene property can't be empty" if not next_scene else "" func level_completion() -> void: - GlobalState.remove_savepoint(levelName) - signal_manager.emit_signal("level_completed") + GlobalState.remove_savepoint(levelName) + signal_manager.emit_signal("level_completed") func activate_portal(_time: float) -> void: - $AnimationPlayer.play("activatePortal") - monitoring = true + $AnimationPlayer.play("activatePortal") + monitoring = true func teleport() -> void: - GlobalAudio.play_scene_independent("res://assets/sounds/MAGIC_SPELL_Morphing_Synth_Harp_Scales_stereo.wav", "Music", -15) - get_tree().paused = true - anim_player.play("fade_in") - # TODO This doesn't pause the game but should - yield(anim_player, "animation_finished") - if ResourceLoader.exists(next_scene): - get_tree().change_scene(next_scene) + GlobalAudio.play_scene_independent("res://assets/sounds/MAGIC_SPELL_Morphing_Synth_Harp_Scales_stereo.wav", "Music", -15) + get_tree().paused = true + anim_player.play("fade_in") + # TODO This doesn't pause the game but should + yield(anim_player, "animation_finished") + if ResourceLoader.exists(next_scene): + get_tree().change_scene(next_scene) func _on_body_entered(_body: Node) -> void: - level_completion() - teleport() + level_completion() + teleport() diff --git a/src/Levels/Level 0.1.tscn b/src/Levels/Level 0.1.tscn index dc1dcf2..dca3788 100644 --- a/src/Levels/Level 0.1.tscn +++ b/src/Levels/Level 0.1.tscn @@ -57,7 +57,6 @@ [ext_resource path="res://assets/environment/decor/longductor/Longductor9.png" type="Texture" id=55] [ext_resource path="res://assets/environment/decor/screen/Screen1.png" type="Texture" id=56] [ext_resource path="res://assets/environment/decor/Ceiling-Struct.png" type="Texture" id=57] -[ext_resource path="res://addons/ACVoicebox/ACVoicebox.tscn" type="PackedScene" id=58] [sub_resource type="Shader" id=15] code = "shader_type canvas_item; @@ -1078,10 +1077,6 @@ __meta__ = { "_edit_vertical_guides_": [ 2880.0 ] } -[node name="ACVoicebox" parent="." instance=ExtResource( 58 )] -volume_db = -23.016 -base_pitch = 2.5 - [node name="SceneAudio" parent="." instance=ExtResource( 14 )] visible = false diff --git a/src/Levels/Level 0.3.tscn b/src/Levels/Level 0.3.tscn index 0b87ad7..241ab28 100644 --- a/src/Levels/Level 0.3.tscn +++ b/src/Levels/Level 0.3.tscn @@ -235,10 +235,6 @@ visible = false unique_name_in_owner = true position = Vector2( -180, 113 ) scale = Vector2( 0.878906, 0.936025 ) -mass = null -jump_buffer_filled = null -death_sound_1 = null -death_sound_2 = null [node name="BlobbySprite" parent="Blobby" index="5"] frame = 7 diff --git a/src/Levels/Level 0.4.tscn b/src/Levels/Level 0.4.tscn index 706aaa4..92e550a 100644 --- a/src/Levels/Level 0.4.tscn +++ b/src/Levels/Level 0.4.tscn @@ -124,13 +124,9 @@ drag_margin_bottom = 0.3 unique_name_in_owner = true position = Vector2( -70, 1 ) scale = Vector2( 0.878906, 0.936025 ) -mass = null -jump_buffer_filled = null -death_sound_1 = null -death_sound_2 = null [node name="BlobbySprite" parent="Blobby" index="5"] -frame = 9 +frame = 8 [node name="BlobbymationTree" parent="Blobby/BlobbySprite" index="0"] parameters/playback = SubResource( 6 ) diff --git a/src/Levels/Level 2.tscn b/src/Levels/Level 2.tscn index e5becdb..6a26c58 100644 --- a/src/Levels/Level 2.tscn +++ b/src/Levels/Level 2.tscn @@ -131,6 +131,9 @@ unique_name_in_owner = true position = Vector2( -64, -1.90735e-06 ) scale = Vector2( 0.878906, 0.936025 ) +[node name="BlobbySprite" parent="Blobby" index="5"] +frame = 10 + [node name="BlobbymationTree" parent="Blobby/BlobbySprite" index="0"] parameters/playback = SubResource( 6 ) diff --git a/src/Levels/Level 3.tscn b/src/Levels/Level 3.tscn index 4040d65..5d4a7d2 100644 --- a/src/Levels/Level 3.tscn +++ b/src/Levels/Level 3.tscn @@ -1010,7 +1010,7 @@ position = Vector2( -88, 96 ) scale = Vector2( 0.878906, 0.936025 ) [node name="BlobbySprite" parent="Blobby" index="5"] -frame = 8 +frame = 7 [node name="BlobbymationTree" parent="Blobby/BlobbySprite" index="0"] parameters/playback = SubResource( 6 ) diff --git a/src/Levels/Level 4.tscn b/src/Levels/Level 4.tscn index bad8d02..63260a6 100644 --- a/src/Levels/Level 4.tscn +++ b/src/Levels/Level 4.tscn @@ -119,7 +119,7 @@ position = Vector2( -183, 111 ) scale = Vector2( 0.878906, 0.936025 ) [node name="BlobbySprite" parent="Blobby" index="5"] -frame = 7 +frame = 6 [node name="BlobbymationTree" parent="Blobby/BlobbySprite" index="0"] parameters/playback = SubResource( 6 ) @@ -185,7 +185,7 @@ position = Vector2( -112, -748 ) rotation = -3.14159 [node name="FlyingLaserCutter7" parent="." instance=ExtResource( 13 )] -position = Vector2( -58, -808 ) +position = Vector2( -48, -799 ) rotation = -3.14159 [node name="FlyingLaserCutter8" parent="." instance=ExtResource( 13 )] diff --git a/src/Levels/Level 5.tscn b/src/Levels/Level 5.tscn index 6fc0983..389f83b 100644 --- a/src/Levels/Level 5.tscn +++ b/src/Levels/Level 5.tscn @@ -194,7 +194,7 @@ position = Vector2( -45, -5.96046e-08 ) scale = Vector2( 0.878906, 0.936025 ) [node name="BlobbySprite" parent="Blobby" index="5"] -frame = 8 +frame = 5 [node name="BlobbymationTree" parent="Blobby/BlobbySprite" index="0"] parameters/playback = SubResource( 6 ) diff --git a/src/Levels/Templates/LevelTemplate.gd b/src/Levels/Templates/LevelTemplate.gd index 6e7407e..db6aa78 100644 --- a/src/Levels/Templates/LevelTemplate.gd +++ b/src/Levels/Templates/LevelTemplate.gd @@ -11,19 +11,19 @@ onready var level_state := $"%LevelState" func _ready() -> void: - $TransitionLayer.visible = true - var transition_tween = Tween.new() - add_child(transition_tween) - var property = "shader_param/position" - var node = $TransitionLayer/SceneTransition - transition_tween.interpolate_property(node.material, property,-1.5, 1.0, 0.94, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT) - transition_tween.start() - # should spawn the tutorial thingies which are still remembered in the progress dictionary - signal_manager.connect("terminal_activated", self, "stop_level_music") - signal_manager.emit_signal("level_loaded") - get_tree().paused = false - $SceneAudio.play_parallel_sound(level_music, level_music_attenuation, false, 1.0, 0, "Music") - $SceneAudio.play_parallel_sound(level_ambiance, level_ambiance_attenuation) + $TransitionLayer.visible = true + var transition_tween = Tween.new() + add_child(transition_tween) + var property = "shader_param/position" + var node = $TransitionLayer/SceneTransition + transition_tween.interpolate_property(node.material, property,-1.5, 1.0, 0.94, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT) + transition_tween.start() + # should spawn the tutorial thingies which are still remembered in the progress dictionary + signal_manager.connect("terminal_activated", self, "stop_level_music") + signal_manager.emit_signal("level_loaded") + get_tree().paused = false + $SceneAudio.play_parallel_sound(level_music, level_music_attenuation, false, 1.0, 0, "Music") + $SceneAudio.play_parallel_sound(level_ambiance, level_ambiance_attenuation) func stop_level_music(_unused: float) -> void: - $SceneAudio.stop_parallel_sound(level_music) + $SceneAudio.stop_parallel_sound(level_music) diff --git a/src/Sounds/default_bus_layout.tres b/src/Sounds/default_bus_layout.tres index 3abf623..c24fd87 100644 --- a/src/Sounds/default_bus_layout.tres +++ b/src/Sounds/default_bus_layout.tres @@ -41,7 +41,7 @@ resource_name = "LowPassFilter" cutoff_hz = 3000.0 [resource] -bus/0/volume_db = inf_neg +bus/0/volume_db = -20.0 bus/1/name = "Music" bus/1/solo = false bus/1/mute = false diff --git a/src/UserInterface/Screens/InGameMenu/PauseScreen.gd b/src/UserInterface/Screens/InGameMenu/PauseScreen.gd index c394673..b750330 100644 --- a/src/UserInterface/Screens/InGameMenu/PauseScreen.gd +++ b/src/UserInterface/Screens/InGameMenu/PauseScreen.gd @@ -11,58 +11,58 @@ var paused := false setget set_paused var block_ui_cancel = false func _ready(): - #signal_manager.connect("player_died", self, "_on_GlobalState_player_died") - $ControlsMenu.visible = false - $ControlsMenu.set_process_input(false) - $AudioMenu.set_process_input(false) - signal_manager.connect("game_paused", self, "set_paused") - pass + #signal_manager.connect("player_died", self, "_on_GlobalState_player_died") + $ControlsMenu.visible = false + $ControlsMenu.set_process_input(false) + $AudioMenu.set_process_input(false) + signal_manager.connect("game_paused", self, "set_paused") + pass func open_audio_menu(): - block_ui_cancel = true - pause_overlay.visible = false - $AudioMenu.visible = true - $AudioMenu.set_process_input(true) - $"%MasterSlider".grab_focus() + block_ui_cancel = true + pause_overlay.visible = false + $AudioMenu.visible = true + $AudioMenu.set_process_input(true) + $"%MasterSlider".grab_focus() func close_audio_menu(): - $AudioMenu.visible = false - pause_overlay.visible = true - $AudioMenu.set_process_input(false) - $"%Continue".grab_focus() - get_tree().set_input_as_handled() + $AudioMenu.visible = false + pause_overlay.visible = true + $AudioMenu.set_process_input(false) + $"%Continue".grab_focus() + get_tree().set_input_as_handled() func _on_GlobalState_player_died() -> void: - self.paused = true - pause_title.text = "You lost" + self.paused = true + pause_title.text = "You lost" func _input(event: InputEvent) -> void: - if !event.is_action("pause"): - return - if block_ui_cancel || $"%ControlsMenu".visible: - block_ui_cancel = false - get_tree().set_input_as_handled() - return - #not oder ! schaltet einen boolean um - #Ist self hier notwendig? - - self.paused = not paused - block_ui_cancel = true + if !event.is_action("pause"): + return + if block_ui_cancel || $"%ControlsMenu".visible: + block_ui_cancel = false + get_tree().set_input_as_handled() + return + #not oder ! schaltet einen boolean um + #Ist self hier notwendig? + + self.paused = not paused + block_ui_cancel = true func set_paused(value: bool) -> void: - paused = value - get_tree().paused = value - pause_overlay.visible = value - if value == true: - $"%Continue".grab_focus() + paused = value + get_tree().paused = value + pause_overlay.visible = value + if value == true: + $"%Continue".grab_focus() func _on_Controls_button_up() -> void: - $ControlsMenu.visible = true - $ControlsMenu.set_process_input(true) - block_ui_cancel = true - pause_overlay.visible = false - $"%ProfilesMenu".grab_focus() + $ControlsMenu.visible = true + $ControlsMenu.set_process_input(true) + block_ui_cancel = true + pause_overlay.visible = false + $"%ProfilesMenu".grab_focus() diff --git a/src/UserInterface/Screens/MainMenu/MainScreen.gd b/src/UserInterface/Screens/MainMenu/MainScreen.gd index 8c2105d..4f10008 100644 --- a/src/UserInterface/Screens/MainMenu/MainScreen.gd +++ b/src/UserInterface/Screens/MainMenu/MainScreen.gd @@ -2,5 +2,5 @@ extends Control func _ready() -> void: - $"%PlayButton".grab_focus() - GlobalAudio.play_scene_independent("res://assets/music/Shopping For The Future (LOOP).wav","Music", -17, true) + $"%PlayButton".grab_focus() + GlobalAudio.play_scene_independent("res://assets/music/Shopping For The Future (LOOP).wav","Music", -17, true) diff --git a/src/UserInterface/Screens/MainMenu/MainScreen.tscn b/src/UserInterface/Screens/MainMenu/MainScreen.tscn index 5b5aad6..914e56a 100644 --- a/src/UserInterface/Screens/MainMenu/MainScreen.tscn +++ b/src/UserInterface/Screens/MainMenu/MainScreen.tscn @@ -225,8 +225,7 @@ scroll_horizontal_enabled = false script = ExtResource( 11 ) [node name="VBoxContainer" type="VBoxContainer" parent="MenuContainer/Panel/LevelList"] -margin_right = 123.0 -margin_bottom = 102.0 +margin_right = 119.0 grow_horizontal = 2 grow_vertical = 2 size_flags_horizontal = 3 diff --git a/src/Utilities/LevelState.gd b/src/Utilities/LevelState.gd index 8d16dbf..afa6b1f 100644 --- a/src/Utilities/LevelState.gd +++ b/src/Utilities/LevelState.gd @@ -11,105 +11,105 @@ var freed_frogs := [] var is_dead: = false setget set_dead func _ready() -> void: - GlobalState.gsr.last_played_level = levelName - SaveManager.save_default() - signal_manager.connect("level_completed", self, "_on_level_completed") - signal_manager.connect("player_died", self, "player_dying") + GlobalState.gsr.last_played_level = levelName + SaveManager.save_default() + signal_manager.connect("level_completed", self, "_on_level_completed") + signal_manager.connect("player_died", self, "player_dying") func reset() -> void: - deaths = 0 - currency = 0 - freed_frogs = [] - # TODO Maybe not the place for this? - if GlobalState.gsr.progress_dict.has(levelName): - GlobalState.gsr.progress_dict[levelName].erase("savepoint") + deaths = 0 + currency = 0 + freed_frogs = [] + # TODO Maybe not the place for this? + if GlobalState.gsr.progress_dict.has(levelName): + GlobalState.gsr.progress_dict[levelName].erase("savepoint") func set_currency(value: int) -> void: - currency = value - signal_manager.emit_signal("currency_updated") + currency = value + signal_manager.emit_signal("currency_updated") func set_deaths(value: int) -> void: - deaths = value + deaths = value func set_dead(value: bool) -> void: - is_dead = value + is_dead = value func register_frog(number: int, freed: bool = false) -> void: - update_global_state() - if(!GlobalState.gsr.progress_dict[levelName]["froggies"].has(number)): - GlobalState.gsr.progress_dict[levelName]["froggies"][number] = freed - GlobalState.save() + update_global_state() + if(!GlobalState.gsr.progress_dict[levelName]["froggies"].has(number)): + GlobalState.gsr.progress_dict[levelName]["froggies"][number] = freed + GlobalState.save() func free_a_frog(number: int) -> void: - freed_frogs.append(number) + freed_frogs.append(number) func needs_tutorial(lesson: String) -> bool: - if(!GlobalState.gsr.tutorial_prompts.has(lesson)): - return false - return GlobalState.gsr.tutorial_prompts[lesson] + if(!GlobalState.gsr.tutorial_prompts.has(lesson)): + return false + return GlobalState.gsr.tutorial_prompts[lesson] func register_tutorial(lesson: String) -> void: - if(GlobalState.gsr.tutorial_prompts.has(lesson)): - return - GlobalState.gsr.tutorial_prompts[lesson] = true - GlobalState.save() + if(GlobalState.gsr.tutorial_prompts.has(lesson)): + return + GlobalState.gsr.tutorial_prompts[lesson] = true + GlobalState.save() func absolved_tutorial(lesson: String) -> void: - if(!GlobalState.gsr.tutorial_prompts.has(lesson)): - return - GlobalState.gsr.tutorial_prompts[lesson] = false - GlobalState.save() + if(!GlobalState.gsr.tutorial_prompts.has(lesson)): + return + GlobalState.gsr.tutorial_prompts[lesson] = false + GlobalState.save() # Spends the currency when enough is available # and returns true if so. Else it does not spend and return false. func spend_currency(cost: int) -> bool: - # TODO member that - if(OS.is_debug_build()): - return true - if GlobalState.gsr.wallet + currency < cost: - return false - var remainder = currency - cost - if remainder >= 0: - currency = remainder - else: - currency = 0 - GlobalState.set_wallet(GlobalState.gsr.wallet + remainder) - return true + # TODO member that + if(OS.is_debug_build()): + return true + if GlobalState.gsr.wallet + currency < cost: + return false + var remainder = currency - cost + if remainder >= 0: + currency = remainder + else: + currency = 0 + GlobalState.set_wallet(GlobalState.gsr.wallet + remainder) + return true func _on_level_completed(): - #if(OS.is_debug_build()): - # return - update_global_state() - reset() + #if(OS.is_debug_build()): + # return + update_global_state() + reset() func update_global_state() -> void: - var progress_dict : Dictionary = GlobalState.get_progress() - var levelProgress : Dictionary = {} + var progress_dict : Dictionary = GlobalState.get_progress() + var levelProgress : Dictionary = {} - levelProgress["currency"] = currency - levelProgress["deaths"] = deaths - - # TODO Doesnt account for multiple plays of same level - if !progress_dict.has(levelName): - progress_dict[levelName] = levelProgress - else: - progress_dict[levelName]["currency"] = GlobalState.get_property_value(levelName,"currency") + currency - progress_dict[levelName]["deaths"] = GlobalState.get_property_value(levelName,"deaths") + deaths - if !progress_dict[levelName].has("froggies"): - progress_dict[levelName]["froggies"] = {} - else: - for frog_number in freed_frogs: - if progress_dict[levelName]["froggies"].has(frog_number): - progress_dict[levelName]["froggies"][frog_number] = true + levelProgress["currency"] = currency + levelProgress["deaths"] = deaths + + # TODO Doesnt account for multiple plays of same level + if !progress_dict.has(levelName): + progress_dict[levelName] = levelProgress + else: + progress_dict[levelName]["currency"] = GlobalState.get_property_value(levelName,"currency") + currency + progress_dict[levelName]["deaths"] = GlobalState.get_property_value(levelName,"deaths") + deaths + if !progress_dict[levelName].has("froggies"): + progress_dict[levelName]["froggies"] = {} + else: + for frog_number in freed_frogs: + if progress_dict[levelName]["froggies"].has(frog_number): + progress_dict[levelName]["froggies"][frog_number] = true - # TODO Wallet is independant from progress_dict because??? - GlobalState.set_wallet(GlobalState.gsr.wallet + currency) - GlobalState.set_progress(progress_dict) + # TODO Wallet is independant from progress_dict because??? + GlobalState.set_wallet(GlobalState.gsr.wallet + currency) + GlobalState.set_progress(progress_dict) func player_dying(animation_number: int = 0) -> void: - currency = 0 - is_dead = true - freed_frogs = [] - deaths += 1 - update_global_state() - deaths = 0 + currency = 0 + is_dead = true + freed_frogs = [] + deaths += 1 + update_global_state() + deaths = 0 diff --git a/src/Utilities/SceneAudio.gd b/src/Utilities/SceneAudio.gd index 02acc84..c7de026 100644 --- a/src/Utilities/SceneAudio.gd +++ b/src/Utilities/SceneAudio.gd @@ -8,74 +8,74 @@ onready var static_player: AudioStreamPlayer = $StaticPlayer # Plays sound with the static player, interrupting sounds if currently playing func play_sound( - sound_name: String, - attenuation: float = 0.0, - random_pitch = false, - pitch = 1.0, - start_time = 0.0, - bus: String = "Effects" + sound_name: String, + attenuation: float = 0.0, + random_pitch = false, + pitch = 1.0, + start_time = 0.0, + bus: String = "Effects" ) -> void: - # TODO is it bad to grab the stream each time? - var stream = GlobalState.sound_library[sound_name] - if random_pitch: - stream = AudioStreamRandomPitch.new() - stream.audio_stream = GlobalState.sound_library[sound_name] - static_player.stream = stream - static_player.volume_db = attenuation - static_player.bus = bus - static_player.pitch_scale = pitch - static_player.stream_paused = false - static_player.play(start_time) + # TODO is it bad to grab the stream each time? + var stream = GlobalState.sound_library[sound_name] + if random_pitch: + stream = AudioStreamRandomPitch.new() + stream.audio_stream = GlobalState.sound_library[sound_name] + static_player.stream = stream + static_player.volume_db = attenuation + static_player.bus = bus + static_player.pitch_scale = pitch + static_player.stream_paused = false + static_player.play(start_time) func stop_sound(): - static_player.stream_paused = true + static_player.stream_paused = true # Mirrors the GlobalAudio Method which can play sounds across scenes func play_parallel_sound( - sound_name: String, - attenuation: float = 0.0, - random_pitch = false, - pitch = 1.0, - start_time = 0.0, - bus: String = "Effects", - singleton = false + sound_name: String, + attenuation: float = 0.0, + random_pitch = false, + pitch = 1.0, + start_time = 0.0, + bus: String = "Effects", + singleton = false ) -> void: - if singleton && players.has(sound_name): - return - var disposable_player = AudioStreamPlayer.new() - add_child(disposable_player) - var stream = GlobalState.sound_library[sound_name] - if random_pitch: - stream = AudioStreamRandomPitch.new() - stream.audio_stream = GlobalState.sound_library[sound_name] - disposable_player.stream = stream - disposable_player.volume_db = attenuation - disposable_player.bus = bus - disposable_player.pitch_scale = pitch - disposable_player.play(start_time) - disposable_player.connect("finished", self, "dispose_parallel_player", [weakref(disposable_player)]) - players[sound_name] = weakref(disposable_player) + if singleton && players.has(sound_name): + return + var disposable_player = AudioStreamPlayer.new() + add_child(disposable_player) + var stream = GlobalState.sound_library[sound_name] + if random_pitch: + stream = AudioStreamRandomPitch.new() + stream.audio_stream = GlobalState.sound_library[sound_name] + disposable_player.stream = stream + disposable_player.volume_db = attenuation + disposable_player.bus = bus + disposable_player.pitch_scale = pitch + disposable_player.play(start_time) + disposable_player.connect("finished", self, "dispose_parallel_player", [weakref(disposable_player)]) + players[sound_name] = weakref(disposable_player) func dispose_parallel_player(player: WeakRef) -> void: - if !player.get_ref(): - return - player.get_ref().queue_free() + if !player.get_ref(): + return + player.get_ref().queue_free() func pause_parallel_sound(sound_name: String): - if players.has(sound_name) && players[sound_name].get_ref(): - players[sound_name].set_stream_paused(true) + if players.has(sound_name) && players[sound_name].get_ref(): + players[sound_name].set_stream_paused(true) func continue_parallel_sound(sound_name: String): - if players.has(sound_name) && players[sound_name].get_ref(): - players[sound_name].set_stream_paused(false) + if players.has(sound_name) && players[sound_name].get_ref(): + players[sound_name].set_stream_paused(false) func stop_parallel_sound(sound_name: String): - if players.has(sound_name) && players[sound_name].get_ref(): - dispose_parallel_player(players[sound_name]) - players.erase(sound_name) + if players.has(sound_name) && players[sound_name].get_ref(): + dispose_parallel_player(players[sound_name]) + players.erase(sound_name) diff --git a/src/Utilities/SignalManager.gd b/src/Utilities/SignalManager.gd index ea99f68..3d7759b 100644 --- a/src/Utilities/SignalManager.gd +++ b/src/Utilities/SignalManager.gd @@ -17,4 +17,4 @@ signal savemanager_saved() signal game_paused(value) func _on_Timer_timeout() -> void: - emit_signal("getback_timer_up") + emit_signal("getback_timer_up")