diff --git a/screen_main.go b/screen_main.go index c3bd59f..2a1c9d4 100644 --- a/screen_main.go +++ b/screen_main.go @@ -16,6 +16,7 @@ const ( modeRun modeRunInput modePause + modeGameOver ) type mainScreen struct { @@ -39,7 +40,7 @@ func (screen *mainScreen) handleKeyPress(event termbox.Event) int { screen.GameMode = modeRun } } - if screen.GameMode == modePause { + if screen.GameMode == modePause || screen.GameMode == modeGameOver { screen.PauseMenu.HandleKeyPress(event) if screen.PauseMenu.IsDone() { selOpt := screen.PauseMenu.GetSelectedOption() @@ -54,60 +55,26 @@ func (screen *mainScreen) handleKeyPress(event termbox.Event) int { } } if screen.GameMode == modeRunInput { + p := screen.Player1 + if screen.PlayerTurn == 2 { + p = screen.Player2 + } if event.Key == termbox.KeySpace { - if screen.PlayerTurn == 1 { - screen.Bullet.launchTime = time.Now() - screen.Bullet.angle = screen.Player1.projAngle - screen.Bullet.speed = screen.Player1.projSpeed - screen.Bullet.startX, screen.Bullet.startY = screen.Player1.GetBulletHandPos() - } else { - screen.Bullet.launchTime = time.Now() - screen.Bullet.angle = 180 - screen.Player2.projAngle - screen.Bullet.speed = screen.Player2.projSpeed - screen.Bullet.startX, screen.Bullet.startY = screen.Player2.GetBulletHandPos() - } - screen.Bullet.x = screen.Bullet.startX - screen.Bullet.y = screen.Bullet.startY + screen.Bullet.init(p) screen.animating = true screen.GameMode = modeRun } else if event.Key == termbox.KeyArrowLeft || event.Ch == 'a' { - if screen.PlayerTurn == 1 { - if screen.Player1.projAngle < 180 { - screen.Player1.projAngle++ - } - } else { - if screen.Player2.projAngle > 0 { - screen.Player2.projAngle-- - } + if p.projAngle < 180 { + p.projAngle++ } } else if event.Key == termbox.KeyArrowRight || event.Ch == 'd' { - if screen.PlayerTurn == 1 { - if screen.Player1.projAngle > 0 { - screen.Player1.projAngle-- - } - } else { - if screen.Player2.projAngle > 180 { - screen.Player2.projAngle++ - } + if p.projAngle > 0 { + p.projAngle-- } } else if event.Key == termbox.KeyArrowUp || event.Ch == 'w' { - if screen.PlayerTurn == 1 { - // TODO: Upper speed limit - screen.Player1.projSpeed++ - } else { - // TODO: Upper speed limit - screen.Player2.projSpeed++ - } + p.projSpeed++ } else if event.Key == termbox.KeyArrowDown || event.Ch == 's' { - if screen.PlayerTurn == 1 { - if screen.Player1.projSpeed > 0 { - screen.Player1.projSpeed-- - } - } else { - if screen.Player2.projSpeed > 0 { - screen.Player2.projSpeed-- - } - } + p.projSpeed-- } } return mainScreenIndex @@ -141,7 +108,7 @@ func (screen *mainScreen) performLayout(style style) { if ScreenWidth-(bldCity+w) < 5 { w += ScreenWidth - (bldCity + w) } - b := building{width: w, height: h, color: c} + b := building{startX: bldCity, width: w, height: h, color: c} screen.Buildings = append(screen.Buildings, b) bldCity += w } @@ -157,6 +124,7 @@ func (screen *mainScreen) performLayout(style style) { p2x, p2y = screen.getRndPosForBuilding(bld - 1) } screen.Player2 = createPlayer(p2x, p2y) + screen.Player2.projAngle = 135 screen.PauseMenu = termboxUtil.CreateMenu("** GOPHER BATTLE **", []string{"Resume", "Restart", "Exit"}, @@ -176,11 +144,45 @@ func createPlayer(px, py int) *player { func (screen *mainScreen) update() { if screen.GameMode == modeRun { if !screen.animating { + if screen.PlayerTurn == 1 { + screen.PlayerTurn = 2 + } else { + screen.PlayerTurn = 1 + } screen.GameMode = modeRunInput } else { if screen.Bullet.x > 0 && screen.Bullet.x < ScreenWidth && screen.Bullet.y < ScreenHeight && screen.Bullet.y > -5000 { screen.Bullet.update() // Check for collisions + if screen.Player1.didCollide(screen.Bullet) { + screen.PauseMenu.SetOptionDisabled(0) + if screen.PlayerTurn == 1 { + // Self kill + screen.PauseMenu.SetTitle("Player 1 LOSES.") + } else { + // Victory! + screen.PauseMenu.SetTitle("Player 1 Wins!") + } + screen.GameMode = modePause + } + if screen.Player2.didCollide(screen.Bullet) { + screen.PauseMenu.SetOptionDisabled(0) + if screen.PlayerTurn == 2 { + // Self kill + screen.PauseMenu.SetTitle("Player 2 LOSES.") + } else { + // Victory! + screen.PauseMenu.SetTitle("Player 2 Wins!") + } + screen.GameMode = modePause + } + for i := range screen.Buildings { + if screen.Buildings[i].didCollide(screen.Bullet) { + // Collision + screen.animating = false + break + } + } } else { // Bullet went off the sides of the screen screen.animating = false @@ -190,10 +192,6 @@ func (screen *mainScreen) update() { } 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 { @@ -221,6 +219,12 @@ func (screen *mainScreen) drawScreen(style style) { termboxUtil.DrawStringAtPoint("'space' to fire", ScreenWidth-15, 2, style.defaultFg, style.defaultBg) } } + + // Draw Player 1 + screen.Player1.draw() + // Draw Player 2 + screen.Player2.draw() + if screen.GameMode == modePause { // Draw the pause menu screen.PauseMenu.Draw() @@ -259,17 +263,23 @@ type projectile struct { launchTime time.Time } +func (p *projectile) init(pl *player) { + p.launchTime = time.Now() + p.angle = pl.projAngle + p.speed = pl.projSpeed + p.startX, p.startY = pl.GetBulletHandPos() + p.x = p.startX + p.y = p.startY +} + func (p *projectile) update() { - // On an update we increase the tick tm := time.Since(p.launchTime).Seconds() useSpeed := float64(p.speed) useX, useY := float64(p.startX), float64(p.startY) - halfG := 0.5 * p.gravity - p.x = int(useX + (useSpeed * tm)) - p.y = int(useY + (useSpeed * tm) - (halfG * tm * tm)) - //p.x = int(useX + (math.Cos(degToRad(p.angle)) * useSpeed * tm)) - //p.y = int(useY + (math.Sin(degToRad(p.angle)) * useSpeed * tm * halfG * tm * tm)) - WriteToLog(fmt.Sprintf("(%d) %d,%d (s:%d;a:%d)\n", tm, p.x, p.y, useSpeed, p.angle)) + useA := float64(p.angle) + p.x = int(useX + (useSpeed * math.Cos(useA) * tm)) + p.y = int(useY + (useSpeed*math.Sin(useA)*tm - p.gravity*tm*tm/2)) + WriteToLog(fmt.Sprintf("%f - S:%d; (%d,%d)=>(%d,%d)\n", useA, p.speed, p.startX, p.startY, p.x, p.y)) } func (p *projectile) draw() { @@ -319,6 +329,15 @@ func (p *player) draw() { termbox.SetCell(bulletHandX, bulletHandY, 'O', termbox.ColorBlack, p.baseColor) } +func (p *player) didCollide(pr *projectile) bool { + WriteToLog(fmt.Sprintf("Player: (%d,%d) -> (%d,%d)\n", p.x, p.y-4, p.x+4, p.y)) + WriteToLog(fmt.Sprintf("Projectile: (%d,%d)\n", pr.x, pr.y)) + if pr.x >= p.x && pr.x <= p.x+4 { + return pr.y <= p.y && pr.y >= p.y-4 + } + return false +} + func (p *player) GetBulletHandPos() (int, int) { if p.projAngle <= 11 { return p.x + 5, p.y - 2 @@ -349,6 +368,7 @@ func (p *player) GetBulletHandPos() (int, int) { } type building struct { + startX int width, height int color termbox.Attribute windowsOn []int @@ -369,3 +389,10 @@ func (b *building) draw(x int) { } } } + +func (b *building) didCollide(p *projectile) bool { + if p.x >= b.startX && p.x <= b.startX+b.width { + return p.y >= ScreenHeight-b.height + } + return false +}