mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-04-26 14:03:28 -04:00
Merge pull request #1289 from jayant1992/terrain-generator
Terrain generator
This commit is contained in:
commit
2a571b5ce2
5 changed files with 345 additions and 0 deletions
app
styles
templates
views
128
app/styles/terrain_randomise.sass
Normal file
128
app/styles/terrain_randomise.sass
Normal file
|
@ -0,0 +1,128 @@
|
|||
#terrain-randomise-modal
|
||||
|
||||
.choose-option
|
||||
margin-bottom: 15px
|
||||
width: 100%
|
||||
height: 100px
|
||||
overflow: hidden
|
||||
background: white
|
||||
border: 1px solid #333
|
||||
position: relative
|
||||
|
||||
-webkit-transition: opacity 0.3s ease-in-out
|
||||
-moz-transition: opacity 0.3s ease-in-out
|
||||
-ms-transition: opacity 0.3s ease-in-out
|
||||
-o-transition: opacity 0.3s ease-in-out
|
||||
transition: opacity 0.3s ease-in-out
|
||||
|
||||
opacity: 0.4
|
||||
|
||||
border-radius: 5px
|
||||
.only-one
|
||||
-webkit-transition: opacity 0.3s ease-in-out
|
||||
-moz-transition: opacity 0.3s ease-in-out
|
||||
-ms-transition: opacity 0.3s ease-in-out
|
||||
-o-transition: opacity 0.3s ease-in-out
|
||||
transition: opacity 0.3s ease-in-out
|
||||
opacity: 0
|
||||
|
||||
.choose-option:hover
|
||||
opacity: 1
|
||||
.only-one
|
||||
opacity: 1
|
||||
|
||||
.my-icon
|
||||
position: relative
|
||||
left: 0
|
||||
top: -10px
|
||||
z-index: 1
|
||||
|
||||
.my-team-icon
|
||||
height: 60px
|
||||
position: relative
|
||||
top: -10px
|
||||
left: 10px
|
||||
z-index: 0
|
||||
|
||||
.opponent-team-icon
|
||||
height: 60px
|
||||
position: relative
|
||||
top: 10px
|
||||
right: 10px
|
||||
z-index: 0
|
||||
float: right
|
||||
-moz-transform: scaleX(-1)
|
||||
-o-transform: scaleX(-1)
|
||||
-webkit-transform: scaleX(-1)
|
||||
transform: scaleX(-1)
|
||||
filter: FlipH
|
||||
-ms-filter: "FlipH"
|
||||
|
||||
.opponent-icon
|
||||
position: relative
|
||||
float: right
|
||||
right: 0
|
||||
top: -10px
|
||||
-moz-transform: scaleX(-1)
|
||||
-o-transform: scaleX(-1)
|
||||
-webkit-transform: scaleX(-1)
|
||||
transform: scaleX(-1)
|
||||
filter: FlipH
|
||||
-ms-filter: "FlipH"
|
||||
z-index: 1
|
||||
|
||||
.name-label
|
||||
border-bottom: 20px solid lightslategray
|
||||
height: 0
|
||||
width: 40%
|
||||
position: absolute
|
||||
bottom: 0
|
||||
color: black
|
||||
font-weight: bold
|
||||
text-align: center
|
||||
z-index: 2
|
||||
|
||||
span
|
||||
position: relative
|
||||
top: 1px
|
||||
|
||||
.my-name
|
||||
border-right: 15px solid transparent
|
||||
left: 0
|
||||
span
|
||||
left: 3px
|
||||
|
||||
.preset-size
|
||||
border-left: 15px solid transparent
|
||||
right: 0
|
||||
//text-align: right
|
||||
span
|
||||
right: 3px
|
||||
|
||||
.preset-name
|
||||
border-top: 25px solid darkgray
|
||||
border-left: 20px solid transparent
|
||||
border-right: 20px solid transparent
|
||||
height: 0
|
||||
width: 30%
|
||||
position: absolute
|
||||
left: 35%
|
||||
top: 0
|
||||
color: black
|
||||
text-align: center
|
||||
font-size: 18px
|
||||
font-weight: bold
|
||||
|
||||
span
|
||||
position: relative
|
||||
top: -25px
|
||||
|
||||
.easy-option .preset-name
|
||||
border-top: 25px solid limegreen
|
||||
|
||||
.medium-option .preset-name
|
||||
border-top: 25px solid darkorange
|
||||
|
||||
.hard-option .preset-name
|
||||
border-top: 25px solid black
|
||||
color: white
|
|
@ -79,6 +79,8 @@ block header
|
|||
a(data-i18n="common.fork")#fork-level-start-button Fork
|
||||
li(class=anonymous ? "disabled": "")
|
||||
a(data-toggle="coco-modal", data-target="modal/revert", data-i18n="editor.revert")#revert-button Revert
|
||||
li(class=anonymous ? "disabled": "")
|
||||
a(data-toggle="coco-modal", data-target="modal/terrain_randomise", data-i18n="editor.randomise")#randomise-button Randomise
|
||||
li(class=anonymous ? "disabled": "")
|
||||
a(data-i18n="editor.pop_i18n")#pop-level-i18n-button Populate i18n
|
||||
li.divider
|
||||
|
|
14
app/templates/modal/terrain_randomise.jade
Normal file
14
app/templates/modal/terrain_randomise.jade
Normal file
|
@ -0,0 +1,14 @@
|
|||
extends /templates/modal/modal_base
|
||||
|
||||
block modal-header-content
|
||||
h3(data-i18n="editor.pick_a_terrain") Pick a Terrain
|
||||
|
||||
block modal-body-content
|
||||
div#normal-view
|
||||
a(href="#")
|
||||
div.choose-option(data-preset-type="grassy", data-preset-size="small")
|
||||
div.preset-size.name-label
|
||||
span(data-i18n="ladder.small") Small
|
||||
div.preset-name
|
||||
span(data-i18n="ladder.grassy") Grassy
|
||||
//- for model in models
|
|
@ -43,6 +43,7 @@ module.exports = class ThangsTabView extends View
|
|||
'sprite:mouse-up': 'onSpriteMouseUp'
|
||||
'sprite:double-clicked': 'onSpriteDoubleClicked'
|
||||
'surface:stage-mouse-up': 'onStageMouseUp'
|
||||
'randomise:terrain-generated': 'onRandomiseTerrain'
|
||||
|
||||
events:
|
||||
'click #extant-thangs-filter button': 'onFilterExtantThangs'
|
||||
|
@ -57,6 +58,8 @@ module.exports = class ThangsTabView extends View
|
|||
'delete, del, backspace': 'deleteSelectedExtantThang'
|
||||
'left': -> @moveAddThangSelection -1
|
||||
'right': -> @moveAddThangSelection 1
|
||||
'ctrl+z': 'undoAction'
|
||||
'ctrl+shift+z': 'redoAction'
|
||||
|
||||
constructor: (options) ->
|
||||
super options
|
||||
|
@ -221,6 +224,11 @@ module.exports = class ThangsTabView extends View
|
|||
return unless e.thang
|
||||
@editThang thangID: e.thang.id
|
||||
|
||||
onRandomiseTerrain: (e) ->
|
||||
for thang in e.thangs
|
||||
@selectAddThangType thang.id
|
||||
@addThang @addThangType, thang.pos
|
||||
|
||||
# TODO: figure out a good way to have all Surface clicks and Treema clicks just proxy in one direction, so we can maintain only one way of handling selection and deletion
|
||||
onExtantThangSelected: (e) ->
|
||||
@selectedExtantSprite?.setNameLabel? null unless @selectedExtantSprite is e.sprite
|
||||
|
@ -450,6 +458,12 @@ module.exports = class ThangsTabView extends View
|
|||
$('#add-thangs-column').toggle()
|
||||
@onWindowResize e
|
||||
|
||||
undoAction: (e) ->
|
||||
@thangsTreema.undo()
|
||||
|
||||
redoAction: (e) ->
|
||||
@thangsTreema.redo()
|
||||
|
||||
class ThangsNode extends TreemaNode.nodeMap.array
|
||||
valueClass: 'treema-array-replacement'
|
||||
getChildren: ->
|
||||
|
|
187
app/views/modal/terrain_randomise_modal.coffee
Normal file
187
app/views/modal/terrain_randomise_modal.coffee
Normal file
|
@ -0,0 +1,187 @@
|
|||
ModalView = require 'views/kinds/ModalView'
|
||||
template = require 'templates/modal/terrain_randomise'
|
||||
CocoModel = require 'models/CocoModel'
|
||||
|
||||
clusters = {
|
||||
'rocks': ['Rock 1', 'Rock 2', 'Rock 3', 'Rock 4', 'Rock 5', 'Rock Cluster 1', 'Rock Cluster 2', 'Rock Cluster 3']
|
||||
'trees': ['Tree 1', 'Tree 2', 'Tree 3', 'Tree 4']
|
||||
'shrubs': ['Shrub 1', 'Shrub 2', 'Shrub 3']
|
||||
'houses': ['House 1', 'House 2', 'House 3', 'House 4']
|
||||
'animals': ['Cow', 'Horse']
|
||||
'wood': ['Firewood 1', 'Firewood 2', 'Firewood 3', 'Barrel']
|
||||
'farm': ['Farm']
|
||||
}
|
||||
|
||||
presets = {
|
||||
# 'dungeon': {
|
||||
# 'type':'dungeon'
|
||||
# 'borders':['Dungeon Wall']
|
||||
# 'floors':['Dungeon Floor']
|
||||
# 'decorations':[]
|
||||
# }
|
||||
'grassy': {
|
||||
'type':'grassy'
|
||||
'borders':['Tree 1', 'Tree 2', 'Tree 3']
|
||||
'floors':['Grass01', 'Grass02', 'Grass03']
|
||||
'decorations': {
|
||||
'house': {
|
||||
'num':[1,2] #min-max
|
||||
'width': 20
|
||||
'height': 20
|
||||
'clusters': {
|
||||
'houses':[1,1]
|
||||
'trees':[1,2]
|
||||
'shrubs':[0,3]
|
||||
'rocks':[1,2]
|
||||
}
|
||||
}
|
||||
'farm': {
|
||||
'num':[1,2] #min-max
|
||||
'width': 20
|
||||
'height': 20
|
||||
'clusters': {
|
||||
'farm':[1,1]
|
||||
'shrubs':[2,3]
|
||||
'wood':[2,4]
|
||||
'animals':[2,3]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sizes = {
|
||||
'small': {
|
||||
'x':80
|
||||
'y':68
|
||||
}
|
||||
'large': {
|
||||
'x':160
|
||||
'y':136
|
||||
}
|
||||
'floorSize': {
|
||||
'x':20
|
||||
'y':20
|
||||
}
|
||||
'borderSize': {
|
||||
'x':4
|
||||
'y':4
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = class TerrainRandomiseModal extends ModalView
|
||||
id: 'terrain-randomise-modal'
|
||||
template: template
|
||||
thangs = []
|
||||
|
||||
events:
|
||||
'click .choose-option': 'onRandomise'
|
||||
|
||||
onRevertModel: (e) ->
|
||||
id = $(e.target).val()
|
||||
CocoModel.backedUp[id].revert()
|
||||
$(e.target).closest('tr').remove()
|
||||
@reloadOnClose = true
|
||||
|
||||
onRandomise: (e) ->
|
||||
target = $(e.target)
|
||||
presetType = target.attr 'data-preset-type'
|
||||
presetSize = target.attr 'data-preset-size'
|
||||
@randomiseThangs presetType, presetSize
|
||||
Backbone.Mediator.publish('randomise:terrain-generated',
|
||||
'thangs': @thangs
|
||||
)
|
||||
|
||||
randomiseThangs: (presetName, presetSize) ->
|
||||
preset = presets[presetName]
|
||||
presetSize = sizes[presetSize]
|
||||
@thangs = []
|
||||
@randomiseFloor preset, presetSize
|
||||
@randomiseBorder preset, presetSize
|
||||
@randomiseDecorations preset, presetSize
|
||||
|
||||
randomiseFloor: (preset, presetSize) ->
|
||||
for i in _.range(0, presetSize.x, sizes.floorSize.x)
|
||||
for j in _.range(0, presetSize.y, sizes.floorSize.y)
|
||||
@thangs.push {
|
||||
'id': @getRandomThang(preset.floors)
|
||||
'pos': {
|
||||
'x': i
|
||||
'y': j
|
||||
}
|
||||
}
|
||||
|
||||
randomiseBorder: (preset, presetSize) ->
|
||||
for i in _.range(0-sizes.floorSize.x/2+sizes.borderSize.x, presetSize.x-sizes.floorSize.x/2, sizes.borderSize.x)
|
||||
@thangs.push {
|
||||
'id': @getRandomThang(preset.borders)
|
||||
'pos': {
|
||||
'x': i
|
||||
'y': 0-sizes.floorSize.x/2
|
||||
}
|
||||
}
|
||||
@thangs.push {
|
||||
'id': @getRandomThang(preset.borders)
|
||||
'pos': {
|
||||
'x': i
|
||||
'y': presetSize.y - sizes.borderSize.y
|
||||
}
|
||||
}
|
||||
|
||||
for i in _.range(0-sizes.floorSize.y/2, presetSize.y-sizes.borderSize.y, sizes.borderSize.y)
|
||||
@thangs.push {
|
||||
'id': @getRandomThang(preset.borders)
|
||||
'pos': {
|
||||
'x': 0-sizes.floorSize.x/2+sizes.borderSize.x
|
||||
'y': i
|
||||
}
|
||||
}
|
||||
@thangs.push {
|
||||
'id': @getRandomThang(preset.borders)
|
||||
'pos': {
|
||||
'x': presetSize.x - sizes.borderSize.x - sizes.floorSize.x/2
|
||||
'y': i
|
||||
}
|
||||
}
|
||||
|
||||
randomiseDecorations: (preset, presetSize)->
|
||||
for name, decoration of preset.decorations
|
||||
for num in _.range(_.random(decoration.num[0], decoration.num[1]))
|
||||
center =
|
||||
{
|
||||
'x':_.random(decoration.width, presetSize.x - decoration.width),
|
||||
'y':_.random(decoration.height, presetSize.y - decoration.height)
|
||||
}
|
||||
min =
|
||||
{
|
||||
'x':center.x - decoration.width/2
|
||||
'y':center.y - decoration.height/2
|
||||
}
|
||||
max =
|
||||
{
|
||||
'x':center.x + decoration.width/2
|
||||
'y':center.y + decoration.height/2
|
||||
}
|
||||
for cluster, range of decoration.clusters
|
||||
for i in _.range(_.random(range[0], range[1]))
|
||||
@thangs.push {
|
||||
'id':@getRandomThang(clusters[cluster])
|
||||
'pos':{
|
||||
'x':_.random(min.x, max.x)
|
||||
'y':_.random(min.y, max.y)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
getRandomThang: (thangList) ->
|
||||
return thangList[_.random(0, thangList.length-1)]
|
||||
|
||||
getRenderData: ->
|
||||
c = super()
|
||||
models = _.values CocoModel.backedUp
|
||||
models = (m for m in models when m.hasLocalChanges())
|
||||
c.models = models
|
||||
c
|
||||
|
||||
onHidden: ->
|
||||
location.reload() if @reloadOnClose
|
Loading…
Add table
Add a link
Reference in a new issue