mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-03-13 22:49:51 -04:00
Showing the new hero levels instead of the old campaign levels on the /play-hero map.
This commit is contained in:
parent
bbb6300f1f
commit
ec21637adf
8 changed files with 312 additions and 35 deletions
|
@ -38,3 +38,17 @@
|
|||
background-image: none
|
||||
@include opacity(0.65)
|
||||
@include box-shadow(none)
|
||||
|
||||
// keyframes mixin from https://gist.github.com/ericam/1607696
|
||||
=keyframes($name)
|
||||
@-webkit-keyframes #{$name}
|
||||
@content
|
||||
@-moz-keyframes #{$name}
|
||||
@content
|
||||
@-ms-keyframes #{$name}
|
||||
@content
|
||||
@-o-keyframes #{$name}
|
||||
@content
|
||||
@keyframes #{$name}
|
||||
@content
|
||||
|
||||
|
|
|
@ -1,17 +1,5 @@
|
|||
@import "../../../bootstrap/mixins"
|
||||
|
||||
// keyframes mixin from https://gist.github.com/ericam/1607696
|
||||
=keyframes($name)
|
||||
@-webkit-keyframes #{$name}
|
||||
@content
|
||||
@-moz-keyframes #{$name}
|
||||
@content
|
||||
@-ms-keyframes #{$name}
|
||||
@content
|
||||
@-o-keyframes #{$name}
|
||||
@content
|
||||
@keyframes #{$name}
|
||||
@content
|
||||
@import "app/styles/bootstrap/mixins"
|
||||
@import "app/styles/mixins"
|
||||
|
||||
+keyframes(castablePulse)
|
||||
from
|
||||
|
|
4
app/styles/play/modal/play-level-modal.sass
Normal file
4
app/styles/play/modal/play-level-modal.sass
Normal file
|
@ -0,0 +1,4 @@
|
|||
#play-level-modal
|
||||
h3
|
||||
color: black
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
@import "app/styles/bootstrap/mixins"
|
||||
@import "app/styles/bootstrap/variables"
|
||||
@import "app/styles/mixins"
|
||||
|
||||
$forestMapWidth: 2500
|
||||
$forestMapHeight: 1536
|
||||
|
@ -14,13 +15,23 @@ $levelClickRadius: 40px
|
|||
$gameControlSize: 80px
|
||||
$gameControlMargin: 40px
|
||||
|
||||
+keyframes(levelStartedPulse)
|
||||
from
|
||||
@include box-shadow(0px 0px 4px #333)
|
||||
margin-bottom: -$levelDotHeight / 3 + $levelDotZ
|
||||
50%
|
||||
@include box-shadow(0px 0px 22px skyblue)
|
||||
margin-bottom: -$levelDotHeight / 3 + ($levelDotHoverZ + $levelDotZ) / 2
|
||||
to
|
||||
@include box-shadow(0px 0px 4px #333)
|
||||
margin-bottom: -$levelDotHeight / 3 + $levelDotZ
|
||||
|
||||
#world-map-view
|
||||
width: 100%
|
||||
height: 100%
|
||||
background-color: $forestMapSeaBackground
|
||||
|
||||
.map
|
||||
//background: white url("/images/pages/play/map_forest.jpg") no-repeat center center
|
||||
position: relative
|
||||
|
||||
.map-background
|
||||
|
@ -44,12 +55,26 @@ $gameControlMargin: 40px
|
|||
&.disabled
|
||||
opacity: 0.7
|
||||
|
||||
&.first
|
||||
&.next
|
||||
width: 2 * $levelDotWidth
|
||||
height: 2 * $levelDotHeight
|
||||
margin-left: -0.5 * 2 * $levelDotWidth
|
||||
margin-bottom: -2 * $levelDotHeight / 3 + 2 * $levelDotZ
|
||||
|
||||
&.started, &.next
|
||||
border: 3px solid lightgreen
|
||||
@include box-shadow(0px 0px 35px skyblue)
|
||||
|
||||
// Would be cool, but kills performance, since we have to re-render all the time.
|
||||
//&:not(:hover)
|
||||
// -webkit-animation-name: levelStartedPulse
|
||||
// -webkit-animation-duration: 3s
|
||||
// -webkit-animation-iteration-count: infinite
|
||||
|
||||
&.complete
|
||||
border: 3px solid gold
|
||||
@include box-shadow(0px 0px 35px skyblue)
|
||||
|
||||
.level-shadow
|
||||
z-index: 1
|
||||
width: $levelDotShadowWidth
|
||||
|
@ -57,10 +82,10 @@ $gameControlMargin: 40px
|
|||
margin-left: -0.5 * $levelDotShadowWidth
|
||||
margin-bottom: -$levelDotShadowHeight / 3
|
||||
background-color: black
|
||||
box-shadow: 0px 0px 10px black
|
||||
@include box-shadow(0px 0px 10px black)
|
||||
@include opacity(0.75)
|
||||
|
||||
&.first
|
||||
&.next
|
||||
width: 2 * $levelDotShadowWidth
|
||||
height: 2 * $levelDotShadowHeight
|
||||
margin-left: -0.5 * 2 * $levelDotShadowWidth
|
||||
|
@ -68,6 +93,10 @@ $gameControlMargin: 40px
|
|||
|
||||
.level:hover
|
||||
margin-bottom: -$levelDotHeight / 3 + $levelDotHoverZ
|
||||
@include box-shadow(0px 0px 35px skyblue)
|
||||
|
||||
&.next
|
||||
margin-bottom: -2 * $levelDotHeight / 3 + 2 * $levelDotHoverZ
|
||||
|
||||
.level
|
||||
a
|
||||
|
@ -77,7 +106,7 @@ $gameControlMargin: 40px
|
|||
margin-top: -0.5 * $levelClickRadius
|
||||
border-radius: $levelClickRadius
|
||||
|
||||
&.first a
|
||||
&.next a
|
||||
padding: 2 * $levelClickRadius
|
||||
margin-left: 2 * -0.5 * $levelClickRadius
|
||||
margin-top: 2 * -0.5 * $levelClickRadius
|
||||
|
@ -132,15 +161,15 @@ $gameControlMargin: 40px
|
|||
background: url(/images/pages/play/menu_icons.png) no-repeat
|
||||
background-size: cover
|
||||
@include transition(0.5s ease)
|
||||
box-shadow: 2px 2px 4px black
|
||||
@include box-shadow(2px 2px 4px black)
|
||||
border: 0
|
||||
border-radius: 12px
|
||||
|
||||
&:hover
|
||||
box-shadow: 0 0 12px #bbf
|
||||
@include box-shadow(0 0 12px #bbf)
|
||||
|
||||
&:active
|
||||
box-shadow: 0 0 20px white
|
||||
@include box-shadow(0 0 20px white)
|
||||
|
||||
&.heroes
|
||||
background-position-x: -1 * $gameControlSize
|
||||
|
|
11
app/templates/play/modal/play-level-modal.jade
Normal file
11
app/templates/play/modal/play-level-modal.jade
Normal file
|
@ -0,0 +1,11 @@
|
|||
extends /templates/modal/modal_base
|
||||
|
||||
block modal-header-content
|
||||
h3(data-i18n="play.todotodotodo") Play the Level Man: #{levelName} at #{levelPath}/#{levelID}
|
||||
|
||||
block modal-body-content
|
||||
p TODO: show dat hero selection view
|
||||
|
||||
#choose-hero-view
|
||||
|
||||
#inventory-view
|
|
@ -1,11 +1,14 @@
|
|||
.map
|
||||
img.map-background(src="/images/pages/play/map_forest.jpg", alt="")
|
||||
|
||||
- var seenNext = false;
|
||||
each campaign in campaigns
|
||||
each level in campaign.levels
|
||||
div(style="left: #{level.x}%; bottom: #{level.y}%; background-color: #{campaign.color}", class="level" + (level.first ? " first" : "") + (level.disabled ? " disabled" : ""), data-level-id=level.id)
|
||||
a(href=level.disabled ? "/play" : "/play/#{level.levelPath || 'level'}/#{level.id}", disabled=level.disabled, class=levelStatusMap[level.id] || "")
|
||||
div(style="left: #{level.x}%; bottom: #{level.y}%", class="level-shadow" + (level.first ? " first" : ""))
|
||||
- var next = !seenNext && levelStatusMap[level.id] != "complete";
|
||||
- seenNext = seenNext || next;
|
||||
div(style="left: #{level.x}%; bottom: #{level.y}%; background-color: #{campaign.color}", class="level" + (next ? " next" : "") + (level.disabled ? " disabled" : "") + " " + levelStatusMap[level.id] || "", data-level-id=level.id)
|
||||
a(href=level.type == 'hero' ? '#' : level.disabled ? "/play" : "/play/#{level.levelPath || 'level'}/#{level.id}", disabled=level.disabled, data-level-id=level.id, data-level-path=level.levelPath || 'level', data-level-name=level.name)
|
||||
div(style="left: #{level.x}%; bottom: #{level.y}%", class="level-shadow" + (next ? " next" : "") + " " + levelStatusMap[level.id] || "")
|
||||
.level-info-container(data-level-id=level.id)
|
||||
if level.image
|
||||
img.level-image(src="#{level.image}", alt="#{level.name}")
|
||||
|
|
|
@ -3,6 +3,7 @@ template = require 'templates/play/world-map-view'
|
|||
LevelSession = require 'models/LevelSession'
|
||||
CocoCollection = require 'collections/CocoCollection'
|
||||
AudioPlayer = require 'lib/AudioPlayer'
|
||||
PlayLevelModal = require 'views/play/modal/PlayLevelModal'
|
||||
|
||||
class LevelSessionsCollection extends CocoCollection
|
||||
url: ''
|
||||
|
@ -18,7 +19,7 @@ module.exports = class WorldMapView extends RootView
|
|||
|
||||
events:
|
||||
'click .map': 'onClickMap'
|
||||
'click .game-controls button': 'onClickGameControl'
|
||||
'click .level a': 'onClickLevel'
|
||||
'mouseenter .level a': 'onMouseEnterLevel'
|
||||
'mouseleave .level a': 'onMouseLeaveLevel'
|
||||
'mousemove .map': 'onMouseMoveMap'
|
||||
|
@ -82,8 +83,9 @@ module.exports = class WorldMapView extends RootView
|
|||
y = (1 - e.offsetY / @$el.find('.map-background').height())
|
||||
console.log " x: #{(100 * x).toFixed(2)}\n y: #{(100 * y).toFixed(2)}\n"
|
||||
|
||||
onClickGameControl: (e) ->
|
||||
|
||||
onClickLevel: (e) ->
|
||||
playLevelModal = new PlayLevelModal supermodel: @options.supermodel, levelID: $(e.target).data('level-id'), levelPath: $(e.target).data('level-path'), levelName: $(e.target).data('level-name')
|
||||
@openModalView playLevelModal
|
||||
|
||||
onMouseEnterLevel: (e) ->
|
||||
levelID = $(e.target).parents('.level').data('level-id')
|
||||
|
@ -137,7 +139,6 @@ tutorials = [
|
|||
id: 'rescue-mission'
|
||||
image: '/file/db/level/52740644904ac0411700067c/rescue_mission_icon.png'
|
||||
description: 'Tharin has been captured! Start here.'
|
||||
first: true
|
||||
x: 17.23
|
||||
y: 36.94
|
||||
}
|
||||
|
@ -467,10 +468,195 @@ playerCreated = [
|
|||
}
|
||||
]
|
||||
|
||||
campaigns = [
|
||||
{id: 'beginner', name: 'Beginner Campaign', description: '... in which you learn the wizardry of programming.', levels: tutorials, color: "rgb(255, 80, 60)"}
|
||||
{id: 'multiplayer', name: 'Multiplayer Arenas', description: '... in which you code head-to-head against other players.', levels: arenas, color: "rgb(80, 5, 60)"}
|
||||
{id: 'dev', name: 'Random Harder Levels', description: '... in which you learn the interface while doing something a little harder.', levels: experienced, color: "rgb(80, 60, 255)"}
|
||||
{id: 'classic' ,name: 'Classic Algorithms', description: '... in which you learn the most popular algorithms in Computer Science.', levels: classicAlgorithms, color: "rgb(110, 80, 120)"}
|
||||
{id: 'player_created', name: 'Player-Created', description: '... in which you battle against the creativity of your fellow <a href=\"/contribute#artisan\">Artisan Wizards</a>.', levels: playerCreated, color: "rgb(160, 160, 180)"}
|
||||
hero = [
|
||||
{
|
||||
name: 'Dungeons of Kithgard'
|
||||
type: 'hero'
|
||||
difficulty: 1
|
||||
id: 'dungeons-of-kithgard'
|
||||
image: '/file/db/level/52740644904ac0411700067c/rescue_mission_icon.png'
|
||||
description: 'Grab the gem, but touch nothing else. Start here.'
|
||||
x: 17.23
|
||||
y: 36.94
|
||||
}
|
||||
{
|
||||
name: 'Gems in the Deep'
|
||||
type: 'hero'
|
||||
difficulty: 1
|
||||
id: 'gems-in-the-deep'
|
||||
image: '/file/db/level/529662dfe0df8f0000000007/grab_the_mushroom_icon.png'
|
||||
description: 'Quickly collect the gems; you will need them.'
|
||||
x: 22.6
|
||||
y: 35.1
|
||||
}
|
||||
{
|
||||
name: 'Shadow Guard'
|
||||
type: 'hero'
|
||||
difficulty: 1
|
||||
id: 'shadow-guard'
|
||||
image: '/file/db/level/525dc5589a0765e496000006/drink_me_icon.png'
|
||||
description: 'Evade the Kithgard minion.'
|
||||
x: 27.74
|
||||
y: 35.17
|
||||
}
|
||||
{
|
||||
name: 'True Names'
|
||||
type: 'hero'
|
||||
difficulty: 1
|
||||
id: 'true-names'
|
||||
image: '/file/db/level/5276c9bdcf83207a2801ff8f/taunt_icon.png'
|
||||
description: 'Learn an enemy\'s true name to defeat it.'
|
||||
x: 32.7
|
||||
y: 36.7
|
||||
}
|
||||
{
|
||||
name: 'The Raised Sword'
|
||||
type: 'hero'
|
||||
difficulty: 1
|
||||
id: 'the-raised-sword'
|
||||
image: '/file/db/level/528aea2d7f37fc4e0700016b/its_a_trap_icon.png'
|
||||
description: 'Learn to equip yourself for combat.'
|
||||
x: 36.6
|
||||
y: 39.5
|
||||
}
|
||||
{
|
||||
name: 'The First Kithmaze'
|
||||
type: 'hero'
|
||||
difficulty: 1
|
||||
id: 'the-first-kithmaze'
|
||||
image: '/file/db/level/5275272c69abdcb12401216e/break_the_prison_icon.png'
|
||||
description: 'The builders of Kith constructed many mazes to confuse travelers.'
|
||||
x: 38.4
|
||||
y: 43.5
|
||||
}
|
||||
{
|
||||
name: 'The Second Kithmaze'
|
||||
type: 'hero'
|
||||
difficulty: 1
|
||||
id: 'the-second-kithmaze'
|
||||
image: '/file/db/level/525f150306e1ab0962000018/taunt_icon.png'
|
||||
description: 'Many have tried, few have found their way through this maze.'
|
||||
x: 38.9
|
||||
y: 48.1
|
||||
}
|
||||
{
|
||||
name: 'New Sight'
|
||||
type: 'hero'
|
||||
difficulty: 1
|
||||
id: 'new-sight'
|
||||
image: '/file/db/level/525abfd9b12777d78e000009/cowardly_taunt_icon.png'
|
||||
description: 'A true name can only be seen with the correct lenses.'
|
||||
x: 39.3
|
||||
y: 53.1
|
||||
}
|
||||
{
|
||||
name: 'Lowest Kithmen'
|
||||
type: 'hero'
|
||||
difficulty: 1
|
||||
id: 'lowest-kithguards'
|
||||
image: '/file/db/level/525ef8ef06e1ab0962000003/commanding_followers_icon.png'
|
||||
description: 'Use your glasses to seek out and attack the Kithmen.'
|
||||
x: 39.4
|
||||
y: 57.7
|
||||
}
|
||||
{
|
||||
name: 'A Bolt in the Dark'
|
||||
type: 'hero'
|
||||
difficulty: 1
|
||||
id: 'a-bolt-in-the-dark'
|
||||
image: '/file/db/level/525085419851b83f4b000001/mobile_artillery_icon.png'
|
||||
description: 'Kithmen are not the only ones to stand in your way.'
|
||||
x: 40.0
|
||||
y: 63.2
|
||||
}
|
||||
{
|
||||
name: 'The Final Kithmaze'
|
||||
type: 'hero'
|
||||
difficulty: 2
|
||||
id: 'the-final-kithmaze'
|
||||
image: '/file/db/level/526bda3fe79aefde2a003e36/mobile_artillery_icon.png'
|
||||
description: 'To escape you must find your way through an Elder Kithman\'s maze.'
|
||||
x: 42.67
|
||||
y: 67.98
|
||||
}
|
||||
{
|
||||
name: 'Kithgard Gates'
|
||||
type: 'hero'
|
||||
difficulty: 1
|
||||
id: 'kithgard-gates'
|
||||
image: '/file/db/level/526fd3043c637ece50001bb2/the_herd_icon.png'
|
||||
description: 'Board up Kithguard and escape into the forest.'
|
||||
x: 47.38
|
||||
y: 70.55
|
||||
}
|
||||
{
|
||||
name: 'Defence of Plainswood'
|
||||
type: 'hero'
|
||||
difficulty: 1
|
||||
id: 'defence-of-plainswood'
|
||||
image: '/file/db/level/525dc5589a0765e496000006/drink_me_icon.png'
|
||||
description: 'Protect the peasants from the pursuing ogres.'
|
||||
x: 52.66
|
||||
y: 69.66
|
||||
}
|
||||
#{
|
||||
# name: ''
|
||||
# type: 'hero'
|
||||
# difficulty: 1
|
||||
# id: ''
|
||||
# image: '/file/db/level/529662dfe0df8f0000000007/grab_the_mushroom_icon.png'
|
||||
# description: ''
|
||||
# x: 58.46
|
||||
# y: 66.38
|
||||
# }
|
||||
#{
|
||||
# name: ''
|
||||
# type: 'hero'
|
||||
# difficulty: 1
|
||||
# id: ''
|
||||
# image: '/file/db/level/526ae95c1e5cd30000000008/zone_of_danger_icon.png'
|
||||
# description: ''
|
||||
# x: 63.11
|
||||
# y: 62.74
|
||||
# }
|
||||
#{
|
||||
# name: ''
|
||||
# type: 'hero'
|
||||
# difficulty: 1
|
||||
# id: ''
|
||||
# image: '/file/db/level/529662dfe0df8f0000000007/grab_the_mushroom_icon.png'
|
||||
# description: ''
|
||||
# x: 69.19
|
||||
# y: 60.61
|
||||
# }
|
||||
#{
|
||||
# name: ''
|
||||
# type: 'hero'
|
||||
# difficulty: 1
|
||||
# id: ''
|
||||
# image: '/file/db/level/52740644904ac0411700067c/rescue_mission_icon.png'
|
||||
# description: ''
|
||||
# x: 77.54
|
||||
# y: 65.94
|
||||
#}
|
||||
#{
|
||||
# name: ''
|
||||
# type: 'hero'
|
||||
# difficulty: 1
|
||||
# id: ''
|
||||
# image: '/file/db/level/526711d9add4f8965f000002/hunter_triplets_icon.png'
|
||||
# description: ''
|
||||
# x: 84.29
|
||||
# y: 61.23
|
||||
#}
|
||||
|
||||
]
|
||||
|
||||
campaigns = [
|
||||
#{id: 'beginner', name: 'Beginner Campaign', description: '... in which you learn the wizardry of programming.', levels: tutorials, color: "rgb(255, 80, 60)"}
|
||||
#{id: 'multiplayer', name: 'Multiplayer Arenas', description: '... in which you code head-to-head against other players.', levels: arenas, color: "rgb(80, 5, 60)"}
|
||||
#{id: 'dev', name: 'Random Harder Levels', description: '... in which you learn the interface while doing something a little harder.', levels: experienced, color: "rgb(80, 60, 255)"}
|
||||
#{id: 'classic' ,name: 'Classic Algorithms', description: '... in which you learn the most popular algorithms in Computer Science.', levels: classicAlgorithms, color: "rgb(110, 80, 120)"}
|
||||
#{id: 'player_created', name: 'Player-Created', description: '... in which you battle against the creativity of your fellow <a href=\"/contribute#artisan\">Artisan Wizards</a>.', levels: playerCreated, color: "rgb(160, 160, 180)"}
|
||||
{id: 'beginner', name: 'Beginner Campaign', levels: hero, color: 'rgb(255, 80, 60)'}
|
||||
]
|
||||
|
|
42
app/views/play/modal/PlayLevelModal.coffee
Normal file
42
app/views/play/modal/PlayLevelModal.coffee
Normal file
|
@ -0,0 +1,42 @@
|
|||
ModalView = require 'views/kinds/ModalView'
|
||||
template = require 'templates/play/modal/play-level-modal'
|
||||
ChooseHeroView = require 'views/game-menu/ChooseHeroView'
|
||||
InventoryView = require 'views/game-menu/InventoryView'
|
||||
|
||||
module.exports = class PlayLevelModal extends ModalView
|
||||
className: 'modal fade play-modal'
|
||||
template: template
|
||||
modalWidthPercent: 90
|
||||
id: 'play-level-modal'
|
||||
#instant: true
|
||||
|
||||
#events:
|
||||
# 'change input.select': 'onSelectionChanged'
|
||||
|
||||
constructor: (options) ->
|
||||
super options
|
||||
@options.showDevBits = true
|
||||
|
||||
getRenderData: (context={}) ->
|
||||
context = super(context)
|
||||
context.levelID = @options.levelID
|
||||
context.levelPath = @options.levelPath
|
||||
context.levelName = @options.levelName
|
||||
context
|
||||
|
||||
afterRender: ->
|
||||
super()
|
||||
return unless @supermodel.finished()
|
||||
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-open', volume: 1
|
||||
@addChooseHeroView()
|
||||
@addInventoryView()
|
||||
|
||||
onHidden: ->
|
||||
super()
|
||||
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-close', volume: 1
|
||||
|
||||
addChooseHeroView: ->
|
||||
@insertSubView new ChooseHeroView @options
|
||||
|
||||
addInventoryView: ->
|
||||
@insertSubView new InventoryView @options
|
Loading…
Reference in a new issue