Implement basic X/Z control surface

This commit is contained in:
Tom
2020-09-16 21:40:41 -07:00
parent 70bb24a7fb
commit a981ab84f5
5 changed files with 47 additions and 4 deletions

View File

@ -24,6 +24,7 @@ type Client struct {
settings Settings settings Settings
Wd world.World //the map data Wd world.World //the map data
Inputs phy.Inputs
Physics phy.State Physics phy.State
lastPosTx time.Time lastPosTx time.Time

View File

@ -82,7 +82,7 @@ func (c *Client) HandleGame() error {
case <-c.closing: case <-c.closing:
return http.ErrServerClosed return http.ErrServerClosed
case <-cTick.C: case <-cTick.C:
if err := c.Physics.Tick(&c.Wd); err != nil { if err := c.Physics.Tick(c.Inputs, &c.Wd); err != nil {
c.disconnect() c.disconnect()
return err return err
} }

8
bot/phy/inputs.go Normal file
View File

@ -0,0 +1,8 @@
package phy
// Inputs describes the desired movements of the player.
type Inputs struct {
Yaw, Pitch float32
ThrottleX, ThrottleZ float64
}

View File

@ -14,7 +14,13 @@ const (
playerHeight = 1.8 playerHeight = 1.8
resetVel = 0.003 resetVel = 0.003
gravity = 0.08 yawSpeed = 3.0
gravity = 0.08
drag = 0.98
acceleration = 0.02
inertia = 0.91
slipperiness = 0.6
) )
// World represents a provider of information about the surrounding world. // World represents a provider of information about the surrounding world.
@ -81,10 +87,33 @@ func (s *State) surroundings(query AABB, w World) Surrounds {
return out return out
} }
func (s *State) Tick(w World) error { func (s *State) applyInputs(input Inputs, acceleration, inertia float64) {
speed := math.Sqrt(input.ThrottleX*input.ThrottleX + input.ThrottleZ*input.ThrottleZ)
if speed < 0.01 {
return
}
speed = acceleration / math.Max(speed, 1)
input.ThrottleX *= speed
input.ThrottleZ *= speed
s.Vel.X += input.ThrottleX
s.Vel.Z += input.ThrottleZ
}
func (s *State) Tick(input Inputs, w World) error {
if !s.Run { if !s.Run {
return nil return nil
} }
var inertia = inertia
var acceleration = acceleration
if s.onGround {
inertia *= slipperiness
acceleration = 0.1 * (0.1627714 / (inertia * inertia * inertia))
}
s.applyInputs(input, acceleration, inertia)
// Deadzone velocities when they get too low.
if math.Abs(s.Vel.X) < resetVel { if math.Abs(s.Vel.X) < resetVel {
s.Vel.X = 0 s.Vel.X = 0
} }
@ -94,7 +123,12 @@ func (s *State) Tick(w World) error {
if math.Abs(s.Vel.Z) < resetVel { if math.Abs(s.Vel.Z) < resetVel {
s.Vel.Z = 0 s.Vel.Z = 0
} }
// Gravity
s.Vel.Y -= gravity s.Vel.Y -= gravity
// Drag & friction.
s.Vel.Y *= drag
s.Vel.X *= inertia
s.Vel.Z *= inertia
// Apply collision. // Apply collision.
var ( var (

View File

@ -60,7 +60,7 @@ type ChunkLoc struct {
func (w *World) GetBlockStatus(x, y, z int) BlockStatus { func (w *World) GetBlockStatus(x, y, z int) BlockStatus {
// Use n>>4 rather then n/16. It acts wrong if n<0. // Use n>>4 rather then n/16. It acts wrong if n<0.
c := w.Chunks[ChunkLoc{x >> 4, z >> 4}] c := w.Chunks[ChunkLoc{x >> 4, z >> 4}]
if c != nil { if c != nil && y >= 0 {
if sec := c.Sections[y>>4]; sec != nil { if sec := c.Sections[y>>4]; sec != nil {
return sec.GetBlock(SectionIdx(x&15, y&15, z&15)) return sec.GetBlock(SectionIdx(x&15, y&15, z&15))
} }