[pixi.js] MagicLight (4) ~Sprite, TouchEvent~

pixijsを使って、MagicLightを作ってみるよ。 :bouzu:

pixijs_magiclight4

SpriteクラスTextureクラスで表示してみたよ。 :boy:
画面をドラッグすると、光が発生するよ! :cake:

index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MagicLight [Sprite + Texture] | pixi.js</title>
<script src="js/pixi.min.js"></script>
<script src="js/stats.min.js"></script>

<style type="text/css">
  body {
    margin: 0;
    padding: 0;
  }
</style>

<script>
var stage, renderer, stats;
var loader;
var texture;
var container, back;
var bw = 1200;
var bh = 800;
var cx = 600;
var cy = 400;
var point = {x: 0, y: 0};
var position = {x: 0, y: 0, vx: 0, vy: 0};
var power = 0;
var head, tail;
var playing = false;
var deceleration = 0.992;
var max = 3;
var dragging = false;

function init() {
  stats = new Stats();
  stats.setMode(0);
  stats.domElement.style.position = "fixed";
  stats.domElement.style.right = "0px";
  stats.domElement.style.top = "0px";
  document.body.appendChild(stats.domElement);

  stage = new PIXI.Container();
  renderer = PIXI.autoDetectRenderer(bw, bh, {backgroundColor: 0x000000});
  document.body.appendChild(renderer.view);
  renderer.view.style.display = "block";

  loader = new PIXI.loaders.Loader();
  loader.add("circle", "assets/circle.png");
  loader.on("complete", complete);
  loader.load();

  update();

  resize();
  window.onresize = window.onorientationchange = resize;
}
function update() {
  if (playing) {
    emit(0);
    emit(1);
    emit(2);
  }

  renderer.render(stage);
  requestAnimationFrame(update);

  stats.update();
}
function complete() {
  texture = PIXI.Texture.fromImage("assets/circle.png");

  background();
  initialize();
  setup();
}
function initialize() {
  container = new PIXI.Container();
  stage.addChild(container);
  container.position.x = cx;
  container.position.y = cy;

  playing = true;
}
function setup() {
  stage.interactive = true;
  stage.buttonMode = true;
  stage.on("mousedown", press);
  stage.on("touchstart", press);
  stage.on("mouseup", release);
  stage.on("mouseupoutside", release);
  stage.on("touchend", release);
  stage.on("touchendoutside", release);
  stage.on("mousemove", drag);
  stage.on("touchmove", drag);
}
function press(event) {
  //event.data.originalEvent.preventDefault();
  dragging = true;
}
function release(event) {
  dragging = false;
}
function drag(event) {
    if (dragging) {
      var position = event.data.getLocalPosition(this);
      point.x = position.x - cx;
      point.y = position.y - cy;
    }
}
function emit(n) {
  position.vx *= 0.75;
  position.vy *= 0.75;
  position.vx += (point.x - position.x)*0.2*(n + 1)/max;
  position.vy += (point.y - position.y)*0.2*(n + 1)/max;
  position.x += position.vx;
  position.y += position.vy;
  power += Math.sqrt(position.vx*position.vx + position.vy*position.vy)*1.6*n/max;
  power *= 0.8;
  if (power > 256) power = 256;

  var circle = new PIXI.Sprite(texture);
  circle.pivot.x = 64;
  circle.pivot.y = 64;
  circle.width = circle.height = power*2;
  circle.tint = randomRGB();
  circle.blendMode = PIXI.BLEND_MODES.ADD;

  var particle = {};
  particle.vx = 0;
  particle.vy = 0;
  particle.scale = 3.2;
  particle.prev = null;
  particle.next = null;
  particle.live = true;
  particle.image = circle;
  particle.x = position.x - position.vx*n/max + (Math.random() - 0.5)*40;
  particle.y = position.y - position.vy*n/max + (Math.random() - 0.5)*40;
  particle.vx = position.vx*0.3;
  particle.vy = position.vy*0.3;
  particle.size = power/64;
  particle.update = function() {
    if (this.image.width < 5) {
      this.live = false;
      return;
    }
    this.scale *= deceleration;
    this.vx *= deceleration;
    this.vy *= deceleration;
    this.x += this.vx;
    this.y += this.vy;
    if (this.image.width < 40) {
      this.image.alpha = this.image.width/40;
    }
    this.image.x = this.x;
    this.image.y = this.y;
    this.image.scale.x = this.image.scale.y = this.size*this.scale;
  };

  container.addChild(particle.image);

  if (head == null) {
    head = tail = particle;
  } else {
    particle.prev = tail;
    tail = tail.next = particle;
  }
  particle = head;
  while (particle != null) {
    particle.update();
    if (!particle.live) {
      container.removeChild(particle.image);
      if (particle.prev == null) {
        head = particle.next;
      } else {
        particle.prev.next = particle.next;
      }
      if (particle.next == null) {
        tail = particle.prev;
      } else {
        particle.next.prev = particle.prev;
      }
    }
    particle = particle.next;
  }
}
function randomRGB() {
  var hue = Math.random()*360;
  var saturation = Math.random()*0.4 + 0.6;
  var rgb = HSVtoRGB(hue, saturation, 1);
  return rgb;
}
function HSVtoRGB(h, s, v) {
  var r, g, b, i, f, p, q, t;
  if (h && s === undefined && v === undefined) {
    s = h.s, v = h.v, h = h.h;
  }
  i = Math.floor(h * 6);
  f = h * 6 - i;
  p = v * (1 - s);
  q = v * (1 - f * s);
  t = v * (1 - (1 - f) * s);
  switch (i % 6) {
    case 0: r = v, g = t, b = p; break;
    case 1: r = q, g = v, b = p; break;
    case 2: r = p, g = v, b = t; break;
    case 3: r = p, g = q, b = v; break;
    case 4: r = t, g = p, b = v; break;
    case 5: r = v, g = p, b = q; break;
  }
  var rgb = (Math.floor(r*0xFF) << 16) | (Math.floor(g*0xFF) << 8) | Math.floor(b*0xFF);
  return rgb;
}
function resize(event) {
  bw = window.innerWidth;
  bh = window.innerHeight;
  cx = bw >> 1;
  cy = bh >> 1;
  renderer.resize(bw, bh);
  if (container) {
    container.position.x = cx;
    container.position.y = cy;
  }
  if (back) {
    back.clear();
    back.beginFill(0x000000);
    back.drawRect(0, 0, bw, bh);
    back.endFill();
  }
}
function background() {
  back = new PIXI.Graphics();
  stage.addChild(back);
  back.beginFill(0x000000);
  back.drawRect(0, 0, bw, bh);
  back.endFill();

  var version = PIXI.VERSION;
  var rendererType;
  switch (renderer.type) {
    case PIXI.RENDERER_TYPE.WEBGL :
      rendererType = "WebGL";
      break;
    case PIXI.RENDERER_TYPE.CANVAS :
      rendererType = "Context2D";
      break;
  }
  var txt = "HTML5 / pixi.js [" + version + "] (" + rendererType + ")";
  var basic = new PIXI.Text(txt, {"font": "14px Arial", "fill": "#FFFFFF", "align": "left"});
  stage.addChild(basic);
  basic.position.x = 4;
  basic.position.y = 2;
  basic.alpha = 0.6;
}
</script>
</head>
<body onload="init();" style="background-color:#000000">
</body>
</html>


[修正] (15/04/29 Wed 14:24)
pixi.js v3.0.2 にバージョンアップ。
PIXI.AssetLoader を PIXI.loaders.Loader に変更。PIXI.DisplayObjectContainer を PIXI.Container に変更。PIXI.blendModes を PIXI.BLEND_MODES に変更。イベントの処理方法も変更。
[修正] (15/05/10 Sun 18:27)
pixi.js v3.0.3 にバージョンアップ。