web前端项目-超级玛丽【附源码】

超级玛丽

【超级玛丽】是一个基于HTML5JavaScript开发的经典电子游戏。玩家需要控制主角马里奥在各种关卡中跳跃、奔跑、消灭敌人,以完成游戏目标。玩家通过浏览器可以体验经典的超级玛丽关卡和冒险。

运行效果:方向键控制马里奥的左右移动、跳跃、奔跑;CTRL键发射子弹
web前端项目-超级玛丽【附源码】_第1张图片
web前端项目-超级玛丽【附源码】_第2张图片
web前端项目-超级玛丽【附源码】_第3张图片

HTML源码-mario.html

DOCTYPE html>
<html lang="en-us">
<head>
    <meta charset="utf-8">
    <title>Full Screen Mariotitle>
    <link href="mario.css" rel="stylesheet">
    <link href="Fonts/stylesheet.css" rel="stylesheet">
    <script src="data.js">script>
    <script src="editor.js">script>
    <script src="events.js">script>
    <script src="generator.js">script>
    <script src="library.js">script>
    <script src="load.js">script>
    <script src="maps.js">script>
    <script src="mario.js">script>
    <script src="quadrants.js">script>
    <script src="sounds.js">script>
    <script src="sprites.js">script>
    <script src="things.js">script>
    <script src="toned.js">script>
    <script src="triggers.js">script>
    <script src="upkeep.js">script>
    <script src="utility.js">script>
    <script src="gamepad.js">script>
head>
<body onload="FullScreenMario()">
body>
html>

CSS源码-mario.css

html { background: black; }
html, body, .text, .display {
  border: 0;
  margin: 0;
  padding: 0;
  color: #fafafa;
  text-align: center;
  vertical-align: middle;
  font-family: 'Press Start';
  z-index: 84;
  -webkit-font-smoothing: none;
  -webkit-user-select: none;
}

body { 
  width: 100%;
  height: 100%;
  overflow: hidden;
}

canvas {
  position: absolute;
  left: 0;
}

.display {
  position: fixed;
  font-size: 21px;
}
.indisplay {
  margin: 7px 14px 0 14px;
  text-align: center;
  z-index: 14;
}
.indisplay.counter, .indisplay.seed {
  position: fixed;
  padding: 3px 7px;
  bottom: 0;
  background: rgba(0,0,0,.49);
}
.indisplay.counter { right: 0; }
.indisplay.seed{ left: 0; }

.text {
  position: absolute;
  z-index: 14;
  text-align: left;
  line-height: 210%;
  vertical-align: middle;
}
.text * {
  margin: 0;
}

.score {
  width: 35px;
  height: 14px;
  font-size: 21px;
  z-index: 14;
 }

.editor #data_display {
  display: none;
}
 
#sidebar {
  background: black;
  position: fixed;
  right: -322px;
  width: 343px;
  height: 100%;
  z-index: 96;
  border-left: 2px solid #ccc;
  transition: right 280ms;
}
#sidebar:hover , #sidebar.expanded { right: 0; }
#sidebar * {
  font-family: 'Press Start';
  line-height: 140%;
  color: #ddd;
}
#sidebar #sectionselect {
  font-size: 1.4em;
}
#sidebar h1 {
  font-size: 1.4em;
  padding-bottom: 14px;
  border-bottom: 2px solid #999;
}
#sidebar .group {
  padding: 7px;
  width: 100%;
  min-height: 70px;
  line-height: 175%;
}
#sidebar .group select , #sidebar .group input{
  padding-bottom: 3px;
  height: 21px;
  border: 1px solid #333;
  border-radius: 3px;
  background-color: black;
}
#sidebar #options {
  font-size: 17px;
}
#sidebar .options.big {
  padding-top: 3px;
  height: 28px;
  text-align: center;
  font-size: 21px;
}
#sidebar #options h3.title {
  margin-top: -21px;
  padding-right: 105px;
  border-bottom: 1px solid #777;
  text-align: right;
  font-size: 19px;
}
#sidebar #options input, #sidebar #options select {
  margin-top: -14px;
  padding: 3px;
  max-width: 175px;
  min-height: 24px;
  background: black;
  border: 1px solid #333;
  text-align: left;
}
#sidebar #options .auto {
  padding: 3px 7px;
  text-align: left;
}
#sidebar #options input[type=Number] {
  max-width: 63px;
}
#sidebar #options .optspan {
  margin-right: 3px;
  font-size: 14px;
  color: #aaa;
}
#sidebar #options .optspan + input {
  margin-top: -3px;
}
#options tr td:first-of-type {
  text-align: right;
}
#options tr td:last-of-type {
  text-align: left;
}

#controls {
  position: absolute;
  bottom: 0;
  right: 3px;
  transition: 70ms opacity;
}
.control {
  float: right;
  width: 64px;
  height: 64px;
  border: 2px solid #aaa;
  cursor: pointer;
  transition: 49ms opacity;
  opacity: .7;
}
.control:hover, .control.enabled { opacity: 1; }
.controltext {
  padding-top: 21px;
  font-size: 11px;
  opacity: .49;
}

#bottombar {
  position: absolute;
  bottom: 68px;
  background: #111;
  transition: all 280ms, visibility 0;
  opacity: .7;
}
#bottombar:hover { 
  opacity: 1;
}
#bottombar .holder {
  float: left;
  width: 64px;
  height: 64px;
  border: 2px solid white;
  cursor: pointer;
  overflow: hidden;
}
#bottombar canvas {
  position: static;
  max-height: 100%;
}

#maplines {
  position: fixed;
  height: 100%;
  width: 100%;
  opacity: .49;
  border-left: 2px dashed #ddd;
  cursor: crosshair;
}
.mapline {
  position: fixed;
  padding: 1px;
  width: 100%;
  border-top: 2px dashed #eee;
  text-align: left;
  cursor: crosshair;
}

#erasing canvas, .erasing #maplines, .erasing .mapline, .erasing #follower {
  cursor: url(Theme/EraserTip.gif), pointer;
}

#follower {
  cursor: crosshair;
}

.scroller {
  position: fixed;
  width: 64px;
  height: 128px;
  opacity: .21;
  z-index: 7;
  cursor: none;
  background: url('Theme/Hand.gif') center center no-repeat;
}
.scroller:hover { opacity: .84; }
.scroller.off {
  display: none;
  visibility: hidden;
  z-index: -35;
}

.flipped {
  -moz-transform: scaleX(-1);
  -o-transform: scaleX(-1);
  -webkit-transform: scaleX(-1);
  transform: scaleX(-1);
  filter: FlipH;
  -ms-filter: "FlipH";
}

#input_window {
  position: fixed;
  height: 100%;
  padding-top: 42px;
  background: rgba(7,21,0,.84);
  box-shadow: 0 0 210px rgba(0,0,1,.7) inset;
  z-index: 98;
}
#input_window textarea {
  margin-top: 35px;
  padding: 7px 21px 14px 28px;
  width: 100%;
  height: 50%;
  background-color: rgba(14, 14, 14, .77);
  background-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAGZmZv///yH5BAEAAAEALAAAAAABAAEAAAICRAEAOw==);
  background-repeat: repeat-y;
  background-position: 21px;
  border-width: 1px 0 1px 0;
  color: white;
  vertical-align: top;
  font-family: "Courier New", "Courier", monospace;
}
#input_window textarea:focus {
  outline: 0;
  border-color: gold;
}
#input_window .window_button {
  float: right;
  margin: 0 21px 0 0;
  padding: 11px;
  padding-bottom: 7px;
  border: 3px solid rgba(175,175,175,.7);
  border-top: 0;
  border-bottom-right-radius: 7px;
  border-bottom-left-radius: 7px;
  cursor: pointer;
}

#window_submit { 
  margin-right: 4%;
  background: rgba(14,70,14,.84);
  font-size: 21px;
}
#window_cancel {
  margin-right: 14px;
  background: rgba(70,14,14,.84);
}

JS源码

(1)mario.js
function FullScreenMario() {
  var time_start = Date.now();
  ensureLocalStorage();
  TonedJS(true);
  window.body = document.body;
  window.bodystyle = body.style;
  window.verbosity = {Maps: false,
                      Sounds: false,
                      };
  if(Function.prototype.name === undefined && Object.defineProperty !== undefined) {
    Object.defineProperty(Function.prototype, 'name', {
        get: function() {
            var funcNameRegex = /function\s([^(]{1,})\(/,
                results = (funcNameRegex).exec((this).toString());
            return (results && results.length > 1) ? results[1].trim() : "";
        },
        set: function(value) {}
    });
  }
  window.requestAnimationFrame = window.requestAnimationFrame
                           || window.mozRequestAnimationFrame
                           || window.webkitRequestAnimationFrame
                           || window.msRequestAnimationFrame
                           || function(func) { setTimeout(func, timer); };
  window.cancelAnimationFrame = window.cancelAnimationFrame
                           || window.webkitCancelRequestAnimationFrame
                           || window.mozCancelRequestAnimationFrame
                           || window.oCancelRequestAnimationFrame
                           || window.msCancelRequestAnimationFrame
                           || clearTimeout;

  window.Uint8ClampedArray = window.Uint8ClampedArray
                          || window.Uint8Array
                          || Array;
  window.Uint8ArrayName = Uint8ClampedArray.name || "Uint8Array"; // ie

  resetMeasurements();
  resetLibrary();
  resetCanvas();
  resetMaps();
  resetScenery();
  resetTriggers();
  resetSeed();
  resetSounds();
  
  window.gameon = true;
  setMap(1,1);
  startLoadingSounds();
  
  log("It took " + (Date.now() - time_start) + " milliseconds to start.");
}
function ensureLocalStorage() {
  var ls_ok = false;
  try {
  if(!window.hasOwnProperty("localStorage"))
    window.localStorage = { crappy: true };
  
  if(window.localStorage) ls_ok = true;
 }
 catch(err) {
    ls_ok = false;
  }
  if(!ls_ok) {
    var nope = document.body.innerText = "It seems your browser does not allow localStorage!";
    throw nope;
  }
}

function resetMeasurements() {
  resetUnitsize(4);
  resetTimer(1000 / 60);
  
  window.jumplev1 = 32;
  window.jumplev2 = 64;
  window.ceillev  = 88;
  window.ceilmax  = 104;
  window.castlev  = -48;
  window.paused   = true;
  
  resetGameScreen();
  if(!window.parentwindow) window.parentwindow = false;
}

function resetUnitsize(num) {
  window.unitsize = num;
  for(var i = 2; i <= 64; ++i) {
    window["unitsizet" + i] = unitsize * i;
    window["unitsized" + i] = unitsize / i;
  }
  window.scale = unitsized2;
  window.gravity = round(12 * unitsize) / 100;
}

function resetTimer(num) {
  num = roundDigit(num, .001);
  window.timer = window.timernorm = num;
  window.timert2 = num * 2;
  window.timerd2 = num / 2;
  window.fps = window.fps_target = roundDigit(1000 / num, .001);
  window.time_prev = Date.now();
}

function resetGameScreen() {
  window.gamescreen = new getGameScreen();
}
function getGameScreen() {
  resetGameScreenPosition(this);
  this.middlex = (this.left + this.right) / 2;
  window.botmax = this.height - ceilmax;
  if(botmax < unitsize) {
    body.innerHTML = "

Your screen isn't high enough. Make it taller, then refresh.
"
; } this.deathheight = this.bottom + 48; } function resetGameScreenPosition(me) { me = me || window.gamescreen; me.left = me.top = 0; me.bottom = innerHeight; me.right = innerWidth; me.height = innerHeight / unitsize; me.width = innerWidth / unitsize; me.unitheight = innerHeight; me.unitwidth = innerWidth; } function resetGameState(nocount) { clearAllTimeouts(); resetData(); window.nokeys = window.spawning = window.spawnon = window.notime = window.editing = window.qcount = window.lastscroll = 0; window.paused = window.gameon = true; if(!nocount) window.gamecount = 0; resetQuadrants(); window.gamehistory = []; window.gamehistory = []; pauseAllSounds(); sounds = {}; } function scrollWindow(x, y) { x = x || 0; y = y || 0; var xinv = -x, yinv = -y; gamescreen.left += x; gamescreen.right += x; gamescreen.top += y; gamescreen.bottom += y; shiftAll(characters, xinv, yinv); shiftAll(solids, xinv, yinv); shiftAll(scenery, xinv, yinv); shiftAll(quads, xinv, yinv); shiftElements(texts, xinv, yinv); updateQuads(xinv); if(window.playediting) scrollEditor(x, y); } function shiftAll(stuff, x, y) { for(var i = stuff.length - 1; i >= 0; --i) shiftBoth(stuff[i], x, y); } function shiftElements(stuff, x, y) { for(var i = stuff.length - 1, elem; i >= 0; --i) { elem = stuff[i]; elementShiftLeft(elem, x); elementShiftTop(elem, y); } } function scrollMario(x, y, see) { var saveleft = mario.left, savetop = mario.top; y = y || 0; scrollWindow(x,y); setLeft(mario, saveleft, see); setTop(mario, savetop + y * unitsize, see); updateQuads(); } function mlog(type) { if(verbosity[type]) { log.apply(console, arguments); } }
(2)data.js
function resetData() {
  var check;
  if(check = document.getElementById("data_display"))
    body.removeChild(check);
  
  if(!window.data) {
    window.data = new Data();
  }
}
function Data() {
  this.mariopower = 1;
  this.traveled = this.traveledold = 0;
  this.scorelevs = [100, 200, 400, 500, 800, 1000, 2000, 4000, 5000, 8000];
  this.score = new DataObject(0, 6, "SCORE");
  this.time = new DataObject(350, 3, "TIME");
  this.world = new DataObject(0, 0, "WORLD");
  this.coins = new DataObject(0, 0, "COINS");
  this.lives = new DataObject(3, 1, "LIVES");
  this.time.dir = -1;
  this.scoreold = 0;
}

function DataObject(amount, length, name) {
  this.amount = amount;
  this.length = length;
  this.name = name;
  this.element = createElement("td", {className: "indisplay"});
}

function setDataDisplay() {
  var display = createElement("table", {
            id: "data_display",
            className: "display",
            style: {
              width: (gamescreen.right + 14) + "px"
            }}),
      elems = ["score", "coins", "world", "time", "lives"];
  body.appendChild(display);
  data.display = display;
  for(var i in elems) {
    display.appendChild(data[elems[i]].element);
    updateDataElement(data[elems[i]]);
  }
  body.appendChild(data.display);
}

function clearDataDisplay() {
  body.removeChild(data_display);
}

function startDataTime() {
  addEventInterval(updateDataTime, 25, Infinity, data.time);
}
function updateDataTime(me) {
  if(me.dir != 1) {
    if(me.amount == 100) playCurrentThemeHurry(); 
    else if(me.amount <= 0) killMario(mario, true);
  }
  if(!notime) {
    map.time = me.amount += me.dir;
    updateDataElement(me);
  }
}

function updateDataElement(me) {
  var text = me.name + "
"
+ (me.amount == "Infinity" ? "Inf" : me.amount); me.element.innerHTML = text; me.element.style.width = ""; } function score(me, amount, appears) { if(amount <= 0) return; if(arguments.length == 1) return score(mario, me); localStorage.highscore = max(localStorage.highscore, data.score.amount += amount); if(appears) { var text = addText(amount, me.left, me.top); text.yvel = -unitsized4; addEvent(killScore, 49, text); } while(data.score > 10000) { gainLife(); data.score.amount = data.score.amount % 10000; } updateDataElement(data.score); } function killScore(text) { body.removeChild(text); killNormal(text); deleteThing(text, texts, texts.indexOf(text)); } function findScore(lev) { if(lev < data.scorelevs.length) return data.scorelevs[lev]; gainLife(); return -1; } function gainLife(num, nosound) { data.lives.amount += typeof(num) == "number" ? num : 1; if(!nosound) play("Gain Life"); updateDataElement(data.lives); } function setLives(num) { data.lives.amount = Number(num); updateDataElement(data.lives); } function storeMarioStats() { data.mariopower = mario.power; } function clearMarioStats() { data.mariopower = mario.power = 1; }
(3)events.js
function addEvent(func, count) {
  if(!(func instanceof Function)) return false;
  count = count || 1;

  var args = arrayMake(arguments);
  args.splice(0, 2);

  var contents = {
    func: func,
    count: gamecount + count,
    args: args,
    timeout: count,
    repeat: true
  };
  insertSortedEvent(events, contents, contents.count);
  return contents;
}

function addEventInterval(func, count, reptimes) {

  if(!(func instanceof Function)) return false;
  count = count || 1;
  
  var args = arrayMake(arguments);
  args.splice(0, 3);
  
  var contents = {
    func: func,
    count: gamecount + count,
    args: args,
    timeout: count,
    repeat: reptimes
  };
  
  contents.func.event = contents;
  
  insertSortedEvent(events, contents, contents.count);
  return contents;
}

function addEventIntervalSynched(func, count, reptimes, me, settings) {
  var calctime = count * settings.length,
      entry = ceil(gamecount / calctime) * calctime,
      scope = this,
      addfunc = function(scope, args, me) {
        me.startcount = gamecount;
        return addEventInterval.apply(scope, args);
      };
  
  if(entry == gamecount) {
    return addfunc(scope, arguments, me);
  }
  else {
    var dt = entry - gamecount;
    addEvent(addfunc, dt, scope, arguments, me);
  }
}

function handleEvents() {
  ++gamecount;
  var events_current = events[gamecount],
      event, repfunc,
      len, i;
  
  if(!events_current) return;
  
  for(i = 0, len = events_current.length; i < len; ++i) {
    event = events_current[i];

    if(event.repeat && !event.func.apply(null, event.args)) {
      
      if(event.count_changer) event.count_changer(event);

      if(event.repeat instanceof Function) {
        repfunc = event.repeat.bind(event);
        if(repfunc()) {
          event.count += event.timeout;
          insertSortedEvent(events, event, event.count);
        }
      }
      
      else {
        if(--event.repeat != 0) {
          event.count += event.timeout;
          insertSortedEvent(events, event, event.count);
        }
      }
    }
  }
  
  delete events[gamecount];
}

function insertSortedEvent(events, contents, count) {
  if(!events[count]) events[count] = [];
  events[count].push(contents);
}

function clearEvent(event) {
  if(!event) return;
  event.repeat = false;
}
function clearEventInterval(event) {
  if(!event) return;
  event.repeat = false;
}

function addSpriteCycle(me, settings, name, timing) {
  if(!me.cycles) me.cycles = {};
  clearClassCycle(me, name);
  var cycle = me.cycles[name || 0] = setSpriteCycle(me, settings, typeof(timing) == "function" ? 0 : timing);
  if(cycle.event && typeof(timing) == "function") cycle.event.count_changer = timing;
  cycleClass(me, settings);
  return cycle;
}
function addSpriteCycleSynched(me, settings, name, timing) {
  if(!me.cycles) me.cycles = {}
  settings = settings || ["one", "two"];
  var cycle = me.cycles[name || 0] = setSpriteCycle(me, settings, timing, true);
  clearClassCycle(me, name);
  cycleClass(me, settings);
  return cycle;
}

function setSpriteCycle(me, settings, timing, synched) {
  settings.loc = -1;
  settings.oldclass = "761deadsoldiers";
  me.onadding = function() { 
    if(synched) settings.event = addEventIntervalSynched(cycleClass, timing || 9, Infinity, me, settings);
    else settings.event = addEventInterval(cycleClass, timing || 9, Infinity, me, settings);
  }
  if(me.placed) me.onadding();
  return settings;
}

function clearClassCycles(me, names) {
  names = names.split(" ");
  for(var i = names.length - 1; i >= 0; --i)
    clearClassCycle(me, names[i]);
}
function clearClassCycle(me, name) {
  if(!characterIsAlive(me) || !me.cycles[name]) return;
  me.cycles[name][0] = false;
  me.cycles[name].length = 1;
  delete me.cycles[name];
}
function clearAllCycles(me) {
  for(var i in me.cycles)
    clearClassCycle(me, i);
}

function cycleClass(me, settings) {
  if(!me || !settings || !settings.length) return true;
  
  if(settings.oldclass != "") removeClass(me, settings.oldclass);
  settings.loc = ++settings.loc % settings.length;
  var current = settings[settings.loc];
  if(current) {
    var name = current instanceof Function ? current(me, settings) : current;
    if(typeof(name) == "string") {
      settings.oldclass = name;
      addClass(me, name);
      return false;
    } 
    else return (name === false);
  }
  else {
    return (current === false);
  }
}

function addSpriteCycleManual(me, settings, name, timing) {
  if(!me.cycles) me.cycles = {}
  me.cycles[name || 0] = setSpriteCycleManual(me, settings, timing);
}
function setSpriteCycleManual(me, settings, timing) {
  settings.loc = -1;
  settings.oldclass = "761deadsoldiers";
  timing = (timing || 9) * timer;
  var interval = setInterval(function() {
    if(cycleClass(me, settings))
      clearInterval(interval);
  }, timing);
  return settings;
}

function removeSpriteCycle(me, name) {
}

function scrollTime(dx) {
  dx = dx || 21;
  mario.nofall = mario.nocollide = nokeys = true;
  addEventInterval(scrollMario, 1, Infinity, dx);
  
  mario.oldtop = mario.top;
  mario.siny = -Math.PI;
  addEventInterval(function() {
    setTop(mario, mario.oldtop - Math.sin(mario.siny -= .125) * unitsizet8);
  }, 1, Infinity);
  addEventInterval(function() {
    shiftVert(mario, -1.4);
    mario.oldtop -= 1.4;
  }, 1, 49);
  
  addEventInterval(function() {
    if(map.has_lakitu) killFlip(map.has_lakitu);
  }, 70);
}
(4)gamepad.js
(function(exports) {
	'use strict';
	var nullFunction = function() {};
	var nullPlatform = {
		getType: function() {
			return 'null';
		},
		isSupported: function() {
			return false;
		},
		update: nullFunction
	};

	var AnimFrameUpdateStrategy = function(requestAnimationFrame) {
		var that = this;
		var win = window;

		this.update = nullFunction;

		this.requestAnimationFrame = requestAnimationFrame || win.requestAnimationFrame ||
			win.webkitRequestAnimationFrame || win.mozRequestAnimationFrame;

		this.tickFunction = function() {
			that.update();
			that.startTicker();
		};

		this.startTicker = function() {
			that.requestAnimationFrame.apply(win, [that.tickFunction]);
		};
	};

	AnimFrameUpdateStrategy.prototype.start = function(updateFunction) {
		this.update = updateFunction || nullFunction;
		this.startTicker();
	};

	var ManualUpdateStrategy = function() {

	};

	ManualUpdateStrategy.prototype.update = nullFunction;

	ManualUpdateStrategy.prototype.start = function(updateFunction) {
		this.update = updateFunction || nullFunction;
	};

	var WebKitPlatform = function(listener, gamepadGetter) {
		this.listener = listener;
		this.gamepadGetter = gamepadGetter;
		this.knownGamepads = [];
	};

	WebKitPlatform.factory = function(listener) {
		var platform = nullPlatform;
		var navigator = window && window.navigator;

		if (navigator) {
			if (typeof(navigator.webkitGamepads) !== 'undefined') {
				platform = new WebKitPlatform(listener, function() {
					return navigator.webkitGamepads;
				});
			} else if (typeof(navigator.webkitGetGamepads) !== 'undefined') {
				platform = new WebKitPlatform(listener, function() {
					return navigator.webkitGetGamepads();
				});
			}
		}

		return platform;
	};

	WebKitPlatform.getType = function() {
		return 'WebKit';
	},

	WebKitPlatform.prototype.getType = function() {
		return WebKitPlatform.getType();
	},

	WebKitPlatform.prototype.isSupported = function() {
		return true;
	};

	WebKitPlatform.prototype.update = function() {
		var that = this;
		var gamepads = Array.prototype.slice.call(this.gamepadGetter(), 0);
		var gamepad;
		var i;

		for (i = this.knownGamepads.length - 1; i >= 0; i--) {
			gamepad = this.knownGamepads[i];
			if (gamepads.indexOf(gamepad) < 0) {
				this.knownGamepads.splice(i, 1);
				this.listener._disconnect(gamepad);
			}
		}

		for (i = 0; i < gamepads.length; i++) {
			gamepad = gamepads[i];
			if (gamepad && (that.knownGamepads.indexOf(gamepad) < 0)) {
				that.knownGamepads.push(gamepad);
				that.listener._connect(gamepad);
			}
		}
	};

	var FirefoxPlatform = function(listener) {
		this.listener = listener;

		window.addEventListener('gamepadconnected', function(e) {
			listener._connect(e.gamepad);
		});
		window.addEventListener('gamepaddisconnected', function(e) {
			listener._disconnect(e.gamepad);
		});
	};

	FirefoxPlatform.factory = function(listener) {
		var platform = nullPlatform;

		if (window && (typeof(window.addEventListener) !== 'undefined')) {
			platform = new FirefoxPlatform(listener);
		}

		return platform;
	};

	FirefoxPlatform.getType = function() {
		return 'Firefox';
	},

	FirefoxPlatform.prototype.getType = function() {
		return FirefoxPlatform.getType();
	},

	FirefoxPlatform.prototype.isSupported = function() {
		return true;
	};

	FirefoxPlatform.prototype.update = nullFunction;

	var Gamepad = function(updateStrategy) {
		this.updateStrategy = updateStrategy || new AnimFrameUpdateStrategy();
		this.gamepads = [];
		this.listeners = {};
		this.platform = nullPlatform;
		this.deadzone = 0.03;
		this.maximizeThreshold = 0.97;
	};

	Gamepad.UpdateStrategies = {
		AnimFrameUpdateStrategy: AnimFrameUpdateStrategy,
		ManualUpdateStrategy: ManualUpdateStrategy
	};

	Gamepad.PlatformFactories = [WebKitPlatform.factory, FirefoxPlatform.factory];

	Gamepad.Type = {
		PLAYSTATION: 'playstation',
		LOGITECH: 'logitech',
		XBOX: 'xbox',
		UNKNOWN: 'unknown'
	};

	Gamepad.Event = {
		CONNECTED: 'connected',

		UNSUPPORTED: 'unsupported',

		DISCONNECTED: 'disconnected',

		TICK: 'tick',

		BUTTON_DOWN: 'button-down',

		BUTTON_UP: 'button-up',

		AXIS_CHANGED: 'axis-changed'
	};

	Gamepad.StandardButtons = [
		'FACE_1', 'FACE_2', 'FACE_3', 'FACE_4',
		'LEFT_TOP_SHOULDER', 'RIGHT_TOP_SHOULDER', 'LEFT_BOTTOM_SHOULDER', 'RIGHT_BOTTOM_SHOULDER',
		'SELECT_BACK', 'START_FORWARD', 'LEFT_STICK', 'RIGHT_STICK',
		'DPAD_UP', 'DPAD_DOWN', 'DPAD_LEFT', 'DPAD_RIGHT',
		'HOME'
	];

	Gamepad.StandardAxes = ['LEFT_STICK_X', 'LEFT_STICK_Y', 'RIGHT_STICK_X', 'RIGHT_STICK_Y'];

	var getControlName = function(names, index, extraPrefix) {
		return (index < names.length) ? names[index] : extraPrefix + (index - names.length + 1);
	};

	Gamepad.StandardMapping = {
		env: {},
		buttons: {
			byButton: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
		},
		axes: {
			byAxis: [0, 1, 2, 3]
		}
	};

	Gamepad.Mappings = [
		{
			env: {
				platform: FirefoxPlatform.getType(),
				type: Gamepad.Type.PLAYSTATION
			},
			buttons: {
				byButton: [14, 13, 15, 12, 10, 11, 8, 9, 0, 3, 1, 2, 4, 6, 7, 5, 16]
			},
			axes: {
				byAxis: [0, 1, 2, 3]
			}
		},
		{
			env: {
				platform: WebKitPlatform.getType(),
				type: Gamepad.Type.LOGITECH
			},
			buttons: { // TODO: This can't be right - LEFT/RIGHT_STICK have same mappings as HOME/DPAD_UP
				byButton: [1, 2, 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 10]
			},
			axes: {
				byAxis: [0, 1, 2, 3]
			}
		},
		{
			env: {
				platform: FirefoxPlatform.getType(),
				type: Gamepad.Type.LOGITECH
			},
			buttons: {
				byButton: [0, 1, 2, 3, 4, 5, -1, -1, 6, 7, 8, 9, 11, 12, 13, 14, 10],
				byAxis: [-1, -1, -1, -1, -1, -1, [2, 0, 1],
					[2, 0, -1]
				]
			},
			axes: {
				byAxis: [0, 1, 3, 4]
			}
		}
	];

	Gamepad.prototype.init = function() {
		var platform = Gamepad.resolvePlatform(this);
		var that = this;

		this.platform = platform;
		this.updateStrategy.start(function() {
			that._update();
		});

		return platform.isSupported();
	};

	Gamepad.prototype.bind = function(event, listener) {
		if (typeof(this.listeners[event]) === 'undefined') {
			this.listeners[event] = [];
		}

		this.listeners[event].push(listener);

		return this;
	};

	Gamepad.prototype.unbind = function(type, listener) {
		if (typeof(type) === 'undefined') {
			this.listeners = {};

			return;
		}

		if (typeof(listener) === 'undefined') {
			this.listeners[type] = [];

			return;
		}

		if (typeof(this.listeners[type]) === 'undefined') {
			return false;
		}

		for (var i = 0; i < this.listeners[type].length; i++) {
			if (this.listeners[type][i] === listener) {
				this.listeners[type].splice(i, 1);

				return true;
			}
		}

		return false;
	};

	Gamepad.prototype.count = function() {
		return this.gamepads.length;
	};

	Gamepad.prototype._fire = function(event, data) {
		if (typeof(this.listeners[event]) === 'undefined') {
			return;
		}

		for (var i = 0; i < this.listeners[event].length; i++) {
			this.listeners[event][i].apply(this.listeners[event][i], [data]);
		}
	};

	Gamepad.getNullPlatform = function() {
		return Object.create(nullPlatform);
	};

	Gamepad.resolvePlatform = function(listener) {
		var platform = nullPlatform;
		var i;

		for (i = 0; !platform.isSupported() && (i < Gamepad.PlatformFactories.length); i++) {
			platform = Gamepad.PlatformFactories[i](listener);
		}

		return platform;
	};

	Gamepad.prototype._connect = function(gamepad) {
		var mapping = this._resolveMapping(gamepad);
		var count;
		var i;

		gamepad.state = {};
		gamepad.lastState = {};
		gamepad.updater = [];

		count = mapping.buttons.byButton.length;
		for (i = 0; i < count; i++) {
			this._addButtonUpdater(gamepad, mapping, i);
		}

		count = mapping.axes.byAxis.length;
		for (i = 0; i < count; i++) {
			this._addAxisUpdater(gamepad, mapping, i);
		}

		this.gamepads[gamepad.index] = gamepad;

		this._fire(Gamepad.Event.CONNECTED, gamepad);
	};


	Gamepad.prototype._addButtonUpdater = function(gamepad, mapping, index) {
		var updater = nullFunction;
		var controlName = getControlName(Gamepad.StandardButtons, index, 'EXTRA_BUTTON_');
		var getter = this._createButtonGetter(gamepad, mapping.buttons, index);
		var that = this;
		var buttonEventData = {
			gamepad: gamepad,
			control: controlName
		};

		gamepad.state[controlName] = 0;
		gamepad.lastState[controlName] = 0;

		updater = function() {
			var value = getter();
			var lastValue = gamepad.lastState[controlName];
			var isDown = value > 0.5;
			var wasDown = lastValue > 0.5;

			gamepad.state[controlName] = value;

			if (isDown && !wasDown) {
				that._fire(Gamepad.Event.BUTTON_DOWN, Object.create(buttonEventData));
			} else if (!isDown && wasDown) {
				that._fire(Gamepad.Event.BUTTON_UP, Object.create(buttonEventData));
			}

			if ((value !== 0) && (value !== 1) && (value !== lastValue)) {
				that._fireAxisChangedEvent(gamepad, controlName, value);
			}

			gamepad.lastState[controlName] = value;
		};

		gamepad.updater.push(updater);
	};

	Gamepad.prototype._addAxisUpdater = function(gamepad, mapping, index) {
		var updater = nullFunction;
		var controlName = getControlName(Gamepad.StandardAxes, index, 'EXTRA_AXIS_');
		var getter = this._createAxisGetter(gamepad, mapping.axes, index);
		var that = this;

		gamepad.state[controlName] = 0;
		gamepad.lastState[controlName] = 0;

		updater = function() {
			var value = getter();
			var lastValue = gamepad.lastState[controlName];

			gamepad.state[controlName] = value;

			if ((value !== lastValue)) {
				that._fireAxisChangedEvent(gamepad, controlName, value);
			}

			gamepad.lastState[controlName] = value;
		};

		gamepad.updater.push(updater);
	};

	Gamepad.prototype._fireAxisChangedEvent = function(gamepad, controlName, value) {
		var eventData = {
			gamepad: gamepad,
			axis: controlName,
			value: value
		};

		this._fire(Gamepad.Event.AXIS_CHANGED, eventData);
	};

	Gamepad.prototype._createButtonGetter = (function() {
		var nullGetter = function() {
			return 0;
		};

		var createRangeGetter = function(valueGetter, from, to) {
			var getter = nullGetter;

			if (from < to) {
				getter = function() {
					var range = to - from;
					var value = valueGetter();

					value = (value - from) / range;

					return (value < 0) ? 0 : value;
				};
			} else if (to < from) {
				getter = function() {
					var range = from - to;
					var value = valueGetter();

					value = (value - to) / range;

					return (value > 1) ? 0 : (1 - value);
				};
			}

			return getter;
		};

		var isArray = function(thing) {
			return Object.prototype.toString.call(thing) === '[object Array]';
		};

		return function(gamepad, buttons, index) {
			var getter = nullGetter;
			var entry;
			var that = this;

			entry = buttons.byButton[index];
			if (entry !== -1) {
				if ((typeof(entry) === 'number') && (entry < gamepad.buttons.length)) {
					getter = function() {
						return gamepad.buttons[entry];
					};
				}
			} else if (buttons.byAxis && (index < buttons.byAxis.length)) {
				entry = buttons.byAxis[index];
				if (isArray(entry) && (entry.length == 3) && (entry[0] < gamepad.axes.length)) {
					getter = function() {
						var value = gamepad.axes[entry[0]];

						return that._applyDeadzoneMaximize(value);
					};

					getter = createRangeGetter(getter, entry[1], entry[2]);
				}
			}

			return getter;
		};
	})();

	Gamepad.prototype._createAxisGetter = (function() {
		var nullGetter = function() {
			return 0;
		};

		return function(gamepad, axes, index) {
			var getter = nullGetter;
			var entry;
			var that = this;

			entry = axes.byAxis[index];
			if (entry !== -1) {
				if ((typeof(entry) === 'number') && (entry < gamepad.axes.length)) {
					getter = function() {
						var value = gamepad.axes[entry];

						return that._applyDeadzoneMaximize(value);
					};
				}
			}

			return getter;
		};
	})();

	Gamepad.prototype._disconnect = function(gamepad) {
		var newGamepads = [],
			i;

		if (typeof(this.gamepads[gamepad.index]) !== 'undefined') {
			delete this.gamepads[gamepad.index];
		}

		for (i = 0; i < this.gamepads.length; i++) {
			if (typeof(this.gamepads[i]) !== 'undefined') {
				newGamepads[i] = this.gamepads[i];
			}
		}

		this.gamepads = newGamepads;

		this._fire(Gamepad.Event.DISCONNECTED, gamepad);
	};

	Gamepad.prototype._resolveControllerType = function(id) {
		id = id.toLowerCase();

		if (id.indexOf('playstation') !== -1) {
			return Gamepad.Type.PLAYSTATION;
		} else if (
			id.indexOf('logitech') !== -1 || id.indexOf('wireless gamepad') !== -1) {
			return Gamepad.Type.LOGITECH;
		} else if (id.indexOf('xbox') !== -1 || id.indexOf('360') !== -1) {
			return Gamepad.Type.XBOX;
		} else {
			return Gamepad.Type.UNKNOWN;
		}
	};

	Gamepad.prototype._resolveMapping = function(gamepad) {
		var mappings = Gamepad.Mappings;
		var mapping = null;
		var env = {
			platform: this.platform.getType(),
			type: this._resolveControllerType(gamepad.id)
		};
		var i;
		var test;

		for (i = 0; !mapping && (i < mappings.length); i++) {
			test = mappings[i];
			if (Gamepad.envMatchesFilter(test.env, env)) {
				mapping = test;
			}
		}

		return mapping || Gamepad.StandardMapping;
	};

	Gamepad.envMatchesFilter = function(filter, env) {
		var result = true;
		var field;

		for (field in filter) {
			if (filter[field] !== env[field]) {
				result = false;
			}
		}

		return result;
	};

	Gamepad.prototype._update = function() {
		this.platform.update();

		this.gamepads.forEach(function(gamepad) {
			if (gamepad) {
				gamepad.updater.forEach(function(updater) {
					updater();
				});
			}
		});

		if (this.gamepads.length > 0) {
			this._fire(Gamepad.Event.TICK, this.gamepads);
		}
	},

	Gamepad.prototype._applyDeadzoneMaximize = function(
		value,
		deadzone,
		maximizeThreshold) {
		deadzone = typeof(deadzone) !== 'undefined' ? deadzone : this.deadzone;
		maximizeThreshold = typeof(maximizeThreshold) !== 'undefined' ? maximizeThreshold : this.maximizeThreshold;

		if (value >= 0) {
			if (value < deadzone) {
				value = 0;
			} else if (value > maximizeThreshold) {
				value = 1;
			}
		} else {
			if (value > -deadzone) {
				value = 0;
			} else if (value < -maximizeThreshold) {
				value = -1;
			}
		}

		return value;
	};

	exports.Gamepad = Gamepad;

})(((typeof(module) !== 'undefined') && module.exports) || window);

parser文件:

(1)parser.html
DOCTYPE html>
<html lang="en-us">
<head>
    <meta charset="utf-8">
    <title>Image Parsertitle>
    
    <link href="parser.css" rel="stylesheet">
    
    <script src="parser.js">script>

head>
<body onload="load()">
  <h1>Sprite Image Converterh1>
  
  <div id="sources" style="float:left" >
    <div id="left" class="column">
      <h2>Upload filesh2>
      <div id="dropzone">Drag & drop herediv>
      <ol id="curlist">ol>
    div>
    
    <div id="middle" class="column" style="max-width:420px">
      <h2>Select your color paletteh2>
      <div id="palettes">
        
      div>
    div>
  div>
  
  <div id="right" class="column">
    <h2>Get your outputh2>
    <ol id="outlist">ol>
  div>
  
body>
html>
(2)parser.css
* {
  text-shadow: 1px 1px 3px white;
  transition: all 350ms linear;
}

body {
  margin: 0;
}

html {
  background: rgb(245,245,245);
  font-family: Georgia;
}

grey {
  color: rgb(140,140,140);
}

weak {
  font-style: italic;
  margin-left: 14px;
}

.column {
  margin: 14px;
  background: white;
  border-radius: 7px;
  border: 1px solid rgb(210,210,210);
  box-shadow: 3px 3px 7px rgb(210,210,210);
  float: left;
  min-width: 280px;
}

h1 {
  background: black;
  border-bottom: 1px solid white;
  color: white;
  margin: 0;
  padding: 0 0 3px 3px;
}

h2 {
  margin-top: 3px;
  padding: 0 7px 0 7px;
}

h3 {
  padding: 0 0 0 14px;
}

#dropzone {
  margin: 7px 7px -7px 7px;
  padding: 14px;
  font-size: 1.4em;
  border: 2px dashed rgb(140,140,140);
  border-radius: 7px;
  text-align: center;
}
#dropzone:hover {
  background: rgb(252,252,252);
  border-color: rgb(117,117,210);
}

#scaler {
  margin-top: 14px;
}
#scaler h3 {
  margin: 7px;
  float: left;
}
#scaler div {
  width: 35%;
  float: right;
  clear: right;
  margin: -3px 3px 0 7px;
}
#scaler input {
  width: 70px;
}

#curlist {
  clear: both;
}

.squares {
  margin: 3px 0 3px 0;
  transition: 140ms all;
  clear: both;
  cursor: pointer;
}
.squares:hover, .squares.selected {
  margin-left: 7px;
  background: rgb(245,245,245);
}

.palettename {
  margin: 7px 0 0 14px;
  padding: 3px 7px 0 0;
  float: right;
  font-style: italic;
  color: darkgrey;
}

.square {
  margin: 3px;
  width: 28px;
  height: 28px;
  border: 1px solid white;
  outline: 1px solid darkgrey;
  display: inline-block;
  background: url('squarebackground.gif');
}

.squarein {
  width: 100%;
  height: 100%;
}

#outlist {
  overflow: hidden;
}

.output {
  padding-bottom: 7px;
  height: 84px;
  width: 490px;
  border: 1px solid rgb(210,240,210);
  border-top-left-radius: 3px;
  border-bottom-left-radius: 7px;
}

.status {
  height: 0;
  padding-top: 7px;
  padding-left: 7px;
  font-weight: bold;
}

.progress {
  background: lightgreen;
  height: 35px;
  margin-top: -7px;
  width: 0;
  z-index: 7;
}

.title {
  position: absolute;
  width: 70px;
  text-align: right;
}

.displayer { margin-bottom: 3px; }

.display {
  margin: 3px 0 0 77px;
  font-family: "Courier New", "Courier", monospace;
  width: 406px;
}
(3)parser.js
var num_files, dropzone, curlist, outlist, numdisplay, files, scale_x = 1, scale_y = 1, digitsize = 1,
  palette, palettes, palette_name, palette_names, palette_elem, palette_elems,
  max = Math.max, min = Math.min, round = Math.round, abs = Math.abs;

function load() {
  dropzone = document.getElementById("dropzone");
  curlist = document.getElementById("curlist");
  outlist = document.getElementById("outlist");
  numdisplay = document.getElementById("num_files");
  num_files = 0;
  dropzone.onchange = handleInputChange;
  dropzone.ondragover = handleDragOver;
  dropzone.ondragleave = handleDragOff;
  dropzone.ondrop = handleFileSelect;
  
  initializePalettes();
}

function handleInputChange(event) {
  dropzone.ondragleave();
  event.target.ondragleave();
  console.log(window.e = event);
}

function handleFileSelect(event) {
  preventAll(event);
  this.style.backgroundColor = "";
  
  var files = window.files = event.dataTransfer.files,
      output = [],
      type;
  for(var i = 0, f; f = files[i]; i++) {
    type = f.type.split("/")[1];
    if(type == "gif" || type == "png" || type == "jpeg" || type == "jpg") {
      ++num_files;
      output.push("
  • ", f.name, " (", type, ")"); outlist.appendChild(getWorkerElement(f)); } else output.push("
  • Only images are supported! (" + type + ")
  • "
    ); } dropzone.innerHTML = files.length + " file" + (files.length == 1 ? "" : "s") + " selected" curlist.innerHTML = output.join(""); } function getWorkerElement(file) { var element = getOutputListElement(file.name), reader = new FileReader(); reader.onprogress = updateProgress; reader.element = element; reader.onloadend = startWorking; reader.readAsDataURL(file); return element; } function getOutputListElement(name) { var element = document.createElement("li"), status = document.createElement("div"), progress = document.createElement("div"), base64 = document.createElement("div"), results = document.createElement("div"), close = document.createElement("div"); element.name = name; element.statusbase = status.innerText = "Uploading " + name + "..."; element.status = status; element.progress = progress element.base64 = base64, element.results = results; element.close = close; element.appendChild(status); element.appendChild(progress); element.appendChild(base64); element.appendChild(results); element.appendChild(close); status.className = "status"; element.className = "output"; progress.className = "progress"; base64.className = "base64"; results.className = "results"; close.className = "close"; setTextDisplayer(base64, "Base 64"); setTextDisplayer(results, "Sprite"); return element; } function updateProgress(event) { if(event.lengthComputable) { var percentLoaded = round((event.loaded / event.total) * 100); if(percentLoaded <= 100) { this.element.status.innerText = this.element.statusbase + " (" + percentLoaded + "%)"; this.element.progress.style.width = percentLoaded + "%"; } } } function startWorking(event) { var reader = event.currentTarget, element = reader.element, result = reader.result; setTimeout(function() { element.status.innerText = "Working on " + element.name + "..."; element.progress.style.backgroundColor = "rgb(117,175,245)"; }, 350); setDisplayerText(element.base64, result); var canvas = document.createElement("canvas"), context = canvas.getContext("2d"); var img = document.createElement("image"); img.src = result; img.onload = function() { canvas.width = img.width; canvas.height = img.height; context.drawImage(img, 0, 0); var data = context.getImageData(0, 0, img.width, img.height), output; setTimeout(function() { element.status.innerHTML = "" + element.name + "(" + palette_name + ")"; element.status.style.color = "white"; element.progress.style.backgroundColor = "rgb(35,35,70)"; output = parseData(data.data, element, palette); setDisplayerText(element.results, output); }, 350); } } function parseData(data, element) { var outs = [], occurences = {}, me, i, j, len = data.length; for(i = 0, j = 0; i < len; i += 4, ++j) { me = outs[j] = getClosestPalette([data[i], data[i+1], data[i+2], data[i+3]]); if(occurences[me]) ++occurences[me]; else occurences[me] = 1; } return combineSimilarChars(outs, getNewPaletteFromOccurences(occurences)); } function combineSimilarChars(textraw, paletteinfo) { var newpalette = paletteinfo[0], digitsize = paletteinfo[1], threshold = max(3, round(4 / digitsize)), text = "", i, j, len, cur; console.log(digitsize); for(i = 0, len = textraw.length; i < len; ++i) { j = i + 1; cur = textraw[i]; while(cur == textraw[j]) ++j; if(j - i > threshold) { text += "x" + makedigit(cur, digitsize, newpalette) + String(j - i) + ","; i = j - 1; } else text += makedigit(cur, digitsize, newpalette); } return "p[" + grabKeys(newpalette) + "]" + text; } function getNewPaletteFromOccurences(occurences) { var counts = [], key, len = 0; for(key in occurences) { counts[key] = len; ++len; } console.log(len); return [counts,getDigitSizeFromLength(len)]; } function makedigit(num, digitsize, newpalette) { return fillChars(max(0, digitsize - String(num).length), "0") + newpalette[num]; } function fillChars(num, a) { var text = ""; while(num--) text += a; return text; } function grabKeys(object) { var output = [], i; for(i in object) output.push(i); return output.join(","); } function getClosestPalette(rgba) { var i, bestloc, diff, bestdiff = Infinity; for(i = palette.length - 1; i >= 0; --i) { diff = arrayDiff(rgba, palette[i]); if(diff < bestdiff) { bestdiff = diff; bestloc = i; } } return bestloc; } function arrayDiff(a, b) { var sum = 0, i; for(i = a.length - 1; i >= 0; --i) sum += abs(a[i] - b[i]); return sum; } function arrayEquals(a,b) { return !(a<b || b<a); } function handleDragOver(event) { preventAll(event); event.dataTransfer.dropEffect = "copy"; this.style.backgroundColor = "lightgrey"; } function handleDragOff(event) { this.style.backgroundColor = ""; } function preventAll(event) { event.stopPropagation(); event.preventDefault(); } function setTextDisplayer(element, intitle) { element.className += " displayer"; var title = element.title = document.createElement("div"), display = element.display = document.createElement("input"), copyout = element.copyout = document.createElement("div"); title.innerText = intitle + ": "; title.className = "title"; display.className = "display"; element.appendChild(title); element.appendChild(display); } function setDisplayerText(element, text) { element.display.value = text; } function initializePalettes() { palettes = [ [ [0,0,0,0], [255,255,255,255], [0,0,0,255] ], [ [0,0,0,0], [255,255,255,255], [0,0,0,255], [199,199,192,255], [128,128,128,255] ], [ [0,0,0,0], // Grayscales (1-4) [255,255,255,255], [0,0,0,255], [188,188,188,255], [116,116,116,255], // Reds & Browns (5-11) [252,216,168,255], [252,152,56,255], [252,116,180,255], [216,40,0,255], [200,76,12,255], [136,112,0,255], [124,7,0,255], // Greens (12-14) [168,250,188,255], [128,208,16,255], [0,168,0,255], // Blues (15-20) [24,60,92,255], [0,128,136,255], [32,56,236,255], [156,252,240,255], [60,188,252,255], [92,148,252,255] ] ]; palette_names = [ "Black & White", "GameBoy", "Mario" ]; var container = document.getElementById("palettes"), i, j, len, current, mine, square, squarein; palette_elems = [] for(i = 0, len = palettes.length; i < len; ++i) { current = palettes[i]; palette_elems[i] = mine = document.createElement("div"); mine.innerHTML = "

    " + palette_names[i] + "

    "
    ; for(j = 0; j < current.length; ++j) { square = document.createElement("div"); squarein = document.createElement("div"); square.className = "square"; squarein.className = "squarein"; squarein.style.background = getColorFromArray(current[j]); square.appendChild(squarein); mine.appendChild(square); } mine.palettenum = i; mine.onclick = setCurrentPalette; mine.className = "squares"; container.appendChild(mine); } palette_elems[localStorage.palette_num || 0].click(); } function getColorFromArray(arr) { return "rgba(" + arr.join(", ") + ")"; } function setCurrentPalette(event) { var num = this.palettenum; palette = palettes[num]; palette_name = palette_names[num]; digitsize = getDigitSize(palette); digitsize = palette.length >= 10 ? 2 : 1; if(palette_elem) palette_elem.className = "squares"; palette_elem = this; this.className = "squares selected"; localStorage.palette_num = num; } function getDigitSize(palette) { return Number(String(palette.length).length) } function getDigitSizeFromLength(length) { return Number(String(length).length) } function setScaleValue(event) { window["scale_" + this.alpha] = Number(this.value) || 1; } function sum(a,b) { return Number(a) + Number(b); }

    Maps文件:

    (1)World12.js
    map.locs = [
      new Location(0, walkToPipe),
      new Location(1),
      new Location(2),
      new Location(1, exitPipeVert),
      new Location(3, exitPipeVert),
      new Location(1, false, 1000)
    ];
    map.areas = [
      new Area("Overworld", function() {
        setLocationGeneration(0);
        
        pushPreCastle();
        pushPrePattern("backcloud", 0, 4, 1);
        pushPreFloor(0, 0, 24);
        pushPreThing(PipeSide, 80, 16, 1);
        pushPrePipe(96, 0, 32);
      }),
      new Area("Underworld", function() {
        setLocationGeneration(1);
      
        fillPreThing(Brick, 0, 8, 1, 11, 8, 8);
        pushPreFloor(0, 0, 80);
        makeCeiling(48, 83);
        pushPreThing(Block, 80, jumplev1, Mushroom);
        fillPreThing(Block, 88, jumplev1, 4, 1, 8, 8);
        
        pushPreThing(Goomba, 128, 8);
        pushPreThing(Stone, 136, 8);
        pushPreThing(Goomba, 136, 16);
        pushPreThing(Stone, 152, 16, 1, 2);
        pushPreThing(Stone, 168, 24, 1, 3);
        pushPreThing(Stone, 184, 32, 1, 4);
        pushPreThing(Stone, 200, 32, 1, 4);
        pushPreThing(Stone, 216, 24, 1, 3);
        pushPreThing(Goomba, 232, 8);
        pushPreThing(Brick, 232, 40, Coin);
        pushPreThing(Stone, 248, 24, 1, 3);
        pushPreThing(Stone, 264, 16, 1, 2);
        
        fillPreThing(Brick, 312, 32, 1, 3, 8, 8);
        pushPreThing(Brick, 320, 32);
        pushPreThing(Coin, 321, 39);
        fillPreThing(Brick, 328, 32, 1, 3, 8, 8);
        fillPreThing(Coin, 330, 63, 4, 1, 8, 8);
        pushPreThing(Brick, 336, 48);
        pushPreThing(Brick, 344, 48);
        fillPreThing(Koopa, 352, 12, 2, 1, 12);
        fillPreThing(Brick, 352, 32, 1, 3, 8, 8);
        
        // pushPreThing(Coin, 360, 62);
        pushPreThing(Brick, 360, 32);
        fillPreThing(Brick, 368, 32, 1, 2, 8, 8);
        pushPreThing(Coin, 361, 39);
        pushPreThing(Brick, 368, 48, Star);
        fillPreThing(Brick, 416, 32, 2, 5, 8, 8);
        fillPreThing(Brick, 432, 16, 2, 3, 8, 8);
        fillPreThing(Brick, 432, 72, 2, 2, 8, 8);
        fillPreThing(Brick, 464, 32, 4, 1, 8, 8);
        fillPreThing(Brick, 464, 72, 5, 2, 8, 8);
        fillPreThing(Coin, 465, 39, 4, 1, 8, 8);
        pushPreThing(Koopa, 472, 12);
        fillPreThing(Brick, 496, 32, 2, 7, 8, 8);
        pushPreThing(Goomba, 494, 8);
        pushPreThing(Goomba, 510, 8);
        
        fillPreThing(Brick, 528, 72, 4, 2, 8, 8);
        fillPreThing(Brick, 536, 32, 1, 5, 8, 8);
        fillPreThing(Brick, 544, 32, 2, 1, 8, 8);
        pushPreThing(Coin, 545, 39);
        pushPreThing(Brick, 552, 40, Mushroom);
        
        fillPreThing(Brick, 576, 32, 2, 1, 8, 8);
        pushPreThing(Brick, 576, 40);
        fillPreThing(Brick, 576, 48, 2, 3, 8, 8);
        pushPreThing(Brick, 584, 40, Coin);
        pushPreThing(Goomba, 584, 72);
        
        fillPreThing(Brick, 608, 32, 4, 1, 8);
        fillPreThing(Brick, 608, 72, 4, 2, 8);
        fillPreThing(Goomba, 608, 40, 2, 1, 12);
        
        pushPreFloor(664, 0, 34);
        fillPreThing(Brick, 672, 40, 6, 2, 8, 8);
        fillPreThing(Coin, 674, 64, 6, 1, 8, 8);
        pushPreThing(Brick, 712, 88, [Mushroom, 1]);
        makeCeiling(720, 45);
        fillPreThing(Goomba, 768, 8, 3, 1, 12, 8);
        pushPrePipe(800, 0, 24, true, 2);
        pushPrePipe(848, 0, 32, true);
        pushPrePipe(896, 0, 16, true, false, 3);
        
        pushPreFloor(952, 0, 2);
        fillPreThing(Brick, 952, 8, 2, 3, 8, 8);
        
        pushPreFloor(984, 0, 12);
        pushPreThing(Stone, 1040, 8);
        pushPreThing(Stone, 1048, 16, 1, 2);
        pushPreThing(Stone, 1056, 24, 1, 3);
        pushPreThing(Stone, 1064, 32, 1, 4);
        pushPreThing(Stone, 1072, 32, 1, 4);
        pushPrePlatformGenerator(1096, 6, 1);
        // pushPreThing(PlatformGenerator, 1096, ceilmax, 6, 1);
        
        pushPreFloor(1144, 0, 8);
        fillPreThing(Brick, 1144, 40, 5, 1, 8, 8);
        pushPreThing(Koopa, 1152, 12, true);
        pushPreThing(Brick, 1184, 40, Mushroom);
        pushPrePlatformGenerator(1224, 6, -1);
        // pushPreThing(PlatformGenerator, 1224, ceilmax, 6, -1);
        
        pushPreFloor(1266, 0, 32);
        fillPreThing(Brick, 1266, 8, 17, 3, 8, 8);
        pushPreThing(PipeSide, 1314, 40, 4);
        pushPreThing(PipeVertical, 1330, 88, 64);
        makeCeiling(1274, 7);
        fillPreThing(Brick, 1346, 32, 7, 7, 8, 8);
        pushPreThing(ScrollEnabler, 1340, ceilmax);
        makeCeiling(1346, 17);
        pushPreWarpWorld(1400, 0, [[4,1],[3,1],[2,1]], 0, true);
        fillPreThing(Brick, 1506, 8, 2, 11, 8, 8);
      }),
      new Area("Underworld", function() {
        setLocationGeneration(2);
        
        pushPreFloor(0, 0, 17);
        fillPreThing(Brick, 0, 8, 1, 11, 8, 8);
        fillPreThing(Coin, 25, 7, 9, 1, 8, 8);
        fillPreThing(Brick, 24, 32, 9, 1, 8, 8);
        fillPreThing(Coin, 33, 39, 8, 1, 8, 8);
        pushPreThing(Brick, 96, 32, Coin);
        fillPreThing(Brick, 24, 64, 10, 4, 8, 8);
        fillPreThing(Brick, 104, 24, 2, 9, 8, 8);
        pushPreThing(PipeSide, 104, 16, 3);
        pushPreThing(PipeVertical, 120, 100, 100);
      }),
      new Area("Overworld", function() {
        setLocationGeneration(4);
        
        pushPrePattern("backreg", 104, 0, 1);
        pushPreFloor(0, 0, 58);
        pushPrePipe(0, 0, 16, false, false, 4);
        pushPreThing(Stone, 16, 8);
        pushPreThing(Stone, 24, 16, 1, 2);
        pushPreThing(Stone, 32, 24, 1, 3);
        pushPreThing(Stone, 40, 32, 1, 4);
        pushPreThing(Stone, 48, 40, 1, 5);
        pushPreThing(Stone, 56, 48, 1, 6);
        pushPreThing(Stone, 64, 56, 1, 7);
        pushPreThing(Stone, 72, 64, 2, 8);
        endCastleOutside(148);
      })
    ];
    
    (2)World13.js
    map.time = 300;
    map.locs = [
      new Location(0, true)
    ];
    map.areas = [
      new Area("Overworld", function() {
        setLocationGeneration(0);
    
        pushPreCastle();
        pushPrePattern("backcloud", 0, 4, 5);
        pushPreFloor(0, 0, 16);
        
        pushPreTree(144, 8, 4);
        pushPreTree(192, 32, 8);
        pushPreTree(208, 64, 5);
        fillPreThing(Coin, 217, 71, 3, 1, 8, 8, true);
        pushPreThing(Koopa, 240, 76, true);
        pushPreTree(256, 8, 3);
        pushPreThing(Coin, 266, 15);
        pushPreTree(280, 40, 5);
        fillPreThing(Coin, 297, 87, 2, 1, 8);
        pushPreTree(320, 72, 7);
        fillPreThing(Goomba, 352, 80, 2, 1, 16);
        pushPreTree(400, 0, 4);
        fillPreThing(Coin, 402, 55, 2, 1, 8, 8);
        pushPreThing(Platform, 440, 56, 6, [moveFloating, -4, 56]);
        pushPreTree(472, 0, 5);
        pushPreThing(Block, 472, 24, Mushroom);
        pushPreTree(480, 64, 4);
        fillPreThing(Coin, 482, 71, 4, 1, 8);
        pushPreTree(520, 0, 5);
        pushPreTree(560, 32, 3);
        pushPreThing(Koopa, 592, 76, true, [16, 88]);
        pushPreTree(608, 56, 6);
        pushPreThing(Goomba, 640, 64);
        fillPreThing(Coin, 681, 63, 2, 1, 8, 8);
        pushPreThing(Platform, 688, 40, 6, [moveSliding, 660, 720]);
        fillPreThing(Coin, 745, 71, 2, 1, 8, 8);
        pushPreThing(Platform, 752, 32, 6, [moveSliding, 700, 776]);
        fillPreThing(Coin, 777, 71, 2, 1, 8, 8);
        pushPreTree(784, 16, 4);
        pushPreTree(832, 48, 8);
        pushPreThing(Koopa, 880, 60, true);
        pushPreTree(904, 0, 3);
        fillPreThing(Coin, 906, 7, 3, 1, 8, 8);
        pushPreThing(Koopa, 912, 68, true, [4, 76]);
        pushPreTree(928, 32, 4);
        fillPreThing(Coin, 962, 63, 2, 1, 8, 8);
        pushPreTree(976, 32, 4);
        
        pushPreFloor(1032, 0, 46);
        pushPreThing(Platform, 1048, 56, 6, [moveSliding, 1008, 1076]);
        pushPreThing(Koopa, 1064, 12, true); 
        pushPreThing(Stone, 1104, 32, 1, 4);
        pushPreThing(Stone, 1112, 32, 1, 4);
        pushPreThing(Stone, 1120, 48, 1, 6);
        pushPreThing(Stone, 1128, 48, 1, 6);
        pushPreThing(Stone, 1136, 64, 1, 8);
        pushPreThing(Stone, 1144, 64, 1, 8);
        
        endCastleOutside(1220, 0, true, 11);
      })
    ];
    

    注意:

    由于博客字数限制,本篇文章只展示了部分代码。本项目的完整代码及素材包我已上传至资源

    你可能感兴趣的:(web前端项目-源码自取,前端,html,css,javascript)