Skip to content

Commit

Permalink
finished project... for now
Browse files Browse the repository at this point in the history
  • Loading branch information
oschijns committed Feb 25, 2018
1 parent c9c63c6 commit 640a635
Show file tree
Hide file tree
Showing 11 changed files with 93 additions and 60 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@

# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
.glide/

/backup/**
Binary file added bannerBlack.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added bannerWhite.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified goban.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added stoneBlack.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added stoneWhite.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed stone_b.png
Binary file not shown.
Binary file removed stone_w.png
Binary file not shown.
7 changes: 6 additions & 1 deletion vector.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ type Vec2 struct {

// Inv return the inverse vector
func (v Vec2) Inv() Vec2 {
return Vec2{v.x, v.y}
return Vec2{-v.x, -v.y}
}

// Add return the sum of two vectors
Expand Down Expand Up @@ -39,3 +39,8 @@ func (v Vec2) Rot(rot int8) Vec2 {
func (v Vec2) ID() uint {
return (uint(v.x) & 0xff) | ((uint(v.y) & 0xff) << 8)
}

// return a vector that is invalid
func InvalidVec() Vec2 {
return Vec2{int8(-1), int8(-1)}
}
144 changes: 85 additions & 59 deletions window.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package main

import (
"fmt"
//"fmt"
"log"
"image/color"
"image"
//"image/color"
_ "image/png"

"github.com/hajimehoshi/ebiten"
Expand All @@ -12,27 +13,25 @@ import (

// size, padding, scaling
const (
GOBAN_SIZE = 512
STONE_SIZE = 25.5

// hardcoded values relative to sprites used
GOBAN_SCALE = 1.0 / 4.0
STONE_SCALE = 1.0 / 10.0
PADDING = 27

START_X = PADDING - STONE_SIZE / 2.0
START_Y = GOBAN_SIZE - PADDING - STONE_SIZE / 2.0
GOBAN_SIZE = 608
STONE_SIZE = 32
BANNER_SIZE = 32
)

// store the necessities to draw the board
type Window struct {
// images to draw the board
gobanImage, blackImage, whiteImage * ebiten.Image
// draw options for the board
gobanOpts * ebiten.DrawImageOptions
stoneBlackImage, bannerBlackImage,
stoneWhiteImage, bannerWhiteImage,
gobanImage * ebiten.Image

// draw options for the board and banner
gobanOpts, bannerOpts * ebiten.DrawImageOptions

// position of the selector when using key inputs
selectorPos Vec2
selectorPos Vec2 // TODO: not used yet
wasClicked bool // true if the mouse button was pressed already on the frame before

// the board to display
board * Board
// team to play
Expand All @@ -45,73 +44,100 @@ func (win * Window) Init(board * Board) {

// get the images to display
var err error
if win.gobanImage, _, err = ebitenutil.NewImageFromFile( "goban.png", ebiten.FilterNearest); err != nil {log.Fatal(err)}
if win.blackImage, _, err = ebitenutil.NewImageFromFile("stone_b.png", ebiten.FilterNearest); err != nil {log.Fatal(err)}
if win.whiteImage, _, err = ebitenutil.NewImageFromFile("stone_w.png", ebiten.FilterNearest); err != nil {log.Fatal(err)}
if win.gobanImage, _, err = ebitenutil.NewImageFromFile("goban.png", ebiten.FilterNearest); err != nil {log.Fatal(err)}
if win.stoneBlackImage, _, err = ebitenutil.NewImageFromFile("stoneBlack.png", ebiten.FilterNearest); err != nil {log.Fatal(err)}
if win.stoneWhiteImage, _, err = ebitenutil.NewImageFromFile("stoneWhite.png", ebiten.FilterNearest); err != nil {log.Fatal(err)}
if win.bannerBlackImage, _, err = ebitenutil.NewImageFromFile("bannerBlack.png", ebiten.FilterNearest); err != nil {log.Fatal(err)}
if win.bannerWhiteImage, _, err = ebitenutil.NewImageFromFile("bannerWhite.png", ebiten.FilterNearest); err != nil {log.Fatal(err)}

// if we cannot load the icon, it doesn't matter
_, icon, err := ebitenutil.NewImageFromFile("icon.png", ebiten.FilterNearest)
if err == nil {ebiten.SetWindowIcon([]image.Image{icon})}

// create a single draw option for the board
win.gobanOpts = &ebiten.DrawImageOptions{}
win.gobanOpts.GeoM.Scale(GOBAN_SCALE, GOBAN_SCALE) // 4 times smaller
win.gobanOpts = &ebiten.DrawImageOptions{}
win.bannerOpts = &ebiten.DrawImageOptions{}
win.bannerOpts.GeoM.Translate(0, GOBAN_SIZE)

win.board = board
win.team = false
window = win

// place the selector in the center
win.selectorPos.x = int8(10)
win.selectorPos.y = int8(10)
win.wasClicked = false

// run the game loop
if err := ebiten.Run(update, GOBAN_SIZE, GOBAN_SIZE, 1, "GoGo"); err != nil {log.Fatal(err)}
if err := ebiten.Run(update, GOBAN_SIZE, GOBAN_SIZE + BANNER_SIZE, 1, "GoGo"); err != nil {log.Fatal(err)}
}


func update (screen * ebiten.Image) error {

/* update game state */

// update selector position and play the game
func (win * Window) Update() {
// get inputs
if ebiten.IsKeyPressed(ebiten.KeyUp ) {window.selectorPos.y += 1}
if ebiten.IsKeyPressed(ebiten.KeyDown ) {window.selectorPos.y -= 1}
if ebiten.IsKeyPressed(ebiten.KeyLeft ) {window.selectorPos.x -= 1}
if ebiten.IsKeyPressed(ebiten.KeyRight) {window.selectorPos.x += 1}
if ebiten.IsKeyPressed(ebiten.KeyUp ) {win.selectorPos.y += 1}
if ebiten.IsKeyPressed(ebiten.KeyDown ) {win.selectorPos.y -= 1}
if ebiten.IsKeyPressed(ebiten.KeyLeft ) {win.selectorPos.x -= 1}
if ebiten.IsKeyPressed(ebiten.KeyRight) {win.selectorPos.x += 1}

// we prefer interactions with the mouse
x, y := ebiten.CursorPosition()
c := ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft)
click := ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft)

// when we click try to place a stone in the board
// if it succedes, end turn
if c {
posX := (float64(x) - START_X) / STONE_SIZE
posY := (START_Y - float64(y)) / STONE_SIZE
stone := Stone{Vec2{int8(posX), int8(posY + 1)}, window.team}
if window.board.Place(stone) {
window.team = !window.team // end turn
if click && !win.wasClicked {
stone := Stone{win.BoardCoords(x, y), win.team}
if win.board.Place(stone) {
win.team = !win.team // end turn
}
}

// do not force the system to render if it gets too slow
if ebiten.IsRunningSlowly() { return nil }
// keep track of the state of click
if click {win.wasClicked = true} else {win.wasClicked = false}
}

/* render the game */
// used to redraw the board only when necessary
func (win * Window) Redraw(screen * ebiten.Image) {
// draw the goban and the banner
screen.DrawImage(win.gobanImage, win.gobanOpts)
if win.team {screen.DrawImage(win.bannerWhiteImage, win.bannerOpts)
} else {screen.DrawImage(win.bannerBlackImage, win.bannerOpts)}

// draw a cool pattern
screen.Fill(color.NRGBA{0x30, 0x30, 0x30, 0xff})
// for each stone on the board, draw it on the display
for _, stone := range win.board.set {
x, y := win.WindowCoords(stone.Vec2)
opts := &ebiten.DrawImageOptions{}
opts.GeoM.Translate(x, y)
if stone.team {screen.DrawImage(win.stoneWhiteImage, opts)
} else {screen.DrawImage(win.stoneBlackImage, opts)}
}
}

// draw the goban
screen.DrawImage(window.gobanImage, window.gobanOpts)
// from window coords, get board coords
// used to click on the board
func (win * Window) BoardCoords(x, y int) Vec2 {
if x < 0 || y < 0 || x > GOBAN_SIZE || y > GOBAN_SIZE {return InvalidVec()}
return Vec2{int8(x / STONE_SIZE), int8(y / STONE_SIZE)}
}

ebitenutil.DebugPrint(screen, fmt.Sprintf("X: %d, Y: %d, FPS: %f", x, y, ebiten.CurrentFPS()))
if c { ebitenutil.DebugPrint(screen, "\n\nClick") }
// from board coords, get window coords
// used to draw elements on the board
func (win * Window) WindowCoords(pos Vec2) (float64, float64) {
return float64(pos.x) * STONE_SIZE, float64(pos.y) * STONE_SIZE
}

if window.team {ebitenutil.DebugPrint(screen, "\nWHITE")
} else {ebitenutil.DebugPrint(screen, "\nBLACK")}
// function called in loop by ebiten
func update (screen * ebiten.Image) error {

/* update game state */
window.Update()

// do not force the system to render if it gets too slow
if ebiten.IsRunningSlowly() { return nil }

/* render the game */
window.Redraw(screen)

// for each stone on the board, draw it on the display
for _, stone := range window.board.set {
posX := START_X + float64(stone.Vec2.x) * STONE_SIZE
posY := START_Y - float64(stone.Vec2.y) * STONE_SIZE
opts := &ebiten.DrawImageOptions{}
opts.GeoM.Scale(STONE_SCALE, STONE_SCALE) // ten times smaller
opts.GeoM.Translate(posX, posY)
if stone.team {screen.DrawImage(window.whiteImage, opts)
} else {screen.DrawImage(window.blackImage, opts)}
}
return nil
}

0 comments on commit 640a635

Please sign in to comment.