Internationalize student UI for game dev levels

This commit is contained in:
Scott Erickson 2016-08-10 12:45:41 -07:00
parent ff2d505720
commit 2e5c15cc6d
7 changed files with 34 additions and 22 deletions

View file

@ -583,6 +583,8 @@
restart: "Restart Level"
play: "Play Level"
play_more_codecombat: "Play More CodeCombat"
default_student_instructions: "Click to control your hero and win your game!"
back_to_coding: "Back to Coding"
game_menu:
inventory_tab: "Inventory"

View file

@ -278,6 +278,7 @@ LevelSchema = c.object {
c.extendNamedProperties LevelSchema # let's have the name be the first property
_.extend LevelSchema.properties,
description: {title: 'Description', description: 'A short explanation of what this level is about.', type: 'string', maxLength: 65536, format: 'markdown'}
studentPlayInstructions: {title: 'Student Play Instructions', description: 'Instructions for game dev levels when students play them.', type: 'string', maxLength: 65536, format: 'markdown'}
loadingTip: { type: 'string', title: 'Loading Tip', description: 'What to show for this level while it\'s loading.' }
documentation: c.object {title: 'Documentation', description: 'Documentation articles relating to this level.', 'default': {specificArticles: [], generalArticles: []}},
specificArticles: c.array {title: 'Specific Articles', description: 'Specific documentation articles that live only in this level.', uniqueItems: true }, SpecificArticleSchema
@ -312,7 +313,7 @@ _.extend LevelSchema.properties,
body: {type: 'string', format: 'markdown', title: 'Body Text', description: 'Inserted into the Victory Modal once this level is complete. Tell the player they did a good job and what they accomplished!'},
i18n: {type: 'object', format: 'i18n', props: ['body'], description: 'Help translate this victory message'}
}
i18n: {type: 'object', format: 'i18n', props: ['name', 'description', 'loadingTip'], description: 'Help translate this level'}
i18n: {type: 'object', format: 'i18n', props: ['name', 'description', 'loadingTip', 'studentPlayInstructions'], description: 'Help translate this level'}
icon: {type: 'string', format: 'image-file', title: 'Icon'}
banner: {type: 'string', format: 'image-file', title: 'Banner'}
goals: c.array {title: 'Goals', description: 'An array of goals which are visible to the player and can trigger scripts.'}, GoalSchema

View file

@ -52,17 +52,15 @@ if view.showAds()
button.btn.btn-lg.btn-warning.banner.header-font#stop-real-time-playback-button(title="Stop real-time playback")
if view.level && view.level.isType('game-dev')
| Back to coding
span(data-i18n="play_game_dev_level.back_to_coding")
else
span(data-i18n="play_level.skip")
#how-to-play-game-dev-panel.panel.panel-default.hide.style-flat
.panel-heading
h3.panel-title How to play:
.panel-body
p Use the mouse to control the hero!
p Click anywhere on the map to move to that location.
p Click on the ogres to attack them.
h3.panel-title(data-i18n="play_game_dev_level.how_to_play_title")
.panel-body!= view.howToPlayText
.hints-view.hide

View file

@ -16,7 +16,7 @@ module.exports = class SettingsTabView extends CocoView
'name', 'description', 'documentation', 'nextLevel', 'background', 'victory', 'i18n', 'icon', 'goals',
'type', 'terrain', 'showsGuide', 'banner', 'employerDescription', 'loadingTip', 'requiresSubscription',
'helpVideos', 'replayable', 'scoreTypes', 'concepts', 'picoCTFProblem', 'practice', 'practiceThresholdMinutes'
'shareable'
'shareable', 'studentPlayInstructions'
]
subscriptions:

View file

@ -17,6 +17,8 @@ module.exports = class I18NEditLevelView extends I18NEditModelView
@wrapRow 'Level description', ['description'], description, i18n[lang]?.description, []
if loadingTip = @model.get('loadingTip')
@wrapRow 'Loading tip', ['loadingTip'], loadingTip, i18n[lang]?.loadingTip, []
if studentPlayInstructions = @model.get('studentPlayInstructions')
@wrapRow 'Student Play Instructions', ['studentPlayInstructions'], studentPlayInstructions, i18n[lang]?.studentPlayInstructions, []
# goals
for goal, index in @model.get('goals') ? []

View file

@ -211,7 +211,12 @@ module.exports = class PlayLevelView extends RootView
@$el.addClass 'web-dev' # Hide some of the elements we won't be using
return
@world = @levelLoader.world
@$el.addClass 'game-dev' if @level.isType('game-dev')
if @level.isType('game-dev')
@$el.addClass 'game-dev'
@howToPlayText = utils.i18n(@level.attributes, 'studentPlayInstructions')
@howToPlayText ?= $.i18n.t('play_game_dev_level.default_student_instructions')
@howToPlayText = marked(@howToPlayText, { sanitize: true })
@renderSelectors('#how-to-play-game-dev-panel')
@$el.addClass 'hero' if @level.isType('hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev') # TODO: figure out what this does and comment it
@$el.addClass 'flags' if _.any(@world.thangs, (t) -> (t.programmableProperties and 'findFlags' in t.programmableProperties) or t.inventory?.flag) or @level.get('slug') is 'sky-span'
# TODO: Update terminology to always be opponentSession or otherSession
@ -639,18 +644,21 @@ module.exports = class PlayLevelView extends RootView
if @level.isType('game-dev')
panel = @$('#how-to-play-game-dev-panel')
panel.removeClass('hide')
lines = switch @level.get('slug')
when 'over-the-garden-wall' then ['Watch to see if the peasants are properly protected.']
when 'click-gait' then ['Move to each red "X".', 'Click on the screen to move the Knight there.']
when 'heros-journey' then ['Move to each red "X".', 'Click on the screen to move the Knight there.']
when 'a-maze-ing' then ['Move to the chest of gems.', 'Click on the screen to move the Duelist there.']
when 'gemtacular' then ['Move to each of the gems.', 'Click on the screen to move the Captain there.']
when 'vorpal-mouse' then ['Slay the ogres.', 'Click on the screen to move the Guardian there.', 'Click on the munchkins to attack them!']
when 'crushing-it' then ['Slay the ogres.', 'Click on the screen to move the Goliath there.', 'Click on the munchkins to attack them!']
when 'tabula-rasa' then ['Slay any ogres.', 'Collect any coins.', 'Click on the screen to move the Raider there.', 'Click on any munchkins to attack them!']
else ['Click to control your hero and win your game!']
html = _.map(lines, (line) -> "<p>#{line}</p>").join('')
panel.find('.panel-body').html(html)
# TODO: Remove this once these levels have studentPlayInstructions set.
if not @level.get('studentPlayInstructions')
lines = switch @level.get('slug')
when 'over-the-garden-wall' then ['Watch to see if the peasants are properly protected.']
when 'click-gait' then ['Move to each red "X".', 'Click on the screen to move the Knight there.']
when 'heros-journey' then ['Move to each red "X".', 'Click on the screen to move the Knight there.']
when 'a-maze-ing' then ['Move to the chest of gems.', 'Click on the screen to move the Duelist there.']
when 'gemtacular' then ['Move to each of the gems.', 'Click on the screen to move the Captain there.']
when 'vorpal-mouse' then ['Slay the ogres.', 'Click on the screen to move the Guardian there.', 'Click on the munchkins to attack them!']
when 'crushing-it' then ['Slay the ogres.', 'Click on the screen to move the Goliath there.', 'Click on the munchkins to attack them!']
when 'tabula-rasa' then ['Slay any ogres.', 'Collect any coins.', 'Click on the screen to move the Raider there.', 'Click on any munchkins to attack them!']
else null
if lines
html = _.map(lines, (line) -> "<p>#{line}</p>").join('')
panel.find('.panel-body').html(html)
@onWindowResize()

View file

@ -68,7 +68,8 @@ LevelHandler = class LevelHandler extends Handler
'scoreTypes'
'concepts'
'picoCTFProblem'
'practiceThresholdMinutes'
'practiceThresholdMinutes',
'studentPlayInstructions'
]
postEditableProperties: ['name']