Add jumping

This commit is contained in:
Trevor Slocum 2023-01-13 15:49:45 -08:00
parent ea60aa70d4
commit 1dfe1a004c
3 changed files with 128 additions and 108 deletions

View file

@ -82,8 +82,8 @@ var AllPlayerFrames = [][][]FrameData{
}
type Player struct {
X float64
Y float64
X, Y float64
VX, VY float64
Color color.Color
PlayerNum int

View file

@ -136,10 +136,6 @@ func (g *Game) startNetworkGame() {
world.ConnectionActive = true
}
func (g *Game) playerStateUpdated() {
world.Player1, world.Player2 = g.Players[0], g.Players[1]
}
func (g *Game) InitNetworking(localPort int, numPlayers int, players []ggpo.Player, numSpectators int) {
var result error
var inputBits InputBits = 0
@ -174,6 +170,122 @@ func (g *Game) InitNetworking(localPort int, numPlayers int, players []ggpo.Play
peer.SetDisconnectNotifyStart(1000)
}
func (g *Game) ReadInputs() InputBits {
var in InputBits
if ebiten.IsKeyPressed(ebiten.KeyArrowUp) || ebiten.IsKeyPressed(ebiten.KeyW) {
in.setButton(ButtonUp)
}
if ebiten.IsKeyPressed(ebiten.KeyArrowDown) || ebiten.IsKeyPressed(ebiten.KeyS) {
in.setButton(ButtonDown)
}
if ebiten.IsKeyPressed(ebiten.KeyArrowLeft) || ebiten.IsKeyPressed(ebiten.KeyA) {
in.setButton(ButtonLeft)
}
if ebiten.IsKeyPressed(ebiten.KeyArrowRight) || ebiten.IsKeyPressed(ebiten.KeyD) {
in.setButton(ButtonRight)
}
if inpututil.IsKeyJustPressed(ebiten.KeyH) {
in.setButton(ButtonPunch)
}
return in
}
func (g *Game) applyPhysics() {
for i := 0; i < 2; i++ {
p := &g.Players[i]
// Apply gravity.
if p.VY > -world.Gravity {
p.VY -= 1
if p.VY < -world.Gravity {
p.VY = -world.Gravity
}
}
// Apply velocity.
p.X, p.Y = p.X+p.VX, p.Y+p.VY
// TODO check player collision.
// Apply ground collision.
if p.Y-component.PlayerSize < 0 {
p.Y = component.PlayerSize
}
}
}
func (g *Game) UpdateByInputs(inputs []InputBits) {
for i, input := range inputs {
opp := 0
if i == 0 {
opp = 1
}
playerRect := world.FloatRect(g.Players[i].X, g.Players[i].Y, g.Players[i].X+float64(component.PlayerSize), g.Players[i].Y+float64(component.PlayerSize))
oppRect := world.FloatRect(g.Players[opp].X, g.Players[opp].Y, g.Players[opp].X+float64(component.PlayerSize), g.Players[opp].Y+float64(component.PlayerSize))
g.Players[i].VX = g.Players[i].VX * 0.8
g.Players[i].VY = g.Players[i].VY * 0.8
if input.isButtonOn(ButtonUp) && !component.TranslateRect(playerRect, 0, -1).Overlaps(oppRect) {
grounded := g.Players[i].Y == float64(component.PlayerSize)
// TODO check when last jump, grounded
if grounded {
g.Players[i].VY = 20
}
log.Println("JUMP", grounded)
}
if input.isButtonOn(ButtonDown) && !component.TranslateRect(playerRect, 0, 1).Overlaps(oppRect) {
//g.Players[i].VY = -1
// TODO crouch
}
if input.isButtonOn(ButtonLeft) && !component.TranslateRect(playerRect, -1, 0).Overlaps(oppRect) {
g.Players[i].VX = -1
}
if input.isButtonOn(ButtonRight) && !component.TranslateRect(playerRect, 1, 0).Overlaps(oppRect) {
g.Players[i].VX = 1
}
if g.Players[i].Action == component.ActionIdle {
if input.isButtonOn(ButtonPunch) {
g.Players[i].Action = component.ActionPunch
g.Players[i].ActionTicksLeft = len(component.AllPlayerFrames[component.ActionPunch]) // TODO
continue
}
}
if g.Players[i].ActionTicksLeft != 0 {
g.Players[i].ActionTicksLeft--
if g.Players[i].ActionTicksLeft == 0 {
g.Players[i].Action = component.ActionIdle
g.Players[i].ActionTicksLeft = len(component.AllPlayerFrames[component.ActionIdle]) // TODO
}
// TODO Apply hitboxes
if g.Players[i].ActionTicksLeft != 0 {
//frameNum := g.Players[i].ActionTicksLeft - 1
//frame := component.AllPlayerFrames[g.Players[i].Action][frameNum]
//log.Printf("frame %+v", frame)
}
}
}
g.applyPhysics()
}
func (g *Game) ReadInputsP2() InputBits {
var in InputBits
// TODO Support local multiplayer?
return in
}
func (g *Game) playerStateUpdated() {
world.Player1, world.Player2 = g.Players[0], g.Players[1]
}
func (g *Game) RunFrame() {
input := g.ReadInputs()
buffer := encodeInputs(input)
@ -204,107 +316,6 @@ func (g *Game) RunFrame() {
g.playerStateUpdated()
}
func (g *Game) AdvanceFrame(inputs []InputBits, disconnectFlags int) {
g.UpdateByInputs(inputs)
err := world.Backend.AdvanceFrame(uint32(g.Checksum()))
if err != nil {
panic(err)
}
}
func (g *Game) applyPhysics() {
// Apply gravity.
for i := 0; i < 2; i++ {
p := &g.Players[i]
p.Y -= world.Gravity
if p.Y-component.PlayerSize < 0 {
p.Y = component.PlayerSize
}
}
}
func (g *Game) UpdateByInputs(inputs []InputBits) {
for i, input := range inputs {
opp := 0
if i == 0 {
opp = 1
}
playerRect := world.FloatRect(g.Players[i].X, g.Players[i].Y, g.Players[i].X+float64(component.PlayerSize), g.Players[i].Y+float64(component.PlayerSize))
oppRect := world.FloatRect(g.Players[opp].X, g.Players[opp].Y, g.Players[opp].X+float64(component.PlayerSize), g.Players[opp].Y+float64(component.PlayerSize))
if input.isButtonOn(ButtonUp) && !component.TranslateRect(playerRect, 0, -1).Overlaps(oppRect) {
g.Players[i].Y--
}
if input.isButtonOn(ButtonDown) && !component.TranslateRect(playerRect, 0, 1).Overlaps(oppRect) {
g.Players[i].Y++
}
if input.isButtonOn(ButtonLeft) && !component.TranslateRect(playerRect, -1, 0).Overlaps(oppRect) {
g.Players[i].X--
}
if input.isButtonOn(ButtonRight) && !component.TranslateRect(playerRect, 1, 0).Overlaps(oppRect) {
g.Players[i].X++
}
if g.Players[i].Action == component.ActionIdle {
if input.isButtonOn(ButtonPunch) {
g.Players[i].Action = component.ActionPunch
g.Players[i].ActionTicksLeft = len(component.AllPlayerFrames[component.ActionPunch]) // TODO
continue
}
}
if g.Players[i].ActionTicksLeft != 0 {
g.Players[i].ActionTicksLeft--
if g.Players[i].ActionTicksLeft == 0 {
g.Players[i].Action = component.ActionIdle
g.Players[i].ActionTicksLeft = len(component.AllPlayerFrames[component.ActionIdle]) // TODO
}
// TODO Apply hitboxes
if g.Players[i].ActionTicksLeft != 0 {
//frameNum := g.Players[i].ActionTicksLeft - 1
//frame := component.AllPlayerFrames[g.Players[i].Action][frameNum]
//log.Printf("frame %+v", frame)
}
}
}
g.applyPhysics()
}
func (g *Game) ReadInputs() InputBits {
var in InputBits
if ebiten.IsKeyPressed(ebiten.KeyArrowUp) || ebiten.IsKeyPressed(ebiten.KeyW) {
in.setButton(ButtonUp)
}
if ebiten.IsKeyPressed(ebiten.KeyArrowDown) || ebiten.IsKeyPressed(ebiten.KeyS) {
in.setButton(ButtonDown)
}
if ebiten.IsKeyPressed(ebiten.KeyArrowLeft) || ebiten.IsKeyPressed(ebiten.KeyA) {
in.setButton(ButtonLeft)
}
if ebiten.IsKeyPressed(ebiten.KeyArrowRight) || ebiten.IsKeyPressed(ebiten.KeyD) {
in.setButton(ButtonRight)
}
if inpututil.IsKeyJustPressed(ebiten.KeyH) {
in.setButton(ButtonPunch)
}
return in
}
func (g *Game) ReadInputsP2() InputBits {
var in InputBits
// TODO Support local multiplayer?
return in
}
func (g *Game) Checksum() int {
h := sha1.New()
h.Write([]byte(g.String()))
@ -316,6 +327,15 @@ func (g *Game) Checksum() int {
return sum
}
func (g *Game) AdvanceFrame(inputs []InputBits, disconnectFlags int) {
g.UpdateByInputs(inputs)
err := world.Backend.AdvanceFrame(uint32(g.Checksum()))
if err != nil {
panic(err)
}
}
func (g *Game) Update() error {
if ebiten.IsWindowBeingClosed() || (!world.WASM && ebiten.IsKeyPressed(ebiten.KeyEscape)) {
g.Exit()

View file

@ -15,7 +15,7 @@ const (
InternalScreenWidth, InternalScreenHeight = 854, 480
Gravity = 1.0
Gravity = 8.0
GroundHeight = 100 // TODO