mobiusWorld

Procedurally generated worlds without seams. Uses Zynga's Scroller library.

by not important

HTML

<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="http://zynga.github.io/scroller/src/Raf.js"></script>
<script src="http://zynga.github.io/scroller/src/Animate.js"></script>
<script src="http://zynga.github.io/scroller/src/Scroller.js"></script>
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<div class="container">
     <h1>mobiusWorld</h1>
    <p class="lead">Procedurally generated worlds displayed with the <a href="http://zynga.github.io/scroller/">Scroller</a> library. The worlds are seamless and scrolling is infinite</p>

    <div class="row">
        <div class="col-md-12" id="canvas-container">
        </div>
    </div>
</div>

CSS

body {
    margin: 40px 0;
}

CoffeeScript

tilesetUri = 'http://clindsey.github.io/SmootherScroller/images/tileset.png'
tilesetImg = undefined
seed = +new Date #20130428
canvasWidth = 640
canvasHeight = 640
cellWidth = 32
cellHeight = 32
worldChunkWidth = 32
worldChunkHeight = 32
chunkTileWidth = 8
chunkTileHeight = 8
worldTileWidth = worldChunkWidth * chunkTileWidth
worldTileHeight = worldChunkHeight * chunkTileHeight
contentWidth = (canvasWidth * 3) - cellWidth
contentHeight = (canvasHeight * 3) - cellHeight
$canvasEl = $ '<canvas>'
$canvasEl.attr
    width: canvasWidth
    height: canvasHeight
$('#canvas-container').append $canvasEl
context = $canvasEl.get(0).getContext '2d'

utils =
    clamp: (index, size) ->
        (index + size) % size

class WorldGenerator
  constructor: (@seed, @options) ->
    @tileCache = []
    @cellCache = []

  cacheAllTiles: ->
    for y in [[email protected] - 1]
      for x in [[email protected] - 1]
        chunk = @getChunk x, y

        for cy in [0..chunk.length - 1]
          for cx in [0..chunk[0].length - 1]
            vx = x * @options.chunkTileWidth + cx
            vy = y * @options.chunkTileHeight + cy

            @getCell vx, vy

  getCell: (worldX, worldY) ->
    if @cellCache[worldY] and @cellCache[worldY][worldX]?
      return @cellCache[worldY][worldX]

    worldChunkX = Math.floor worldX / @options.chunkTileWidth
    worldChunkY = Math.floor worldY / @options.chunkTileHeight
    chunkX = worldX % @options.chunkTileWidth
    chunkY = worldY % @options.chunkTileHeight

    chunk = @getChunk worldChunkX, worldChunkY

    cell = +(chunk[chunkY][chunkX] >= @options.waterCutoff)
    
    @cellCache[worldY] = [] unless @cellCache[worldY]?
    @cellCache[worldY][worldX] = cell

    cell

  getTile: (worldX, worldY) ->
    if @tileCache[worldY] and @tileCache[worldY][worldX]?
      return @tileCache[worldY][worldX]

    cell = @getCell worldX, worldY
    neighbors = @collectNeighbors worldX, worldY
    index = @getIndexByNeighbors cell,...