Support local multiplayer

This commit is contained in:
Trevor Slocum 2023-02-01 09:13:31 -08:00
parent 1aa0cc9912
commit 3b8602014d
4 changed files with 74 additions and 36 deletions

View File

@ -188,19 +188,19 @@ func (g *Game) InitNetworking(localPort int, numPlayers int, players []ggpo.Play
}
}
func (g *Game) ReadInputs() InputBits {
func (g *Game) ReadInputsP1() InputBits {
var in InputBits
if ebiten.IsKeyPressed(ebiten.KeyArrowUp) || ebiten.IsKeyPressed(ebiten.KeyW) {
if ebiten.IsKeyPressed(ebiten.KeyW) {
in.setButtonOn(ButtonUp)
}
if ebiten.IsKeyPressed(ebiten.KeyArrowDown) || ebiten.IsKeyPressed(ebiten.KeyS) {
if ebiten.IsKeyPressed(ebiten.KeyS) {
in.setButtonOn(ButtonDown)
}
if ebiten.IsKeyPressed(ebiten.KeyArrowLeft) || ebiten.IsKeyPressed(ebiten.KeyA) {
if ebiten.IsKeyPressed(ebiten.KeyA) {
in.setButtonOn(ButtonLeft)
}
if ebiten.IsKeyPressed(ebiten.KeyArrowRight) || ebiten.IsKeyPressed(ebiten.KeyD) {
if ebiten.IsKeyPressed(ebiten.KeyD) {
in.setButtonOn(ButtonRight)
}
@ -227,6 +227,45 @@ func (g *Game) ReadInputs() InputBits {
return in
}
func (g *Game) ReadInputsP2() InputBits {
var in InputBits
if ebiten.IsKeyPressed(ebiten.KeyArrowUp) {
in.setButtonOn(ButtonUp)
}
if ebiten.IsKeyPressed(ebiten.KeyArrowDown) {
in.setButtonOn(ButtonDown)
}
if ebiten.IsKeyPressed(ebiten.KeyArrowLeft) {
in.setButtonOn(ButtonLeft)
}
if ebiten.IsKeyPressed(ebiten.KeyArrowRight) {
in.setButtonOn(ButtonRight)
}
if ebiten.IsKeyPressed(ebiten.KeySlash) {
in.setButtonOn(ButtonPunch)
}
if ebiten.IsKeyPressed(ebiten.KeyQuote) {
in.setButtonOn(ButtonKick)
}
if ebiten.IsKeyPressed(ebiten.KeyBracketRight) {
in.setButtonOn(ButtonBlock)
}
if ebiten.IsKeyPressed(ebiten.KeyBackspace) {
in.setButtonOn(ButtonTaunt)
}
if ebiten.IsKeyPressed(ebiten.KeyEnter) || ebiten.IsKeyPressed(ebiten.KeyKPEnter) {
in.setButtonOn(ButtonStart)
}
return in
}
func (g *Game) applyPhysics() {
for i := 0; i < 2; i++ {
opp := 0
@ -536,13 +575,6 @@ func (g *Game) UpdateByInputs(inputs []InputBits) {
g.applyPhysics()
}
func (g *Game) ReadInputsP2() InputBits {
var in InputBits
// TODO Support local multiplayer?
return in
}
func (g *Game) playerStateUpdated() {
if g.Winner != 0 && g.Players[0].PlayAgain && g.Players[1].PlayAgain {
g.reset()
@ -555,7 +587,7 @@ func (g *Game) playerStateUpdated() {
func (g *Game) RunLocalFrame() {
inputs := make([]InputBits, 2)
inputs[0] = g.ReadInputs()
inputs[0] = g.ReadInputsP1()
if world.AI == world.AIStandard {
inputs[1] = botInput()
@ -564,6 +596,8 @@ func (g *Game) RunLocalFrame() {
} else if world.AI == world.AIBlock {
inputs[1] = inputs[0]
inputs[1].setButtonOn(ButtonBlock)
} else { // AINone
inputs[1] = g.ReadInputsP2()
}
g.UpdateByInputs(inputs)
@ -571,7 +605,7 @@ func (g *Game) RunLocalFrame() {
}
func (g *Game) RunFrame() {
input := g.ReadInputs()
input := g.ReadInputsP1()
buffer := encodeInputs(input)
//fmt.Println("Attempting to add local inputs")
@ -637,11 +671,11 @@ func (g *Game) Update() error {
if inpututil.IsKeyJustPressed(ebiten.KeyO) && ebiten.IsKeyPressed(ebiten.KeyControl) {
switch world.AI {
case world.AIStandard:
world.AI = world.AINone
case world.AINone:
world.AI = world.AIMirror
case world.AIMirror:
world.AI = world.AIBlock
case world.AIBlock:
world.AI = world.AINone
default:
world.AI = world.AIStandard
}

View File

@ -134,9 +134,9 @@ func botInput() InputBits {
botPunchDistance = 25
botKickDistance = 25
botKickChance = 4
botBlockDistance = 30
botBlockDistance = 35
botBlockTime = 35
botBlockChance = 3
botBlockChance = 5
botTauntMinTime = 60
botTauntTime = 200
botTauntMaxTime = 550

View File

@ -18,17 +18,21 @@ import (
const uiStartPrompt = `BOX BRAWL`
const uiBrowserIntro = `Click anywhere to enable keyboard input.`
const uiComputerPrompt = `Press <Enter> to play against the computer.`
const uiHostPrompt = `Press <H> to host a match against a remote player.`
const uiHostInfoPrompt = `Type your opponent's IP address and port
(address:port) to host a match.`
const uiComputerPrompt = `Press <Enter> to play against
the computer or a local player.`
const uiHostPrompt = `Press <H> to host a network
match against a remote player.`
const uiHostInfoPrompt = `Type your opponent's IP address
and port (address:port) to host a match.`
const uiHostStartPrompt = `Press <Enter> to start hosting.`
const uiRemotePrompt = `Type your opponent's IP address and port
(address:port) to join a match.`
const uiRemotePrompt = `Type your opponent's IP address
and port (address:port) to join a match.`
const uiConnectPrompt = `Press <Enter> to connect.`
const uiBrowserPrompt = `Playing against remote players is unavailable in the browser version.
const uiBrowserPrompt = `Playing against remote players is
unavailable in the browser version.
Download Box Brawl for Windows or Linux to play against remote players.`
Download Box Brawl for Windows or
Linux to play against remote players.`
const uiHostListeningPrompt = `Waiting for opponent to connect
from %s...`
const uiClientConnectingPrompt = `Connecting to %s...`
@ -242,14 +246,14 @@ func (u *UISystem) Draw(e gohan.Entity, screen *ebiten.Image) error {
if world.Local {
u.tmpImg.Clear()
aiLabel := "NONE"
aiLabel := "LOCAL PLAYER"
switch world.AI {
case world.AIStandard:
aiLabel = "STANDARD"
aiLabel = "STANDARD AI"
case world.AIMirror:
aiLabel = "MIRROR"
aiLabel = "MIRROR AI"
case world.AIBlock:
aiLabel = "BLOCK"
aiLabel = "BLOCK AI"
}
label := fmt.Sprintf("OPPONENT TYPE: %s (CONTROL+O)", aiLabel)
ebitenutil.DebugPrint(u.tmpImg, label)

View File

@ -19,21 +19,19 @@ const (
JumpVelocity = 20
MaxDebug = 2
FloatValueThreshold = 1 // This is required because image.Rectangle uses integers
GroundWidth = 600
GroundHeight = 100
MaxDebug = 2
)
type AIType int
const (
AIStandard AIType = iota
AINone
AIMirror
AIBlock
AINone
)
var (
@ -65,8 +63,10 @@ var (
AI AIType // AI configuration
Backend ggpo.Backend
)
// These variables are cached to prevent race conditions.
// These variables are cached to prevent race conditions.
var (
Player1 component.Player
Player2 component.Player
Winner int