<commit_before>import React from 'react';
import { Body } from 'reactabular-sticky';
import { bodyChildContextTypes } from './types';

class VirtualizedBody extends React.Component {
  constructor(props) {
    super(props);

    this.measuredRows = [];
    this.ref = null;

    this.state = {
      amountOfRowsToRender: 3, // First few rows for initial measurement
      startIndex: 0, // Index where to start rendering

      // Heights for extra rows to mimic scrolling
      startHeight: 0,
      endHeight: 0,

      // Show extra row (even/odd issue)
      showExtraRow: false
    };

    this.updateRowsToRender = this.updateRowsToRender.bind(this);
  }
  componentDidMount() {
    this.updateRowsToRender();
  }
  getChildContext() {
    const { startHeight, endHeight, showExtraRow } = this.state;

    return {
      startHeight,
      endHeight,
      showExtraRow,
      updateHeight: (index, height) => {
        this.measuredRows[index] = height;
      }
    };
  }
  render() {
    const { onRow, rows, ...props } = this.props;
    const { startIndex, amountOfRowsToRender } = this.state;
    const rowsToRender = rows.slice(
      startIndex,
      startIndex + amountOfRowsToRender
    );

    if (process.env.NODE_ENV !== 'production') {
      console.log( // eslint-disable-line no-console
        'rendering', rowsToRender.length, '/', rows.length,
        'rows to render', rowsToRender,
        'start index', startIndex,
        'amount of rows to render', amountOfRowsToRender
      );
    }

    return React.createElement(
      Body,
      {
        ...props,
        onRow: (row, rowIndex) => {
          const rowProps = onRow ? onRow(row, rowIndex) : {};

          return {
            // Pass index so that row heights can be tracked properly
            'data-rowindex': startIndex + rowIndex,
            ...rowProps
          };
        },
        rows: rowsToRender,
        ref: body => {
          this.ref = body && body.getRef();
        },
        onScroll: ({ target: { scrollTop } }) => {
          this.updateRowsToRender(scrollTop);
        }
      }
    );
  }
  updateRowsToRender(scrollTop = 0) {
    // Render visible rows after initial measurement
    const bodyHeight = this.props.height;
    const measuredSample = this.measuredRows;

    // Calculate amount of rows to render based on average height
    const amountOfMeasuredRows = measuredSample.filter(a => a).length;
    const averageHeight = measuredSample
      .reduce((a, b) => (
        a + (b / amountOfMeasuredRows)
      ), 0);
    const amountOfRowsToRender = Math.ceil(bodyHeight / averageHeight) + 2;

    const startIndex = Math.floor(scrollTop / averageHeight);
    const rowsToRender = this.props.rows.slice(
      startIndex,
      startIndex + amountOfRowsToRender
    );

    // Escape if there are no rows to render for some reason
    if (!rowsToRender.length) {
      return;
    }

    const startHeight = startIndex * averageHeight;

    // Calculate the padding of the last row so we can match whole height. This
    // won't be totally accurate if row heights differ but should get close
    // enough in most cases.
    const endHeight = Math.max(
      (
        (
          this.props.rows.length - amountOfRowsToRender
        ) * averageHeight
      ) - startHeight,
      0
    );

    if (process.env.NODE_ENV !== 'production') {
      console.log( // eslint-disable-line no-console
        'measured sample', measuredSample,
        'measured rows', this.measuredRows,
        'average height', averageHeight,
        'body height', bodyHeight,
        'amount of rows to render', amountOfRowsToRender,
        'start index', startIndex,
        'scroll top', scrollTop,
        'start height', startHeight,
        'end height', endHeight
      );
    }

    // Update state and render now that data has changed
    this.setState({
      amountOfRowsToRender,
      startIndex,
      showExtraRow: !(startIndex % 2),
      startHeight,
      endHeight
    });
  }
  getRef() {
    return this.ref;
  }
}
VirtualizedBody.defaultProps = Body.defaultProps;
VirtualizedBody.propTypes = {
  ...Body.propTypes,
  height: React.PropTypes.number.isRequired
};
VirtualizedBody.childContextTypes = bodyChildContextTypes;

export default VirtualizedBody;
<commit_msg>virtualized - Allow `Body` `onScroll` to be overridden<commit_after>import React from 'react';
import { Body } from 'reactabular-sticky';
import { bodyChildContextTypes } from './types';

class VirtualizedBody extends React.Component {
  constructor(props) {
    super(props);

    this.measuredRows = [];
    this.ref = null;

    this.state = {
      amountOfRowsToRender: 3, // First few rows for initial measurement
      startIndex: 0, // Index where to start rendering

      // Heights for extra rows to mimic scrolling
      startHeight: 0,
      endHeight: 0,

      // Show extra row (even/odd issue)
      showExtraRow: false
    };

    this.updateRowsToRender = this.updateRowsToRender.bind(this);
  }
  componentDidMount() {
    this.updateRowsToRender();
  }
  getChildContext() {
    const { startHeight, endHeight, showExtraRow } = this.state;

    return {
      startHeight,
      endHeight,
      showExtraRow,
      updateHeight: (index, height) => {
        this.measuredRows[index] = height;
      }
    };
  }
  render() {
    const { onRow, rows, onScroll, ...props } = this.props;
    const { startIndex, amountOfRowsToRender } = this.state;
    const rowsToRender = rows.slice(
      startIndex,
      startIndex + amountOfRowsToRender
    );

    if (process.env.NODE_ENV !== 'production') {
      console.log( // eslint-disable-line no-console
        'rendering', rowsToRender.length, '/', rows.length,
        'rows to render', rowsToRender,
        'start index', startIndex,
        'amount of rows to render', amountOfRowsToRender
      );
    }

    return React.createElement(
      Body,
      {
        ...props,
        onRow: (row, rowIndex) => {
          const rowProps = onRow ? onRow(row, rowIndex) : {};

          return {
            // Pass index so that row heights can be tracked properly
            'data-rowindex': startIndex + rowIndex,
            ...rowProps
          };
        },
        rows: rowsToRender,
        ref: body => {
          this.ref = body && body.getRef();
        },
        onScroll: e => {
          onScroll && onScroll(e);

          const { target: { scrollTop } } = e;

          this.updateRowsToRender(scrollTop);
        }
      }
    );
  }
  updateRowsToRender(scrollTop = 0) {
    // Render visible rows after initial measurement
    const bodyHeight = this.props.height;
    const measuredSample = this.measuredRows;

    // Calculate amount of rows to render based on average height
    const amountOfMeasuredRows = measuredSample.filter(a => a).length;
    const averageHeight = measuredSample
      .reduce((a, b) => (
        a + (b / amountOfMeasuredRows)
      ), 0);
    const amountOfRowsToRender = Math.ceil(bodyHeight / averageHeight) + 2;

    const startIndex = Math.floor(scrollTop / averageHeight);
    const rowsToRender = this.props.rows.slice(
      startIndex,
      startIndex + amountOfRowsToRender
    );

    // Escape if there are no rows to render for some reason
    if (!rowsToRender.length) {
      return;
    }

    const startHeight = startIndex * averageHeight;

    // Calculate the padding of the last row so we can match whole height. This
    // won't be totally accurate if row heights differ but should get close
    // enough in most cases.
    const endHeight = Math.max(
      (
        (
          this.props.rows.length - amountOfRowsToRender
        ) * averageHeight
      ) - startHeight,
      0
    );

    if (process.env.NODE_ENV !== 'production') {
      console.log( // eslint-disable-line no-console
        'measured sample', measuredSample,
        'measured rows', this.measuredRows,
        'average height', averageHeight,
        'body height', bodyHeight,
        'amount of rows to render', amountOfRowsToRender,
        'start index', startIndex,
        'scroll top', scrollTop,
        'start height', startHeight,
        'end height', endHeight
      );
    }

    // Update state and render now that data has changed
    this.setState({
      amountOfRowsToRender,
      startIndex,
      showExtraRow: !(startIndex % 2),
      startHeight,
      endHeight
    });
  }
  getRef() {
    return this.ref;
  }
}
VirtualizedBody.defaultProps = Body.defaultProps;
VirtualizedBody.propTypes = {
  ...Body.propTypes,
  height: React.PropTypes.number.isRequired
};
VirtualizedBody.childContextTypes = bodyChildContextTypes;

export default VirtualizedBody;
<|endoftext|>


<commit_before>'use strict';

function create_gates(new_gates){
    new_gates = new_gates || [{}];
    for(var gate in new_gates){
        gates.push({
          'color': new_gates[gate]['color'] || '#fff',
          'destroy': new_gates[gate]['destroy'] !== void 0
            ? new_gates[gate]['destroy']
            : false,
          'dx': new_gates[gate]['dx'] || false,
          'dy': new_gates[gate]['dy'] || false,
          'event': new_gates[gate]['event'] || function(){},
          'height': new_gates[gate]['height'] || 40,
          'interval': new_gates[gate]['interval'] || 0,
          'x': new_gates[gate]['x'] || 0,
          'y': new_gates[gate]['y'] || 0,
          'width': new_gates[gate]['width'] || 40,
        });
    }
}

function create_particles(new_particles){
    if(particles.length >= core_storage_data['max-particles']){
        return;
    }

    new_particles = new_particles || [{}];
    for(var particle in new_particles){
        particles.push({
          'dx': new_particles[particle]['dx'] || 0,
          'dy': new_particles[particle]['dy'] || 0,
          'height': new_particles[particle]['height'] || core_storage_data['particle-height'],
          'width': new_particles[particle]['width'] || core_storage_data['particle-width'],
          'x': new_particles[particle]['x'] || 0,
          'y': new_particles[particle]['y'] || 0,
        });
    }
}

function draw_logic(){
    canvas_buffer.save();
    canvas_buffer.translate(
      canvas_x - camera_x,
      canvas_y - camera_y
    );

    // Draw background.
    canvas_buffer.fillStyle = '#111';
    canvas_buffer.fillRect(
      boundaries['x'],
      boundaries['y'],
      boundaries['width'],
      boundaries['height']
    );

    // Draw gates.
    for(var gate in gates){
        canvas_buffer.fillStyle = gates[gate]['color'];
        canvas_buffer.fillRect(
          gates[gate]['x'],
          gates[gate]['y'],
          gates[gate]['width'],
          gates[gate]['height']
       );
    }

    // Draw particles.
    canvas_buffer.fillStyle = '#fff';
    for(var particle in particles){
        canvas_buffer.fillRect(
          particles[particle]['x'],
          particles[particle]['y'],
          particles[particle]['width'],
          particles[particle]['height']
        );
    };

    canvas_buffer.restore();

    canvas_buffer.fillStyle = '#fff';
    // Draw camera position.
    canvas_buffer.fillText(
      camera_x + 'x ' + camera_y + 'y',
      5,
      25
    );

    // Draw number of particles
    //   and max-particles.
    canvas_buffer.fillText(
      particles.length
        + '/'
        + core_storage_data['max-particles'],
      5,
      50
    );
}

function logic(){
    // Move camera down.
    if(core_keys[83]['state']
      && camera_y < boundaries['y'] + boundaries['height']){
        camera_y += core_storage_data['scroll-speed'];
    }

    // Move camera left.
    if(core_keys[65]['state']
      && camera_x > boundaries['x']){
        camera_x -= core_storage_data['scroll-speed'];
    }

    // Move camera right.
    if(core_keys[68]['state']
      && camera_x < boundaries['x'] + boundaries['width']){
        camera_x += core_storage_data['scroll-speed'];
    }

    // Move camera up.
    if(core_keys[87]['state']
      && camera_y > boundaries['y']){
        camera_y -= core_storage_data['scroll-speed'];
    }

    frame_counter += 1;
    if(frame_counter > 99){
        frame_counter = 0;
    }

    for(var particle in particles){
        particles[particle]['x'] += particles[particle]['dx'];
        particles[particle]['y'] += particles[particle]['dy'];

        if(!math_rectangle_overlap({
          'h0': particles[particle]['height'],
          'h1': boundaries['height'],
          'w0': particles[particle]['width'],
          'w1': boundaries['width'],
          'x0': particles[particle]['x'],
          'x1': boundaries['x'],
          'y0': particles[particle]['y'],
          'y1': boundaries['y'],
        })){
            particles.splice(
              particle,
              1
            );
        }
    }

    for(var gate in gates){
        if(gates[gate]['interval'] > 0
          && frame_counter % gates[gate]['interval'] === 0){
            gates[gate]['event']();
        }

        for(var particle in particles){
            if(math_rectangle_overlap({
              'h0': particles[particle]['height'],
              'h1': gates[gate]['height'],
              'w0': particles[particle]['width'],
              'w1': gates[gate]['width'],
              'x0': particles[particle]['x'],
              'x1': gates[gate]['x'],
              'y0': particles[particle]['y'],
              'y1': gates[gate]['y'],
            })){
                if(gates[gate]['destroy']){
                    particles.splice(
                      particle,
                      1
                    );
                    continue;
                }

                if(gates[gate]['dx'] !== false){
                    particles[particle]['dx'] = gates[gate]['dx'];
                }
                if(gates[gate]['dy'] !== false){
                    particles[particle]['dy'] = gates[gate]['dy'];
                }
            }
        }
    }
}

function repo_init(){
    core_repo_init({
      'info': '<input onclick=canvas_setmode({newgame:true}) type=button value="Test Level">',
      'keybinds': {
        65: {},
        68: {},
        72: {
          'todo': function(){
              camera_x = 0;
              camera_y = 0;
          },
        },
        83: {},
        87: {},
      },
      'menu': true,
      'storage': {
        'max-particles': 1000,
        'particle-height': 5,
        'particle-width': 5,
        'scroll-speed': 5,
      },
      'storage-menu': '

<input id=max-particles>Max Particles
<input id=particle-height>Particle Height
<input id=particle-width>Particle Width
<input id=scroll-speed>Scroll Speed
',
      'title': 'ParticleRun-2D.htm',
    });
    canvas_init();
}

var boundaries = {};
var camera_x = 0;
var camera_y = 0;
var frame_counter = 0;
var gates = [];
var particles = [];
<commit_msg>added repo-ui usage<commit_after>'use strict';

function create_gates(new_gates){
    new_gates = new_gates || [{}];
    for(var gate in new_gates){
        gates.push({
          'color': new_gates[gate]['color'] || '#fff',
          'destroy': new_gates[gate]['destroy'] !== void 0
            ? new_gates[gate]['destroy']
            : false,
          'dx': new_gates[gate]['dx'] || false,
          'dy': new_gates[gate]['dy'] || false,
          'event': new_gates[gate]['event'] || function(){},
          'height': new_gates[gate]['height'] || 40,
          'interval': new_gates[gate]['interval'] || 0,
          'x': new_gates[gate]['x'] || 0,
          'y': new_gates[gate]['y'] || 0,
          'width': new_gates[gate]['width'] || 40,
        });
    }
}

function create_particles(new_particles){
    if(particles.length >= core_storage_data['max-particles']){
        return;
    }

    new_particles = new_particles || [{}];
    for(var particle in new_particles){
        particles.push({
          'dx': new_particles[particle]['dx'] || 0,
          'dy': new_particles[particle]['dy'] || 0,
          'height': new_particles[particle]['height'] || core_storage_data['particle-height'],
          'width': new_particles[particle]['width'] || core_storage_data['particle-width'],
          'x': new_particles[particle]['x'] || 0,
          'y': new_particles[particle]['y'] || 0,
        });
    }
}

function draw_logic(){
    canvas_buffer.save();

    canvas_buffer.translate(
      canvas_x - camera_x,
      canvas_y - camera_y
    );

    // Draw background.
    canvas_buffer.fillStyle = '#111';
    canvas_buffer.fillRect(
      boundaries['x'],
      boundaries['y'],
      boundaries['width'],
      boundaries['height']
    );

    // Draw gates.
    for(var gate in gates){
        canvas_buffer.fillStyle = gates[gate]['color'];
        canvas_buffer.fillRect(
          gates[gate]['x'],
          gates[gate]['y'],
          gates[gate]['width'],
          gates[gate]['height']
       );
    }

    // Draw particles.
    canvas_buffer.fillStyle = '#fff';
    for(var particle in particles){
        canvas_buffer.fillRect(
          particles[particle]['x'],
          particles[particle]['y'],
          particles[particle]['width'],
          particles[particle]['height']
        );
    };

    canvas_buffer.restore();
}

function logic(){
    // Move camera down.
    if(core_keys[83]['state']
      && camera_y < boundaries['y'] + boundaries['height']){
        camera_y += core_storage_data['scroll-speed'];
    }

    // Move camera left.
    if(core_keys[65]['state']
      && camera_x > boundaries['x']){
        camera_x -= core_storage_data['scroll-speed'];
    }

    // Move camera right.
    if(core_keys[68]['state']
      && camera_x < boundaries['x'] + boundaries['width']){
        camera_x += core_storage_data['scroll-speed'];
    }

    // Move camera up.
    if(core_keys[87]['state']
      && camera_y > boundaries['y']){
        camera_y -= core_storage_data['scroll-speed'];
    }

    frame_counter += 1;
    if(frame_counter > 99){
        frame_counter = 0;
    }

    for(var particle in particles){
        particles[particle]['x'] += particles[particle]['dx'];
        particles[particle]['y'] += particles[particle]['dy'];

        if(!math_rectangle_overlap({
          'h0': particles[particle]['height'],
          'h1': boundaries['height'],
          'w0': particles[particle]['width'],
          'w1': boundaries['width'],
          'x0': particles[particle]['x'],
          'x1': boundaries['x'],
          'y0': particles[particle]['y'],
          'y1': boundaries['y'],
        })){
            particles.splice(
              particle,
              1
            );
        }
    }

    for(var gate in gates){
        if(gates[gate]['interval'] > 0
          && frame_counter % gates[gate]['interval'] === 0){
            gates[gate]['event']();
        }

        for(var particle in particles){
            if(math_rectangle_overlap({
              'h0': particles[particle]['height'],
              'h1': gates[gate]['height'],
              'w0': particles[particle]['width'],
              'w1': gates[gate]['width'],
              'x0': particles[particle]['x'],
              'x1': gates[gate]['x'],
              'y0': particles[particle]['y'],
              'y1': gates[gate]['y'],
            })){
                if(gates[gate]['destroy']){
                    particles.splice(
                      particle,
                      1
                    );
                    continue;
                }

                if(gates[gate]['dx'] !== false){
                    particles[particle]['dx'] = gates[gate]['dx'];
                }
                if(gates[gate]['dy'] !== false){
                    particles[particle]['dy'] = gates[gate]['dy'];
                }
            }
        }
    }

    core_ui_update({
      'ids': {
        'particles': particles.length + '/' + core_storage_data['max-particles'],
        'x': camera_x,
        'y': camera_y,
      },
    });
}

function repo_init(){
    core_repo_init({
      'info': '<input onclick=canvas_setmode({newgame:true}) type=button value="Test Level">',
      'keybinds': {
        65: {},
        68: {},
        72: {
          'todo': function(){
              camera_x = 0;
              camera_y = 0;
          },
        },
        83: {},
        87: {},
      },
      'menu': true,
      'storage': {
        'max-particles': 1000,
        'particle-height': 5,
        'particle-width': 5,
        'scroll-speed': 5,
      },
      'storage-menu': '

<input id=max-particles>Max Particles
<input id=particle-height>Particle Height
<input id=particle-width>Particle Width
<input id=scroll-speed>Scroll Speed
',
      'title': 'ParticleRun-2D.htm',
      'ui': '<input id=ui-particles>Particles
<input id=ui-x>X
<input id=ui-y>Y',
    });
    canvas_init();
}

var boundaries = {};
var camera_x = 0;
var camera_y = 0;
var frame_counter = 0;
var gates = [];
var particles = [];
<|endoftext|>


<commit_before>function create_gate(gate){
    gate = gate || {};
    gates.push({
      'color': gate['color'] || '#fff',
      'dx': gate['dx'] || 0,
      'dy': gate['dy'] || 0,
      'event': gate['event'] || function(){},
      'height': gate['height'] || 40,
      'interval': gate['interval'] || 0,
      'x': gate['x'] || 0,
      'y': gate['y'] || 0,
      'width': gate['width'] || 40,
    });
}

function draw(){
    buffer.clearRect(
      0,
      0,
      width,
      height
    );

    buffer.save();
    buffer.translate(
      x - camera_x,
      y - camera_y
    );

    // Draw gates.
    for(var gate in gates){
        buffer.fillStyle = gates[gate]['color'];
        buffer.fillRect(
          gates[gate]['x'],
          gates[gate]['y'],
          gates[gate]['width'],
          gates[gate]['height']
       );
    }

    // Draw particles.
    buffer.fillStyle = '#fff';
    for(var particle in particles){
        buffer.fillRect(
          particles[particle]['x'],
          particles[particle]['y'],
          5,
          5
        );
    };

    buffer.restore();

    // Setup text display.
    buffer.fillStyle = '#fff';
    buffer.font = '23pt sans-serif';
    buffer.textAlign = 'left';

    // Draw camera position.
    buffer.fillText(
      camera_x + 'x ' + camera_y + 'y',
      5,
      25
    );

    // Draw number of particles.
    buffer.fillText(
      particles.length,
      5,
      50
    );

    canvas.clearRect(
      0,
      0,
      width,
      height
    );
    canvas.drawImage(
      document.getElementById('buffer'),
      0,
      0
    );

    animationFrame = window.requestAnimationFrame(draw);
}

function logic(){
    if(key_left){
        camera_x -= 5;
    }

    if(key_right){
        camera_x += 5;
    }

    if(key_down){
        camera_y += 5;
    }

    if(key_up){
        camera_y -= 5;
    }

    frame_counter += 1;
    if(frame_counter > 99){
        frame_counter = 0;
    }

    for(var particle in particles){
        particles[particle]['x'] += particles[particle]['dx'];
        particles[particle]['y'] += particles[particle]['dy'];

        if(Math.abs(particles[particle]['x']) > 999
          || Math.abs(particles[particle]['y']) > 999){
            particles.splice(
              particle,
              1
            );
        }
    }

    for(var gate in gates){
        if(gates[gate]['interval'] > 0
          && frame_counter % gates[gate]['interval'] == 0){
            gates[gate]['event']();
        }

        for(var particle in particles){
            if(particles[particle]['x'] > gates[gate]['x']
              && particles[particle]['x'] < gates[gate]['x'] + gates[gate]['width']
              && particles[particle]['y'] > gates[gate]['y']
              && particles[particle]['y'] < gates[gate]['y'] + gates[gate]['height']){
                particles[particle]['dx'] = gates[gate]['dx'];
                particles[particle]['dy'] = gates[gate]['dy'];
            }
        }
    }
}

function play_audio(id){
    if(settings['audio-volume'] <= 0){
        return;
    }

    document.getElementById(id).currentTime = 0;
    document.getElementById(id).play();
}

function reset(){
    if(!window.confirm('Reset settings?')){
        return;
    }

    document.getElementById('audio-volume').value = 1;
    document.getElementById('movement-keys').value = 'WASD';
    document.getElementById('max-particles').value = 1000;
    document.getElementById('ms-per-frame').value = 25;
    document.getElementById('restart-key').value = 'H';

    save();
}

function resize(){
    if(mode <= 0){
        return;
    }

    height = window.innerHeight;
    document.getElementById('buffer').height = height;
    document.getElementById('canvas').height = height;
    y = height / 2;

    width = window.innerWidth;
    document.getElementById('buffer').width = width;
    document.getElementById('canvas').width = width;
    x = width / 2;
}

// Save settings into window.localStorage if they differ from default.
function save(){
    var ids = {
      'audio-volume': 1,
      'max-particles': 1000,
      'ms-per-frame': 25,
    };
    for(var id in ids){
        if(isNaN(document.getElementById(id).value)
          || document.getElementById(id).value == ids[id]){
            window.localStorage.removeItem('ParticleRun-2D.htm-' + id);
            settings[id] = ids[id];

        }else{
            settings[id] = parseFloat(document.getElementById(id).value);
            window.localStorage.setItem(
              'ParticleRun-2D.htm-' + id,
              settings[id]
            );
        }
    }

    ids = {
      'movement-keys': 'WASD',
      'restart-key': 'H',
    };
    for(id in ids){
        if(document.getElementById(id).value === ids[id]){
            window.localStorage.removeItem('ParticleRun-2D.htm-' + id);
            settings[id] = ids[id];

        }else{
            settings[id] = document.getElementById(id).value;
            window.localStorage.setItem(
              'ParticleRun-2D.htm-' + id,
              settings[id]
            );
        }
    }
}

function setmode(newmode, newgame){
    window.cancelAnimationFrame(animationFrame);
    window.clearInterval(interval);

    gates = [];
    particles = [];

    mode = newmode;

    // New game mode.
    if(mode > 0){
        // If it's a newgame from the main menu, save settings.
        if(newgame){
            save();
        }

        // Reset.
        camera_x = 0;
        camera_y = 0;
        frame_counter = 0;
        key_left = false;
        key_right = false;

        // If it's a newgame from the main menu, setup canvas and buffers.
        if(newgame){
            document.getElementById('page').innerHTML = '<canvas id=canvas></canvas><canvas id=buffer style=display:none></canvas>';

            buffer = document.getElementById('buffer').getContext('2d');
            canvas = document.getElementById('canvas').getContext('2d');

            resize();
        }

        load_level();

        animationFrame = window.requestAnimationFrame(draw);
        interval = window.setInterval(
          'logic()',
          settings['ms-per-frame']
        );

        return;
    }

    // Main menu mode.
    buffer = 0;
    canvas = 0;

    document.getElementById('page').innerHTML = '

New Run

<input disabled style=border:0 value=ESC>Main Menu
<input id=movement-keys maxlength=4 value='
      + settings['movement-keys'] + '>Camera ↑←↓→
<input id=restart-key maxlength=1 value='
      + settings['restart-key'] + '>Restart

<input id=audio-volume max=1 min=0 step=.01 type=range value='
      + settings['audio-volume'] + '>Audio
<input id=max-particles value='
      + settings['max-particles'] + '>Max Particles
<input id=ms-per-frame value='
      + settings['ms-per-frame'] + '>ms/Frame
Reset Settings

';
}

var animationFrame = 0;
var buffer = 0;
var camera_x = 0;
var camera_y = 0;
var canvas = 0;
var gates = [];
var height = 0;
var interval = 0;
var key_down = false;
var key_left = false;
var key_right = false;
var key_up = false;
var mode = 0;
var particles = [];
var settings = {
  'audio-volume': parseFloat(window.localStorage.getItem('ParticleRun-2D.htm-audio-volume')) || 1,
  'movement-keys': window.localStorage.getItem('ParticleRun-2D.htm-movement-keys') || 'WASD',
  'max-particles': parseInt(window.localStorage.getItem('ParticleRun-2D.htm-max-particles')) || 1000,
  'ms-per-frame': parseInt(window.localStorage.getItem('ParticleRun-2D.htm-ms-per-frame')) || 25,
  'restart-key': window.localStorage.getItem('ParticleRun-2D.htm-restart-key') || 'H',
};
var x = 0;
var width = 0;
var y = 0;

window.onkeydown = function(e){
    if(mode <= 0){
        return;
    }

    var key = e.keyCode || e.which;

    // ESC: return to main menu.
    if(key === 27){
        setmode(
          0,
          true
        );
        return;
    }

    key = String.fromCharCode(key);

    if(key === settings['movement-keys'][0]){
        key_up = true;

    }else if(key === settings['movement-keys'][1]){
        key_left = true;

    }else if(key === settings['movement-keys'][2]){
        key_down = true;

    }else if(key === settings['movement-keys'][3]){
        key_right = true;

    }else if(key === settings['restart-key']){
        setmode(
          mode,
          false
        );
    }
};

window.onkeyup = function(e){
    var key = String.fromCharCode(e.keyCode || e.which);

    if(key === settings['movement-keys'][0]){
        key_up = false;

    }else if(key === settings['movement-keys'][1]){
        key_left = false;

    }else if(key === settings['movement-keys'][2]){
        key_down = false;

    }else if(key === settings['movement-keys'][3]){
        key_right = false;
    }
};

window.onload = function(e){
    setmode(
      0,
      true
    );
};

window.onresize = resize;
<commit_msg>removed useless textAlign<commit_after>function create_gate(gate){
    gate = gate || {};
    gates.push({
      'color': gate['color'] || '#fff',
      'dx': gate['dx'] || 0,
      'dy': gate['dy'] || 0,
      'event': gate['event'] || function(){},
      'height': gate['height'] || 40,
      'interval': gate['interval'] || 0,
      'x': gate['x'] || 0,
      'y': gate['y'] || 0,
      'width': gate['width'] || 40,
    });
}

function draw(){
    buffer.clearRect(
      0,
      0,
      width,
      height
    );

    buffer.save();
    buffer.translate(
      x - camera_x,
      y - camera_y
    );

    // Draw gates.
    for(var gate in gates){
        buffer.fillStyle = gates[gate]['color'];
        buffer.fillRect(
          gates[gate]['x'],
          gates[gate]['y'],
          gates[gate]['width'],
          gates[gate]['height']
       );
    }

    // Draw particles.
    buffer.fillStyle = '#fff';
    for(var particle in particles){
        buffer.fillRect(
          particles[particle]['x'],
          particles[particle]['y'],
          5,
          5
        );
    };

    buffer.restore();

    // Setup text display.
    buffer.fillStyle = '#fff';
    buffer.font = '23pt sans-serif';

    // Draw camera position.
    buffer.fillText(
      camera_x + 'x ' + camera_y + 'y',
      5,
      25
    );

    // Draw number of particles.
    buffer.fillText(
      particles.length,
      5,
      50
    );

    canvas.clearRect(
      0,
      0,
      width,
      height
    );
    canvas.drawImage(
      document.getElementById('buffer'),
      0,
      0
    );

    animationFrame = window.requestAnimationFrame(draw);
}

function logic(){
    if(key_left){
        camera_x -= 5;
    }

    if(key_right){
        camera_x += 5;
    }

    if(key_down){
        camera_y += 5;
    }

    if(key_up){
        camera_y -= 5;
    }

    frame_counter += 1;
    if(frame_counter > 99){
        frame_counter = 0;
    }

    for(var particle in particles){
        particles[particle]['x'] += particles[particle]['dx'];
        particles[particle]['y'] += particles[particle]['dy'];

        if(Math.abs(particles[particle]['x']) > 999
          || Math.abs(particles[particle]['y']) > 999){
            particles.splice(
              particle,
              1
            );
        }
    }

    for(var gate in gates){
        if(gates[gate]['interval'] > 0
          && frame_counter % gates[gate]['interval'] == 0){
            gates[gate]['event']();
        }

        for(var particle in particles){
            if(particles[particle]['x'] > gates[gate]['x']
              && particles[particle]['x'] < gates[gate]['x'] + gates[gate]['width']
              && particles[particle]['y'] > gates[gate]['y']
              && particles[particle]['y'] < gates[gate]['y'] + gates[gate]['height']){
                particles[particle]['dx'] = gates[gate]['dx'];
                particles[particle]['dy'] = gates[gate]['dy'];
            }
        }
    }
}

function play_audio(id){
    if(settings['audio-volume'] <= 0){
        return;
    }

    document.getElementById(id).currentTime = 0;
    document.getElementById(id).play();
}

function reset(){
    if(!window.confirm('Reset settings?')){
        return;
    }

    document.getElementById('audio-volume').value = 1;
    document.getElementById('movement-keys').value = 'WASD';
    document.getElementById('max-particles').value = 1000;
    document.getElementById('ms-per-frame').value = 25;
    document.getElementById('restart-key').value = 'H';

    save();
}

function resize(){
    if(mode <= 0){
        return;
    }

    height = window.innerHeight;
    document.getElementById('buffer').height = height;
    document.getElementById('canvas').height = height;
    y = height / 2;

    width = window.innerWidth;
    document.getElementById('buffer').width = width;
    document.getElementById('canvas').width = width;
    x = width / 2;
}

// Save settings into window.localStorage if they differ from default.
function save(){
    var ids = {
      'audio-volume': 1,
      'max-particles': 1000,
      'ms-per-frame': 25,
    };
    for(var id in ids){
        if(isNaN(document.getElementById(id).value)
          || document.getElementById(id).value == ids[id]){
            window.localStorage.removeItem('ParticleRun-2D.htm-' + id);
            settings[id] = ids[id];

        }else{
            settings[id] = parseFloat(document.getElementById(id).value);
            window.localStorage.setItem(
              'ParticleRun-2D.htm-' + id,
              settings[id]
            );
        }
    }

    ids = {
      'movement-keys': 'WASD',
      'restart-key': 'H',
    };
    for(id in ids){
        if(document.getElementById(id).value === ids[id]){
            window.localStorage.removeItem('ParticleRun-2D.htm-' + id);
            settings[id] = ids[id];

        }else{
            settings[id] = document.getElementById(id).value;
            window.localStorage.setItem(
              'ParticleRun-2D.htm-' + id,
              settings[id]
            );
        }
    }
}

function setmode(newmode, newgame){
    window.cancelAnimationFrame(animationFrame);
    window.clearInterval(interval);

    gates = [];
    particles = [];

    mode = newmode;

    // New game mode.
    if(mode > 0){
        // If it's a newgame from the main menu, save settings.
        if(newgame){
            save();
        }

        // Reset.
        camera_x = 0;
        camera_y = 0;
        frame_counter = 0;
        key_left = false;
        key_right = false;

        // If it's a newgame from the main menu, setup canvas and buffers.
        if(newgame){
            document.getElementById('page').innerHTML = '<canvas id=canvas></canvas><canvas id=buffer style=display:none></canvas>';

            buffer = document.getElementById('buffer').getContext('2d');
            canvas = document.getElementById('canvas').getContext('2d');

            resize();
        }

        load_level();

        animationFrame = window.requestAnimationFrame(draw);
        interval = window.setInterval(
          'logic()',
          settings['ms-per-frame']
        );

        return;
    }

    // Main menu mode.
    buffer = 0;
    canvas = 0;

    document.getElementById('page').innerHTML = '

New Run

<input disabled style=border:0 value=ESC>Main Menu
<input id=movement-keys maxlength=4 value='
      + settings['movement-keys'] + '>Camera ↑←↓→
<input id=restart-key maxlength=1 value='
      + settings['restart-key'] + '>Restart

<input id=audio-volume max=1 min=0 step=.01 type=range value='
      + settings['audio-volume'] + '>Audio
<input id=max-particles value='
      + settings['max-particles'] + '>Max Particles
<input id=ms-per-frame value='
      + settings['ms-per-frame'] + '>ms/Frame
Reset Settings

';
}

var animationFrame = 0;
var buffer = 0;
var camera_x = 0;
var camera_y = 0;
var canvas = 0;
var gates = [];
var height = 0;
var interval = 0;
var key_down = false;
var key_left = false;
var key_right = false;
var key_up = false;
var mode = 0;
var particles = [];
var settings = {
  'audio-volume': parseFloat(window.localStorage.getItem('ParticleRun-2D.htm-audio-volume')) || 1,
  'movement-keys': window.localStorage.getItem('ParticleRun-2D.htm-movement-keys') || 'WASD',
  'max-particles': parseInt(window.localStorage.getItem('ParticleRun-2D.htm-max-particles')) || 1000,
  'ms-per-frame': parseInt(window.localStorage.getItem('ParticleRun-2D.htm-ms-per-frame')) || 25,
  'restart-key': window.localStorage.getItem('ParticleRun-2D.htm-restart-key') || 'H',
};
var x = 0;
var width = 0;
var y = 0;

window.onkeydown = function(e){
    if(mode <= 0){
        return;
    }

    var key = e.keyCode || e.which;

    // ESC: return to main menu.
    if(key === 27){
        setmode(
          0,
          true
        );
        return;
    }

    key = String.fromCharCode(key);

    if(key === settings['movement-keys'][0]){
        key_up = true;

    }else if(key === settings['movement-keys'][1]){
        key_left = true;

    }else if(key === settings['movement-keys'][2]){
        key_down = true;

    }else if(key === settings['movement-keys'][3]){
        key_right = true;

    }else if(key === settings['restart-key']){
        setmode(
          mode,
          false
        );
    }
};

window.onkeyup = function(e){
    var key = String.fromCharCode(e.keyCode || e.which);

    if(key === settings['movement-keys'][0]){
        key_up = false;

    }else if(key === settings['movement-keys'][1]){
        key_left = false;

    }else if(key === settings['movement-keys'][2]){
        key_down = false;

    }else if(key === settings['movement-keys'][3]){
        key_right = false;
    }
};

window.onload = function(e){
    setmode(
      0,
      true
    );
};

window.onresize = resize;
<|endoftext|>


<commit_before>

function PitchStairCase() {

    this.Stairs = [];

    this.makeStairs = function (start) {

        if(start === -1) {
            start = 0;
        } else {
            for (var j = start; j < this.Stairs.length-1; j++) {
                console.log(j);
                console.log(docById("playStairTable" + j));
                 docById("playStairTable" + j).remove();
                docById("stairTable"+ j).remove();
            }
        }
        var thisStair = this;
        var iconSize = Math.floor(this.cellScale * 24);

        var StairDiv = docById('pitchstaircase');
        var StairDivPosition = StairDiv.getBoundingClientRect();

        var playPitchDiv = docById('playPitch');
        var playPitchDivPosition = playPitchDiv.getBoundingClientRect();

        for (var i = start; i < thisStair.Stairs.length; i++) {

            var playTable = document.createElement('TABLE');
            playTable.setAttribute('id', 'playStairTable' + i);
            playTable.style.textAlign = 'center';
            playTable.style.borderCollapse = 'collapse';
            playTable.cellSpacing = 0;
            playTable.cellPadding = 0;
            playPitchDiv.appendChild(playTable);

            var header = playTable.createTHead();
            var playrow = header.insertRow(-1);
            playrow.style.left = Math.floor(playPitchDivPosition.left) + 'px';
            playrow.style.top = Math.floor(MATRIXBUTTONHEIGHT * this.cellScale) + 'px';
            playrow.setAttribute('id', "playStair" + i);

            var playcell = playrow.insertCell(-1);
            playcell.style.width = Math.floor(MATRIXBUTTONHEIGHT * this.cellScale) + 'px';
            playcell.innerHTML = '    ';
            playcell.style.minWidth = playcell.style.width;
            playcell.style.maxWidth = playcell.style.width;
            playcell.style.height = Math.floor(RHYTHMRULERHEIGHT * this.cellScale) + 'px';
            playcell.style.backgroundColor = MATRIXBUTTONCOLOR;

            playcell.onclick = function() {
                console.log(playcell.parentNode.id);
                thisStair.PlayOne(playcell.parentNode.id[9]);
            };

            var StairTable = document.createElement('TABLE');
            StairTable.setAttribute('id', 'stairTable' + i);
            StairTable.style.textAlign = 'center';
            StairTable.style.borderCollapse = 'collapse';
            StairTable.cellSpacing = 0;
            StairTable.cellPadding = 0;
            StairDiv.appendChild(StairTable);

            var header = StairTable.createTHead();
            var row = header.insertRow(-1);
            row.style.left = Math.floor(StairDivPosition.left) + 'px';
            row.style.top = Math.floor(MATRIXBUTTONHEIGHT * this.cellScale) + 'px';
            row.setAttribute('id','stair' + i)

            var solfege = this.Stairs[i][0];
            var octave = this.Stairs[i][1];

            var solfegetonote = this.logo.getNote(solfege, octave, 0, this.logo.keySignature[this.logoturtle])[0];

            var cell = row.insertCell(-1);
            cell.style.width = (StairDivPosition.width)* parseFloat(this.Stairs[0][2]/this.Stairs[i][2]) * this.cellScale/2 + 'px';
            cell.innerHTML = thisStair.Stairs[i][0] + thisStair.Stairs[i][1] + " "  + Math.floor(thisStair.Stairs[i][2]);
            cell.style.minWidth = cell.style.width;
            cell.style.maxWidth = cell.style.width;
            cell.style.height = Math.floor(RHYTHMRULERHEIGHT * this.cellScale) + 'px';
            cell.style.lineHeight = 60 + '%';
            cell.style.backgroundColor = MATRIXNOTECELLCOLOR;

            cell.addEventListener('click', function(event) {
                thisStair.dissectStair(event);
            });
        }
    }

    this.dissectStair = function(event) {
        var that = this;

        var inputNum = prompt(_('Divide By:'), "3 2");

      //  if(!isInt(inputNum)) {
     //       alert(_('Please Input a Integer'));
     //       inputNum = prompt(_('Divide By:'), 2);
     //   }

        var arr = inputNum.split(" ");
        console.log(arr);

        inputNum = parseFloat(arr[1]/arr[0]);

        if(inputNum === null) {
            return ;
        }
        var oldcell = event.target;
        var frequency = that.Stairs[oldcell.parentNode.id[5]][2];
        var obj = frequencyToPitch(parseFloat(frequency)/inputNum);

        var flag = 0;

        for (var i=0 ; i < this.Stairs.length; i++) {

            if (this.Stairs[i][2] < parseFloat(frequency)/inputNum) {
                this.Stairs.splice(i, 0, [obj[0], obj[1], parseFloat(frequency)/inputNum]);
                flag = 1;
                break;
            }
        }
        if(flag === 0) {
            this.Stairs.push([obj[0], obj[1], parseFloat(frequency)/inputNum]);
        }
        this.makeStairs(i);
    };

    this.PlayOne = function(stairno) {
        var pitchnotes = [];
        console.log(this.Stairs[stairno]);
        var note = this.Stairs[stairno][0] + this.Stairs[stairno][1];
        pitchnotes.push(note.replace(/♭/g, 'b').replace(/♯/g, '#'));
        console.log(pitchnotes);
        this.logo.synth.trigger(pitchnotes, 0.125, 'poly');
    }

    this.playAll = function() {
        var pitchnotes = [];
        var note = this.Stairs[this.Stairs.length-1][0] + this.Stairs[this.Stairs.length-1][1];
        pitchnotes.push(note.replace(/♭/g, 'b').replace(/♯/g, '#'));
        var laststair = this.Stairs.length - 1;
        console.log("Playing stair " + laststair);
        var row = docById('stair' + laststair);
        console.log(row.cells[0]);
        row.cells[0].style.backgroundColor = MATRIXBUTTONCOLOR;
        console.log(row.cells[0]);
        this.logo.synth.trigger(pitchnotes, 1, 'poly');
        this.playAllStairs(this.Stairs.length-2);
    }

    this.playAllStairs = function(stairno) {
        var that = this;
        setTimeout(function () {
            if(stairno > -1) {
                var pitchnotes = [];
                console.log("Playing stair " + stairno);
                var note = that.Stairs[stairno][0] + that.Stairs[stairno][1];
                pitchnotes.push(note.replace(/♭/g, 'b').replace(/♯/g, '#'));
                var row = docById('stair' + stairno);
                console.log(row.cells[0]);
                row.cells[0].style.backgroundColor = MATRIXBUTTONCOLOR;
                console.log(row.cells[0]);
                that.logo.synth.trigger(pitchnotes, 1, 'poly');
                that.playAllStairs(stairno-1);
            } else {
                for(var i = 0; i < that.Stairs.length; i++) {
                    var row = docById('stair' + i);
                    row.cells[0].style.backgroundColor = MATRIXNOTECELLCOLOR;
                }
            }
        }, 1000 + that.logo.turtleDelay);
    }

    this.save = function (stairno) {
        var that = this;
        for (var name in this.logo.blocks.palettes.dict) {
            this.logo.blocks.palettes.dict[name].hideMenu(true);
        }

        this.logo.refreshCanvas();

        setTimeout(function() {
       //     var stair = docById('stair' + stairno);
            var noteobj = frequencyToPitch(that.Stairs[stairno][2]);
            console.log(noteobj);
            var note  = that.Stairs[stairno][0];
            var octave = that.Stairs[stairno][1];

            var newStack = [[0, ['action', {'collapsed': false}], 100, 100, [null, 1, 2, null]], [1, ['text', {'value': 'stair'}], 0, 0, [0]]];
            var endOfStackIdx = 0;
            var previousBlock = 0;

            var pitchblockidx = newStack.length;
            var noteidx = pitchblockidx + 1;
            var octaveidx = pitchblockidx + 2;
            var hiddenidx = pitchblockidx + 3;

            newStack.push([pitchblockidx, 'pitch', 0, 0, [previousBlock, noteidx, octaveidx, hiddenidx]]);
            newStack.push([noteidx, ['text', {'value': note}], 0, 0, [pitchblockidx]]);
            newStack.push([octaveidx, ['number', {'value': octave}], 0, 0, [pitchblockidx]]);
            newStack.push([hiddenidx, 'hidden', 0, 0, [pitchblockidx, null]]);

            var previousBlock = hiddenidx;

            that.logo.blocks.loadNewBlocks(newStack);
            if (stairno > that.Stairs.length - 2) {
                return;
            } else {
                that.save(stairno+1);
            }
        }, 500);
    }

	this.init = function(logo) {

        console.log(this.Stairs);

		console.log("init PitchStairCase");
		this.logo = logo;

		docById('pitchstaircase').style.display = 'inline';
        console.log('setting PitchStairCase visible');
        docById('pitchstaircase').style.visibility = 'visible';
        docById('pitchstaircase').style.border = 2;

        docById('playPitch').style.display = 'inline';
        docById('playPitch').style.visibility = 'visible';
        docById('playPitch').style.border = 2;

        var w = window.innerWidth;
        this.cellScale = w / 1200;
        docById('pitchstaircase').style.width = Math.floor(w / 2) + 'px';
        docById('pitchstaircase').style.overflowX = 'auto';

    		var thisStair = this;

        var tables = document.getElementsByTagName('TABLE');

      //  console.log(tables);

        var noofTables = tables.length

        for (var i = 0; i < noofTables; i++) {
                tables[0].parentNode.removeChild(tables[0]);
        }

        var iconSize = Math.floor(this.cellScale * 24);

        var x = document.createElement('TABLE');
        x.setAttribute('id', 'buttonTable');
        x.style.textAlign = 'center';
        x.style.borderCollapse = 'collapse';
        x.cellSpacing = 0;
        x.cellPadding = 0;

        var StairDiv = docById('pitchstaircase');
        StairDiv.style.paddingTop = 0 + 'px';
        StairDiv.style.paddingLeft = 0 + 'px';
        StairDiv.appendChild(x);
        StairDivPosition = StairDiv.getBoundingClientRect();

        var x = document.createElement('TABLE');
        x.setAttribute('id', 'playAllStairTable');
        x.style.textAlign = 'center';
        x.style.borderCollapse = 'collapse';
        x.cellSpacing = 0;
        x.cellPadding = 0;

        var playPitchDiv = docById('playPitch');
        playPitchDiv.style.paddingTop = 0 + 'px';
        playPitchDiv.style.paddingLeft = 0 + 'px';
        playPitchDiv.appendChild(x);
        playPitchDivPosition = playPitchDiv.getBoundingClientRect();

        var table = docById('playAllStairTable');
        var header = table.createTHead();
        var row = header.insertRow(-1);
        row.style.left = Math.floor(playPitchDivPosition.left) + 'px';
        row.style.top = Math.floor(playPitchDivPosition.top) + 'px';
        row.setAttribute('id', 'playAllStair');

        var cell = row.insertCell(-1);
        cell.innerHTML = '    ';
        cell.style.width = Math.floor(MATRIXBUTTONHEIGHT * this.cellScale) + 'px';
        cell.style.minWidth = cell.style.width;
        cell.style.maxWidth = cell.style.width;
        cell.style.height = Math.floor(MATRIXBUTTONHEIGHT * this.cellScale) + 'px';
        cell.style.backgroundColor = MATRIXBUTTONCOLOR;
        cell.onclick = function() {
            thisStair.playAll();
        }

        var table = docById('buttonTable');
        var header = table.createTHead();
        var row = header.insertRow(0);
        row.style.left = Math.floor(StairDivPosition.left) + 'px';
        row.style.top = Math.floor(StairDivPosition.top) + 'px';

        var cell = row.insertCell(-1);
        cell.innerHTML = '    ';
        cell.style.width = Math.floor(MATRIXBUTTONHEIGHT * this.cellScale) + 'px';
        cell.style.minWidth = cell.style.width;
        cell.style.maxWidth = cell.style.width;
        cell.style.height = Math.floor(MATRIXBUTTONHEIGHT * this.cellScale) + 'px';
        cell.style.backgroundColor = MATRIXBUTTONCOLOR;

        cell.onclick=function() {
            thisStair.save(0);
        };

        cell.onmouseover=function() {
            this.style.backgroundColor = MATRIXBUTTONCOLORHOVER;
        };

        cell.onmouseout=function() {
            this.style.backgroundColor = MATRIXBUTTONCOLOR;
        };

        var cell = row.insertCell(1);
        cell.innerHTML = '    ';
        cell.style.width = Math.floor(MATRIXBUTTONHEIGHT * this.cellScale) + 'px';
        cell.style.minWidth = cell.style.width;
        cell.style.maxWidth = cell.style.width;
        cell.style.height = Math.floor(MATRIXBUTTONHEIGHT * this.cellScale) + 'px';
        cell.style.backgroundColor = MATRIXBUTTONCOLOR;

        cell.onclick=function() {
            docById('pitchstaircase').style.visibility = 'hidden';
            docById('playPitch').style.visibility = 'hidden';
        };

        cell.onmouseover=function() {
            this.style.backgroundColor = MATRIXBUTTONCOLORHOVER;
        };

        cell.onmouseout=function() {
            this.style.backgroundColor = MATRIXBUTTONCOLOR;
        };

        this.makeStairs(-1);
	};

};<commit_msg>play all feature revised<commit_after>

function PitchStairCase() {

    this.Stairs = [];

    this.makeStairs = function (start) {

        if(start === -1) {
            start = 0;
        } else {
            for (var j = start; j < this.Stairs.length-1; j++) {
                console.log(j);
                console.log(docById("playStairTable" + j));
                docById("playStairTable" + j).remove();
                docById("stairTable"+ j).remove();
            }
        }
        var thisStair = this;
        var iconSize = Math.floor(this.cellScale * 24);

        var StairDiv = docById('pitchstaircase');
        var StairDivPosition = StairDiv.getBoundingClientRect();

        var playPitchDiv = docById('playPitch');
        var playPitchDivPosition = playPitchDiv.getBoundingClientRect();

        for (var i = start; i < thisStair.Stairs.length; i++) {

            var playTable = document.createElement('TABLE');
            playTable.setAttribute('id', 'playStairTable' + i);
            playTable.style.textAlign = 'center';
            playTable.style.borderCollapse = 'collapse';
            playTable.cellSpacing = 0;
            playTable.cellPadding = 0;
            playPitchDiv.appendChild(playTable);

            var header = playTable.createTHead();
            var playrow = header.insertRow(-1);
            playrow.style.left = Math.floor(playPitchDivPosition.left) + 'px';
            playrow.style.top = Math.floor(MATRIXBUTTONHEIGHT * this.cellScale) + 'px';
            playrow.setAttribute('id', "playStair" + i);

            var playcell = playrow.insertCell(-1);
            playcell.style.width = Math.floor(MATRIXBUTTONHEIGHT * this.cellScale) + 'px';
            playcell.innerHTML = '    ';
            playcell.style.minWidth = playcell.style.width;
            playcell.style.maxWidth = playcell.style.width;
            playcell.style.height = Math.floor(RHYTHMRULERHEIGHT * this.cellScale) + 'px';
            playcell.style.backgroundColor = MATRIXBUTTONCOLOR;

            playcell.onclick = function() {
                console.log(playcell.parentNode.id);
                thisStair.PlayOne(event);
            };

            var StairTable = document.createElement('TABLE');
            StairTable.setAttribute('id', 'stairTable' + i);
            StairTable.style.textAlign = 'center';
            StairTable.style.borderCollapse = 'collapse';
            StairTable.cellSpacing = 0;
            StairTable.cellPadding = 0;
            StairDiv.appendChild(StairTable);

            var header = StairTable.createTHead();
            var row = header.insertRow(-1);
            row.style.left = Math.floor(StairDivPosition.left) + 'px';
            row.style.top = Math.floor(MATRIXBUTTONHEIGHT * this.cellScale) + 'px';
            row.setAttribute('id','stair' + i)

            var solfege = this.Stairs[i][0];
            var octave = this.Stairs[i][1];

            var solfegetonote = this.logo.getNote(solfege, octave, 0, this.logo.keySignature[this.logoturtle])[0];

            var cell = row.insertCell(-1);
            cell.style.width = (StairDivPosition.width)* parseFloat(this.Stairs[0][2]/this.Stairs[i][2]) * this.cellScale/2 + 'px';
            cell.innerHTML = thisStair.Stairs[i][0] + thisStair.Stairs[i][1] + " "  + Math.floor(thisStair.Stairs[i][2]);
            cell.style.minWidth = cell.style.width;
            cell.style.maxWidth = cell.style.width;
            cell.style.height = Math.floor(RHYTHMRULERHEIGHT * this.cellScale) + 'px';
            cell.style.lineHeight = 60 + '%';
            cell.style.backgroundColor = MATRIXNOTECELLCOLOR;

            cell.addEventListener('click', function(event) {
                thisStair.dissectStair(event);
            });
        }
    }

    this.dissectStair = function(event) {
        var that = this;

        var inputNum = prompt(_('Divide By:'), "3 2");

      //  if(!isInt(inputNum)) {
     //       alert(_('Please Input a Integer'));
     //       inputNum = prompt(_('Divide By:'), 2);
     //   }

        var arr = inputNum.split(" ");
        console.log(arr);

        inputNum = parseFloat(arr[1]/arr[0]);

        if(inputNum === null) {
            return ;
        }
        var oldcell = event.target;
        var frequency = that.Stairs[oldcell.parentNode.id[5]][2];
        var obj = frequencyToPitch(parseFloat(frequency)/inputNum);

        var flag = 0;

        for (var i=0 ; i < this.Stairs.length; i++) {

            if (this.Stairs[i][2] < parseFloat(frequency)/inputNum) {
                this.Stairs.splice(i, 0, [obj[0], obj[1], parseFloat(frequency)/inputNum]);
                flag = 1;
                break;
            }
        }
        if(flag === 0) {
            this.Stairs.push([obj[0], obj[1], parseFloat(frequency)/inputNum]);
        }
        this.makeStairs(i);
    };

    this.PlayOne = function(event) {
        var that = this;
        var cell = event.target;
        var stairno = cell.parentNode.id[9];
        var pitchnotes = [];
        console.log(this.Stairs[stairno]);
        var note = this.Stairs[stairno][0] + this.Stairs[stairno][1];
        pitchnotes.push(note.replace(/♭/g, 'b').replace(/♯/g, '#'));
        console.log(pitchnotes);
        console.log(stairno);
        var stair = docById('stair' + stairno);
        stair.cells[0].style.backgroundColor = MATRIXBUTTONCOLOR;
        this.logo.synth.trigger(pitchnotes, 1, 'poly');
        setTimeout(function () {
                stair.cells[0].style.backgroundColor = MATRIXNOTECELLCOLOR;
        }, 1000)
    }

    this.playAll = function() {
        var that = this;
        var pitchnotes = [];
        for (var i=0; i < this.Stairs.length; i++) {
            var note = this.Stairs[i][0] + this.Stairs[i][1];
            pitchnotes.push(note.replace(/♭/g, 'b').replace(/♯/g, '#'));

            var row = docById('stair' + i);
            row.cells[0].style.backgroundColor = MATRIXBUTTONCOLOR;
            this.logo.synth.trigger(pitchnotes, 1, 'poly');
        }
        setTimeout(function () {
            for (var i = 0; i < that.Stairs.length; i++) {
                var stair = docById('stair' + i);
                stair.cells[0].style.backgroundColor = MATRIXNOTECELLCOLOR;
            }
        }, 1000)

    }

    this.save = function (stairno) {
        var that = this;
        for (var name in this.logo.blocks.palettes.dict) {
            this.logo.blocks.palettes.dict[name].hideMenu(true);
        }

        this.logo.refreshCanvas();

        setTimeout(function() {
       //     var stair = docById('stair' + stairno);
            var noteobj = frequencyToPitch(that.Stairs[stairno][2]);
            console.log(noteobj);
            var note  = that.Stairs[stairno][0];
            var octave = that.Stairs[stairno][1];

            var newStack = [[0, ['action', {'collapsed': false}], 100, 100, [null, 1, 2, null]], [1, ['text', {'value': 'stair'}], 0, 0, [0]]];
            var endOfStackIdx = 0;
            var previousBlock = 0;

            var pitchblockidx = newStack.length;
            var noteidx = pitchblockidx + 1;
            var octaveidx = pitchblockidx + 2;
            var hiddenidx = pitchblockidx + 3;

            newStack.push([pitchblockidx, 'pitch', 0, 0, [previousBlock, noteidx, octaveidx, hiddenidx]]);
            newStack.push([noteidx, ['text', {'value': note}], 0, 0, [pitchblockidx]]);
            newStack.push([octaveidx, ['number', {'value': octave}], 0, 0, [pitchblockidx]]);
            newStack.push([hiddenidx, 'hidden', 0, 0, [pitchblockidx, null]]);

            var previousBlock = hiddenidx;

            that.logo.blocks.loadNewBlocks(newStack);
            if (stairno > that.Stairs.length - 2) {
                return;
            } else {
                that.save(stairno+1);
            }
        }, 500);
    }

	this.init = function(logo) {

        console.log(this.Stairs);

		console.log("init PitchStairCase");
		this.logo = logo;

		docById('pitchstaircase').style.display = 'inline';
        console.log('setting PitchStairCase visible');
        docById('pitchstaircase').style.visibility = 'visible';
        docById('pitchstaircase').style.border = 2;

        docById('playPitch').style.display = 'inline';
        docById('playPitch').style.visibility = 'visible';
        docById('playPitch').style.border = 2;

        var w = window.innerWidth;
        this.cellScale = w / 1200;
        docById('pitchstaircase').style.width = Math.floor(w / 2) + 'px';
        docById('pitchstaircase').style.overflowX = 'auto';

    		var thisStair = this;

        var tables = document.getElementsByTagName('TABLE');

      //  console.log(tables);

        var noofTables = tables.length

        for (var i = 0; i < noofTables; i++) {
                tables[0].parentNode.removeChild(tables[0]);
        }

        var iconSize = Math.floor(this.cellScale * 24);

        var x = document.createElement('TABLE');
        x.setAttribute('id', 'buttonTable');
        x.style.textAlign = 'center';
        x.style.borderCollapse = 'collapse';
        x.cellSpacing = 0;
        x.cellPadding = 0;

        var StairDiv = docById('pitchstaircase');
        StairDiv.style.paddingTop = 0 + 'px';
        StairDiv.style.paddingLeft = 0 + 'px';
        StairDiv.appendChild(x);
        StairDivPosition = StairDiv.getBoundingClientRect();

        var x = document.createElement('TABLE');
        x.setAttribute('id', 'playAllStairTable');
        x.style.textAlign = 'center';
        x.style.borderCollapse = 'collapse';
        x.cellSpacing = 0;
        x.cellPadding = 0;

        var playPitchDiv = docById('playPitch');
        playPitchDiv.style.paddingTop = 0 + 'px';
        playPitchDiv.style.paddingLeft = 0 + 'px';
        playPitchDiv.appendChild(x);
        playPitchDivPosition = playPitchDiv.getBoundingClientRect();

        var table = docById('playAllStairTable');
        var header = table.createTHead();
        var row = header.insertRow(-1);
        row.style.left = Math.floor(playPitchDivPosition.left) + 'px';
        row.style.top = Math.floor(playPitchDivPosition.top) + 'px';
        row.setAttribute('id', 'playAllStair');

        var cell = row.insertCell(-1);
        cell.innerHTML = '    ';
        cell.style.width = Math.floor(MATRIXBUTTONHEIGHT * this.cellScale) + 'px';
        cell.style.minWidth = cell.style.width;
        cell.style.maxWidth = cell.style.width;
        cell.style.height = Math.floor(MATRIXBUTTONHEIGHT * this.cellScale) + 'px';
        cell.style.backgroundColor = MATRIXBUTTONCOLOR;
        cell.onclick = function() {
            thisStair.playAll();
        }

        var table = docById('buttonTable');
        var header = table.createTHead();
        var row = header.insertRow(0);
        row.style.left = Math.floor(StairDivPosition.left) + 'px';
        row.style.top = Math.floor(StairDivPosition.top) + 'px';

        var cell = row.insertCell(-1);
        cell.innerHTML = '    ';
        cell.style.width = Math.floor(MATRIXBUTTONHEIGHT * this.cellScale) + 'px';
        cell.style.minWidth = cell.style.width;
        cell.style.maxWidth = cell.style.width;
        cell.style.height = Math.floor(MATRIXBUTTONHEIGHT * this.cellScale) + 'px';
        cell.style.backgroundColor = MATRIXBUTTONCOLOR;

        cell.onclick=function() {
            thisStair.save(0);
        };

        cell.onmouseover=function() {
            this.style.backgroundColor = MATRIXBUTTONCOLORHOVER;
        };

        cell.onmouseout=function() {
            this.style.backgroundColor = MATRIXBUTTONCOLOR;
        };

        var cell = row.insertCell(1);
        cell.innerHTML = '    ';
        cell.style.width = Math.floor(MATRIXBUTTONHEIGHT * this.cellScale) + 'px';
        cell.style.minWidth = cell.style.width;
        cell.style.maxWidth = cell.style.width;
        cell.style.height = Math.floor(MATRIXBUTTONHEIGHT * this.cellScale) + 'px';
        cell.style.backgroundColor = MATRIXBUTTONCOLOR;

        cell.onclick=function() {
            docById('pitchstaircase').style.visibility = 'hidden';
            docById('playPitch').style.visibility = 'hidden';
        };

        cell.onmouseover=function() {
            this.style.backgroundColor = MATRIXBUTTONCOLORHOVER;
        };

        cell.onmouseout=function() {
            this.style.backgroundColor = MATRIXBUTTONCOLOR;
        };

        this.makeStairs(-1);
	};

};<|endoftext|>


<commit_before>function decode(data) {
	return JSON.parse(data);
}

function encode(data) {
	return JSON.stringify(data);
}

var files = [
	// {
	// 	localLocation = NULL, // location in the local filesystem
	// 	originalId = NULL, // original resource ID
	// 	uploadedId = NULL, // server-assigned ID
	// 	content = NULL, //decoded JSON content
	// 	uploaded = NULL, // 'true' for an uploaded resource
	// 	jsId = NULL, // ID that's assigned for use in main.js
	// }
];

// keeps track of the resource's original ID and uploaded one
var idMap = [
	// ["Patient/digitalhealth-f001"] = "Patient/spark2494"
];

function isObject(obj) {
  return obj === Object(obj);
}

var serverUrl;

function findReferences(data, key, f) {
	$.each(data, function(k, v) {
		if (k === key) {
			f(data, k, v);
		}

		if (isObject(v)) {
			findReferences(v, key, f);
		}
	});
}

function getResourceType(fileContent) {
	return fileContent.resourceType;
}

// pull out the original ID of the resource and delete it from the resource as well
function getResourceId (fileContent) {
	var id = fileContent.id;
	delete fileContent.id;

	return id;
}

function upload(file) {
	var fileLocation = file.localLocation;
	var resourceType = file.type;
	var jqxhr = $.ajax({
		url: serverUrl + '/' + resourceType,
		method: "POST",
		type: "POST",
		contentType: "application/json+fhir",
		data: encode(file.content),
		headers: {
        	Accept: "application/json+fhir; charset=utf-8",
        	Prefer: "return=representation"
    	}
	}).done(function() {
		uploadDone(decode(jqxhr.responseText));
	}).fail(function(err) {
		console.log("upload failed: " + err.responseText);
		failedUpload();
	});
}

function uploadDone(result) {
	var resultType = result.resourceType;
	var file = getCurrentFile();
	var fileName = file.localLocation;

	if (resultType === "OperationOutcome") {
		console.log(fileName + ": " + result.text.div);
		return;
	}

	var id = result.id;
	file.uploadedId = id;
	file.uploaded = true;

	idMap[file.type + "/" + file.originalId] = file.type + "/" + file.uploadedId;
	console.log(fileName + ": " + serverUrl + "/" + file.type + "/" + id);

	uploadedResource(file.jsId, file.uploadedId, file.type);

	var uploadingNext = doUpload();
	if (!uploadingNext) {
		console.log("All resources uploaded");
		completeUpload();
	}
}

function loadFile(file) {
	var fileName = file.localLocation;
	var jqxhr = $.ajax(fileName);
	jqxhr.done(function() {
		file.content = decode(jqxhr.responseText);
		file.content = updateResourceReferences(file.content);
		file.originalId = getResourceId(file.content);
		file.type = getResourceType(file.content);

		upload(file);
	});
}

function updateResourceReferences(content) {
	// replace references in structured content of resource
	findReferences(content, "reference", function(data, key, value) {
			if (idMap[value]) {
				data[key] = idMap[value];
			}
		}
	);

	// replace references in the narrative
	if (content.text && content.text.div) {
		var narrative = content.text;

		for (var oldId in idMap) {
			var newId = idMap[oldId];
			// not escaping characters here yet - not sure why was it needed before
			narrative.div = narrative.div.replace(oldId, newId);
		}
	}

	return content;
}

function getCurrentFile() {
	for (var file of files) {
		if (!file.uploaded) {
			return file;
		}
	}
}

function uploadAll() {
	serverUrl = uploadServer;
	files = [];

	for (var resourceData of uploadResources) {
		files.push({localLocation: resourceData[1], jsId: resourceData[0]});
	}

	doUpload();
}

function doUpload() {
	for (var file of files) {
		if (!file.uploaded) {
			// load this resource's data in
			var fileName = file.localLocation;
			console.log("Uploading " + fileName);

			file.content = loadFile(file);
			return true;
		}

	}

	return false;
}<commit_msg>Replaced an EC6 feature<commit_after>function decode(data) {
	return JSON.parse(data);
}

function encode(data) {
	return JSON.stringify(data);
}

var files = [
	// {
	// 	localLocation = NULL, // location in the local filesystem
	// 	originalId = NULL, // original resource ID
	// 	uploadedId = NULL, // server-assigned ID
	// 	content = NULL, //decoded JSON content
	// 	uploaded = NULL, // 'true' for an uploaded resource
	// 	jsId = NULL, // ID that's assigned for use in main.js
	// }
];

// keeps track of the resource's original ID and uploaded one
var idMap = [
	// ["Patient/digitalhealth-f001"] = "Patient/spark2494"
];

function isObject(obj) {
  return obj === Object(obj);
}

var serverUrl;

function findReferences(data, key, f) {
	$.each(data, function(k, v) {
		if (k === key) {
			f(data, k, v);
		}

		if (isObject(v)) {
			findReferences(v, key, f);
		}
	});
}

function getResourceType(fileContent) {
	return fileContent.resourceType;
}

// pull out the original ID of the resource and delete it from the resource as well
function getResourceId (fileContent) {
	var id = fileContent.id;
	delete fileContent.id;

	return id;
}

function upload(file) {
	var fileLocation = file.localLocation;
	var resourceType = file.type;
	var jqxhr = $.ajax({
		url: serverUrl + '/' + resourceType,
		method: "POST",
		type: "POST",
		contentType: "application/json+fhir",
		data: encode(file.content),
		headers: {
        	Accept: "application/json+fhir; charset=utf-8",
        	Prefer: "return=representation"
    	}
	}).done(function() {
		uploadDone(decode(jqxhr.responseText));
	}).fail(function(err) {
		console.log("upload failed: " + err.responseText);
		failedUpload();
	});
}

function uploadDone(result) {
	var resultType = result.resourceType;
	var file = getCurrentFile();
	var fileName = file.localLocation;

	if (resultType === "OperationOutcome") {
		console.log(fileName + ": " + result.text.div);
		return;
	}

	var id = result.id;
	file.uploadedId = id;
	file.uploaded = true;

	idMap[file.type + "/" + file.originalId] = file.type + "/" + file.uploadedId;
	console.log(fileName + ": " + serverUrl + "/" + file.type + "/" + id);

	uploadedResource(file.jsId, file.uploadedId, file.type);

	var uploadingNext = doUpload();
	if (!uploadingNext) {
		console.log("All resources uploaded");
		completeUpload();
	}
}

function loadFile(file) {
	var fileName = file.localLocation;
	var jqxhr = $.ajax(fileName);
	jqxhr.done(function() {
		file.content = decode(jqxhr.responseText);
		file.content = updateResourceReferences(file.content);
		file.originalId = getResourceId(file.content);
		file.type = getResourceType(file.content);

		upload(file);
	});
}

function updateResourceReferences(content) {
	// replace references in structured content of resource
	findReferences(content, "reference", function(data, key, value) {
			if (idMap[value]) {
				data[key] = idMap[value];
			}
		}
	);

	// replace references in the narrative
	if (content.text && content.text.div) {
		var narrative = content.text;

		for (var oldId in idMap) {
			var newId = idMap[oldId];
			// not escaping characters here yet - not sure why was it needed before
			narrative.div = narrative.div.replace(oldId, newId);
		}
	}

	return content;
}

function getCurrentFile() {
	for (var f in files) {
		var file = files[f];
		if (!file.uploaded) {
			return file;
		}
	}
}

function uploadAll() {
	serverUrl = uploadServer;
	files = [];

	for (var r in uploadResources) {
		var resourceData = uploadResources[r];
		files.push({localLocation: resourceData[1], jsId: resourceData[0]});
	}

	doUpload();
}

function doUpload() {
	for (var f in files) {
		var file = files[f];
		if (!file.uploaded) {
			// load this resource's data in
			var fileName = file.localLocation;
			console.log("Uploading " + fileName);

			file.content = loadFile(file);
			return true;
		}

	}

	return false;
}<|endoftext|>


<commit_before>rpgPhase = function(game) {
    Phaser.State.call(this);

    this._game = game;
    this._freeTiles = [];
    this._game.stage.smoothed = false;
}

//Extend the rpgPhase object to be a Phaser.State
rpgPhase.prototype = Object.create(Phaser.State.prototype);
rpgPhase.prototype.constructor = rpgPhase;

rpgPhase.prototype.update = function(){
    var map = this._game.state.getCurrentState()._map;
    var items = map._items;

    //Check whether the collectables are collected,and whether we are not yet in the last level of the phase.
        if(items.children.length == 0 && !ran && this._game._level != 12){
            ran = true;
            run = true;
            this._game._level++;
        }
}

rpgPhase.prototype.create = function(){
    //instantiate worldmap and create layer (this displays the map)
    this._map = new WorldMap(this._game, 'level', 'tiles_rpg', 32, 'collectable_rpg');
    this._layer = this._map.createLayer(0);
    this._layer.resizeWorld();

    //add items to the game
    this._game.add.existing(this._map._items);

    //Instantiate new player object
    this._player = new Player(this._game, 1, 'player_rpg', 150);

    // and new NPC object

    //DENNIS @ PIETER: really rough generation template, better put this in map
    //PIETER @ DENNIS: tried putting it in map, but somehow it does not show the NPCs then
    this._map._npcs = new Phaser.Group(this._game, null, "NPCs", false);

    for (var i = 0; i < 3; i++){
        var choice = Math.ceil(ROT.RNG.getUniform() * 7);
        var npc = new NPC(this._game, (32/27), 'npc'+choice+'_rpg');
        this._game.physics.enable(npc);
        npc.body.immovable = true;
        this._map._npcs.add(npc);
    }

    this._game.add.existing(this._map._npcs);

    //postpone character creation for a sec to avoid rendering problems
    setTimeout((function(self) { return function() {
            self._game.add.existing(self._player);
        }})(this),200);

    this._score = new Phaser.Group(this._game, null, "score", false);

    var collectable = this._game.add.sprite(this._game.camera.width - 25, this._game.camera.height - 25, 'collectable_rpg');
    collectable.anchor.setTo(0.5, 0.5);
    this._collectableText = this._game.add.text(this._game.camera.width - 60, this._game.camera.height - 25, "0x",{ font: "14px 'Press Start 2P'", fill: "#fff" });
    this._collectableText.anchor.setTo(0.5, 0.5);

    this._score.fixedToCamera = true;
    this._score.add(collectable);
    this._score.add(this._collectableText);
    this._game.add.existing(this._score);
};

//Returns a position on the map where the player or an item can spawn
rpgPhase.prototype.getItemPosition =
rpgPhase.prototype.getPlayerPosition = function(){
    //shuffle the array of free tiles
    shuffle(this._freeTiles);

    //returns an array of x and y position (nth tile) that is free,
    //and remove it from the list so no other item can spawn on this position.
    var randomPosition = this._freeTiles.pop();
    return [randomPosition[0]*32, randomPosition[1]*32];
}

//map generation for RPG (cellular automata)
rpgPhase.prototype.generate = function(){
    this._freeTiles = [];

    var w = 80, h = 60;
    var map = new ROT.Map.Cellular(w, h, {
        born: [5,6,7,8],
        survive: [4,5,6,7,8]
    });
    map.randomize(0.52);

    var display;
    var digCallback = function(x, y, value) {
        if (value) {
            var tile = [x, y+1]; //+1 for border tile compensation
            this._freeTiles.push(tile);
        }

        //channel info to debug so the preview can be rendered.
        display.DEBUG(x,y,value);
    }

    //[> generate x generations <]
    for (var i=0; i<10; i++) {
        display = new ROT.Display({width:w, height:h, fontSize:4});

        if(i < 9){
            map.create();
        } else {
            map.create(digCallback.bind(this));
        }
    }

    //add a row to the TOP of the map
    for(var i = 0; i < map._map.length; i++){ map._map[i].unshift("border"); }

    //add a column to the LEFT of the map
    map._map[0] = [];
    for(var i = 0; i < map._map[1].length; i++){ map._map[0].push("border"); }

    //add a column to the RIGHT of the map
    map._map[map._map.length-1] = [];
    for(var i = 0; i < map._map[1].length; i++){ map._map[map._map.length-1].push("border"); }

    //add a row to the BOTTOM of the map
    for(var i = 0; i < map._map.length; i++){ map._map[i].push("border"); }

    //show map in canvas
    if (pixelEvolution._showMinimap){
        $('#minimap').html(display.getContainer());
    }

    var level = "";

    for (var i=0; i<map._map[0].length; i++) {
        for (var j=0; j<map._map.length; j++) {
            var point = map._map[j][i]+"";

            if(point=="0" || point=="border"){
                point = "1";
            } else {
                point = "0";
            }

            level += point + ",";
        }
        level = level.substring(0,level.length-1) + "\n";
    }

    // calculate the biggest part of the map where we can freely move around
    var union = new UnionFind(this._freeTiles.length);

    // the sets are already made, create reverse free tiles

    var h = map._map.length;
    var w = map._map[0].length;

    var rFreeTiles = new Array(h);
    for (var i = 0; i < h; i++) {
        rFreeTiles[i] = new Array(w);
    }

    for (var i = 0; i < this._freeTiles.length; i++) {
        var tile = this._freeTiles[i];
       rFreeTiles[tile[0]][tile[1]] = i;
    }

    // now, unionize all free tiles together

    for (var i = 0; i < this._freeTiles.length; i++) {
        var tile = this._freeTiles[i];
        if (tile[0] > 0) {
            var val = map._map[tile[0] - 1][tile[1]];
            if (val == '1') {
                union.link(i, rFreeTiles[tile[0] - 1][tile[1]]);
            }
        }
        if (tile[0] < h - 1) {
            var val = map._map[tile[0] + 1][tile[1]];
            if (val == '1') {
                union.link(i, rFreeTiles[tile[0] + 1][tile[1]]);
            }
        }
        if (tile[1] > 0) {
            var val = map._map[tile[0]][tile[1] - 1];
            if (val == '1') {
                union.link(i, rFreeTiles[tile[0]][tile[1] - 1]);
            }
        }
        if (tile[1] < w - 1) {
            var val = map._map[tile[0]][tile[1] + 1];
            if (val == '1') {
                union.link(i, rFreeTiles[tile[0]][tile[1] + 1]);
            }
        }
    }

    // find all open fields
    var fields = {};

    for (var i = 0; i < this._freeTiles.length; i++) {
        var field = union.find(i);
        if (!(field in fields)) {
            fields[field] = [];
        }
        fields[field].push(this._freeTiles[i]);
    }

    // find the largest open field
    var max = 0;
    var largest;
    $.each(fields, function(index, field) {
        if (field.length > max) {
            max = field.length;
            largest = field;
        }
    });

    this._freeTiles = largest;

    return level;
};

//helper method: shuffles arrays
function shuffle(o){
    for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
    return o;
};
<commit_msg>Added moving enemy to RPG phase.<commit_after>rpgPhase = function(game) {
    Phaser.State.call(this);

    this._game = game;
    this._freeTiles = [];
    this._game.stage.smoothed = false;
}

//Extend the rpgPhase object to be a Phaser.State
rpgPhase.prototype = Object.create(Phaser.State.prototype);
rpgPhase.prototype.constructor = rpgPhase;

rpgPhase.prototype.update = function(){
    var map = this._game.state.getCurrentState()._map;
    var items = map._items;

    //Check whether the collectables are collected,and whether we are not yet in the last level of the phase.
        if(items.children.length == 0 && !ran && this._game._level != 12){
            ran = true;
            run = true;
            this._game._level++;
        }
}

rpgPhase.prototype.create = function(){
    //instantiate worldmap and create layer (this displays the map)
    this._map = new WorldMap(this._game, 'level', 'tiles_rpg', 32, 'collectable_rpg');
    this._layer = this._map.createLayer(0);
    this._layer.resizeWorld();

    //add items to the game
    this._game.add.existing(this._map._items);

    //Instantiate new player object
    this._player = new Player(this._game, 1, 'player_rpg', 150);

    // and new NPC object

    //DENNIS @ PIETER: really rough generation template, better put this in map
    //PIETER @ DENNIS: tried putting it in map, but somehow it does not show the NPCs then
    this._map._npcs = new Phaser.Group(this._game, null, "NPCs", false);

    for (var i = 0; i < 3; i++){
        var choice = Math.ceil(ROT.RNG.getUniform() * 7);
        var npc = new NPC(this._game, (32/27), 'npc'+choice+'_rpg');
        this._game.physics.enable(npc);
        npc.body.immovable = true;
        this._map._npcs.add(npc);
    }

    this._game.add.existing(this._map._npcs);

    // create one enemy
    // the current collision handler implementation in the player does not allow more
    // to be created
    this._enemy = new Enemy(this._game, 1, 'enemy_pacman1');

    this._enemy.update = function() {
        ticks++;
        this.spriteSize = 32;
        var tiles = this._game.state.getCurrentState()._layer;
        this._game.physics.arcade.overlap(this.sprite, tiles, this.collisionHandler, null, this.update);

        if(ticks > 40) {
            ticks = 0;

            var options = [];

            var tileX = this.position.x/32;
            var tileY = this.position.y/32;

            var state = this._game.state.getCurrentState();

            try{
                if(state._map.getTileBelow(0, tileX,tileY).index == "0") {
                    options.push("down");
                    //console.log("down");
                }
            } catch(e) {
            }
            try{
                if(state._map.getTileAbove(0, tileX,tileY).index == "0") {
                    options.push("up");
                    //console.log("up");
                }
            } catch(e) {
            }
            try {
                if(state._map.getTileLeft(0, tileX,tileY).index == "0") {
                    options.push("left");
                    //console.log("left");
                }
            } catch(e) {
            }
            try {
                if(state._map.getTileRight(0, tileX,tileY).index == "0") {
                    options.push("right");
                    //console.log("right");
                }
            } catch(e) {
            }

            var index = Math.floor(Math.random() * options.length);
            var direction = options[index];

            switch (direction) {
                case "down":
                    this.position.y = this.position.y+this.spriteSize;
                    if (this.facing != 'down'){
                        this.animations.play('down');
                        this.facing = 'down';
                    }
                    break;
                case "up":
                    this.position.y = this.position.y-this.spriteSize;
                    if (this.facing != 'up'){
                        this.animations.play('up');
                        this.facing = 'up';
                    }
                    break;
                case "left":
                    this.position.x = this.position.x-this.spriteSize;
                    if (this.facing != 'left'){
                        this.animations.play('left');
                        this.facing = 'left';
                    }
                    break;
                case "right":
                    this.position.x = this.position.x+this.spriteSize;
                    if (this.facing != 'right'){
                        this.animations.play('right');
                        this.facing = 'right';
                    }
                    break;
            }
        }
    };

    //postpone character creation for a sec to avoid rendering problems
    setTimeout((function(self) { return function() {
            self._game.add.existing(self._player);
            self._game.add.existing(self._enemy);
        }})(this),200);

    this._score = new Phaser.Group(this._game, null, "score", false);

    var collectable = this._game.add.sprite(this._game.camera.width - 25, this._game.camera.height - 25, 'collectable_rpg');
    collectable.anchor.setTo(0.5, 0.5);
    this._collectableText = this._game.add.text(this._game.camera.width - 60, this._game.camera.height - 25, "0x",{ font: "14px 'Press Start 2P'", fill: "#fff" });
    this._collectableText.anchor.setTo(0.5, 0.5);

    this._score.fixedToCamera = true;
    this._score.add(collectable);
    this._score.add(this._collectableText);
    this._game.add.existing(this._score);
};

//Returns a position on the map where the player or an item can spawn
rpgPhase.prototype.getItemPosition =
rpgPhase.prototype.getEnemyPosition =
rpgPhase.prototype.getPlayerPosition = function(){
    //shuffle the array of free tiles
    shuffle(this._freeTiles);

    //returns an array of x and y position (nth tile) that is free,
    //and remove it from the list so no other item can spawn on this position.
    var randomPosition = this._freeTiles.pop();
    return [randomPosition[0]*32, randomPosition[1]*32];
}

//map generation for RPG (cellular automata)
rpgPhase.prototype.generate = function(){
    this._freeTiles = [];

    var w = 80, h = 60;
    var map = new ROT.Map.Cellular(w, h, {
        born: [5,6,7,8],
        survive: [4,5,6,7,8]
    });
    map.randomize(0.52);

    var display;
    var digCallback = function(x, y, value) {
        if (value) {
            var tile = [x, y+1]; //+1 for border tile compensation
            this._freeTiles.push(tile);
        }

        //channel info to debug so the preview can be rendered.
        display.DEBUG(x,y,value);
    }

    //[> generate x generations <]
    for (var i=0; i<10; i++) {
        display = new ROT.Display({width:w, height:h, fontSize:4});

        if(i < 9){
            map.create();
        } else {
            map.create(digCallback.bind(this));
        }
    }

    //add a row to the TOP of the map
    for(var i = 0; i < map._map.length; i++){ map._map[i].unshift("border"); }

    //add a column to the LEFT of the map
    map._map[0] = [];
    for(var i = 0; i < map._map[1].length; i++){ map._map[0].push("border"); }

    //add a column to the RIGHT of the map
    map._map[map._map.length-1] = [];
    for(var i = 0; i < map._map[1].length; i++){ map._map[map._map.length-1].push("border"); }

    //add a row to the BOTTOM of the map
    for(var i = 0; i < map._map.length; i++){ map._map[i].push("border"); }

    //show map in canvas
    if (pixelEvolution._showMinimap){
        $('#minimap').html(display.getContainer());
    }

    var level = "";

    for (var i=0; i<map._map[0].length; i++) {
        for (var j=0; j<map._map.length; j++) {
            var point = map._map[j][i]+"";

            if(point=="0" || point=="border"){
                point = "1";
            } else {
                point = "0";
            }

            level += point + ",";
        }
        level = level.substring(0,level.length-1) + "\n";
    }

    // calculate the biggest part of the map where we can freely move around
    var union = new UnionFind(this._freeTiles.length);

    // the sets are already made, create reverse free tiles

    var h = map._map.length;
    var w = map._map[0].length;

    var rFreeTiles = new Array(h);
    for (var i = 0; i < h; i++) {
        rFreeTiles[i] = new Array(w);
    }

    for (var i = 0; i < this._freeTiles.length; i++) {
        var tile = this._freeTiles[i];
       rFreeTiles[tile[0]][tile[1]] = i;
    }

    // now, unionize all free tiles together

    for (var i = 0; i < this._freeTiles.length; i++) {
        var tile = this._freeTiles[i];
        if (tile[0] > 0) {
            var val = map._map[tile[0] - 1][tile[1]];
            if (val == '1') {
                union.link(i, rFreeTiles[tile[0] - 1][tile[1]]);
            }
        }
        if (tile[0] < h - 1) {
            var val = map._map[tile[0] + 1][tile[1]];
            if (val == '1') {
                union.link(i, rFreeTiles[tile[0] + 1][tile[1]]);
            }
        }
        if (tile[1] > 0) {
            var val = map._map[tile[0]][tile[1] - 1];
            if (val == '1') {
                union.link(i, rFreeTiles[tile[0]][tile[1] - 1]);
            }
        }
        if (tile[1] < w - 1) {
            var val = map._map[tile[0]][tile[1] + 1];
            if (val == '1') {
                union.link(i, rFreeTiles[tile[0]][tile[1] + 1]);
            }
        }
    }

    // find all open fields
    var fields = {};

    for (var i = 0; i < this._freeTiles.length; i++) {
        var field = union.find(i);
        if (!(field in fields)) {
            fields[field] = [];
        }
        fields[field].push(this._freeTiles[i]);
    }

    // find the largest open field
    var max = 1000000;
    var largest;
    $.each(fields, function(index, field) {
        if (field.length < max) {
            max = field.length;
            largest = field;
        }
    });

    this._freeTiles = largest;

    return level;
};

//helper method: shuffles arrays
function shuffle(o){
    for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
    return o;
};
<|endoftext|>