vimtronner
Version:
A multi-player Vim trainer.
214 lines (187 loc) • 6.99 kB
text/coffeescript
require '../../define_property'
screen = require '../screen'
buffer = require '../buffer'
Game = require '../../models/game'
Cycle = require '../../models/cycle'
CycleView = require './cycle_view'
playerColors = require './player_colors'
ARENA_WALL_CHARS = {
HORIZONTAL: buffer(0xE2, 0x95, 0x90)
VERTICAL: buffer(0xE2, 0x95, 0x91)
TOP_LEFT_CORNER: buffer(0xE2, 0x95, 0x94)
TOP_RIGHT_CORNER: buffer(0xE2, 0x95, 0x97)
BOTTOM_LEFT_CORNER: buffer(0xE2, 0x95, 0x9A)
BOTTOM_RIGHT_CORNER: buffer(0xE2, 0x95, 0x9D)
}
CYCLE_NUMBER_NAMES = {
1: 'ONE'
2: 'TWO'
3: 'THREE'
4: 'FOUR'
5: 'FIVE'
6: 'SIX'
7: 'SEVEN'
8: 'EIGHT'
}
cycleNumberName = (cycleNumber)-> CYCLE_NUMBER_NAMES[cycleNumber]
class GameView
constructor: ->
= []
= ''
'state', get: -> ?.state
'game', {
set: (game)->
= game
if == Game.STATES.COUNTDOWN
if .count != and == Game.STATES.COUNTDOWN
= .count
+= "#{@_game.count}..."
else
delete
= ''
get: ->
}
'stateString', get: ->
switch ?.state
when Game.STATES.WAITING then 'Waiting for other players'
when Game.STATES.COUNTDOWN then 'Get ready'
when Game.STATES.STARTED then 'Go'
when Game.STATES.FINISHED then 'Game over'
'startX', get: ->
Math.round(screen.center.x - (.width/2))
'startY', get: ->
Math.round(screen.center.y - 2 - (.height/2))
generateCycleViews: ->
= (new CycleView(cycle, ) for cycle in .cycles)
render: ->
screen.clear()
screen.hideCursor()
screen.save()
screen.transform(, )
if == Game.STATES.WAITING or ( == Game.STATES.RESTARTING and .ready)
else if == Game.STATES.COUNTDOWN
else if == Game.STATES.FINISHED or == Game.STATES.RESTARTING
else
screen.restore()
renderArena: ->
screen.setForegroundColor 3
xRange = .width - 1
yRange = .height - 1
endX = .width
endY = .height
screen.moveTo(1,1)
screen.render ARENA_WALL_CHARS.TOP_LEFT_CORNER
for x in [2..xRange]
screen.moveTo (x), 1
screen.render ARENA_WALL_CHARS.HORIZONTAL
screen.moveTo endX, 1
screen.render ARENA_WALL_CHARS.TOP_RIGHT_CORNER
for y in [2..yRange]
screen.moveTo endX, y
screen.render ARENA_WALL_CHARS.VERTICAL
screen.moveTo endX, endY
screen.render ARENA_WALL_CHARS.BOTTOM_RIGHT_CORNER
for x in [xRange..1]
screen.moveTo x, endY
screen.render ARENA_WALL_CHARS.HORIZONTAL
screen.moveTo 1, endY
screen.render ARENA_WALL_CHARS.BOTTOM_LEFT_CORNER
for y in [yRange..2]
screen.moveTo 1, y
screen.render ARENA_WALL_CHARS.VERTICAL
renderWaitScreen: ->
instructions = [
'left...................h'
'down...................j'
'up.....................k'
'right..................l'
'insert mode............i'
'normal mode...esc/ctrl-['
]
centerX = Math.round(.width/2)
y = Math.round(.height/2) - 10
screen.setForegroundColor 6
screen.print('vimTronner', centerX, y, screen.TEXT_ALIGN.CENTER)
y += 2
screen.resetColors()
screen.print(instructions[i], centerX, y++, screen.TEXT_ALIGN.CENTER) for i in [0...instructions.length]
y += 1
screen.print("YOU CAN ONLY BUILD WALLS WHEN INSERT MODE IS ON", centerX, y++, screen.TEXT_ALIGN.CENTER)
screen.print("YOU CANNOT CHANGE DIRECTION WHEN INSERT MODE IS ON", centerX, y++, screen.TEXT_ALIGN.CENTER)
screen.setForegroundColor playerColors()
screen.print("YOUR COLOR IS:", centerX, ++y, screen.TEXT_ALIGN.CENTER)
y++
screen.setBackgroundColor playerColors()
screen.print(" ", centerX, y, screen.TEXT_ALIGN.CENTER)
screen.resetColors()
screen.setForegroundColor playerColors()
y += 2
if .ready
screen.print("READY PLAYER #{cycleNumberName(@cycleNumber)}", centerX, y++, screen.TEXT_ALIGN.CENTER)
n = .numberOfPlayers -
screen.print("WAITING FOR #{n} PLAYER#{if n > 1 then 'S' else ''}", centerX, y++, screen.TEXT_ALIGN.CENTER)
else
screen.print("YOU ARE PLAYER #{cycleNumberName(@cycleNumber)}", centerX, y++, screen.TEXT_ALIGN.CENTER)
action = if .isPractice
"START PRACTICE GAME"
else
"WHEN YOU ARE READY"
screen.print("ENTER INSERT MODE TO #{action}", centerX, y++, screen.TEXT_ALIGN.CENTER)
screen.resetColors()
renderCountdown: ->
renderCount: ->
screen.setForegroundColor 3
countX = Math.round(.width/2)
screen.print , countX, Math.round(.height/2), screen.TEXT_ALIGN.CENTER
renderCycleViews: ->
cycleView.render() for cycleView in
renderFinishScreen: ->
centerX = Math.round(.width/2)
y = Math.round(.height/2) - 3
screen.print 'GAME OVER', centerX, y, screen.TEXT_ALIGN.CENTER
y +=2
screen.setForegroundColor playerColors()
if .isPractice
screen.print 'READY FOR A REAL GAME?', centerX, y, screen.TEXT_ALIGN.CENTER
else
if .state == Cycle.STATES.WINNER
screen.print 'YOU WON!!!', centerX, y, screen.TEXT_ALIGN.CENTER
else
screen.print 'YOU LOST!!!', centerX, y, screen.TEXT_ALIGN.CENTER
screen.resetColors()
y += 2
screen.print "ENTER INSERT MODE", centerX, y, screen.TEXT_ALIGN.CENTER
screen.print "FOR REMATCH", centerX, y + 1, screen.TEXT_ALIGN.CENTER
screen.resetColors()
renderGameInfo: ->
if .name? and ?
name = if .isPractice then 'PRACTICE' else .name
screen.setBackgroundColor playerColors()
screen.setForegroundColor 0
screen.print((' ' for i in [1..screen.columns]).join(''), 1, screen.rows - 1)
screen.print("#{name} Player: #{@cycleNumber} State: #{@stateString}", 1, screen.rows - 1)
screen.resetColors()
if .state == 4
screen.setForegroundColor playerColors()
screen.print('-- INSERT --', 1, screen.rows)
screen.resetColors()
'playerCycle', get: ->
(cycle for cycle in .cycles when cycle.number == ).pop()
'numberOfReadyPlayers', get: ->
.cycles.reduce(
((total, cycle)->
if cycle.ready then total + 1 else total
), 0)
module.exports = GameView