mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-03-14 07:00:01 -04:00
PVP waiting screen in real-time view
This commit is contained in:
parent
8143d9c5ba
commit
437ab0feb2
9 changed files with 135 additions and 27 deletions
|
@ -1,4 +1,4 @@
|
|||
module.exports = class FlagCollection extends Backbone.Firebase.Collection
|
||||
module.exports = class RealTimeCollection extends Backbone.Firebase.Collection
|
||||
constructor: (savePath) ->
|
||||
# TODO: Don't hard code this here
|
||||
# TODO: Use prod path in prod
|
||||
|
|
|
@ -10,6 +10,7 @@ Letterbox = require './Letterbox'
|
|||
Dimmer = require './Dimmer'
|
||||
CountdownScreen = require './CountdownScreen'
|
||||
PlaybackOverScreen = require './PlaybackOverScreen'
|
||||
WaitingScreen = require './WaitingScreen'
|
||||
DebugDisplay = require './DebugDisplay'
|
||||
CoordinateDisplay = require './CoordinateDisplay'
|
||||
CoordinateGrid = require './CoordinateGrid'
|
||||
|
@ -67,6 +68,7 @@ module.exports = Surface = class Surface extends CocoClass
|
|||
'level:set-letterbox': 'onSetLetterbox'
|
||||
'application:idle-changed': 'onIdleChanged'
|
||||
'camera:zoom-updated': 'onZoomUpdated'
|
||||
'playback:real-time-playback-waiting': 'onRealTimePlaybackWaiting'
|
||||
'playback:real-time-playback-started': 'onRealTimePlaybackStarted'
|
||||
'playback:real-time-playback-ended': 'onRealTimePlaybackEnded'
|
||||
'level:flag-color-selected': 'onFlagColorSelected'
|
||||
|
@ -101,6 +103,7 @@ module.exports = Surface = class Surface extends CocoClass
|
|||
@dimmer?.destroy()
|
||||
@countdownScreen?.destroy()
|
||||
@playbackOverScreen?.destroy()
|
||||
@waitingScreen?.destroy()
|
||||
@coordinateDisplay?.destroy()
|
||||
@coordinateGrid?.destroy()
|
||||
@stage.clear()
|
||||
|
@ -402,6 +405,7 @@ module.exports = Surface = class Surface extends CocoClass
|
|||
@spriteBoss = new SpriteBoss camera: @camera, surfaceLayer: @surfaceLayer, surfaceTextLayer: @surfaceTextLayer, world: @world, thangTypes: @options.thangTypes, choosing: @options.choosing, navigateToSelection: @options.navigateToSelection, showInvisible: @options.showInvisible
|
||||
@countdownScreen = new CountdownScreen camera: @camera, layer: @screenLayer
|
||||
@playbackOverScreen = new PlaybackOverScreen camera: @camera, layer: @screenLayer
|
||||
@waitingScreen = new WaitingScreen camera: @camera, layer: @screenLayer
|
||||
@initCoordinates()
|
||||
@stage.enableMouseOver(10)
|
||||
@stage.addEventListener 'stagemousemove', @onMouseMove
|
||||
|
@ -571,7 +575,11 @@ module.exports = Surface = class Surface extends CocoClass
|
|||
@stage.update e
|
||||
|
||||
# Real-time playback
|
||||
onRealTimePlaybackWaiting: (e) ->
|
||||
@onRealTimePlaybackStarted e
|
||||
|
||||
onRealTimePlaybackStarted: (e) ->
|
||||
return if @realTime
|
||||
@realTime = true
|
||||
@onResize()
|
||||
@spriteBoss.selfWizardSprite?.toggle false
|
||||
|
|
84
app/lib/surface/WaitingScreen.coffee
Normal file
84
app/lib/surface/WaitingScreen.coffee
Normal file
|
@ -0,0 +1,84 @@
|
|||
CocoClass = require 'lib/CocoClass'
|
||||
RealTimeCollection = require 'collections/RealTimeCollection'
|
||||
|
||||
module.exports = class WaitingScreen extends CocoClass
|
||||
subscriptions:
|
||||
'playback:real-time-playback-waiting': 'onRealTimePlaybackWaiting'
|
||||
'playback:real-time-playback-started': 'onRealTimePlaybackStarted'
|
||||
'playback:real-time-playback-ended': 'onRealTimePlaybackEnded'
|
||||
'real-time-multiplayer:joined-game': 'onJoinedRealTimeMultiplayerGame'
|
||||
'real-time-multiplayer:left-game': 'onLeftRealTimeMultiplayerGame'
|
||||
|
||||
constructor: (options) ->
|
||||
super()
|
||||
options ?= {}
|
||||
@camera = options.camera
|
||||
@layer = options.layer
|
||||
@waitingText = options.text or 'Waiting...'
|
||||
console.error @toString(), 'needs a camera.' unless @camera
|
||||
console.error @toString(), 'needs a layer.' unless @layer
|
||||
@build()
|
||||
|
||||
onCastingBegins: (e) -> @show() unless e.preload
|
||||
onCastingEnds: (e) -> @hide()
|
||||
|
||||
toString: -> '<WaitingScreen>'
|
||||
|
||||
build: ->
|
||||
@dimLayer = new createjs.Container()
|
||||
@dimLayer.mouseEnabled = @dimLayer.mouseChildren = false
|
||||
@dimLayer.addChild @dimScreen = new createjs.Shape()
|
||||
@dimScreen.graphics.beginFill('rgba(0,0,0,0.5)').rect 0, 0, @camera.canvasWidth, @camera.canvasHeight
|
||||
@dimLayer.alpha = 0
|
||||
@dimLayer.addChild @makeWaitingText()
|
||||
|
||||
makeWaitingText: ->
|
||||
size = Math.ceil @camera.canvasHeight / 8
|
||||
text = new createjs.Text @waitingText, "#{size}px Bangers", '#F7B42C'
|
||||
text.shadow = new createjs.Shadow '#000', Math.ceil(@camera.canvasHeight / 300), Math.ceil(@camera.canvasHeight / 300), Math.ceil(@camera.canvasHeight / 120)
|
||||
text.textAlign = 'center'
|
||||
text.textBaseline = 'middle'
|
||||
text.x = @camera.canvasWidth / 2
|
||||
text.y = @camera.canvasHeight / 2
|
||||
@text = text
|
||||
return text
|
||||
|
||||
show: ->
|
||||
return if @showing
|
||||
@showing = true
|
||||
@dimLayer.alpha = 0
|
||||
createjs.Tween.removeTweens @dimLayer
|
||||
createjs.Tween.get(@dimLayer).to({alpha: 1}, 500)
|
||||
@updateText()
|
||||
@layer.addChild @dimLayer
|
||||
|
||||
hide: ->
|
||||
return unless @showing
|
||||
@showing = false
|
||||
createjs.Tween.removeTweens @dimLayer
|
||||
createjs.Tween.get(@dimLayer).to({alpha: 0}, 500).call => @layer.removeChild @dimLayer unless @destroyed
|
||||
|
||||
updateText: ->
|
||||
if @multiplayerSession
|
||||
players = new RealTimeCollection('multiplayer_level_sessions/' + @multiplayerSession.id + '/players')
|
||||
players.each (player) =>
|
||||
if player.id isnt me.id
|
||||
name = player.get('name')
|
||||
@text.text = "Waiting for #{name}..."
|
||||
|
||||
onRealTimePlaybackWaiting: (e) ->
|
||||
@show()
|
||||
|
||||
onRealTimePlaybackStarted: (e) ->
|
||||
@hide()
|
||||
|
||||
onRealTimePlaybackEnded: (e) ->
|
||||
@hide()
|
||||
|
||||
onJoinedRealTimeMultiplayerGame: (e) ->
|
||||
@multiplayerSession = e.session
|
||||
|
||||
onLeftRealTimeMultiplayerGame: (e) ->
|
||||
if @multiplayerSession
|
||||
@multiplayerSession.off()
|
||||
@multiplayerSession = null
|
6
app/models/RealTimeModel.coffee
Normal file
6
app/models/RealTimeModel.coffee
Normal file
|
@ -0,0 +1,6 @@
|
|||
module.exports = class RealTimeModel extends Backbone.Firebase.Model
|
||||
constructor: (savePath) ->
|
||||
# TODO: Don't hard code this here
|
||||
# TODO: Use prod path in prod
|
||||
@firebase = 'https://codecombat.firebaseio.com/test/db/' + savePath
|
||||
super()
|
|
@ -85,6 +85,8 @@ module.exports =
|
|||
|
||||
'playback:stop-real-time-playback': c.object {}
|
||||
|
||||
'playback:real-time-playback-waiting': c.object {}
|
||||
|
||||
'playback:real-time-playback-started': c.object {}
|
||||
|
||||
'playback:real-time-playback-ended': c.object {}
|
||||
|
|
|
@ -26,13 +26,7 @@ module.exports = class MultiplayerView extends CocoView
|
|||
@session = options.session
|
||||
@playableTeams = options.playableTeams
|
||||
@listenTo @session, 'change:multiplayer', @updateLinkSection
|
||||
|
||||
# TODO: only request sessions for this level, !team, etc.
|
||||
# TODO: don't hard code this path all over the place
|
||||
@multiplayerSessions = new RealTimeCollection('multiplayer_level_sessions/')
|
||||
@multiplayerSessions.on 'add', @onMultiplayerSessionAdded
|
||||
@multiplayerSessions.on 'remove', @onMultiplayerSessionRemoved
|
||||
@playersCollections = {}
|
||||
@initMultiplayerSessions()
|
||||
|
||||
destroy: ->
|
||||
@multiplayerSessions?.off()
|
||||
|
@ -83,22 +77,33 @@ module.exports = class MultiplayerView extends CocoView
|
|||
multiplayer = Boolean(@$el.find('#multiplayer').prop('checked'))
|
||||
@session.set('multiplayer', multiplayer)
|
||||
|
||||
|
||||
# TODO: shouldn't have to open MultiplayerView to read existing multiplayerSession?
|
||||
# TODO: No current game shown when: this view closed, opponent leaves your game, this view opened
|
||||
# TODO: if someone leaves your game, it should go back to 'creating' state
|
||||
|
||||
onMultiplayerSessionAdded: (e) =>
|
||||
initMultiplayerSessions: ->
|
||||
@playersCollections = {}
|
||||
# TODO: only request sessions for this level, !team, etc.
|
||||
# TODO: don't hard code this path all over the place
|
||||
@multiplayerSessions = new RealTimeCollection('multiplayer_level_sessions/')
|
||||
@multiplayerSessions.on 'add', @onMultiplayerSessionAdded
|
||||
@multiplayerSessions.on 'remove', @onMultiplayerSessionRemoved
|
||||
@multiplayerSessions.each (ms) => @initMultiplayerSession ms
|
||||
|
||||
initMultiplayerSession: (ms) ->
|
||||
# TODO: double check these players events are needed on top of onMultiplayerSessionChanged
|
||||
@playersCollections[e.id] = new RealTimeCollection('multiplayer_level_sessions/' + e.id + '/players')
|
||||
@playersCollections[e.id].on 'add', @onPlayerAdded
|
||||
@playersCollections[e.id].on 'remove', @onPlayerRemoved
|
||||
# Check if we've already joined this multiplayer session
|
||||
if not @currentMultiplayerSession and e.get('levelID') is @session.get('levelID')
|
||||
@playersCollections[e.id].each (player) =>
|
||||
@playersCollections[ms.id] = new RealTimeCollection('multiplayer_level_sessions/' + ms.id + '/players')
|
||||
@playersCollections[ms.id].on 'add', @onPlayerAdded
|
||||
@playersCollections[ms.id].on 'remove', @onPlayerRemoved
|
||||
if not @currentMultiplayerSession and ms.get('levelID') is @session.get('levelID')
|
||||
@playersCollections[ms.id].each (player) =>
|
||||
if player.id is me.id and player.get('team') is @session.get('team')
|
||||
@currentMultiplayerSession = e
|
||||
@currentMultiplayerSession = ms
|
||||
@currentMultiplayerSession.on 'change', @onMultiplayerSessionChanged
|
||||
Backbone.Mediator.publish 'real-time-multiplayer:joined-game', session: @currentMultiplayerSession
|
||||
|
||||
onMultiplayerSessionAdded: (e) =>
|
||||
console.log 'onMultiplayerSessionAdded', e
|
||||
@initMultiplayerSession e
|
||||
@render()
|
||||
|
||||
onMultiplayerSessionRemoved: (e) =>
|
||||
|
|
|
@ -15,7 +15,6 @@ module.exports = class LevelFlagsView extends CocoView
|
|||
'god:streaming-world-updated': 'onNewWorld'
|
||||
'surface:remove-flag': 'onRemoveFlag'
|
||||
'real-time-multiplayer:joined-game': 'onJoinedMultiplayerGame'
|
||||
'real-time-multiplayer:left-game': 'onLeftMultiplayerGame'
|
||||
|
||||
events:
|
||||
'click .green-flag': -> @onFlagSelected color: 'green', source: 'button'
|
||||
|
@ -43,7 +42,6 @@ module.exports = class LevelFlagsView extends CocoView
|
|||
@onFlagSelected color: null
|
||||
@realTime = false
|
||||
@$el.hide()
|
||||
@multiplayerSession?.set 'state', 'coding'
|
||||
|
||||
onFlagSelected: (e) ->
|
||||
return unless @realTime
|
||||
|
@ -83,10 +81,6 @@ module.exports = class LevelFlagsView extends CocoView
|
|||
@realTimeFlags.on 'add', @onRealTimeMultiplayerFlagAdded
|
||||
|
||||
onLeftMultiplayerGame: (e) ->
|
||||
@multiplayerState = null
|
||||
if @multiplayerSession
|
||||
@multiplayerSession.off()
|
||||
@multiplayerSession = null
|
||||
if @realTimeFlags
|
||||
@realTimeFlags.off()
|
||||
@realTimeFlags = null
|
||||
|
|
|
@ -162,12 +162,14 @@ module.exports = class LevelPlaybackView extends CocoView
|
|||
|
||||
onTomeCast: (e) ->
|
||||
return unless e.realTime
|
||||
@onRealTimeMultiplayerCast e
|
||||
@realTime = true
|
||||
@togglePlaybackControls false
|
||||
Backbone.Mediator.publish 'playback:real-time-playback-started', {}
|
||||
|
||||
onRealTimeMultiplayerCast: (e) ->
|
||||
@realTime = true
|
||||
@togglePlaybackControls false
|
||||
Backbone.Mediator.publish 'playback:real-time-playback-started', {}
|
||||
Backbone.Mediator.publish 'playback:real-time-playback-waiting', {}
|
||||
|
||||
onWindowResize: (s...) =>
|
||||
@barWidth = $('.progress', @$el).width()
|
||||
|
|
|
@ -20,6 +20,7 @@ LevelComponent = require 'models/LevelComponent'
|
|||
Article = require 'models/Article'
|
||||
Camera = require 'lib/surface/Camera'
|
||||
AudioPlayer = require 'lib/AudioPlayer'
|
||||
RealTimeModel = require 'models/RealTimeModel'
|
||||
RealTimeCollection = require 'collections/RealTimeCollection'
|
||||
|
||||
# subviews
|
||||
|
@ -64,6 +65,7 @@ module.exports = class PlayLevelView extends RootView
|
|||
'level:session-will-save': 'onSessionWillSave'
|
||||
'level:started': 'onLevelStarted'
|
||||
'level:loading-view-unveiled': 'onLoadingViewUnveiled'
|
||||
'playback:real-time-playback-waiting': 'onRealTimePlaybackWaiting'
|
||||
'playback:real-time-playback-started': 'onRealTimePlaybackStarted'
|
||||
'playback:real-time-playback-ended': 'onRealTimePlaybackEnded'
|
||||
'real-time-multiplayer:joined-game': 'onJoinedRealTimeMultiplayerGame'
|
||||
|
@ -526,6 +528,10 @@ module.exports = class PlayLevelView extends RootView
|
|||
AudioPlayer.preloadSoundReference sound
|
||||
|
||||
# Real-time playback
|
||||
onRealTimePlaybackWaiting: (e) ->
|
||||
@$el.addClass('real-time').focus()
|
||||
@onWindowResize()
|
||||
|
||||
onRealTimePlaybackStarted: (e) ->
|
||||
@$el.addClass('real-time').focus()
|
||||
@onWindowResize()
|
||||
|
@ -553,11 +559,12 @@ module.exports = class PlayLevelView extends RootView
|
|||
|
||||
onRealTimeMultiplayerPlaybackEnded: ->
|
||||
if @multiplayerSession
|
||||
@multiplayerSession.set 'state', 'coding'
|
||||
players = new RealTimeCollection('multiplayer_level_sessions/' + @multiplayerSession.id + '/players')
|
||||
players.each (player) -> player.set 'state', 'coding' if player.id is me.id
|
||||
|
||||
onJoinedRealTimeMultiplayerGame: (e) ->
|
||||
@multiplayerSession = e.session
|
||||
@multiplayerSession = new RealTimeModel('multiplayer_level_sessions/' + e.session.id)
|
||||
|
||||
onLeftRealTimeMultiplayerGame: (e) ->
|
||||
if @multiplayerSession
|
||||
|
|
Loading…
Reference in a new issue