zworld/engine/object/player/player.go

144 lines
3.0 KiB
Go
Raw Permalink Normal View History

2024-01-20 18:44:07 +08:00
package player
import (
"zworld/engine/object"
"zworld/engine/object/camera"
"zworld/engine/object/light"
"zworld/engine/renderapi/color"
"zworld/plugins/math"
"zworld/plugins/math/quat"
"zworld/plugins/math/vec2"
"zworld/plugins/math/vec3"
"zworld/plugins/system/input/keys"
"zworld/plugins/system/input/mouse"
)
type Player struct {
object.Object
Camera *camera.Object
Speed float32
Friction vec3.T
velocity vec3.T
keys keys.State
mouselook bool
}
func NewPlayer(position vec3.T, rotation quat.T) *Player {
p := object.Builder(object.New("Player", &Player{
Camera: object.Builder(camera.NewObject(camera.Args{
Fov: 58.0,
Near: 0.1,
Far: 500,
Clear: color.Hex("#eddaab"),
})).
Rotation(rotation).
Attach(light.NewPoint(light.PointArgs{
Range: 20,
Intensity: 2.5,
Color: color.White,
})).
Create(),
Speed: float32(33),
Friction: vec3.New(2, 2, 2),
keys: keys.NewState(),
})).
Position(position).
Create()
return p
}
func (p *Player) KeyEvent(e keys.Event) {
p.keys.KeyEvent(e)
}
func (p *Player) Update(scene object.Component, dt float32) {
move := vec3.Zero
moving := false
if p.keys.Down(keys.W) && p.keys.Up(keys.S) {
move.Z += 1.0
moving = true
}
if p.keys.Down(keys.S) && p.keys.Up(keys.W) {
move.Z -= 1.0
moving = true
}
if p.keys.Down(keys.A) && p.keys.Up(keys.D) {
move.X -= 1.0
moving = true
}
if p.keys.Down(keys.D) && p.keys.Up(keys.A) {
move.X += 1.0
moving = true
}
if p.keys.Down(keys.Q) && p.keys.Up(keys.E) {
move.Y -= 1.0
moving = true
}
if p.keys.Down(keys.E) && p.keys.Up(keys.Q) {
move.Y += 1.0
moving = true
}
if moving {
right := p.Camera.Transform().Right().Scaled(move.X)
up := p.Camera.Transform().Up().Scaled(move.Y)
forward := p.Camera.Transform().Forward().Scaled(move.Z)
move = right.Add(forward).Add(up)
move.Normalize()
}
move.Scale(p.Speed)
if p.keys.Shift() {
move.Scale(2)
}
// apply movement
p.velocity = p.velocity.Add(move.Scaled(dt))
// friction
friction := p.velocity.Mul(p.Friction)
p.velocity = p.velocity.Sub(friction.Scaled(dt))
// apply movement
step := p.velocity.Scaled(dt)
position := p.Transform().Position()
position = position.Add(step)
p.Transform().SetPosition(position)
p.Object.Update(scene, dt)
}
func (p *Player) MouseEvent(e mouse.Event) {
if e.Action() == mouse.Press && e.Button() == mouse.Button2 {
p.mouselook = true
mouse.Lock()
e.Consume()
}
if e.Action() == mouse.Release && e.Button() == mouse.Button2 {
p.mouselook = false
mouse.Show()
e.Consume()
}
if e.Action() == mouse.Move && p.mouselook {
sensitivity := vec2.New(0.045, 0.04)
delta := e.Delta().Mul(sensitivity)
eye := p.Camera.Transform().Rotation().Euler()
xrot := eye.X + delta.Y
yrot := eye.Y + delta.X
// camera angle limits
xrot = math.Clamp(xrot, -89.9, 89.9)
yrot = math.Mod(yrot, 360)
rot := quat.Euler(xrot, yrot, 0)
p.Camera.Transform().SetRotation(rot)
e.Consume()
}
}