2023-01-02 07:58:11 +03:00
|
|
|
package main
|
|
|
|
|
2023-01-04 00:00:32 +03:00
|
|
|
import (
|
|
|
|
"cart/w4"
|
|
|
|
"math"
|
2023-01-05 02:33:51 +03:00
|
|
|
"strconv"
|
2023-01-04 00:00:32 +03:00
|
|
|
)
|
2023-01-02 07:58:11 +03:00
|
|
|
|
|
|
|
type Player struct {
|
2023-01-08 12:50:21 +03:00
|
|
|
Index uint8
|
|
|
|
Health uint8
|
|
|
|
KilledBy Actor
|
|
|
|
Position Vector
|
|
|
|
Speed Vector
|
2023-01-04 00:00:32 +03:00
|
|
|
StickGrabbed *Stick
|
|
|
|
StickOffset float64
|
2023-01-08 12:50:21 +03:00
|
|
|
GrabTimer uint8
|
|
|
|
ShootTimer uint8
|
|
|
|
ShootDirX int8
|
|
|
|
ShootDirY int8
|
2023-01-02 07:58:11 +03:00
|
|
|
Gamepad *uint8
|
2023-01-05 02:33:51 +03:00
|
|
|
GamepadLast uint8
|
2023-01-02 07:58:11 +03:00
|
|
|
}
|
|
|
|
|
2023-01-08 12:50:21 +03:00
|
|
|
func (p *Player) GetPosition() Vector {
|
|
|
|
return p.Position
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *Player) Update() bool {
|
|
|
|
var dirX int8 = int8(*p.Gamepad&w4.BUTTON_RIGHT>>5) - int8(*p.Gamepad&w4.BUTTON_LEFT>>4)
|
|
|
|
var dirY int8 = int8(*p.Gamepad&w4.BUTTON_DOWN>>7) - int8(*p.Gamepad&w4.BUTTON_UP>>6)
|
|
|
|
if !(dirX == 0 && dirY == 0) && p.Health > 0 {
|
|
|
|
p.ShootDirX = dirX
|
|
|
|
p.ShootDirY = dirY
|
|
|
|
}
|
2023-01-05 02:33:51 +03:00
|
|
|
lastGamepad := *p.Gamepad & (*p.Gamepad ^ p.GamepadLast)
|
|
|
|
p.GamepadLast = *p.Gamepad
|
2023-01-08 12:50:21 +03:00
|
|
|
if p.GrabTimer > 0 {
|
|
|
|
p.GrabTimer--
|
|
|
|
}
|
|
|
|
if p.ShootTimer > 0 {
|
|
|
|
p.ShootTimer--
|
|
|
|
} else {
|
|
|
|
if *p.Gamepad&w4.BUTTON_1 != 0 && !(p.ShootDirX == 0 && p.ShootDirY == 0) {
|
|
|
|
bullet := &Bullet{
|
|
|
|
Owner: p,
|
|
|
|
Position: p.Position,
|
|
|
|
SpeedX: p.ShootDirX * 3,
|
|
|
|
SpeedY: p.ShootDirY * 3,
|
|
|
|
}
|
|
|
|
// w4.Trace(strconv.Itoa(int(p.ShootDirX)))
|
|
|
|
// w4.Trace(strconv.Itoa(int(p.ShootDirY)))
|
|
|
|
// w4.Trace(p.Position.String())
|
|
|
|
w4.Tone(150|50<<16, 10, 100, w4.TONE_MODE1)
|
|
|
|
p.ShootTimer = 15
|
|
|
|
actors = append(actors, bullet)
|
|
|
|
}
|
2023-01-02 07:58:11 +03:00
|
|
|
}
|
2023-01-08 12:50:21 +03:00
|
|
|
|
2023-01-02 07:58:11 +03:00
|
|
|
isJumping := *p.Gamepad&w4.BUTTON_DOWN == 0
|
2023-01-04 00:00:32 +03:00
|
|
|
p.Speed.Y = math.Min(4, p.Speed.Y+gravity)
|
|
|
|
if p.StickGrabbed != nil {
|
2023-01-05 02:33:51 +03:00
|
|
|
p.Speed.X = 0
|
2023-01-08 12:50:21 +03:00
|
|
|
p.Speed.Y = 0
|
|
|
|
if *p.Gamepad&w4.BUTTON_1 == 0 {
|
|
|
|
p.Speed.X = float64(dirX)
|
|
|
|
p.Speed.Y = float64(dirY)
|
2023-01-04 00:00:32 +03:00
|
|
|
}
|
2023-01-05 02:33:51 +03:00
|
|
|
p.MoveOnRope(p.Speed)
|
2023-01-04 00:00:32 +03:00
|
|
|
if p.StickOffset < 0 {
|
|
|
|
point := p.StickGrabbed.PointA
|
|
|
|
if len(point.Sticks) == 1 {
|
|
|
|
p.StickOffset = 0
|
|
|
|
} else {
|
|
|
|
p.StickGrabbed = point.Sticks[0]
|
|
|
|
p.StickOffset += 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if p.StickOffset > 1 {
|
|
|
|
point := p.StickGrabbed.PointB
|
|
|
|
if len(point.Sticks) == 1 {
|
|
|
|
p.StickOffset = 1
|
|
|
|
} else {
|
|
|
|
p.StickGrabbed = point.Sticks[1]
|
|
|
|
p.StickOffset -= 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
p.Position = p.StickGrabbed.GetPosition(p.StickOffset)
|
2023-01-05 02:33:51 +03:00
|
|
|
if lastGamepad&w4.BUTTON_2 != 0 {
|
2023-01-08 12:50:21 +03:00
|
|
|
p.GrabTimer = 10
|
2023-01-02 07:58:11 +03:00
|
|
|
if isJumping {
|
2023-01-08 12:50:21 +03:00
|
|
|
p.GrabTimer = 10
|
2023-01-05 02:33:51 +03:00
|
|
|
p.Speed = p.Speed.MulScalar(2)
|
|
|
|
if p.Speed.Y <= 0 {
|
|
|
|
p.Speed.Y -= 1 * 2
|
|
|
|
}
|
2023-01-04 00:00:32 +03:00
|
|
|
impulse := p.Speed.MulScalar(-1)
|
|
|
|
p.StickGrabbed.PointA.Position.MoveVec(impulse)
|
|
|
|
p.StickGrabbed.PointB.Position.MoveVec(impulse)
|
2023-01-02 07:58:11 +03:00
|
|
|
}
|
2023-01-04 00:00:32 +03:00
|
|
|
p.StickGrabbed = nil
|
2023-01-02 07:58:11 +03:00
|
|
|
}
|
2023-01-08 12:50:21 +03:00
|
|
|
if p.ShootTimer == 15 {
|
|
|
|
impulse := Vector{-float64(dirX), -float64(dirY)}
|
|
|
|
if p.StickGrabbed != nil {
|
|
|
|
p.StickGrabbed.PointA.Position.MoveVec(impulse)
|
|
|
|
p.StickGrabbed.PointB.Position.MoveVec(impulse)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2023-01-02 07:58:11 +03:00
|
|
|
} else {
|
|
|
|
p.Position.Move(p.Speed.X, p.Speed.Y)
|
2023-01-08 12:50:21 +03:00
|
|
|
if *p.Gamepad&w4.BUTTON_DOWN == 0 && p.GrabTimer == 0 && p.Health > 0 {
|
2023-01-04 00:00:32 +03:00
|
|
|
distance := math.MaxFloat64
|
|
|
|
var selectedPoint *Point
|
2023-01-02 07:58:11 +03:00
|
|
|
for _, point := range points {
|
|
|
|
diff := p.Position.Sub(point.Position)
|
2023-01-04 00:00:32 +03:00
|
|
|
dSquared := diff.LenSquared()
|
|
|
|
if dSquared < distance {
|
|
|
|
distance = dSquared
|
|
|
|
selectedPoint = point
|
|
|
|
}
|
|
|
|
}
|
|
|
|
stickDistance := math.MaxFloat64
|
|
|
|
var selectedStick *Stick
|
|
|
|
for _, stick := range selectedPoint.Sticks {
|
|
|
|
distance := stick.GetDistance(p.Position)
|
|
|
|
if distance < stickDistance {
|
|
|
|
stickDistance = distance
|
|
|
|
selectedStick = stick
|
2023-01-02 07:58:11 +03:00
|
|
|
}
|
|
|
|
}
|
2023-01-04 00:00:32 +03:00
|
|
|
if stickDistance < 4 {
|
|
|
|
p.StickGrabbed = selectedStick
|
|
|
|
p.StickOffset = selectedStick.GetOffset(p.Position)
|
|
|
|
p.StickGrabbed.PointA.Position.MoveVec(p.Speed)
|
|
|
|
p.StickGrabbed.PointB.Position.MoveVec(p.Speed)
|
|
|
|
}
|
2023-01-02 07:58:11 +03:00
|
|
|
}
|
|
|
|
}
|
2023-01-06 01:20:47 +03:00
|
|
|
p.Position.X = math.Min(math.Max(0, p.Position.X), 320)
|
2023-01-08 12:50:21 +03:00
|
|
|
if p.Position.Y > 320 && p.Health > 0 {
|
|
|
|
p.Health = 0
|
|
|
|
p.Death()
|
|
|
|
}
|
|
|
|
return false
|
2023-01-02 07:58:11 +03:00
|
|
|
}
|
|
|
|
|
2023-01-05 02:33:51 +03:00
|
|
|
func (p *Player) MoveOnRope(motion Vector) {
|
|
|
|
newPos := p.Position.Sum(motion)
|
|
|
|
offset := p.StickGrabbed.GetOffset(newPos)
|
|
|
|
p.StickOffset = offset
|
|
|
|
}
|
|
|
|
|
2023-01-02 07:58:11 +03:00
|
|
|
func (p *Player) Draw() {
|
|
|
|
*w4.DRAW_COLORS = 0x34
|
2023-01-08 12:50:21 +03:00
|
|
|
drawX := int(p.Position.X) - 4 - camX
|
|
|
|
drawY := int(p.Position.Y) - 4 - camY
|
|
|
|
w4.Rect(drawX, drawY, 8, 8)
|
|
|
|
|
|
|
|
eyePosX := drawX + 4 + int(p.ShootDirX)
|
|
|
|
eyePosY := drawY + 4 - 2 + int(p.ShootDirY)
|
|
|
|
w4.Rect(eyePosX-2, eyePosY, 1, 2)
|
|
|
|
w4.Rect(eyePosX+1, eyePosY, 1, 2)
|
|
|
|
if pvp {
|
|
|
|
*w4.DRAW_COLORS = 0x4
|
|
|
|
w4.Text("P"+strconv.Itoa(int(p.Index+1)), drawX-3, drawY-10)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *Player) TakeHit(from Actor) {
|
|
|
|
if p.Health > 0 {
|
|
|
|
if p.Health--; p.Health == 0 {
|
|
|
|
if bullet, ok := from.(*Bullet); ok {
|
|
|
|
p.StickGrabbed = nil
|
|
|
|
p.KilledBy = bullet.Owner
|
|
|
|
p.Death()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
w4.Tone(250|200<<16, 15, 60, w4.TONE_PULSE1)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *Player) Death() {
|
|
|
|
p.Speed.Y = -3
|
|
|
|
playersAlive--
|
|
|
|
music.MuteFor(30)
|
|
|
|
w4.Tone(600|200<<16, 15|15<<8, 30, w4.TONE_PULSE2)
|
2023-01-02 07:58:11 +03:00
|
|
|
}
|