diff --git a/screen_main.go b/screen_main.go index 712938a..47ee302 100644 --- a/screen_main.go +++ b/screen_main.go @@ -4,6 +4,7 @@ import ( "fmt" "math" "math/rand" + "strconv" "time" "gogs.bullercodeworks.com/brian/termbox-util" @@ -61,6 +62,10 @@ func (screen *mainScreen) handleKeyPress(event termbox.Event) int { } if event.Key == termbox.KeySpace { screen.Bullet.init(p) + if p.projSpeed <= 5 { + //screen.Bullet.angle = 270 + //screen.Bullet.speed = 8 + } screen.animating = true screen.GameMode = modeRun } else if event.Key == termbox.KeyArrowLeft || event.Ch == 'a' { @@ -83,7 +88,6 @@ func (screen *mainScreen) performLayout(style style) { screen.gravity = float64(-9.81) b := projectile{gravity: screen.gravity} screen.Bullet = &b - // TODO: Reset Buildings screen.Buildings = []building{} // Create a random seed (from time) seed := fmt.Sprintf("%d", time.Now().UnixNano()) @@ -101,10 +105,11 @@ func (screen *mainScreen) performLayout(style style) { case 2: c = termbox.ColorBlue } + if ScreenWidth-(bldCity+w) < 5 { w += ScreenWidth - (bldCity + w) } - b := building{startX: bldCity, width: w, height: h, color: c} + b := building{startX: bldCity, width: w, height: h, color: c, windowsAt: screen.r.Intn(3)} screen.Buildings = append(screen.Buildings, b) bldCity += w } @@ -160,7 +165,7 @@ func (screen *mainScreen) update() { } screen.GameMode = modeRunInput } else { - if screen.Bullet.x > 0 && screen.Bullet.x < ScreenWidth && screen.Bullet.y < ScreenHeight && screen.Bullet.y > -5000 { + if screen.Bullet.x > 0 && screen.Bullet.x < ScreenWidth && screen.Bullet.y < ScreenHeight { screen.Bullet.update() // Check for collisions if screen.Player1.didCollide(screen.Bullet) { @@ -217,16 +222,20 @@ func (screen *mainScreen) drawScreen(style style) { } else if screen.GameMode == modeRunInput { // Draw inputs if screen.PlayerTurn == 1 { - angleText := fmt.Sprintf("Angle: %d", screen.Player1.projAngle) - speedText := fmt.Sprintf("Speed: %d", screen.Player1.projSpeed) - termboxUtil.DrawStringAtPoint(angleText, 0, 0, style.defaultFg, style.defaultBg) - termboxUtil.DrawStringAtPoint(speedText, 0, 1, style.defaultFg, style.defaultBg) + termboxUtil.DrawStringAtPoint( + "Angle: "+strconv.Itoa(screen.Player1.projAngle), + 0, 0, style.defaultFg, style.defaultBg) + termboxUtil.DrawStringAtPoint( + "Speed: "+strconv.Itoa(screen.Player1.projSpeed), + 0, 1, style.defaultFg, style.defaultBg) termboxUtil.DrawStringAtPoint("'space' to fire", 0, 2, style.defaultFg, style.defaultBg) } else { - angleText := fmt.Sprintf("Angle: %d", screen.Player2.projAngle) - speedText := fmt.Sprintf("Speed: %d", screen.Player2.projSpeed) - termboxUtil.DrawStringAtPoint(angleText, ScreenWidth-11, 0, style.defaultFg, style.defaultBg) - termboxUtil.DrawStringAtPoint(speedText, ScreenWidth-11, 1, style.defaultFg, style.defaultBg) + termboxUtil.DrawStringAtPoint( + "Angle: "+strconv.Itoa(screen.Player2.projAngle), + ScreenWidth-11, 0, style.defaultFg, style.defaultBg) + termboxUtil.DrawStringAtPoint( + "Speed: "+strconv.Itoa(screen.Player2.projSpeed), + ScreenWidth-11, 1, style.defaultFg, style.defaultBg) termboxUtil.DrawStringAtPoint("'space' to fire", ScreenWidth-15, 2, style.defaultFg, style.defaultBg) } } @@ -272,14 +281,21 @@ type projectile struct { speed, angle int gravity float64 launchTime time.Time + movingUp bool } func (p *projectile) init(pl *player) { p.launchTime = time.Now() p.angle = pl.projAngle p.speed = pl.projSpeed - p.startX, p.startY = pl.GetClosestTrajectory() - //p.startX, p.startY = pl.x+2, pl.y+2 + if p.speed <= 5 { + p.angle = 270 + p.speed = 10 + p.startX = pl.x + 2 + p.startY = pl.y - 5 + } else { + p.startX, p.startY = pl.GetClosestTrajectory() + } p.x = p.startX p.y = p.startY } @@ -289,13 +305,19 @@ func (p *projectile) update() { useSpeed := float64(p.speed) useX, useY := float64(p.startX), float64(p.startY) useA := degToRad(p.angle) + lastY := p.y p.x = int(useX + (useSpeed * math.Cos(useA) * tm)) p.y = int(useY + (useSpeed*math.Sin(useA)*tm - p.gravity*tm*tm/2)) + p.movingUp = p.y < lastY } func (p *projectile) draw() { if p.y < 0 { - termbox.SetCell(p.x, 0, '^', termbox.ColorYellow, termbox.ColorBlack) + if p.movingUp { + termbox.SetCell(p.x, 0, '^', termbox.ColorYellow, termbox.ColorBlack) + } else { + termbox.SetCell(p.x, 0, 'v', termbox.ColorYellow, termbox.ColorBlack) + } } else { termbox.SetCell(p.x, p.y, '0', termbox.ColorYellow, termbox.ColorBlack) } @@ -347,25 +369,35 @@ func (p *player) draw() { termbox.SetCell(p.x+3, p.y, ' ', p.baseColor, p.baseColor) termbox.SetCell(p.x+4, p.y, ' ', p.baseColor, p.baseColor) - // Now draw the arms + // Now draw the target if p.turn { bulletHandX, bulletHandY := p.GetBulletHandPos() - termbox.SetCell(bulletHandX, bulletHandY, 'X', termbox.ColorRed|termbox.AttrBold, termbox.ColorBlack) + if p.coordCollide(bulletHandX, bulletHandY) { + termbox.SetCell(bulletHandX, bulletHandY, + '!', termbox.ColorRed|termbox.AttrBold, termbox.ColorBlack) + } else { + termbox.SetCell(bulletHandX, bulletHandY, + 'X', termbox.ColorRed|termbox.AttrBold, termbox.ColorBlack) + } } } -func (p *player) didCollide(pr *projectile) bool { - if pr.x >= p.x && pr.x <= p.x+4 { - return pr.y <= p.y && pr.y >= p.y-4 +func (p *player) coordCollide(x, y int) bool { + if x >= p.x && x <= p.x+4 { + return y <= p.y && y >= p.y-4 } return false } +func (p *player) didCollide(pr *projectile) bool { + return p.coordCollide(pr.x, pr.y) +} + func (p *player) GetClosestTrajectory() (int, int) { // Find the spot closest to the player in a direct line with the target bHx, bHy := p.GetBulletHandPos() gx, gy := p.x+2, p.y-2 - for gx >= p.x && gx <= p.x+4 && gy >= p.y-4 && gy <= p.y { + for p.coordCollide(gx, gy) { if math.Abs(float64(bHx-gx)) > math.Abs(float64(bHy-gy)) { if bHx > gx { gx++ @@ -397,20 +429,36 @@ type building struct { startX int width, height int color termbox.Attribute - windowsOn []int + windowsAt int } func (b *building) draw(x int) { for i := 0; i < b.height; i++ { for j := 0; j < b.width; j++ { c := b.color - /* TODO: Windows - if i > 0 && i < b.height && j > 0 && j < b.width { - if i%2 == 1 && j%2 == 1 { - c = termbox.ColorBlack + if b.width%2 == 1 { + // Individual windows + if i > 0 && i < b.height-1 && j > 0 && j < b.width-1 { + if i%3 == b.windowsAt && j%2 == 1 { + if i%5 == b.windowsAt || j%5 == b.windowsAt || (i+j)%5 == b.windowsAt { + c = termbox.ColorYellow + } else { + c = termbox.ColorBlack + } + } + } + } else { + // Floor windows + if i > 0 && i < b.height-1 && j > 0 && j < b.width-1 { + if i%3 == b.windowsAt { + if i%4 == b.windowsAt { + c = termbox.ColorYellow + } else { + c = termbox.ColorBlack + } + } } } - */ termbox.SetCell(x+j, ScreenHeight-i, ' ', c, c) } } diff --git a/screen_title.go b/screen_title.go index 5c650c7..cb9ea04 100644 --- a/screen_title.go +++ b/screen_title.go @@ -1,6 +1,8 @@ package main import ( + "strings" + "github.com/nsf/termbox-go" "gogs.bullercodeworks.com/brian/termbox-util" ) @@ -12,6 +14,7 @@ type command struct { type titleScreen struct { titleArt *termboxUtil.ASCIIArt + directions *termboxUtil.ASCIIArt menu *termboxUtil.Menu initialized bool } @@ -20,9 +23,9 @@ func (screen *titleScreen) handleKeyPress(event termbox.Event) int { if screen.menu.HandleKeyPress(event) { if screen.menu.IsDone() { selOpt := screen.menu.GetSelectedOption() - if selOpt.GetText() == "Exit" { + if strings.Trim(selOpt.GetText(), " ") == "Exit" { return exitScreenIndex - } else if selOpt.GetText() == "New Game" { + } else if strings.Trim(selOpt.GetText(), " ") == "New Game" { screen.initialized = false return mainScreenIndex } @@ -49,7 +52,6 @@ func (screen *titleScreen) performLayout(style style) { tmplt = append(tmplt, " ") tmplt = append(tmplt, " ") } - defaultFg := style.defaultFg defaultBg := style.defaultBg screen.titleArt = termboxUtil.CreateASCIIArt(tmplt, 0, 0, defaultFg, defaultBg) @@ -60,13 +62,23 @@ func (screen *titleScreen) performLayout(style style) { menuY := h/2 - 5 screen.menu = termboxUtil.CreateMenu("", - []string{"New Game", "Continue", "Exit"}, + []string{ + " New Game ", + " Exit "}, menuX, menuY, 20, 10, defaultFg, defaultBg, ) // TODO: Check if we have a suspended game - screen.menu.SetOptionDisabled(1) - screen.menu.SetBordered(true) screen.menu.EnableVimMode() + + var directions []string + directions = append(directions, " Directions: ") + directions = append(directions, " Up/Down adjust Speed ") + directions = append(directions, " Left/Right adjust Angle ") + directions = append(directions, " Space to Fire ") + directions = append(directions, " W,A,S,D also work ") + screen.directions = termboxUtil.CreateASCIIArt(directions, 0, menuX+10, defaultFg, defaultBg) + screen.directions.Align(termboxUtil.AlignCenter, w) + screen.initialized = true } } @@ -76,4 +88,5 @@ func (screen *titleScreen) update() {} func (screen *titleScreen) drawScreen(style style) { screen.titleArt.Draw() screen.menu.Draw() + screen.directions.Draw() }