parent
70c2f97d4d
commit
2aa4c96f4c
5 changed files with 194 additions and 3 deletions
|
@ -1,4 +1,5 @@
|
|||
1.2.1:
|
||||
- Add tutorial
|
||||
- Change lobby button labels
|
||||
|
||||
1.2.0:
|
||||
|
|
|
@ -499,6 +499,8 @@ func NewBoard() *board {
|
|||
b.frame.AddChild(f)
|
||||
}
|
||||
|
||||
b.frame.AddChild(game.tutorialFrame)
|
||||
|
||||
b.fontUpdated()
|
||||
|
||||
for i := range b.Sprites.sprites {
|
||||
|
|
18
game/game.go
18
game/game.go
|
@ -130,6 +130,8 @@ var (
|
|||
historyContainer *etk.Grid
|
||||
listGamesContainer *etk.Grid
|
||||
|
||||
tutorialFrame *etk.Frame
|
||||
|
||||
createGameFrame *etk.Frame
|
||||
joinGameFrame *etk.Frame
|
||||
historyFrame *etk.Frame
|
||||
|
@ -600,6 +602,9 @@ type Game struct {
|
|||
resetInfo *etk.Text
|
||||
resetInProgress bool
|
||||
|
||||
tutorial *tutorialWidget
|
||||
tutorialFrame *etk.Frame
|
||||
|
||||
pressedKeys []ebiten.Key
|
||||
|
||||
cursorX, cursorY int
|
||||
|
@ -664,6 +669,8 @@ func NewGame() *Game {
|
|||
|
||||
TouchInput: AutoEnableTouchInput,
|
||||
|
||||
tutorialFrame: etk.NewFrame(),
|
||||
|
||||
debugImg: ebiten.NewImage(200, 200),
|
||||
volume: 1,
|
||||
scaleFactor: 1,
|
||||
|
@ -671,6 +678,7 @@ func NewGame() *Game {
|
|||
Mutex: &sync.Mutex{},
|
||||
}
|
||||
g.keyboard.SetScheduleFrameFunc(scheduleFrame)
|
||||
g.tutorialFrame.SetPositionChildren(true)
|
||||
game = g
|
||||
|
||||
loadImageAssets(0)
|
||||
|
@ -982,6 +990,7 @@ func NewGame() *Game {
|
|||
createGameFrame.SetPositionChildren(true)
|
||||
createGameFrame.AddChild(createGameContainer)
|
||||
createGameFrame.AddChild(etk.NewFrame(g.lobby.showKeyboardButton))
|
||||
createGameFrame.AddChild(g.tutorialFrame)
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -1014,6 +1023,7 @@ func NewGame() *Game {
|
|||
joinGameFrame.SetPositionChildren(true)
|
||||
joinGameFrame.AddChild(joinGameContainer)
|
||||
joinGameFrame.AddChild(etk.NewFrame(g.lobby.showKeyboardButton))
|
||||
joinGameFrame.AddChild(g.tutorialFrame)
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -1116,6 +1126,7 @@ func NewGame() *Game {
|
|||
|
||||
listGamesFrame.SetPositionChildren(true)
|
||||
listGamesFrame.AddChild(listGamesContainer)
|
||||
listGamesFrame.AddChild(g.tutorialFrame)
|
||||
}
|
||||
|
||||
g.needLayoutConnect = true
|
||||
|
@ -1254,6 +1265,10 @@ func (g *Game) handleEvent(e interface{}) {
|
|||
matchesPlural = ""
|
||||
}
|
||||
l(fmt.Sprintf("*** Welcome, %s. There %s %d client%s playing %d match%s.", ev.PlayerName, areIs, ev.Clients, clientsPlural, ev.Games, matchesPlural))
|
||||
|
||||
if strings.HasPrefix(g.Client.Username, "Guest_") {
|
||||
g.tutorialFrame.AddChild(NewTutorialWidget())
|
||||
}
|
||||
case *bgammon.EventHelp:
|
||||
l(fmt.Sprintf("*** Help: %s", ev.Message))
|
||||
case *bgammon.EventNotice:
|
||||
|
@ -1968,6 +1983,9 @@ func (g *Game) Connect() {
|
|||
username := g.Username
|
||||
go c.Connect()
|
||||
go saveUsername(username)
|
||||
|
||||
// TODO
|
||||
|
||||
}
|
||||
|
||||
func (g *Game) ConnectLocal(conn net.Conn) {
|
||||
|
|
|
@ -37,6 +37,12 @@ msgstr ""
|
|||
msgid "Available"
|
||||
msgstr ""
|
||||
|
||||
msgid "Bearing Off"
|
||||
msgstr ""
|
||||
|
||||
msgid "Board"
|
||||
msgstr ""
|
||||
|
||||
msgid "Boxcars is a client for playing backgammon via bgammon.org, a free and open source backgammon service."
|
||||
msgstr ""
|
||||
|
||||
|
@ -55,6 +61,12 @@ msgstr ""
|
|||
msgid "Connecting..."
|
||||
msgstr ""
|
||||
|
||||
msgid "Create Match"
|
||||
msgstr ""
|
||||
|
||||
msgid "Create a match if you would like to play against someone else. Backgammon and acey-deucey games are supported."
|
||||
msgstr ""
|
||||
|
||||
msgid "Create match"
|
||||
msgstr ""
|
||||
|
||||
|
@ -70,6 +82,9 @@ msgstr ""
|
|||
msgid "Double"
|
||||
msgstr ""
|
||||
|
||||
msgid "Double click a checker to bear it off. Bear off all 15 checkers to win."
|
||||
msgstr ""
|
||||
|
||||
msgid "Download replay"
|
||||
msgstr ""
|
||||
|
||||
|
@ -79,9 +94,6 @@ msgstr ""
|
|||
msgid "Email"
|
||||
msgstr ""
|
||||
|
||||
msgid "Failed to connect to server."
|
||||
msgstr ""
|
||||
|
||||
msgid "Failed to download replay: %s"
|
||||
msgstr ""
|
||||
|
||||
|
@ -100,6 +112,9 @@ msgstr ""
|
|||
msgid "Failed to submit moves: %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Good Luck, Have Fun"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hide Keyboard"
|
||||
msgstr ""
|
||||
|
||||
|
@ -136,6 +151,9 @@ msgstr ""
|
|||
msgid "Match Name"
|
||||
msgstr ""
|
||||
|
||||
msgid "Matches List"
|
||||
msgstr ""
|
||||
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
|
@ -235,12 +253,21 @@ msgstr ""
|
|||
msgid "Submit"
|
||||
msgstr ""
|
||||
|
||||
msgid "This concludes the tutorial. Join the community via Matrix/Discord/IRC at %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "This screen lists the matches that are currently available. A few bots are always available to play against."
|
||||
msgstr ""
|
||||
|
||||
msgid "To download this replay visit"
|
||||
msgstr ""
|
||||
|
||||
msgid "To log in as a guest, enter a username (if you want) and do not enter a password."
|
||||
msgstr ""
|
||||
|
||||
msgid "Tutorial"
|
||||
msgstr ""
|
||||
|
||||
msgid "Type %s to offer a rematch."
|
||||
msgstr ""
|
||||
|
||||
|
@ -265,12 +292,18 @@ msgstr ""
|
|||
msgid "Warning: Received unrecognized event from server."
|
||||
msgstr ""
|
||||
|
||||
msgid "Welcome to the guided tutorial. Click anywhere outside of this message box to close the tutorial. Click anywhere inside of this message box to view the next page."
|
||||
msgstr ""
|
||||
|
||||
msgid "Write error"
|
||||
msgstr ""
|
||||
|
||||
msgid "Yes"
|
||||
msgstr ""
|
||||
|
||||
msgid "You have the black checkers. You can move a checker by either clicking it or dragging it."
|
||||
msgstr ""
|
||||
|
||||
msgid "You may need to upgrade your client."
|
||||
msgstr ""
|
||||
|
||||
|
|
137
game/tutorial.go
Normal file
137
game/tutorial.go
Normal file
|
@ -0,0 +1,137 @@
|
|||
package game
|
||||
|
||||
import (
|
||||
"image"
|
||||
"image/color"
|
||||
"time"
|
||||
|
||||
"code.rocket9labs.com/tslocum/etk"
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
"github.com/leonelquinteros/gotext"
|
||||
)
|
||||
|
||||
type tutorialWidget struct {
|
||||
*etk.Frame
|
||||
grid *etk.Grid
|
||||
page int
|
||||
lastClick time.Time
|
||||
}
|
||||
|
||||
func NewTutorialWidget() *tutorialWidget {
|
||||
w := &tutorialWidget{
|
||||
Frame: etk.NewFrame(),
|
||||
grid: etk.NewGrid(),
|
||||
}
|
||||
w.Frame.SetPositionChildren(true)
|
||||
w.Frame.AddChild(w.grid)
|
||||
|
||||
w.setPage(0)
|
||||
|
||||
return w
|
||||
}
|
||||
|
||||
func (w *tutorialWidget) hide() {
|
||||
game.lobby.showCreateGame = false
|
||||
game.setRoot(listGamesFrame)
|
||||
setViewBoard(false)
|
||||
w.grid.Clear()
|
||||
}
|
||||
|
||||
func (w *tutorialWidget) dialogText(message string) *tutorialDialog {
|
||||
t := etk.NewText(message)
|
||||
t.SetBackgroundColor(bufferBackgroundColor)
|
||||
return &tutorialDialog{
|
||||
Text: t,
|
||||
handler: func() {
|
||||
w.setPage(w.page + 1)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (w *tutorialWidget) newTutorialBox() *tutorialBox {
|
||||
return &tutorialBox{
|
||||
Box: etk.NewBox(),
|
||||
handler: w.hide,
|
||||
}
|
||||
}
|
||||
|
||||
func (w *tutorialWidget) setPage(page int) {
|
||||
if time.Since(w.lastClick) < 250*time.Millisecond {
|
||||
return
|
||||
}
|
||||
w.lastClick = time.Now()
|
||||
w.page = page
|
||||
w.grid.Clear()
|
||||
|
||||
var title string
|
||||
var message string
|
||||
switch w.page {
|
||||
case 0:
|
||||
title = gotext.Get("Tutorial")
|
||||
message = gotext.Get("Welcome to the guided tutorial. Click anywhere outside of this message box to close the tutorial. Click anywhere inside of this message box to view the next page.")
|
||||
case 1:
|
||||
title = gotext.Get("Matches List")
|
||||
message = gotext.Get("This screen lists the matches that are currently available. A few bots are always available to play against.")
|
||||
case 2:
|
||||
game.lobby.showCreateGame = true
|
||||
game.setRoot(createGameFrame)
|
||||
etk.SetFocus(game.lobby.createGameName)
|
||||
title = gotext.Get("Create Match")
|
||||
message = gotext.Get("Create a match if you would like to play against someone else. Backgammon and acey-deucey games are supported.")
|
||||
case 3:
|
||||
game.lobby.showCreateGame = false
|
||||
game.setRoot(listGamesFrame)
|
||||
setViewBoard(true)
|
||||
title = gotext.Get("Board")
|
||||
message = gotext.Get("You have the black checkers. You can move a checker by either clicking it or dragging it.")
|
||||
case 4:
|
||||
title = gotext.Get("Bearing Off")
|
||||
message = gotext.Get("Double click a checker to bear it off. Bear off all 15 checkers to win.")
|
||||
case 5:
|
||||
title = gotext.Get("Good Luck, Have Fun")
|
||||
message = gotext.Get("This concludes the tutorial. Join the community via Matrix/Discord/IRC at %s", "bgammon.org/community")
|
||||
case 6:
|
||||
w.hide()
|
||||
return
|
||||
}
|
||||
message = title + "\n\n" + message
|
||||
|
||||
w.grid.SetColumnSizes(-1, -1, -1, -1)
|
||||
w.grid.SetRowSizes(-1, -1, -1, -1)
|
||||
w.grid.AddChildAt(w.newTutorialBox(), 0, 0, 4, 1)
|
||||
w.grid.AddChildAt(w.newTutorialBox(), 0, 1, 1, 2)
|
||||
w.grid.AddChildAt(w.dialogText(message), 1, 1, 2, 2)
|
||||
w.grid.AddChildAt(w.newTutorialBox(), 3, 1, 1, 2)
|
||||
w.grid.AddChildAt(w.newTutorialBox(), 0, 3, 4, 1)
|
||||
}
|
||||
|
||||
type tutorialDialog struct {
|
||||
*etk.Text
|
||||
handler func()
|
||||
}
|
||||
|
||||
func (d *tutorialDialog) Draw(screen *ebiten.Image) error {
|
||||
screen.SubImage(d.Text.Rect().Inset(-2)).(*ebiten.Image).Fill(color.RGBA{0, 0, 0, 255})
|
||||
return d.Text.Draw(screen)
|
||||
}
|
||||
|
||||
func (d *tutorialDialog) HandleMouse(cursor image.Point, pressed bool, clicked bool) (handled bool, err error) {
|
||||
if !cursor.In(d.Rect()) || !clicked {
|
||||
return false, nil
|
||||
}
|
||||
d.handler()
|
||||
return true, nil
|
||||
}
|
||||
|
||||
type tutorialBox struct {
|
||||
*etk.Box
|
||||
handler func()
|
||||
}
|
||||
|
||||
func (b *tutorialBox) HandleMouse(cursor image.Point, pressed bool, clicked bool) (handled bool, err error) {
|
||||
if !cursor.In(b.Rect()) || !clicked {
|
||||
return false, nil
|
||||
}
|
||||
b.handler()
|
||||
return true, nil
|
||||
}
|
Loading…
Reference in a new issue