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- STOP_EPSILON =
units/sec^2
0.1- FRICTION =
4.0- EDGE_FRICTION =
2.0- STOP_SPEED =
100.0- MAX_SPEED =
320.0- MAX_VELOCITY =
2000.0- FORWARD_SPEED =
200.0- BACK_SPEED =
200.0- SIDE_SPEED =
350.0- UP_SPEED =
200.0- ACCELERATE =
10.0- AIR_ACCELERATE =
10.0- JUMP_SPEED =
270.0- STEP_SIZE =
18.0- WATER_FRICTION =
4.0- WATER_ACCELERATE =
10.0- UNSTICK_DISTANCE =
2.0- MIN_UNSTICK_PROGRESS =
4.0- UNSTICK_DIRECTIONS =
[ Math::Vec3.new(UNSTICK_DISTANCE, 0.0, 0.0), Math::Vec3.new(0.0, UNSTICK_DISTANCE, 0.0), Math::Vec3.new(-UNSTICK_DISTANCE, 0.0, 0.0), Math::Vec3.new(0.0, -UNSTICK_DISTANCE, 0.0), Math::Vec3.new(UNSTICK_DISTANCE, UNSTICK_DISTANCE, 0.0), Math::Vec3.new(-UNSTICK_DISTANCE, UNSTICK_DISTANCE, 0.0), Math::Vec3.new(UNSTICK_DISTANCE, -UNSTICK_DISTANCE, 0.0), Math::Vec3.new(-UNSTICK_DISTANCE, -UNSTICK_DISTANCE, 0.0) ].freeze
- 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- MAX_CLIP_PLANES =
SV_FlyMove (sv_phys.c)
5- CLIP_FLOOR =
1 << 0
- CLIP_WALL =
1 << 1
- CLIP_STOP =
1 << 2
- WATER_JUMP_SPEED =
CheckWaterJump (client.qc)
225.0- WATER_JUMP_TIME =
teleport_time safety net: time + 2
2.0
Instance Attribute Summary collapse
-
#gravity ⇒ Object
Returns the value of attribute gravity.
-
#jump_held ⇒ Object
readonly
Returns the value of attribute jump_held.
-
#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_jump ⇒ Object
Returns the value of attribute water_jump.
-
#water_jump_movedir ⇒ Object
Returns the value of attribute water_jump_movedir.
-
#water_jump_time ⇒ Object
Returns the value of attribute water_jump_time.
-
#water_level ⇒ Object
Returns the value of attribute water_level.
-
#water_type ⇒ Object
Returns the value of attribute water_type.
-
#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
- #up ⇒ Object
- #update(dt, level, keys, brush_entities: nil) ⇒ Object
Constructor Details
#initialize(position:, yaw: 0.0) ⇒ Player
Returns a new instance of Player.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/quake/physics/player.rb', line 62 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 @water_type = CONTENTS_EMPTY @jump_held = false @noclip = false @gravity = GRAVITY @ignore_mouse = 2 @water_jump = false @water_jump_movedir = Math::Vec3::ORIGIN @water_jump_time = 0.0 end |
Instance Attribute Details
#gravity ⇒ Object
Returns the value of attribute gravity.
8 9 10 |
# File 'lib/quake/physics/player.rb', line 8 def gravity @gravity end |
#jump_held ⇒ Object (readonly)
Returns the value of attribute jump_held.
10 11 12 |
# File 'lib/quake/physics/player.rb', line 10 def jump_held @jump_held end |
#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.
11 12 13 |
# File 'lib/quake/physics/player.rb', line 11 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_jump ⇒ Object
Returns the value of attribute water_jump.
9 10 11 |
# File 'lib/quake/physics/player.rb', line 9 def water_jump @water_jump end |
#water_jump_movedir ⇒ Object
Returns the value of attribute water_jump_movedir.
9 10 11 |
# File 'lib/quake/physics/player.rb', line 9 def water_jump_movedir @water_jump_movedir end |
#water_jump_time ⇒ Object
Returns the value of attribute water_jump_time.
9 10 11 |
# File 'lib/quake/physics/player.rb', line 9 def water_jump_time @water_jump_time 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 |
#water_type ⇒ Object
Returns the value of attribute water_type.
8 9 10 |
# File 'lib/quake/physics/player.rb', line 8 def water_type @water_type end |
#yaw ⇒ Object (readonly)
Returns the value of attribute yaw.
11 12 13 |
# File 'lib/quake/physics/player.rb', line 11 def yaw @yaw end |
Instance Method Details
#eye_position ⇒ Object
Camera eye position (origin + view height)
80 81 82 |
# File 'lib/quake/physics/player.rb', line 80 def eye_position Math::Vec3.new(@position.x, @position.y, @position.z + VIEW_HEIGHT) end |
#forward ⇒ Object
Full forward including pitch (for camera)
159 160 161 162 163 164 |
# File 'lib/quake/physics/player.rb', line 159 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)
148 149 150 151 |
# File 'lib/quake/physics/player.rb', line 148 def forward_flat ry = deg2rad(@yaw) Math::Vec3.new(::Math.cos(ry), ::Math.sin(ry), 0.0) end |
#right ⇒ Object
166 167 168 169 |
# File 'lib/quake/physics/player.rb', line 166 def right ry = deg2rad(@yaw - 90.0) Math::Vec3.new(::Math.cos(ry), ::Math.sin(ry), 0.0) end |
#right_flat ⇒ Object
153 154 155 156 |
# File 'lib/quake/physics/player.rb', line 153 def right_flat ry = deg2rad(@yaw - 90.0) Math::Vec3.new(::Math.cos(ry), ::Math.sin(ry), 0.0) end |
#rotate(dx, dy) ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/quake/physics/player.rb', line 84 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 |
#up ⇒ Object
171 172 173 174 175 176 177 178 179 |
# File 'lib/quake/physics/player.rb', line 171 def up ry = deg2rad(@yaw) rp = deg2rad(@pitch) Math::Vec3.new( ::Math.cos(ry) * ::Math.sin(rp), ::Math.sin(ry) * ::Math.sin(rp), ::Math.cos(rp) ) end |
#update(dt, level, keys, brush_entities: nil) ⇒ Object
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/quake/physics/player.rb', line 96 def update(dt, level, keys, brush_entities: nil) if @noclip noclip_move(dt, keys) return end @brush_entities = brush_entities check_velocity categorize_position(level) # Calculate wish direction from input wish_dir, wish_speed = compute_wish_velocity(keys) # QuakeC PlayerPreThink: probe for a jump-out-of-water while swimming check_water_jump(level) if @water_level == 2 && !@water_jump if @water_jump # SV_ClientThink short-circuits friction/accel while FL_WATERJUMP # is set (sv_user.c:357-360); SV_Physics_Client skips gravity. @water_jump_time -= dt water_jump_move elsif @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 (QuakeC PlayerJump: velocity_z = velocity_z + 270) if @on_ground && keys[SDL::SCANCODE_SPACE] && !@jump_held @velocity = Math::Vec3.new(@velocity.x, @velocity.y, @velocity.z + 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 |