summaryrefslogtreecommitdiff
path: root/public/assets/javascripts/rectangles/engine/scenery/randomize.js
blob: 1c2eb5621710f61edcaa9453aa3f4a588947e47f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
  // get the list of media we want to place
  var media_objs = $(".mediaContainer").toArray().map(function(el){
    return $(el).data("media")
  })
  Scenery.randomize.add( media_objs )
*/

Scenery.randomize = {};

// Given a list of media objects, generate their ideal dimensions
Scenery.randomize.get_dimensions = function (media_objs){
  var media_list = media_objs.map(function(media){
    var width, height
    if (media.width > media.height) {
      width = Math.min(DEFAULT_PICTURE_WIDTH, media.width)
      height = media.height/media.width * width
    }
    else {
      height = Math.min(DEFAULT_PICTURE_WIDTH, media.height)
      width = media.width/media.height * height
    }
    return {
      dimensions: new vec2( width, height ),
      media: media,
    }
  })
  return media_list
}

// Build the lookup of empty walls.
// Takes a list of walls to use, or undefined to use all empty walls.
// Returns a lookup of walls to use, keyed by wall ID.
Scenery.randomize.get_empty_walls = function(wall_list){
  // get a list of all walls
  var walls = {};

  (wall_list || Walls.list).forEach(function(wall){
    walls[wall.id] = wall
  })

  // remove the walls that already have stuff on them
  if (! wall_list) {
    Scenery.forEach(function(scenery){
      if (scenery.was_randomly_placed) {
        // remove it and reuse this wall?
        Scenery.remove( scenery.id )
      }
      else {
        delete walls[scenery.wall.id] 
      }
    })
  }
  
  return walls
}

// Randomly place a set of media objects on empty walls.
// Only one object per wall will be added.
// Optionally takes a list of walls to use.
Scenery.randomize.add = function (media_objs, wall_list) {
  var media_list = Scenery.randomize.get_dimensions(media_objs)
  var walls = Scenery.randomize.get_empty_walls(wall_list)
  
  var wall_ids = _.keys(walls)
  if (! wall_ids.length) { return }

  // randomize walls
  shuffle(wall_ids)
  shuffle(media_list)

  // assign each of the media to the walls, until we run out of either
  media_list.some(function(media){
    // bail if we're out of walls
    if (wall_ids.length == 0) { return true }
  
    var i, fits = -1

    for (i = 0; i < wall_ids.length; i++) {
      if (walls[wall_ids[i]].surface.fits(media.dimensions)) {
        fits = i
        break
      }
    }

    if (fits != -1) {
      var wall = walls[wall_ids[fits]]
      wall_ids.splice(fits, 1)
    
      var scenery = Scenery.add({
        media: media.media,
        wall: wall,
        index: 0,
      })
      scenery.was_randomly_placed = true
    }
    else {
      // artwork won't fit anywhere??
    }
  
    return false
  })
}