/*
マップ画面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;
}
}