/* マップ画面4方向スクロール移動テスト 2010-08-08 創作プログラミングの街 */ // HTML出力 document.write('
'); document.write(''); document.write('
'); document.write(''); document.write('
'); // 開始フラグ var testStart = false; // 現在位置 var x = 40; var y = 40; // スクロール状態 var scrollState = 0; // スクロール方向 var scrollDirect = 0; // スクロール位置 var scrollPos = 0; var dx = 0; var dy = 0; // マップチップ画像配列 var chipList = new Array(); // マップデータ配列 var map = new Array(); // マップチップサイズ var tip_width = 20; var tip_height = 20; // マップサイズ var map_cols = 100; var map_rows = 100; // 表示領域サイズ(チップ数) var view_cols = 15; var view_rows = 15; // 表示領域サイズ var view_width = view_cols * tip_width; var view_height = view_rows * tip_height; // 表示Canvas var viewCanvas = document.getElementById('view_canvas'); // マップ描画Canvas(非表示) var mapCanvas = document.getElementById('map_canvas'); // 方向キー状態フラグ var stick = 0; var DIR_UP = 1; var DIR_DOWN = 2; var DIR_LEFT = 4; var DIR_RIGHT = 8; init(); function init() { // CanvasとImageDataが利用できなければ戻る if (!mapCanvas.getContext || !mapCanvas.getContext('2d').createImageData) { return; } var i; var j; // 乱数でマップデータ作成 for (i = 0;i < map_rows;i++) { for (j = 0;j < map_cols;j++) { map[j + i * map_cols] = Math.floor(Math.random() * 4); } } // Canvasのコンテキスト取得 var mapContext = mapCanvas.getContext('2d'); // ImageDataオブジェクトを作成しマップチップ画像配列に追加 for (i = 0;i < 4;i++) { chipList.push(mapContext.createImageData(tip_width, tip_height)); } // チップ0(赤)各ピクセルの色情報設定 for (i = 0;i < tip_width;i++) { for (j = 0;j < tip_height;j++) { // 赤成分 chipList[0].data[j * 4 + i * tip_width * 4] = 224 + Math.floor(Math.random() * 32); // 緑成分 chipList[0].data[1 + j * 4 + i * tip_width * 4] = Math.floor(Math.random() * 32); // 青成分 chipList[0].data[2 + j * 4 + i * tip_width * 4] = Math.floor(Math.random() * 32); // アルファ成分 chipList[0].data[3 + j * 4 + i * tip_width * 4] = 255; } } // チップ1(緑)各ピクセルの色情報設定 for (i = 0;i < tip_width;i++) { for (j = 0;j < tip_height;j++) { // 赤成分 chipList[1].data[j * 4 + i * tip_width * 4] = Math.floor(Math.random() * 32); // 緑成分 chipList[1].data[1 + j * 4 + i * tip_width * 4] = 224 + Math.floor(Math.random() * 32); // 青成分 chipList[1].data[2 + j * 4 + i * tip_width * 4] = Math.floor(Math.random() * 32); // アルファ成分 chipList[1].data[3 + j * 4 + i * tip_width * 4] = 255; } } // チップ2(青)各ピクセルの色情報設定 for (i = 0;i < tip_width;i++) { for (j = 0;j < tip_height;j++) { // 赤成分 chipList[2].data[j * 4 + i * tip_width * 4] = Math.floor(Math.random() * 32); // 緑成分 chipList[2].data[1 + j * 4 + i * tip_width * 4] = Math.floor(Math.random() * 32); // 青成分 chipList[2].data[2 + j * 4 + i * tip_width * 4] = 224 + Math.floor(Math.random() * 32); // アルファ成分 chipList[2].data[3 + j * 4 + i * tip_width * 4] = 255; } } // チップ3(灰)各ピクセルの色情報設定 for (i = 0;i < tip_width;i++) { for (j = 0;j < tip_height;j++) { // 赤成分 chipList[3].data[j * 4 + i * tip_width * 4] = 160 + Math.floor(Math.random() * 32); // 緑成分 chipList[3].data[1 + j * 4 + i * tip_width * 4] = 160 + Math.floor(Math.random() * 32); // 青成分 chipList[3].data[2 + j * 4 + i * tip_width * 4] = 160 + Math.floor(Math.random() * 32); // アルファ成分 chipList[3].data[3 + j * 4 + i * tip_width * 4] = 255; } } // スクロールテスト領域にキーイベントハンドラを追加 document.getElementById("testArea").onkeydown = keydownHandler; document.getElementById("testArea").onkeyup = keyupHandler; // 開始ボタンを有効化 document.getElementById("testBtn").disabled = false; } // 開始ボタンクリック時 function start() { // フォーカス保持用テキスト欄にフォーカス設定 document.getElementById("focusArea").focus(); // 既に開始済みなら戻る if (testStart) { return; } drawScrollCanvas(x, y, 0); draw(); // メインループ呼び出し setTimeout("loop()", 30); testStart = true; } // メインループ function loop() { switch (scrollState) { // 非スクロール時 case 0: switch (stick) { // 上キー押下 case DIR_UP: if (y > 0) { dir = DIR_UP; dx = 0; dy = -1; scrollPos = 0; drawScrollCanvas(x, y, dir); scrollState = 1; } break; // 下キー押下 case DIR_DOWN: if (y < map_rows - (view_rows)) { dir = DIR_DOWN; dx = 0; dy = 1; scrollPos = 0; drawScrollCanvas(x, y, dir); scrollState = 1; } break; // 左キー押下 case DIR_LEFT: if (x > 0) { dir = DIR_LEFT; dx = -1; dy = 0; scrollPos = 0; drawScrollCanvas(x, y, dir); scrollState = 1; } break; // 右キー押下 case DIR_RIGHT: if (x < map_cols - (view_cols)) { dir = DIR_RIGHT; dx = 1; dy = 0; scrollPos = 0; drawScrollCanvas(x, y, dir); scrollState = 1; } break; } break; // スクロール中 case 1: // スクロール位置更新 if (++scrollPos == tip_width) { x += dx; y += dy; // スクロール終了時に同方向キー押下中で移動可能なら続いて移動 if (stick == dir && (x + dx) >= 0 && (x + dx) <= map_cols - (view_cols) && (y + dy) >= 0 && (y + dy) <= map_rows - (view_rows)) { scrollPos = 0; drawScrollCanvas(x, y, dir); } else { scrollState = 0; } } break; } draw(); setTimeout("loop()", 30); } // スクロールキャンバス描画 function drawScrollCanvas(sx, sy, dir) { // Canvasのコンテキスト取得 var mapContext = mapCanvas.getContext('2d'); switch (dir) { // 新規描画 case 0: // マップ描画Canvasにスクロール範囲を描画 for (i = 0;i < view_rows;i++) { for (j = 0;j < view_cols;j++) { mapContext.putImageData(chipList[map[sx + j + (sy + i) * map_cols]], j * tip_width, i * tip_height); } } break; // 上スクロール case DIR_UP: // マップ描画Canvasにスクロール範囲を描画 for (i = 0;i < view_rows + 1;i++) { for (j = 0;j < view_cols;j++) { mapContext.putImageData(chipList[map[sx + j + (sy - 1 + i) * map_cols]], j * tip_width, i * tip_height); } } break; // 下スクロール case DIR_DOWN: // マップ描画Canvasにスクロール範囲を描画 for (i = 0;i < view_rows + 1;i++) { for (j = 0;j < view_cols;j++) { mapContext.putImageData(chipList[map[sx + j + (sy + i) * map_cols]], j * tip_width, i * tip_height); } } break; // 左スクロール case DIR_LEFT: // マップ描画Canvasにスクロール範囲を描画 for (i = 0;i < view_rows;i++) { for (j = 0;j < view_cols + 1;j++) { mapContext.putImageData(chipList[map[sx - 1 + j + (sy + i) * map_cols]], j * tip_width, i * tip_height); } } break; // 右スクロール case DIR_RIGHT: // マップ描画Canvasにスクロール範囲を描画 for (i = 0;i < view_rows;i++) { for (j = 0;j < view_cols + 1;j++) { mapContext.putImageData(chipList[map[sx + j + (sy + i) * map_cols]], j * tip_width, i * tip_height); } } break; } } // 表示Canvasに描画 function draw() { // Canvasのコンテキスト取得 var viewContext = viewCanvas.getContext('2d'); var drawX = 0; var drawY = 0; if (dx > 0) { drawX = dx * scrollPos; } if (dx < 0) { drawX = tip_width + (dx * scrollPos); } if (dy > 0) { drawY = dy * scrollPos; } if (dy < 0) { drawY = tip_height + (dy * scrollPos); } // マップ描画Canvasを転送 viewContext.drawImage(mapCanvas, drawX, drawY, 300, 300, 0, 0, 300, 300); } // キー押下イベント処理 function keydownHandler(e) { var code = 0; code = e.keyCode; // カーソルキー押下状態に応じて方向キーフラグ設定 switch (code) { // 上キー case 38: stick |= DIR_UP; break; // 下キー case 40: stick |= DIR_DOWN; break; // 左キー case 37: stick |= DIR_LEFT; break; // 右キー case 39: stick |= DIR_RIGHT; break; } } // キー解放イベント処理 function keyupHandler(e) { var code = 0; code = e.keyCode; // カーソルキー押下状態に応じて方向キーフラグ設定 switch (code) { // 上キー case 38: stick &= ~DIR_UP; break; // 下キー case 40: stick &= ~DIR_DOWN; break; // 左キー case 37: stick &= ~DIR_LEFT; break; // 右キー case 39: stick &= ~DIR_RIGHT; break; } }