Support local multiplayer
parent
1aa0cc9912
commit
3b8602014d
66
game/game.go
66
game/game.go
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
28
system/ui.go
28
system/ui.go
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue