205 lines
4.8 KiB
Go
205 lines
4.8 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"math/rand"
|
||
|
"time"
|
||
|
|
||
|
"gogs.bullercodeworks.com/brian/termbox-util"
|
||
|
|
||
|
"github.com/nsf/termbox-go"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
modeInit = iota
|
||
|
modeRun
|
||
|
modeRunInput
|
||
|
)
|
||
|
|
||
|
type player struct {
|
||
|
x, y int
|
||
|
projSpeed int
|
||
|
projAngle int
|
||
|
screen *mainScreen
|
||
|
}
|
||
|
|
||
|
func (p *player) draw() {
|
||
|
drawGopher(p.x, p.y, termbox.ColorCyan)
|
||
|
}
|
||
|
|
||
|
type building struct {
|
||
|
width, height int
|
||
|
color termbox.Attribute
|
||
|
windowsOn []int
|
||
|
}
|
||
|
|
||
|
func (b *building) draw(x int) {
|
||
|
// Fill
|
||
|
for i := 0; i < b.height; i++ {
|
||
|
for j := 0; j < b.width; j++ {
|
||
|
c := b.color
|
||
|
/*
|
||
|
if i > 0 && i < b.height && j > 0 && j < b.width {
|
||
|
if i%2 == 1 && j%2 == 1 {
|
||
|
c = termbox.ColorBlack
|
||
|
}
|
||
|
}
|
||
|
*/
|
||
|
termbox.SetCell(x+j, ScreenHeight-i, ' ', c, c)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
type mainScreen struct {
|
||
|
GameMode int
|
||
|
PlayerTurn int
|
||
|
tabIdx int
|
||
|
Player1 player
|
||
|
Player2 player
|
||
|
Buildings []building
|
||
|
}
|
||
|
|
||
|
func (screen *mainScreen) handleKeyEvent(event termbox.Event) int {
|
||
|
if screen.GameMode == modeRunInput {
|
||
|
}
|
||
|
return mainScreenIndex
|
||
|
}
|
||
|
|
||
|
func (screen *mainScreen) performLayout(style style) {
|
||
|
var bldCity int
|
||
|
if screen.GameMode == modeInit {
|
||
|
// Create a random seed (from time)
|
||
|
seed := fmt.Sprintf("%d", time.Now().UnixNano())
|
||
|
r := rand.New(rand.NewSource(getSeedFromString(seed + "-world")))
|
||
|
for bldCity < ScreenWidth {
|
||
|
w := r.Intn(8) + 5
|
||
|
h := r.Intn(ScreenHeight-10) + 2
|
||
|
var c termbox.Attribute
|
||
|
switch r.Intn(3) {
|
||
|
case 0:
|
||
|
c = termbox.ColorRed
|
||
|
case 1:
|
||
|
c = termbox.ColorGreen
|
||
|
case 2:
|
||
|
c = termbox.ColorBlue
|
||
|
}
|
||
|
b := building{width: w, height: h, color: c}
|
||
|
screen.Buildings = append(screen.Buildings, b)
|
||
|
bldCity += w
|
||
|
}
|
||
|
// Player 1 should be on the first 1/3 of the screen
|
||
|
p1x := r.Intn(ScreenWidth / 3)
|
||
|
p1y := 0
|
||
|
// Make sure that p1x is fully on a building
|
||
|
// Find the building for the player's x
|
||
|
var calcX int
|
||
|
for i := range screen.Buildings {
|
||
|
calcX += screen.Buildings[i].width
|
||
|
if calcX > p1x {
|
||
|
if calcX > p1x+5 {
|
||
|
mv := (p1x + 5) - calcX
|
||
|
p1x -= mv
|
||
|
}
|
||
|
p1y = ScreenHeight - screen.Buildings[i].height
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
screen.Player1 = player{x: p1x, y: p1y, screen: screen}
|
||
|
// Player 2 should be on the third 1/3 of the screen
|
||
|
p2x := r.Intn(ScreenWidth/3) + ((ScreenWidth * 2) / 3)
|
||
|
p2y := 0
|
||
|
for i := range screen.Buildings {
|
||
|
calcX += screen.Buildings[i].width
|
||
|
if calcX > p1x {
|
||
|
if calcX > p2x+5 {
|
||
|
mv := (p2x + 5) - calcX
|
||
|
p2x -= mv
|
||
|
}
|
||
|
p2y = ScreenHeight - screen.Buildings[i].height
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
// Make sure that p2x is fully on a building
|
||
|
screen.Player2 = player{x: p2x, y: p2y, screen: screen}
|
||
|
}
|
||
|
screen.GameMode = modeRun
|
||
|
}
|
||
|
|
||
|
// Trigger all updates
|
||
|
func (screen *mainScreen) update() {
|
||
|
if screen.GameMode == modeRun {
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (screen *mainScreen) drawScreen(style style) {
|
||
|
// Draw Player 1
|
||
|
screen.Player1.draw()
|
||
|
// Draw Player 2
|
||
|
screen.Player2.draw()
|
||
|
// Draw Landscape
|
||
|
var x int
|
||
|
for i := range screen.Buildings {
|
||
|
screen.Buildings[i].draw(x)
|
||
|
x += screen.Buildings[i].width
|
||
|
}
|
||
|
if screen.GameMode == modeRun {
|
||
|
// Draw Projectile(s)
|
||
|
} else if screen.GameMode == modeRunInput {
|
||
|
// Draw inputs
|
||
|
if screen.PlayerTurn == 1 {
|
||
|
termboxUtil.DrawStringAtPoint("Angle:", 0, 0, style.defaultFg, style.defaultBg)
|
||
|
termboxUtil.DrawStringAtPoint("Speed:", 0, 1, style.defaultFg, style.defaultBg)
|
||
|
} else {
|
||
|
termboxUtil.DrawStringAtPoint("Angle:", ScreenWidth-11, 0, style.defaultFg, style.defaultBg)
|
||
|
termboxUtil.DrawStringAtPoint("Speed:", ScreenWidth-11, 1, style.defaultFg, style.defaultBg)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func getNowTime() int {
|
||
|
return int(time.Now().UnixNano())
|
||
|
}
|
||
|
|
||
|
func getSeedFromString(seed string) int64 {
|
||
|
// How does this algorithm work for string->seed generation?
|
||
|
// ~\_(o.o)_/~
|
||
|
var ret int64
|
||
|
for i, k := range seed {
|
||
|
ret += int64(k) * int64(i)
|
||
|
}
|
||
|
return ret
|
||
|
}
|
||
|
|
||
|
func drawGopher(x, y int, c termbox.Attribute) {
|
||
|
termbox.SetCell(x, y-4, ' ', c, c)
|
||
|
termbox.SetCell(x+1, y-4, ' ', c, c)
|
||
|
termbox.SetCell(x+2, y-4, ' ', c, c)
|
||
|
termbox.SetCell(x+3, y-4, ' ', c, c)
|
||
|
termbox.SetCell(x+4, y-4, ' ', c, c)
|
||
|
|
||
|
termbox.SetCell(x, y-3, ' ', c, c)
|
||
|
termbox.SetCell(x+1, y-3, '@', termbox.ColorBlack, termbox.ColorWhite)
|
||
|
termbox.SetCell(x+2, y-3, ' ', c, c)
|
||
|
termbox.SetCell(x+3, y-3, '@', termbox.ColorBlack, termbox.ColorWhite)
|
||
|
termbox.SetCell(x+4, y-3, ' ', c, c)
|
||
|
|
||
|
termbox.SetCell(x, y-2, ' ', c, c)
|
||
|
termbox.SetCell(x+1, y-2, ' ', c, c)
|
||
|
termbox.SetCell(x+2, y-2, 'w', termbox.ColorWhite, c)
|
||
|
termbox.SetCell(x+3, y-2, ' ', c, c)
|
||
|
termbox.SetCell(x+4, y-2, ' ', c, c)
|
||
|
|
||
|
termbox.SetCell(x, y-1, ' ', c, c)
|
||
|
termbox.SetCell(x+1, y-1, ' ', c, c)
|
||
|
termbox.SetCell(x+2, y-1, ' ', c, c)
|
||
|
termbox.SetCell(x+3, y-1, ' ', c, c)
|
||
|
termbox.SetCell(x+4, y-1, ' ', c, c)
|
||
|
|
||
|
termbox.SetCell(x, y, ' ', c, c)
|
||
|
termbox.SetCell(x+1, y, ' ', c, c)
|
||
|
termbox.SetCell(x+2, y, ' ', c, c)
|
||
|
termbox.SetCell(x+3, y, ' ', c, c)
|
||
|
termbox.SetCell(x+4, y, ' ', c, c)
|
||
|
}
|