OSDN Git Service

1/11の更新
[html5test/HTML5Test.git] / test / html5test0007.htm
diff --git a/test/html5test0007.htm b/test/html5test0007.htm
new file mode 100644 (file)
index 0000000..bb1e87d
--- /dev/null
@@ -0,0 +1,645 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>HTML5 Test</title>
+  <link rel="stylesheet" href="http://sfpg.seesaa.net/styles-index.css" type="text/css" />
+  <style type="text/css">
+    #disp01 {margin:10px;}
+  </style>
+<script type="text/javascript" src="../scripts/jquery-1.4.4.min.js"></script>
+<!--<script type="text/javascript">
+
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-15457703-1']);
+  _gaq.push(['_setDomainName', '.seesaa.net']);
+  _gaq.push(['_trackPageview']);
+
+  (function () {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+
+</script>-->
+</head>
+<body>
+<div id="div001">
+<canvas id="disp01" width="320" height="240" ></canvas>
+</div>
+<div>
+<button type="button" id="start" disabled="true">開始</button>
+<button type="button" id="stop" disabled="true" >停止</button>
+</div>
+<script type="text/javascript">
+  
+  var sx = 80;
+  var sy = 60;
+  var width = 320;
+  var height = 240;
+
+
+  var ctx_main = $("#disp01")[0].getContext("2d");
+  var screenWidth = $("#disp01")[0].width;
+  var screenHeight = $("#disp01")[0].height;
+  var img;
+  var imageRoot = "../image/";
+  var imageCount = 0;
+  var imageLength = 0;
+  var imageLoaded = false;
+
+  var keyCheck = {up:false,down:false,left:false,right:false,z:false};
+
+  function ImageFile(src) {
+    this.src = src;
+    this.image = new Image();
+    this.image.parent = this;
+    this.image.onload = function () {
+//      this.parent.canvas = $("<canvas>")[0];
+//      this.parent.canvas.width = this.width;
+//      this.parent.canvas.height = this.height;
+//      this.parent.canvas.getContext("2d").drawImage(this, 0, 0);
+      ++imageLength;
+    };
+    this.image.onerror = function () { ExitError("Image Load Error"); };
+    return this;
+  }
+
+  ImageFile.prototype.load = function () { this.image.src = imageRoot + this.src; };
+   
+  var imageFiles = {
+    font : new ImageFile("Font.png"),
+    font1 : new ImageFile("Font2.png"),
+    author : new ImageFile("author.png"),
+    sky : new ImageFile("sky.png"),
+    player: new ImageFile("player.png")
+  };
+
+  var backBuffer = $("<canvas>")[0];
+  backBuffer.width = width + 160;
+  backBuffer.height = height + 120;
+  
+  var eraseColor = "black";
+  var ctx = backBuffer.getContext("2d");
+  var t = 0;
+  var renderTimerId = undefined;
+  var mainTimerId = undefined;
+  var keyBuffer = Array(0);
+  var player;
+
+
+  // プレイヤー
+  function Player() {
+    this.x = width / 2;
+    this.image = imageFiles.player.image;
+    this.y = height - this.image.height;
+    this.dir = 0;
+    this.count = 0;
+    return this;
+  }
+
+  Player.prototype.move = function () {
+
+    if(keyCheck.right){
+      this.dir = 1;
+      this.x += this.dir * 3;
+      if (this.x > (width - 16)) {
+        this.x = width - 16;
+      }
+
+    } else if(keyCheck.left){
+      this.dir = -1;
+      this.x += this.dir * 3;
+      if (this.x < 0) {
+        this.x = 0;
+      }
+    } else {
+      this.dir = 0;
+    }
+    this.count++;
+  }
+
+  Player.prototype.draw = function () {
+    var imagePos = 0;
+    switch (this.dir) {
+      case -1:
+        imagePos = 4 + ((this.count & 4) >> 2);
+        break;
+      case 1:
+        imagePos = 2 + ((this.count & 4) >> 2);
+        break;
+    }
+    ctx.drawImage(this.image, imagePos * 16, 0, 16, 16, this.x, this.y, 16, 16);
+  }
+
+  // ボールオブジェクト
+  function Ball(x, y, radius, xSpeed, ySpeed,index,color) {
+    this.x = x;
+    this.y = y;
+    this.xSpeed = xSpeed;
+    this.ySpeed = ySpeed;
+    this.radius = radius;
+    this.index = index;
+    this.color = color;
+    this.enable = false;
+    return this;
+  };
+
+//  Ball.prototype.init = function (x, y, radius,xSpeed,ySpeed,index) {
+//    this.x = x;
+//    this.y = y;
+//    this.xSpeed = xSpeed;
+//    this.ySpeed = ySpeed;
+//    this.radius = radius;
+//    this.index = index;
+//    this.enable = true;
+//  }
+
+  Ball.prototype.move = function () {
+
+    this.ySpeed += 0.25;
+    this.x += this.xSpeed;
+
+    if ((this.x + this.radius) > width) {
+      this.x = width - this.radius;
+      this.xSpeed = -(this.xSpeed);
+    }
+
+    if (this.x < this.radius) {
+      this.x = this.radius; // -this.x;
+      this.xSpeed = -(this.xSpeed);
+    }
+
+    this.y += this.ySpeed;
+
+    if ((this.y + this.radius) > height) {
+      this.y = height - this.radius;
+      this.ySpeed = -this.ySpeed ;
+    }
+
+    if (this.y < this.radius) {
+      this.y = this.radius;
+      this.ySpeed = -this.ySpeed ;
+    }
+  };
+
+  Ball.prototype.draw = function (pctx) {
+    var fillStyle = pctx.fillStyle;
+    //pctx.globalAlpha = 0.7;
+    pctx.fillStyle = this.color;
+    pctx.beginPath();
+    pctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true);
+    pctx.closePath();
+    pctx.fill();
+    pctx.fillStyle = fillStyle;
+    //pctx.globalAlpha = 1.0;
+  };
+
+  Ball.prototype.checkCollision = function (other) {
+    if (Math.pow(this.x - other.x, 2) + Math.pow(this.y - other.y, 2) < Math.pow(this.radius + other.radius, 2)) {
+      // 衝突しているので反発させる。
+      return true;
+    }
+    return false;
+  };
+
+  // ボール配列
+  var balls = new Array(0);
+   
+  // コンストラクタ
+  function Tasks() {
+    this.array = new Array(0);
+    this.needSort = false;
+    return this;
+  }
+
+
+  Tasks.prototype = {
+    // indexの位置のタスクを置き換える
+    setNextTask: function (index, func, priority) {
+      if (priority == undefined) {
+        priority = 10000;
+      }
+      func.priority = priority;
+      this.array[index] = func;
+      this.needSort = true;
+    },
+
+    pushTask: function (func, priority) {
+      if (priority == undefined) {
+        priority = 10000;
+      }
+      func.priority = priority;
+      for (var i = 0; i < this.length; ++i) {
+        if (this.array[i] == null) {
+          this.array[i] = func;
+          return;
+        }
+      }
+      this.array.push(func);
+      this.needSort = true;
+    },
+    // 配列を取得する
+    getArray: function () {
+      return this.array;
+    },
+    // タスクをクリアする
+    clear: function () {
+      this.array.length = 0;
+    },
+    // ソートが必要かチェックし、ソートする
+    checkSort: function () {
+      if (this.needSort) {
+        this.array.sort(function (a, b) { return a.priority > b.priority; });
+        needSort = false;
+      }
+    }
+  };
+
+  var tasks = new Tasks();
+  var img = new Image();
+
+
+  $(window).ready(function () {
+    ctx.fillStyle = "blue";
+    ctx.fillRect(0, 0, backBuffer.width, backBuffer.height);
+    ctx.setTransform(1, 0, 0, 1, sx, sy);
+    ctx.fillStyle = "white";
+
+    ctx.font = "12px 'MS ゴシック'";
+    ctx.fillText("なんちゃってボール反発です。", 0, 20, 240);
+    ctx.fillText("クリックするとボールが追加されます。", 0, 40, 240);
+    ctx.fillText("背景画像を表示してみました。", 0, 60, 240);
+    render();
+    var color = ["#0030ff", "#0060ff", "#0090ff", "#00c0ff"];
+
+    // 開始ボタンをクリックした時の処理
+    $("#start").click(function () {
+      //      renderTimerId = setInterval(render, 100);
+      tasks.pushTask(init);
+      tasks.pushTask(render, 65000);
+      tasks.pushTask(eraseBackBuffer, 65535);
+      balls.length = 0;
+      for (var i = 0; i < 5; ++i) {
+        var rad = 1 + Math.random() * 10;
+        balls.push(
+        new Ball(
+          Math.random() * (width - rad * 2) + rad,
+          Math.random() * (height - rad * 2) + rad,
+          rad,
+          (Math.random() * 5 + 5) * (Math.random() >= 0.5 ? -1 : 1),
+          Math.random() * 4 + 9,
+          i,
+          color[(Math.random() * 4) | 0]
+          )
+        );
+      }
+      mainTimerId = setTimeout(processMain, 50);
+      $("#stop")[0].disabled = false;
+      $("#start")[0].disabled = true;
+    });
+
+    // 停止ボタンをクリックしたときの処理
+    $("#stop").click(function () {
+      //      if (renderTimerId != undefined) {
+      //        clearInterval(renderTimerId);
+      //        renderTimerId = undefined;
+      //      }
+      if (mainTimerId != undefined) {
+        clearTimeout(mainTimerId);
+        mainTimerId = undefined;
+      }
+
+      tasks.clear();
+
+      $("#stop")[0].disabled = true;
+      $("#start")[0].disabled = false;
+    });
+
+    // マウスクリックした時の処理
+    $("#disp01").click(function (e) {
+      if ($("#start")[0].disabled && balls.length < 300) {
+        var color = ["#ff3000", "#ff6000", "#ff9000", "#ffc000"];
+        var x = e.pageX - this.offsetLeft;
+        var y = e.pageY - this.offsetTop;
+        var rad = 1 + Math.random() * 10;
+        balls.push(
+        new Ball(
+          x,
+          y,
+          rad,
+          (Math.random() * 9) * (Math.random() >= 0.5 ? -1 : 1),
+          Math.random() * -12,
+          balls.length,
+          color[(Math.random() * 4) | 0]
+          )
+        );
+      }
+    });
+
+    $(document.body).keydown(function (e) {
+
+      if (keyBuffer.length > 16) {
+        keyBuffer.shift();
+      }
+      keyBuffer.push(e.keyCode);
+      switch (e.keyCode) {
+        case 37:
+          keyCheck.left = true;
+          break;
+        case 38:
+          keyCheck.up = true;
+          break;
+        case 39:
+          keyCheck.right = true;
+          break;
+        case 40:
+          keyCheck.down = true;
+          break;
+        case 90:
+          keyCheck.z = true;
+          break;
+      }
+    });
+
+    $(document.body).keyup(function (e) {
+      switch (e.keyCode) {
+        case 37:
+          keyCheck.left = false;
+          break;
+        case 38:
+          keyCheck.up = false;
+          break;
+        case 39:
+          keyCheck.right = false;
+          break;
+        case 40:
+          keyCheck.down = false;
+          break;
+        case 90:
+          keyCheck.z = false;
+          break;
+      }
+
+    });
+
+    // 準備ができたので開始ボタンを押せるようにする
+    $("#start")[0].disabled = false;
+  });
+
+  var r = 0;
+
+  // 描画処理
+  function render() {
+    ctx_main.drawImage(backBuffer, sx, sy, width, height, 0, 0, screenWidth, screenHeight);
+  }
+
+  // バックバッファの消去
+  function eraseBackBuffer() {
+    ctx.fillStyle = eraseColor;
+    ctx.fillRect(0, 0, width, height);
+  }
+
+
+  // 処理メイン
+  // バックバッファの描画
+  var period = 0;
+  var ellapsedTime = 0;
+  var processCount = 0;
+
+  function processMain() {
+    var startTime = new Date().getTime();
+    processCount++;
+    // メインに描画
+    try {
+      tasks.checkSort();
+      $.each(tasks.getArray(),function (taskIndex) {
+        if (this != null) {
+          this(taskIndex);
+        }
+      }
+      );
+    } catch(e) {
+      ExitError(e);
+    }
+    //render();
+    //ctx.fillStyle = "black";
+    var endTime = new Date().getTime();
+    ellapsedTime = endTime - startTime;
+    period = 33 - (ellapsedTime) % 33;
+    mainTimerId = setTimeout(processMain, period);
+  }
+
+  // 初期化タスク
+  function init(taskIndex) {
+    if (!imageLoaded) {
+      ctx.fillStyle = "black";
+      ctx.fillRect(0, 0, width, height);
+      ctx.fillStyle = "white";
+      ctx.fillText("Loadint Image Data", 0, 20, 240);
+      $.each(imageFiles, function (key, value) {
+        imageCount++;
+        this.load();
+      });
+    }
+    tasks.setNextTask(taskIndex, checkLoad);
+  }
+
+
+  // エラーで終了する。
+  function ExitError(e) {
+    clearTimeout(mainTimerId);
+    ctx.fillStyle = "red";
+    ctx.fillRect(0, 0, width, height);
+    ctx.fillStyle = "white";
+    ctx.fillText("Error : " + e, 0, 20, 240);
+    render();
+    throw e;
+  }
+
+  // イメージがとロードされたかチェックする
+  function checkLoad(taskIndex) {
+    if (this.message == undefined) {
+      this.message = "Loading Image Data";
+      this.counter = 0;
+    } else {
+      this.counter++;
+      if (counter >= 10) {
+        this.counter = 0;
+        this.message += ".";
+      }
+    }
+    ctx.fillStyle = "black";
+    ctx.fillRect(0, 0, width, height);
+
+    if (imageCount == imageLength || imageLoaded) {
+      this.message = "Loading Image Data";
+      this.counter = 0;
+      imageLoaded = true;
+      tasks.setNextTask(taskIndex, printAuthor());
+      ctx.fillStyle = "white";
+      ctx.fillText(this.message + "OK", 0, 20, width);
+    } else {
+      ctx.fillStyle = "white";
+      ctx.fillText(this.message, 0, 20, width);
+    }
+  }
+
+  // 作者表示
+  function printAuthor() {
+    var step = 0;
+    var count = 0;
+    var wait = 60;
+    keyBuffer.length = 0;
+    return function (taskIndex) {
+
+      // 何かキー入力があった場合は次のタスクへ
+      if (keyBuffer.length > 0) {
+        keyBuffer.length = 0;
+        step = 4;
+      }
+
+      switch (step) {
+        // フェード・イン             
+        case 0:
+          count += 0.1;
+          if (count >= 1.0) step++;
+          break;
+        // 待ち             
+        case 1:
+          if (! --wait) step++;
+          break;
+        //フェードアウト            
+        case 2:
+          count -= 0.1;
+          if (count <= 0.0) {
+            count = 0.0;
+            wait = 30;
+            step++;
+          }
+          break;
+        // 少し待ち            
+        case 3:
+          if (! --wait) {
+            step++;
+          }
+          // 次のタスクへ
+        case 4:
+          tasks.setNextTask(taskIndex, ballAction);
+          tasks.pushTask(function () { ctx.drawImage(imageFiles.sky.image, 0, 0); }, 5000);
+          player = new Player();
+          tasks.pushTask(function () { player.move(); player.draw(); });
+          tasks.pushTask(addCount);
+          break;
+      }
+      var backup = ctx.globalAlpha;
+      ctx.globalAlpha = count;
+      ctx.drawImage(imageFiles.author.image, (width - imageFiles.author.image.width) / 2, (height - imageFiles.author.image.height) / 2);
+      ctx.globalAlpha = backup;
+    };
+  }
+
+  // 処理時間を表示する。
+  function addCount() {
+//    var txt = "処理時間:" + ellapsedTime + "ms";
+//    ctx.textBaseline = "top";
+//    var textWidth = ctx.measureText(txt);
+//    ctx.fillStyle = "black";
+//    ctx.fillRect(0, 0, textWidth.width, 12);
+//    ctx.fillStyle = "white";
+    //    ctx.fillText(txt, 0, 0, textWidth.width);
+    var txt = "Process Time: " + ellapsedTime + "ms\n\nTest Program.";
+    print(0, 0, txt);
+  }
+   
+  // ボール初期化タスク
+  function ballAction() {
+    for (var i = 0, last = balls.length; i < last; ++i) {
+      var srcBall = balls[i];
+      srcBall.move();
+      srcBall.draw(ctx);
+      for (var j = i + 1; j < last; ++j) {
+        if (srcBall.checkCollision(balls[j])) {
+          bound(srcBall, balls[j]);
+        }
+      }
+    }
+  }
+
+  // 衝突時の処理
+  function bound(src, dest) {
+    // 半径を質量と見立てる。
+    var srcMass = src.radius ;
+    var destMass = dest.radius ;
+    var totalMass = srcMass + destMass;
+    var boundRate = 1.95;
+    var c = { x: dest.x - src.x, y: dest.y - src.y };
+
+    // 正規化
+    var vs = Math.sqrt(c.x * c.x + c.y * c.y);
+    c.x = c.x / vs;
+    c.y = c.y / vs;
+
+    // 内積
+    var dot = (src.xSpeed - dest.xSpeed) * c.x + (src.ySpeed - dest.ySpeed) * c.y;
+
+    // めり込みを補正する。
+    if ((src.radius + dest.radius) > vs) {
+      var a = src.radius + dest.radius - vs;
+
+//      var m = (src.radius + dest.radius) / vs;
+      var ax = (c.x * a) / 2;
+      var ay = (c.y * a) / 2;
+      dest.x = dest.x + ax;
+      dest.y = dest.y + ay;
+      src.x = src.x - ax;
+      src.y = src.y - ay;
+//          while ((Math.pow(dest.x - src.x, 2) + Math.pow(dest.y - src.y, 2)) <= Math.pow(src.radius + dest.radius, 2)) {
+//            dest.x += c.x/2;
+//            dest.y += c.y/2;
+//            src.x -= c.x/2;
+//            src.y -= c.y/2;
+//          }  
+//         
+
+    }
+
+
+    // 定数ベクトル
+    var v = { x: boundRate * dot / totalMass * c.x, y: boundRate * dot / totalMass * c.y };
+    src.xSpeed = -destMass * v.x + src.xSpeed;
+    src.ySpeed = -destMass * v.y + src.ySpeed;
+
+    dest.xSpeed = srcMass * v.x + dest.xSpeed;
+    dest.ySpeed = srcMass * v.y + dest.ySpeed;
+
+//    src.x += src.xSpeed;
+//    src.y += src.ySpeed;
+
+//    dest.x += dest.xSpeed;
+//    dest.y += dest.ySpeed;
+
+  }
+
+  // ビットマップキャラクターで文字表示する
+  function print(x, y, str) {
+    var startx = x;
+    var font = imageFiles.font.image;
+    for (var i = 0; i < str.length; ++i) {
+      var c = str.charCodeAt(i);
+      if (c == 0xa) {
+        y += 8;
+        x = startx;
+      } else {
+        c -= 0x20;
+        var ypos = parseInt(c / 16) * 8;
+        var xpos = (c % 16) * 8;
+        ctx.drawImage(font, xpos, ypos, 8, 8, x, y, 8, 8);
+        x += 8;
+      }
+    }
+  }
+
+</script>
+</body>
+</html>