Class: Quake::Physics::Player
- Inherits:
-
Object
- Object
- Quake::Physics::Player
- Defined in:
- lib/quake/physics/player.rb
Overview
Full Quake player physics: gravity, friction, acceleration, jumping, ground detection, stair stepping, and swimming.
Constant Summary collapse
- GRAVITY =
Quake constants
800.0- FRICTION =
units/sec^2
4.0- STOP_SPEED =
100.0- MAX_SPEED =
320.0- ACCELERATE =
10.0- AIR_ACCELERATE =
0.7- JUMP_SPEED =
270.0- STEP_SIZE =
18.0- WATER_FRICTION =
1.0- WATER_ACCELERATE =
10.0- SENSITIVITY =
Camera
0.15- MAX_MOUSE_DELTA =
50- VIEW_HEIGHT =
eye offset from origin (origin is at player feet center)
22.0- MIN_GROUND_NORMAL_Z =
Ground: surface normal Z must be > 0.7 (roughly < 45 degrees from horizontal)
0.7
Instance Attribute Summary collapse
-
#noclip ⇒ Object
Returns the value of attribute noclip.
-
#on_ground ⇒ Object
Returns the value of attribute on_ground.
-
#pitch ⇒ Object
readonly
Returns the value of attribute pitch.
-
#position ⇒ Object
Returns the value of attribute position.
-
#velocity ⇒ Object
Returns the value of attribute velocity.
-
#water_level ⇒ Object
Returns the value of attribute water_level.
-
#yaw ⇒ Object
readonly
Returns the value of attribute yaw.
Instance Method Summary collapse
-
#eye_position ⇒ Object
Camera eye position (origin + view height).
-
#forward ⇒ Object
Full forward including pitch (for camera).
-
#forward_flat ⇒ Object
Forward direction (horizontal only, for movement).
-
#initialize(position:, yaw: 0.0) ⇒ Player
constructor
A new instance of Player.
- #right ⇒ Object
- #right_flat ⇒ Object
- #rotate(dx, dy) ⇒ Object
- #update(dt, level, keys, brush_entities: nil) ⇒ Object
Constructor Details
#initialize(position:, yaw: 0.0) ⇒ Player
Returns a new instance of Player.
31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/quake/physics/player.rb', line 31 def initialize(position:, yaw: 0.0) @position = position @velocity = Math::Vec3::ORIGIN @yaw = yaw @pitch = 0.0 @on_ground = false @water_level = 0 # 0=dry, 1=feet, 2=waist, 3=head @jump_held = false @noclip = false @ignore_mouse = 2 end |
Instance Attribute Details
#noclip ⇒ Object
Returns the value of attribute noclip.
8 9 10 |
# File 'lib/quake/physics/player.rb', line 8 def noclip @noclip end |
#on_ground ⇒ Object
Returns the value of attribute on_ground.
8 9 10 |
# File 'lib/quake/physics/player.rb', line 8 def on_ground @on_ground end |
#pitch ⇒ Object (readonly)
Returns the value of attribute pitch.
9 10 11 |
# File 'lib/quake/physics/player.rb', line 9 def pitch @pitch end |
#position ⇒ Object
Returns the value of attribute position.
8 9 10 |
# File 'lib/quake/physics/player.rb', line 8 def position @position end |
#velocity ⇒ Object
Returns the value of attribute velocity.
8 9 10 |
# File 'lib/quake/physics/player.rb', line 8 def velocity @velocity end |
#water_level ⇒ Object
Returns the value of attribute water_level.
8 9 10 |
# File 'lib/quake/physics/player.rb', line 8 def water_level @water_level end |
#yaw ⇒ Object (readonly)
Returns the value of attribute yaw.
9 10 11 |
# File 'lib/quake/physics/player.rb', line 9 def yaw @yaw end |
Instance Method Details
#eye_position ⇒ Object
Camera eye position (origin + view height)
44 45 46 |
# File 'lib/quake/physics/player.rb', line 44 def eye_position Math::Vec3.new(@position.x, @position.y, @position.z + VIEW_HEIGHT) end |
#forward ⇒ Object
Full forward including pitch (for camera)
113 114 115 116 117 118 |
# File 'lib/quake/physics/player.rb', line 113 def forward ry = deg2rad(@yaw) rp = deg2rad(@pitch) cp = ::Math.cos(rp) Math::Vec3.new(::Math.cos(ry) * cp, ::Math.sin(ry) * cp, -::Math.sin(rp)) end |
#forward_flat ⇒ Object
Forward direction (horizontal only, for movement)
102 103 104 105 |
# File 'lib/quake/physics/player.rb', line 102 def forward_flat ry = deg2rad(@yaw) Math::Vec3.new(::Math.cos(ry), ::Math.sin(ry), 0.0) end |
#right ⇒ Object
120 121 122 123 |
# File 'lib/quake/physics/player.rb', line 120 def right ry = deg2rad(@yaw - 90.0) Math::Vec3.new(::Math.cos(ry), ::Math.sin(ry), 0.0) end |
#right_flat ⇒ Object
107 108 109 110 |
# File 'lib/quake/physics/player.rb', line 107 def right_flat ry = deg2rad(@yaw - 90.0) Math::Vec3.new(::Math.cos(ry), ::Math.sin(ry), 0.0) end |
#rotate(dx, dy) ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/quake/physics/player.rb', line 48 def rotate(dx, dy) if @ignore_mouse > 0 @ignore_mouse -= 1 return end dx = dx.clamp(-MAX_MOUSE_DELTA, MAX_MOUSE_DELTA) dy = dy.clamp(-MAX_MOUSE_DELTA, MAX_MOUSE_DELTA) @yaw -= dx * SENSITIVITY @pitch += dy * SENSITIVITY @pitch = @pitch.clamp(-89.0, 89.0) end |
#update(dt, level, keys, brush_entities: nil) ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/quake/physics/player.rb', line 60 def update(dt, level, keys, brush_entities: nil) if @noclip noclip_move(dt, keys) return end @brush_entities = brush_entities categorize_position(level) # Calculate wish direction from input wish_dir, wish_speed = compute_wish_velocity(keys) if @water_level >= 2 water_move(dt, wish_dir, wish_speed, keys, level) else # Apply gravity if not on ground and not in water unless @on_ground @velocity = Math::Vec3.new(@velocity.x, @velocity.y, @velocity.z - GRAVITY * dt) end # Handle jumping (SET vz, don't add - matches Quake's PM_AirMove) if @on_ground && keys[SDL::SCANCODE_SPACE] && !@jump_held @velocity = Math::Vec3.new(@velocity.x, @velocity.y, JUMP_SPEED) @on_ground = false @jump_held = true end @jump_held = false unless keys[SDL::SCANCODE_SPACE] if @on_ground apply_friction(dt, level) accelerate(wish_dir, wish_speed, ACCELERATE, dt) else air_accelerate(wish_dir, wish_speed, dt) end end # Move with collision walk_move(dt, level) end |