Compare commits
2 Commits
bd10d1789b
...
c365f76d80
| Author | SHA1 | Date | |
|---|---|---|---|
| c365f76d80 | |||
| 32ac46f840 |
+15
-3
@@ -1,3 +1,4 @@
|
||||
class_name IsoCamera
|
||||
extends Camera3D
|
||||
|
||||
@export var height: float = 25.0
|
||||
@@ -16,6 +17,11 @@ var _shake_amount: float = 0.0
|
||||
var _shake_decay: float = 0.0
|
||||
var _user_fov: float = 0.0
|
||||
|
||||
# Per-level framing multiplier: 1.0 = the designer's base shot, >1 dollies the camera
|
||||
# back for a wider view (the lobby uses this). Set by game_shell when a level loads;
|
||||
# kept separate from the scroll-wheel FOV zoom so the two don't fight.
|
||||
var _framing_scale: float = 1.0
|
||||
|
||||
# Trailing-camera state: _focus is the smoothed point the camera frames (it lags
|
||||
# the bull), _drag_offset is the velocity-driven trail that slides it behind.
|
||||
var _focus: Vector3 = Vector3.ZERO
|
||||
@@ -51,15 +57,21 @@ func adjust_zoom(ratio: float) -> void:
|
||||
_user_fov = clampf(_user_fov / ratio, fov_min, fov_max)
|
||||
|
||||
|
||||
## Dolly the camera in/out for the level being loaded. 1.0 is the base framing; >1 pulls
|
||||
## back for a wider shot (the lobby hub uses this). Independent of the scroll-wheel zoom.
|
||||
func set_framing_scale(scale: float) -> void:
|
||||
_framing_scale = maxf(scale, 0.1)
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
fov = lerpf(fov, _user_fov, delta * 8.0)
|
||||
|
||||
var angle_rad := deg_to_rad(horizontal_angle_deg)
|
||||
|
||||
var offset := Vector3(
|
||||
sin(angle_rad) * horizontal_distance,
|
||||
height,
|
||||
cos(angle_rad) * horizontal_distance
|
||||
sin(angle_rad) * horizontal_distance * _framing_scale,
|
||||
height * _framing_scale,
|
||||
cos(angle_rad) * horizontal_distance * _framing_scale
|
||||
)
|
||||
|
||||
var target := get_parent() as Node3D
|
||||
|
||||
@@ -5,6 +5,7 @@ extends Node3D
|
||||
## previous module first, so no old mesh or collider can survive into the next fight.
|
||||
|
||||
@onready var _level_root: Node3D = $LevelRoot
|
||||
@onready var _camera: IsoCamera = $Player/Camera3D
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
@@ -23,4 +24,5 @@ func load_active_level() -> void:
|
||||
if level == null or level.level_scene == null:
|
||||
push_warning("game_shell: active level has no level_scene")
|
||||
return
|
||||
_camera.set_framing_scale(level.camera_zoom)
|
||||
_level_root.add_child(level.level_scene.instantiate())
|
||||
|
||||
@@ -17,6 +17,10 @@ extends Resource
|
||||
@export var level_scene: PackedScene = null
|
||||
## Placeholder pip tint on the map until per-level icon art exists.
|
||||
@export var color: Color = Color(0.80, 0.62, 0.24)
|
||||
## Camera framing multiplier when this level loads — 1.0 is the shell camera's default
|
||||
## shot; >1 dollies the camera back for a wider view (the lobby pulls out so the whole
|
||||
## hub reads). Applied by game_shell; independent of the player's scroll-wheel zoom.
|
||||
@export var camera_zoom: float = 1.0
|
||||
## A boss level caps a run — its node is drawn larger and clearing it ends the map.
|
||||
@export var is_boss: bool = false
|
||||
## The enemy this level pits the bull against. Null → the usual matador wave (the
|
||||
|
||||
@@ -61,6 +61,8 @@ func _ready() -> void:
|
||||
_bear.enemy_scene = _BEAR_SCENE
|
||||
# The lobby is a fightless hub — no enemy_scene, so no wave spawns and no win/lose.
|
||||
_lobby = _make_level(&"lobby", "Lobby", _LOBBY_LEVEL, Color(0.62, 0.66, 0.72), false)
|
||||
# It's a roomy hub with nothing to fight — pull the camera back so more of it reads.
|
||||
_lobby.camera_zoom = 1.6
|
||||
|
||||
|
||||
func _make_level(
|
||||
|
||||
Reference in New Issue
Block a user