mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-03-28 13:50:07 -04:00
Add video tutorials to game guide
This commit is contained in:
parent
fe0c89e433
commit
d494dc9c79
4 changed files with 137 additions and 10 deletions
app
lib
templates/play/menu
views/play/menu
|
@ -1,6 +1,12 @@
|
|||
module.exports = LevelOptions =
|
||||
'dungeons-of-kithgard':
|
||||
disableSpaces: true
|
||||
helpVideos: [
|
||||
{style: 'original', URL: '//www.youtube.com/embed/bHaeKdMPZrA'}
|
||||
{style: 'scripted', URL: '//player.vimeo.com/video/114729726'}
|
||||
{style: 'eccentric', URL: '//player.vimeo.com/video/114729725'}
|
||||
{style: 'edited', URL: '//player.vimeo.com/video/114729724'}
|
||||
]
|
||||
hidesSubmitUntilRun: true
|
||||
hidesPlayButton: true
|
||||
hidesRunShortcut: true
|
||||
|
@ -13,6 +19,7 @@ module.exports = LevelOptions =
|
|||
requiredCode: ['moveRight']
|
||||
'gems-in-the-deep':
|
||||
disableSpaces: true
|
||||
helpVideos: [{style: 'original', URL: '//player.vimeo.com/video/114730449'}]
|
||||
hidesSubmitUntilRun: true
|
||||
hidesPlayButton: true
|
||||
hidesRunShortcut: true
|
||||
|
@ -24,6 +31,7 @@ module.exports = LevelOptions =
|
|||
restrictedGear: {feet: 'leather-boots'}
|
||||
'shadow-guard':
|
||||
disableSpaces: true
|
||||
helpVideos: [{style: 'original', URL: '//player.vimeo.com/video/114734163'}]
|
||||
hidesSubmitUntilRun: true
|
||||
hidesPlayButton: true
|
||||
hidesRunShortcut: true
|
||||
|
@ -35,6 +43,7 @@ module.exports = LevelOptions =
|
|||
restrictedGear: {feet: 'leather-boots', 'right-hand': 'simple-sword'}
|
||||
'kounter-kithwise':
|
||||
disableSpaces: true
|
||||
helpVideos: [{style: 'original', URL: '//player.vimeo.com/video/114734160'}]
|
||||
hidesPlayButton: true
|
||||
hidesRunShortcut: true
|
||||
hidesHUD: true
|
||||
|
@ -44,6 +53,7 @@ module.exports = LevelOptions =
|
|||
requiredGear: {feet: 'simple-boots'}
|
||||
restrictedGear: {feet: 'leather-boots', 'right-hand': 'simple-sword', 'programming-book': 'programmaticon-i'}
|
||||
'crawlways-of-kithgard':
|
||||
helpVideos: [{style: 'original', URL: '//player.vimeo.com/video/114734162'}]
|
||||
hidesPlayButton: true
|
||||
hidesRunShortcut: true
|
||||
hidesHUD: true
|
||||
|
@ -54,6 +64,7 @@ module.exports = LevelOptions =
|
|||
restrictedGear: {feet: 'leather-boots', 'right-hand': 'simple-sword', 'programming-book': 'programmaticon-i'}
|
||||
'forgetful-gemsmith':
|
||||
disableSpaces: true
|
||||
helpVideos: [{style: 'original', URL: '//player.vimeo.com/video/114734165'}]
|
||||
hidesPlayButton: true
|
||||
hidesRunShortcut: true
|
||||
hidesHUD: true
|
||||
|
@ -64,6 +75,7 @@ module.exports = LevelOptions =
|
|||
restrictedGear: {feet: 'leather-boots', 'programming-book': 'programmaticon-i'}
|
||||
'true-names':
|
||||
disableSpaces: true
|
||||
helpVideos: [{style: 'original', URL: '//player.vimeo.com/video/114734166'}]
|
||||
hidesPlayButton: true
|
||||
hidesRunShortcut: true
|
||||
hidesHUD: true
|
||||
|
@ -75,6 +87,7 @@ module.exports = LevelOptions =
|
|||
requiredCode: ['Brak']
|
||||
'favorable-odds':
|
||||
disableSpaces: true
|
||||
helpVideos: [{style: 'original', URL: '//player.vimeo.com/video/114734656'}]
|
||||
hidesPlayButton: true
|
||||
hidesRunShortcut: true
|
||||
hidesHUD: true
|
||||
|
@ -85,6 +98,7 @@ module.exports = LevelOptions =
|
|||
restrictedGear: {feet: 'leather-boots', 'programming-book': 'programmaticon-i'}
|
||||
'the-raised-sword':
|
||||
disableSpaces: true
|
||||
helpVideos: [{style: 'original', URL: '//player.vimeo.com/video/114734655'}]
|
||||
hidesPlayButton: true
|
||||
hidesRunShortcut: true
|
||||
hidesHUD: true
|
||||
|
@ -103,6 +117,11 @@ module.exports = LevelOptions =
|
|||
restrictedGear: {feet: 'leather-boots'}
|
||||
requiredCode: ['loop']
|
||||
'haunted-kithmaze':
|
||||
helpVideos: [
|
||||
{style: 'scripted', URL: '//player.vimeo.com/video/114730074'}
|
||||
{style: 'eccentric', URL: '//player.vimeo.com/video/114729727'}
|
||||
{style: 'edited', URL: '//player.vimeo.com/video/114729723'}
|
||||
]
|
||||
hidesRunShortcut: true
|
||||
hidesHUD: true
|
||||
hidesSay: true
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
ul.nav.nav-tabs
|
||||
for doc in docs
|
||||
li
|
||||
a(data-target="#docs_tab_#{doc.slug}", data-toggle="tab") #{doc.name}
|
||||
div.tab-content
|
||||
for doc in docs
|
||||
div.tab-pane(id="docs_tab_#{doc.slug}")!= doc.html
|
||||
if docs.length === 1
|
||||
if showVideo
|
||||
h3 Video Tutorial
|
||||
div(id="help-video-player")
|
||||
h3 Tips
|
||||
div
|
||||
!= docs[0].html
|
||||
else
|
||||
ul.nav.nav-tabs
|
||||
for doc in docs
|
||||
li
|
||||
a(data-target="#docs_tab_#{doc.slug}", data-toggle="tab") #{doc.name}
|
||||
div.tab-content
|
||||
for doc in docs
|
||||
div.tab-pane(id="docs_tab_#{doc.slug}")!= doc.html
|
||||
|
|
|
@ -60,7 +60,9 @@ module.exports = class GameMenuModal extends ModalView
|
|||
|
||||
onTabShown: (e) ->
|
||||
@playSound 'game-menu-tab-switch'
|
||||
@subviews[e.target.hash.substring(1).replace(/-/g, '_')].onShown?()
|
||||
shownSubviewKey = e.target.hash.substring(1).replace(/-/g, '_')
|
||||
@subviews[shownSubviewKey].onShown?()
|
||||
subview.onHidden?() for subviewKey, subview of @subviews when subviewKey isnt shownSubviewKey
|
||||
|
||||
onHidden: ->
|
||||
super()
|
||||
|
|
|
@ -2,6 +2,7 @@ CocoView = require 'views/core/CocoView'
|
|||
template = require 'templates/play/menu/guide-view'
|
||||
Article = require 'models/Article'
|
||||
utils = require 'core/utils'
|
||||
LevelOptions = require 'lib/LevelOptions'
|
||||
|
||||
# let's implement this once we have the docs database schema set up
|
||||
|
||||
|
@ -9,8 +10,13 @@ module.exports = class LevelGuideView extends CocoView
|
|||
template: template
|
||||
id: 'guide-view'
|
||||
className: 'tab-pane'
|
||||
helpVideoHeight: '295'
|
||||
helpVideoWidth: '471'
|
||||
|
||||
constructor: (options) ->
|
||||
@levelID = options.level.get('slug')
|
||||
@helpVideos = LevelOptions[@levelID]?.helpVideos ? []
|
||||
@trackedHelpVideoStart = @trackedHelpVideoFinish = false
|
||||
@firstOnly = options.firstOnly
|
||||
@docs = options?.docs ? options.level.get('documentation') ? {}
|
||||
general = @docs.generalArticles or []
|
||||
|
@ -33,12 +39,13 @@ module.exports = class LevelGuideView extends CocoView
|
|||
getRenderData: ->
|
||||
c = super()
|
||||
c.docs = @docs
|
||||
c.showVideo = @helpVideos.length > 0
|
||||
c
|
||||
|
||||
afterRender: ->
|
||||
super()
|
||||
if @docs.length is 1
|
||||
@$el.html(@docs[0].html)
|
||||
if @docs.length is 1 and @helpVideos.length > 0
|
||||
@setupVideoPlayer()
|
||||
else
|
||||
# incredible hackiness. Getting bootstrap tabs to work shouldn't be this complex
|
||||
@$el.find('.nav-tabs li:first').addClass('active')
|
||||
|
@ -55,4 +62,95 @@ module.exports = class LevelGuideView extends CocoView
|
|||
Backbone.Mediator.publish 'level:docs-shown', {}
|
||||
|
||||
onHidden: ->
|
||||
createjs?.Sound?.setVolume?(@volume ? 1.0)
|
||||
Backbone.Mediator.publish 'level:docs-hidden', {}
|
||||
|
||||
onShown: ->
|
||||
# TODO: Disable sound only when video is playing?
|
||||
@volume ?= me.get('volume') ? 1.0
|
||||
createjs?.Sound?.setVolume(0.0)
|
||||
|
||||
setupVideoPlayer: () ->
|
||||
return unless @helpVideos.length > 0
|
||||
|
||||
# TODO: run A/B test for different video styles
|
||||
|
||||
helpVideoURL = @helpVideos[0].URL
|
||||
if helpVideoURL.toLowerCase().indexOf('youtube') >= 0
|
||||
@setupYouTubeVideoPlayer helpVideoURL
|
||||
else if helpVideoURL.toLowerCase().indexOf('vimeo') >= 0
|
||||
@setupVimeoVideoPlayer helpVideoURL
|
||||
|
||||
setupYouTubeVideoPlayer: (helpVideoURL) ->
|
||||
# Setup YouTube iframe player
|
||||
# https://developers.google.com/youtube/iframe_api_reference
|
||||
|
||||
onPlayerStateChange = (e) =>
|
||||
if e.data is 1
|
||||
unless @trackedHelpVideoStart
|
||||
window.tracker?.trackEvent 'Start help video', level: @levelID
|
||||
@trackedHelpVideoStart = true
|
||||
else if e.data is 0
|
||||
unless @trackedHelpVideoFinish
|
||||
window.tracker?.trackEvent 'Finish help video', level: @levelID
|
||||
@trackedHelpVideoFinish = true
|
||||
|
||||
if matchVideoID = helpVideoURL.match /www\.youtube\.com\/embed\/(bHaeKdMPZrA)/
|
||||
videoID = matchVideoID[1]
|
||||
else
|
||||
console.warn "Unable to read video ID from help video."
|
||||
# TODO: Default to dungeons-of-kithgard?
|
||||
videoID = 'bHaeKdMPZrA'
|
||||
|
||||
# Add method that will be called by YouTube iframe player when ready
|
||||
window.onYouTubeIframeAPIReady = =>
|
||||
new YT.Player 'help-video-player', {
|
||||
height: @helpVideoHeight,
|
||||
width: @helpVideoWidth,
|
||||
videoId: videoID,
|
||||
events: {
|
||||
'onStateChange': onPlayerStateChange
|
||||
}
|
||||
}
|
||||
|
||||
# Add YouTube video player
|
||||
tag = document.createElement('script')
|
||||
tag.src = "https://www.youtube.com/iframe_api"
|
||||
@$el.find('#help-video-player').before(tag)
|
||||
|
||||
setupVimeoVideoPlayer: (helpVideoURL) ->
|
||||
# Setup Vimeo player
|
||||
# https://developer.vimeo.com/player/js-api#universal-with-postmessage
|
||||
|
||||
# Create Vimeo iframe player
|
||||
tag = document.createElement('iframe')
|
||||
tag.id = 'help-video-player'
|
||||
tag.src = helpVideoURL + "?api=1"
|
||||
tag.height = @helpVideoHeight
|
||||
tag.width = @helpVideoWidth
|
||||
tag.frameborder = '0'
|
||||
@$el.find('#help-video-player').replaceWith(tag)
|
||||
|
||||
onMessageReceived = (e) =>
|
||||
data = JSON.parse(e.data)
|
||||
if data.event is 'ready'
|
||||
# Vimeo player is ready, can now hook up other events
|
||||
# https://developer.vimeo.com/player/js-api#events
|
||||
player = $('#help-video-player')[0]
|
||||
helpVideoURL = 'http:' + helpVideoURL unless helpVideoURL.indexOf('http') is 0
|
||||
player.contentWindow.postMessage JSON.stringify(method: 'addEventListener', value: 'play'), helpVideoURL
|
||||
player.contentWindow.postMessage JSON.stringify(method: 'addEventListener', value: 'finish'), helpVideoURL
|
||||
else if data.event is 'play'
|
||||
unless @trackedHelpVideoStart
|
||||
window.tracker?.trackEvent 'Start help video', level: @levelID
|
||||
@trackedHelpVideoStart = true
|
||||
else if data.event is 'finish'
|
||||
unless @trackedHelpVideoFinish
|
||||
window.tracker?.trackEvent 'Finish help video', level: @levelID
|
||||
@trackedHelpVideoFinish = true
|
||||
|
||||
# Listen for Vimeo player 'ready'
|
||||
if window.addEventListener
|
||||
window.addEventListener('message', onMessageReceived, false)
|
||||
else
|
||||
window.attachEvent('onmessage', onMessageReceived, false)
|
||||
|
|
Loading…
Add table
Reference in a new issue