*シラネーヨとマターリしよーヨ(JScript)

申し訳ありませんが,この動的コンテンツはInternet Explorerでなければ実行できません。

「シラネーヨ」がマウスカーソルを追いかけます。マウスカーソルをつかまえると,「マターリしよーヨ」とおねだりします。Windows98/MeのIEだと「シラネーヨ」が崩れて表示されるかもしれません。

技術資料

クラスライブラリを整備してオブジェクト指向らしいコードに仕上げました(まだ完璧じゃないんだけど)。量が多いので細かい説明はなしです。

使用ツール:Microsoft Visual J++ 6.0

ソースファイル
<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
<TITLE></TITLE>

<script language=JavaScript1.2><!--
  function Point() { // Point(in x, y:number) | Point(in p:Point)
    this.x;
    this.y;
    // assert(arguments.length in [1..2])
    switch (arguments.length) {
      case 1: {
        // assert(typeof arguments[0] == "object")
        // assert(arguments[0].constructor == this.constructor)
        var p = arguments[0];
        this.x = p.x;
        this.y = p.y;
        break;
      }
      case 2:
        // assert(typeof arguments[0] typeof == "number" && typeof arguments[1] == "number")
        this.x = arguments[0];
        this.y = arguments[1];
        break;
      default:
        break;
    }
    this.move = function () // move(in p:Point) | move(in x, y:number)
    {
      // assert(arguments.length in [1..2])
      switch (arguments.length) {
        case 1:
          // assert(typeof arguments[0] == "object")
          // assert(arguments[0].constructor == this.constructor)
          var p = arguments[0];
          this.x = p.x;
          this.y = p.y;
          break;
        case 2:
          // assert(typeof arguments[0] == "number" && typeof arguments[1] == "number")
          this.x = arguments[0];
          this.y = arguments[1];
          break;
        default:
          return;
      }
    }
    this.translate = function ()
    {
      // assert(arguments.length in [1..2])
      switch (arguments.length) {
        case 1:
          // assert(typeof arguments[0] == "object")
          // assert(arguments[0].constructor == this.constructor)
          var p = arguments[0];
          this.x += p.x;
          this.y += p.y;
          break;
        case 2:
          // assert(typeof arguments[0] == "number" && typeof arguments[1] == "number")
          this.x += arguments[0];
          this.y += arguments[1];
          break;
        default:
          return;
      }
      return this;
    }
    this.toString = function ()
    {
      return '(x=' + this.x + ',' + 'y=' + this.y + ')';
    }
    // assert(typeof x == "number")
    // assert(typeof y == "number")
  }

  function Rectangle() {
    this.x;
    this.y;
    this.width;
    this.height;
    // assert(arguments.length in [2..4])
    switch (arguments.length) {
      case 2: // new Rectangle(p:Point, o:Dimension)
        // assert(typeof arguments[0] == "object")
        // assert(arguments[0].constructor == Point)
        // assert(typeof arguments[1] == "object")
        // assert(arguments[1].constructor == Dimension)
        this.x = arguments[0].x;
        this.y = arguments[0].y;
        this.width = arguments[1].width;
        this.height = arguments[1].height;
        break;
      case 3:
        if (typeof arguments[0] == "number" &&
          typeof arguments[1] == "number" &&
          arguments[2].constructor == Dimension)
        {
          // new Rectangle(x, y:number, o:Dimension)
          this.x = arguments[0];
          this.y = arguments[1];
          this.width = arguments[2].width;
          this.height = arguments[2].height;
        }
        else if (arguments[0].constructor == Point &&
          typeof arguments[1] == "number" &&
          typeof arguments[2] == "number")
        {
          // new Rectangle(p:Point, width, height:number)
          this.x = arguments[0].x;
          this.y = arguments[0].y;
          this.width = arguments[1];
          this.height = arguments[2];
        }
        break;
      case 4:  // new Rectangle(x, y, width, height:number)
        this.x = arguments[0];
        this.y = arguments[1];
        this.width = arguments[2];
        this.height = arguments[3];
        break;
      default:
        break;
    }
    this.contains = function (p)
    {
      // assert(p.constructor == Point)
      return
        p.x > this.x && p.x < (this.x + this.width - 1)
        && p.y > this.y && p.y < (this.y + this.height - 1);
    }
    this.toString = function ()
    {
      return '(x=' + this.x + ',' + 'y=' + this.y + 'w=' + this.width + 'h=' + this.height + ')';
    }
    // assert(typeof x == "number")
    // assert(typeof y == "number")
    // assert(typeof width == "number")
    // assert(typeof height == "number")
  }

  function Dimension() {
    this.width;
    this.height;
    // assert(arguments.length in [1..2])
    switch (arguments.length) {
      case 1: // new Dimensioni(d:Dimenstion)
        // assert(typeof arguments[0] == "object")
        // assert(arguments[0].constructor == this.constructor)
        this.width = arguments[0].width;
        this.height = arguments[0].height;
        break;
      case 2: // new Dimension(width, height:number);
        // assert(typeof arguments[0] == "object")
        // assert(arguments[0].constructor == this.constructor)
        this.width = arguments[0];
        this.height = arguments[1];
        break;
      default:
        break;
    }
    this.toString = function ()
    {
      return '(w=' + this.width + ',' + 'h=' + this.height + ')';
    }
  }

  function Wrapper(target) {
    this.target = target;
    this.getBounds = function ()
    {
      var p = this.getPosition();
      var s = this.getSize();
      return new Rectangle(p.x, p.y, s.width, s.height);
    }
    this.getSize = function ()
    {
      return new Dimension(this.target.offsetWidth, this.target.offsetHeight);
    }
    this.getPosition = function ()
    {
      return new Point(this.target.style.pixelLeft, this.target.style.pixelTop);
    }
    this.setPosition = function (x, y)
    {
      this.target.style.pixelLeft = x;
      this.target.style.pixelTop = y;
    }
    this.move = function (x, y)
    {
      this.setPosition(x, y);
    }
    this.translate = function (x, y)
    {
      var p = this.getPosition().translate(x, y);
      this.setPosition(p.x, p.y);
    }
    this.paint = function (str)
    {
      str = str.replace(/□/g, ' ');
      str = str.replace(/\n/g, '<br>');
      this.target.innerHTML = '<nobr>' + str + '</nobr>';
    }
  }

  function Agent(target, behavior) {
    this.proxy = new Wrapper(target); 
    this.actionList = new Array();
    this.currentAction = null;

    this.add = function (action, key) {
      this.actionList[key] = action;
      action.setPainter(this.proxy);
    }
    this.getPosition = function ()
    {
      return this.proxy.getPosition();
    }
    this.getSize = function ()
    {
      return this.proxy.getSize();
    }
    this.setPosition = function ()
    {
      var x, y;
      switch (arguments.length) {
        case 1:
          var p = arguments[0];
          x = p.x;
          y = p.y;
          break;
        case 2:
          x = arguments[0];
          y = arguments[1];
          break;
        default:
          return;
      }
      this.proxy.setPosition(x, y);
    }
    this.move = function ()
    {
      var x, y;
      switch (arguments.length) {
        case 1:
          var p = arguments[0];
          x = p.x;
          y = p.y;
          break;
        case 2:
          x = arguments[0];
          y = arguments[1];
          break;
        default:
          return;
      }
      this.proxy.move(x, y);
    }
    this.translate = function ()
    {
      var x, y;
      switch (arguments.length) {
        case 1:
          var p = arguments[0];
          x = p.x;
          y = p.y;
          break;
        case 2:
          x = arguments[0];
          y = arguments[1];
          break;
        default:
          return;
      }
      this.proxy.translate(x, y);
    }
    this.setAction = function (key)
    {
      this.currentAction = this.actionList[key];
    }
    this.run = behavior;

    this.play = function ()
    {
      if (this.currentAction != null) {
        this.currentAction.play();
      }
    }
  }
//--></script>

</HEAD>
<BODY>

<div id=contentPane style="BACKGROUND: #f0f0ff; FILTER: revealTrans(duration=1.5, transition=3); 
OVERFLOW: hidden; WIDTH: 640px; POSITION: relative; HEIGHT: 640px">
    <div id=charPane1 style="TOP 0px; LEFT: 0px; COLOR: #8080ff; POSITION: absolute; TOP: 500px">
</div>
    <div id=charPane2 style="TOP: 0px; left:500px; COLOR: #8080ff; POSITION: absolute; TOP: 500px">
</div>
    <div id=charPane3 style="TOP 500px; LEFT: 0px; COLOR: #8080ff; POSITION: absolute"></div>
    <div id=charPane4 style="TOP 5000px; LEFT: 500px; COLOR: #8080ff; POSITION: absolute"></div>
</div>

<script language=JavaScript1.2><!--
  document.all['contentPane'].style.background='white';
  document.all['contentPane'].filters.revealTrans.apply();
  document.all['contentPane'].style.background='#fc9';
  document.all['contentPane'].filters.revealTrans.play();
//--></script>

<script language=JavaScript1.2><!--
  function LeftTurn() {
    this.target;
    this.count = 0;
    var frames = [
      // [0]
       ' □ ∧ ∧□□□□□□□□□□□\n'
      +'□(´ー` )□□□□□□□□□□\n'
      +'□ \□< □□□□□□□□□ /| \n'
      +'□□□\ \______// □□□\n'
      +'□□□□ \□□□□□□□/□□\n' 
      +'□□□□□□∪∪ ̄∪∪ □□□□\n',
      // [1]
       ' □ ∧ ∧□□□□□□□□□□□\n'
      +'□(´ー` )□□□□□□□□□□\n'
      +'□ \□< □□□□□□□□□ /| \n'
      +'□□□\ \______// □□□\n'
      +'□□□□ \□□□□□□□/□□\n' 
      +'□□□□□□∪∪ ̄∪∪□□((□□((\n'
    ];
    this.setPainter = function (target)
    {
      this.target = target;
    }
    this.play = function ()
    {
      this.target.paint(frames[this.count]);
      this.count = (this.count + 1) % frames.length;
    }
  }
  function RightTurn() {
    this.target;
    this.count = 0;
    var frames = [
      // [0]
       '□□□□□□□□□□□□□□□ ∧ ∧□□\n'
      +'□□□□□□□□□□□□□□□ ( ´ー`)\n'
      +'□□□□|ヽ□□□□□□□□□□ >□/□□\n'
      +'□□□□ヽ\□□□□□□□□// □□□□\n'
      +'□□□□□ \ ̄ ̄ ̄ ̄ ̄/□□□□□□□□\n'
      +'□□□□□□□∪∪ ̄∪∪ □□□□□□□□\n',
      // [1]
       '□□□□□□□□□□□□□□□ ∧ ∧ □□\n'
      +'□□□□□□□□□□□□□□□ ( ´ー`)\n'
      +'□□□□|ヽ□□□□□□□□□□ >□/□□\n'
      +'□□□□ヽ\□□□□□□□□// □□□□\n'
      +'□□□□□ \ ̄ ̄ ̄ ̄ ̄/□□□□□□□□\n'
      +'□))□□))□□∪∪ ̄∪∪ □□□□□□□□\n'
    ];
    this.setPainter = function (target)
    {
      this.target = target;
    }
    this.play = function ()
    {
      this.target.paint(frames[this.count]);
      this.count = (this.count + 1) % frames.length;
    }
  }

  function Lost() {
    this.target;
    this.count = 0;
    var frames = [
      // [0]
       ' □ ∧ ∧□?□\n'
      +'□(´ー` )□□\n'
      +'□ \□< □□□□□□□□□ /| \n'
      +'□□□\ \______//□□□□□□\n'
      +'□□□□ \□□□□□□□/ □□□□\n'
      +'□□□□□□∪∪ ̄∪∪□□□□□□□\n',
      // [1]
       ' □∧ ∧□ □\n'
      +'□( ´ー`)\n'
      +'□ \□< □□□□□□□□□ /| \n'
      +'□□□\ \______//□□□□□□\n'
      +'□□□□ \□□□□□□□/ □□□□\n'
      +'□□□□□□∪∪ ̄∪∪□□□□□□□\n',
      // [2]
       ' □∧ ∧□ □ □┌─────────\n'
      +'□( ´ー`)□□ <□見失ったーヨ\n'
      +'□ \□< □□□ └───/|────□\n'
      +'□□□\ \______//□□□□□□\n'
      +'□□□□ \□□□□□□□/ □□□□\n'
      +'□□□□□□∪∪ ̄∪∪□□□□□□□\n',
    ];
    this.scenario = [
      "this.target.paint(frames[0]);",
      "this.target.paint(frames[1]);",
      "this.target.paint(frames[0]);",
      "this.target.paint(frames[1]);",
      "",
      "",
      "this.target.paint(frames[2]);",
      "",
      "",
      "",
      "",
    ];
    this.setPainter = function (target)
    {
      this.target = target;
    }
    this.play = function ()
    {
      eval(this.scenario[this.count]);
      this.count = (this.count + 1) % this.scenario.length;
    }
  }

  function Mattari() {
    this.target;
    this.count = 0;
    this.frames = [
      // [0]
       ' □∧ ∧□ □ □┌─────────\n'
      +'□(*´ー`)□□ <□マターリしよーヨ\n'
      +'□ \□< □□□ └───/|────□\n'
      +'□□□\ \______//□□□□□□\n'
      +'□□□□ \□□□□□□□/ □□□□\n'
      +'□□□□□□∪∪ ̄∪∪□□□□□□□\n'
    ];
    this.setPainter = function (target)
    {
      this.target = target;
    }
    this.play = function ()
    {
      this.target.paint(this.frames[this.count]);
      this.count = (this.count + 1) % this.frames.length;
    }
  }

  var contentPane;
  var p0 = new Point(0, 0);
  var sensedCursor = false;
  var step = 10;

  contentPane = document.all['contentPane'];
  contentPane.onmousemove = function () {
    p0.move(window.event.x, window.event.y);
    sensedCursor = true;
  }
  contentPane.onmouseout = function () {
    sensedCursor = false;
  }

  var behavior = function () {
    var p1 = this.getPosition();
    var dx = (p0.x > p1.x) ? step : -step;
    var dy = (p0.y > p1.y) ? step : -step;

    if (Math.abs(p0.x - p1.x) < 8) {
      dx = p0.x - p1.x;
    }

    this.setAction((p0.x <= p1.x) ? 'left' : 'right');

    if (Math.abs(p0.x - p1.x) < 8 && Math.abs(p0.y - p1.y) < 8) {
      this.setAction('mattari');
      dx = 4;
      dy = 4;
    }
    if (sensedCursor) {
      // 位置設定
      this.translate(dx, dy);
    } else {
      this.setAction('lost');
    }
    this.play();
  }

  var o1 = new Agent(document.all['charPane1'], behavior);
  o1.add(new LeftTurn(), 'left');
  o1.add(new RightTurn(), 'right');
  o1.add(new Lost(), 'lost');
  o1.add(new Mattari(), 'mattari');

  function run1() {
    o1.run();
    setTimeout("run1()", 200);
  }
  run1();

  var o2 = new Agent(document.all['charPane2'], behavior);
  o2.add(new LeftTurn(), 'left');
  o2.add(new RightTurn(), 'right');
  o2.add(new Lost(), 'lost');
  o2.add(new Mattari(), 'mattari');
  function run2() {
    o2.run();
    setTimeout("run2()", 300);
  }
  run2();

  var o3 = new Agent(document.all['charPane3'], behavior);
  o3.add(new LeftTurn(), 'left');
  o3.add(new RightTurn(), 'right');
  o3.add(new Lost(), 'lost');
  o3.add(new Mattari(), 'mattari');

  function run3() {
    o3.run();
    setTimeout("run3()", 400);
  }
  run3();

  var o4 = new Agent(document.all['charPane4'], behavior);
  o4.add(new LeftTurn(), 'left');
  o4.add(new RightTurn(), 'right');
  o4.add(new Lost(), 'lost');
  o4.add(new Mattari(), 'mattari');

  function run4() {
    o4.run();
    setTimeout("run4()", 500);
  }
  run4();
//--></script>
</BODY>
</HTML>

関連リンク

yumi-ii/shiraneyo AAアプリ研究室, Copyright (c) MURONO 2001-2002, 2004-2005, murono@mtc.biglobe.ne.jp