15 PUZZLE Ver.1.04(配列記述見直し)

20131127a

アイソン彗星を肉眼で見てみたいと思いますが、悪天候が続く予報で見れそうにありません。・・・今後は、明け方・・・と言うよりは、未明の空に見えるようです。

「国際宇宙ステーション(ISS)に滞在中の若田光一さんが、太陽に近づきつつあるアイソン彗星を超高感度カメラで撮影」というニュースをTVでは観ました。

2013/11/30追記
NASAによると、アイソン彗星は29日未明、太陽に最接近した際に崩壊し、ほとんど蒸発したとのこと。・・・こんなことになるとは・・・無念じゃ。

そんなこんなで、今回も星雲・星団・銀河の写真をネットから収集してみました。

これを機に宇宙に興味を持ってくれる若者が増えてくれることを期待して・・・。

今回、画像の配列(PICTURES)内の要素にラベルをつけることで、ひとつの要素内に、「ファイル名(fname:)」、「タイトル(title:)」、「説明文(txt:)」を記述しました。

これにより、配列を1種類にまとめられ、説明を書くときに「何番目の要素やったかな?」と悩む必要がなくなりました。

また、これまでは写真の下に説明文だけでしたが、「タイトル」と「説明文」にブロックを分け、それぞれCSSで見栄えを変えられるようにしました。



ソースはこちら。


<!doctype html>
<html lang="ja">
<head>
	<meta charset="utf-8">
	<title>15パズル</title>
	<meta name="viewport" content="width=600">
	<link rel="stylesheet" type="text/css" href="../css/15-puzzle.css">
	<script type="text/javascript" src="../js/15-puzzle104.js">
	</script>
</head>
<body onload="init()">
	<div id="top_title"></div>
	<canvas id="gameCanvas" width="600" height="600"></canvas>
	<div id="pict_title"></div>
	<div id="pict_txt"></div>
</body>
</html>

// 各種設定
var PICTURES = [
{fname:'image104/star_LMC.jpg',title:'大マゼラン雲',txt:'Sm 型の棒渦巻銀河とされるが、Irr-I 型の不規則銀河に分類されることもある。小マゼラン雲とともに銀河系の伴銀河となっており、アンドロメダ銀河などとともに局部銀河群を構成している。南天にあるため、日本からは見ることができない。南半球では、かじき座とテーブルさん座にまたがるぼんやりとした雲のように見える。太陽系からおよそ16万光年(5万パーセク)の距離に位置し、質量は銀河系の10分の1程度、直径は銀河系の20分の1程度の矮小銀河であり、局部銀河群の中ではアンドロメダ銀河 (M31)・銀河系・さんかく座銀河 (M33) に次ぐ4番目に大きなメンバーである。'},
{fname:'image104/star_M8_higata.jpg',title:'干潟星雲、M8、NGC6523',txt:'いて座にある散光星雲(輝線星雲)である。散光星雲を南北に横切る帯状の暗黒星雲が存在し、その姿が干潟に似ていることからその名が付けられている。星雲と同じ位置に散開星団 NGC6530 も重なって見える。'},
{fname:'image104/star_M17_hakucyou.jpg',title:'オメガ星雲、白鳥星雲、M17、NGC6618',txt:'いて座に位置する散光星雲である。距離は約4,200光年。1746年にフィリップ・ロワ・ド・シェゾーによって発見された。実直径は約44×36光年。星雲の中にループ状の構造が見えることから、これをいろいろな物に見立てて、「オメガ星雲」「白鳥星雲」などいろいろな呼び名を持つ散光星雲である。'},
{fname:'image104/star_M33_sankaku.jpg',title:'さんかく座銀河、M33、NGC598',txt:'さんかく座に位置し、局部銀河群を構成する渦巻銀河の一つ。アンドロメダ銀河と比較的近い位置にある銀河である。地球から238万~307万光年の距離に位置し、質量は銀河系の0.5から2倍程度とされる。仮にアンドロメダ銀河の254万光年よりも遠ければ、肉眼で見える最も遠い物体である。銀河の直径は約5万光年と推定されている。'},
{fname:'image104/star_M74.jpg',title:'銀河、M74、NGC628',txt:'うお座にある渦巻銀河である。渦巻きの回転軸が太陽系を向いているフェイスオン銀河である。銀河系と同じくらいの径10万光年の大きさを持つ。2002年と2003年にたてつづけに超新星が発生した。2002年のものは日本アマチュア天文家が発見したもので、大変珍しい極超新星である。'},
{fname:'image104/star_M78.jpg',title:'散光星雲、M78、NGC2068',txt:'オリオン座にある散光星雲(反射星雲)である。メシエ天体の一つ。オリオン座の三つ星の東端にあるζ星(アルニタク)から北東に約2.5°離れた位置にある。1780年にフランスのピエール・メシャンによって発見された。M78 は反射星雲の中では全天で最も明るいものの一つである。馬頭星雲やオリオン大星雲 (M42) と同様に、オリオン座付近に広がっているオリオン座分子雲の一部を構成している。<br><br>また、M78星雲は、『ウルトラシリーズ』に登場する架空の星雲。ウルトラマンらの故郷で、銀河系から300万光年離れた所に存在する設定になっている。ただ、当初の設定はM87星雲で、脚本印刷段階でM78と誤植してしまったということです。'},
{fname:'image104/star_M81.jpg',title:'銀河、M81、NGC3031',txt:'おおぐま座にある渦巻銀河。距離は1200万光年。M81の極めて近くにM82があり、双眼鏡では同一視野で観察できる。このM81とM82はM81銀河団と呼ばれる同一の銀河団に所属しているので、実際にもこのふたつの銀河は近くに存在している。M82は巨大なM81の重力の影響を受けている。'},
{fname:'image104/star_M101.jpg',title:'銀河、M101、NGC5457',txt:'おおぐま座にある渦巻銀河。距離約2700万光年。'},
{fname:'image104/star_M102.jpg',title:'銀河、M102、NGC5866',txt:'M102は、シャルル・メシエが作成したメシエカタログに記載された天体。しかし、記載された位置には該当する天体が存在しない。メシエカタログには誤記もあり、「行方不明のメシエ天体」は他にもいくつかある。メシエによるスケッチとの照合などにより、こうした「行方不明の天体」の検討が進められ、多くの場合は実在の天体との同定が行われている。しかし、メシエが観測した「M102」に相当する天体は、いくつかの候補が上げられているもののいずれも強い決め手には欠いており、「行方不明の天体」のままとなっている。その候補のひとつがNGC5866である。NGC5866は、りゅう座にある比較的明るいレンズ状銀河または渦巻銀河である。'},
{fname:'image104/star_M106.jpg',title:'銀河、M106、NGC4258',txt:'りょうけん座にある渦巻銀河である。1950年代以来電波源が見いだされている。1981年3月に超新星が出現した。M108,M109とともに、りょうけん座II銀河群をなしている。渦巻きの中で青く光る部分は、星の生成が活発に行われている部分である。1995年国立天文台野辺山宇宙電波観測所の45メートル宇宙電波望遠鏡による観測で、中心部に巨大ブラックホールがあることが分かった。'},
{fname:'image104/star_NGC104.jpg',title:'きょしちょう座47、NGC104',txt:'きょしちょう座にある球状星団である。肉眼で見ることができる。実視等級が4.0等と明るいため、初めは恒星として「きょしちょう座47番」というフラムスティード番号が与えられて星表に記載された。これ以来、球状星団であることが分かった現在でもこの名前で呼ばれている。'},
{fname:'image104/star_NGC1300.jpg',title:'銀河、NGC1300',txt:'エリダヌス座の方向に約6100万光年離れた位置にある棒渦巻銀河である。直径は11万光年で、我々の銀河系よりも少し大きい。エリダヌスクラスターを構成する。ジョン・ハーシェルによって発見された。画像は、ハッブル宇宙望遠鏡によって撮影されたもの。'},
{fname:'image104/star_NGC2070_tarantula.jpg',title:'タランチュラ星雲、NGC2070',txt:'大マゼラン雲のHII領域にある輝線星雲である。恒星以外の天体としては非常に大きい光度を持つ。その明るさは、もし地球からオリオン大星雲ほどの距離に来たならば、影を生じるほどである。実際に、局部銀河群で知られている最も活発なスターバースト領域である。また局部銀河群のそのような領域としては直径200パーセクと最も大きいことで知られる。星雲は大マゼラン雲の最先端に位置し、そこでは動圧がなくなり、星間物質の圧縮が最大限に達する。核には、直径約35光年の小さな星団R136が存在し、星雲のエネルギーの大部分を生産している。星団の質量は推定45万太陽質量であり、将来は球状星団になると推測されている。画像は、ハッブル宇宙望遠鏡によって撮影されたもの。'},
{fname:'image104/star_NGC5139_omega.jpg',title:'ω星団(おめがせいだん)、NGC5139',txt:'1677年にエドモンド・ハレーが発見したケンタウルス座で見られる大型の球状星団である。肉眼で見ることができる少数の球状星団のうち最大級の物とされている。 ω星団は地球から18,300光年(5,600パーセク)の距離にある。1000万個もの恒星の集団で中心の星は互いに0.1光年ほどしか離れていないと考えられている超高密度の球状星団である。'},
{fname:'image104/star_NGC7000_IC5067.jpg',title:'北アメリカ星雲、NGC7000',txt:'はくちょう座の尾部、デネブの近くに見える散光星雲である。18世紀の天文学者ウィリアム・ハーシェルによって発見された。形が北アメリカ大陸に似ているところから名づけられた。見かけの大きさは面積にして満月の十倍ほどと広大であるが、暗いため肉眼での観測は余程空の暗い場所でもなければ、ほぼ不可能である。ある程度の口径と広い視野角を持つ双眼鏡を使えば、しみのような星雲の姿を観測することができる。赤い星雲の姿を確認するには写真撮影する必要がある。'},
{fname:'image104/star_SMC.jpg',title:'小マゼラン雲',txt:'南天にあるため、日本からは見ることができない。南半球では、きょしちょう座にぼんやりとした雲のように見える。太陽系からおよそ20万光年の距離に位置し、質量は銀河系の6分の1程度とされる。写真左側の球状星団はNGC104。'},
];
var PICTURE_URL = "";	// 画像ファイルのURL
var PICTURE_TITLE = "";	// 写真のタイトル
var PICTURE_TXT = "";	// 写真の説明
var menu_msg = "<h1>15 PUZZLE MENU (写真" + PICTURES.length + "枚)</h1>";	// MENUのタイトル
var play_msg = "<h1>15 PUZZLE</h1>";	// PUZZLEのタイトル
var clear_msg = "<h1>15 PUZZLE CLEAR !</h1>";	// PUZZLE クリア時のタイトル
var BLOCK_W = 150;	// ブロックの幅
var BLOCK_H = 150;	// ブロックの高さ
var ROW_COUNT = 4;	// 列を何枚に切るか
var COL_COUNT = 4;	// 行を何枚に切るか
var NUM_BLOCKS = ROW_COUNT * COL_COUNT;
// 上下左右の相対座標を定義したもの
var UDLR = [[0,-1],[0,1],[-1,0],[1,0]];
// ゲーム全体で使う変数
var context, image, selImage;	// 描画用
var selBlocks = [];	// 各ブロックを管理する配列変数
var blocks = [];	// 各ブロックを管理する配列変数
var isLock;	// マウス操作をロックするかどうか
var selFlag = true;	// 画像選択フラグ
var clearFlag = false;	// ゲームクリアフラグ
// 初期化処理
function init() {
	// 描画コンテキストの取得
	var canvas = document.getElementById("gameCanvas");
	if (!canvas.getContext) {
		alert("Canvasをサポートしていません。");
		return;
	}
	context = canvas.getContext("2d");
	// マウスイベントの設定
	canvas.onmousedown = mouseHandler;
	// 画像を選択
	selectImage();	// ■画像1枚でMENU表示へ
	// メニュー用画像を縮小表示
	// 画像キャプチャー用(使用時は上記selectImageを無効に下記を有効に)
	// drawMenu();	// ■PICTURES縮小でNEMU表示へ
}
// ゲーム画像の選択画面(MENU)を表示
function selectImage() {
	document.getElementById('top_title').innerHTML = menu_msg;
	selFlag = true;
	// 画像を描画
	selImage = new Image();
	selImage.src = "menu_star104.jpg?" + new Date().getTime();	// IE対策
	selImage.onload = function() {
		context.drawImage(selImage, 0, 0);
	}
}
// ゲーム開始時の画面を描画する(画像キャプチャー用)
// この関数はMENU画像作成時にのみ使用
function drawMenu() {
	document.getElementById('top_title').innerHTML = menu_msg;
	for (var i = 0; i < PICTURES.length; i++) {
		// 描画先座標を計算
		var dx = (i % COL_COUNT) * BLOCK_W;
		var dy = Math.floor(i / COL_COUNT) * BLOCK_H;
		selImage = new Image();
		selImage.src = PICTURES[i].fname;
		// 画像を縮小して描画
		context.drawImage(selImage, 0, 0, 600, 600, dx, dy, BLOCK_W, BLOCK_H);
		// 描画の枠を表示
		context.beginPath();
		context.strokeStyle = "white";
		context.lineWidth = 3;
		context.rect(dx, dy, BLOCK_W, BLOCK_H);
		context.stroke();
		context.closePath();
	}
}
// ゲーム開始
function gameStart() {
	document.getElementById('top_title').innerHTML = play_msg;
	// メイン画像を読み出す
	image = new Image();
	image.src = PICTURE_URL;
	image.onload = initGame;	// 読み込んだらゲームを初期化
}
// ゲームの初期化
function initGame() {
	isLock = true;	// ユーザ操作をロックする
	// パズルのブロックを作成する
	for (var i = 0; i < NUM_BLOCKS; i++) {
		blocks[i] = i;
	}
	// 末尾(右下)を空きブロックとする
	blocks[NUM_BLOCKS -1] = -1;
	drawPuzzle();	// 見本を表示する
	// 1秒後にシャッフルを開始する
	setTimeout(shufflePuzzle,1000);
}
// パズルの各ピースをシャッフルする
function shufflePuzzle() {
	var scount = 160;	// シャッフルする回数を指定
	var blank = NUM_BLOCKS - 1;	// 空きブロック位置
	// 一回のみシャッフルを行う関数
	var shuffle = function () {
		scount--;
		if (scount <= 0) {
			isLock = false;	// ゲーム開始
			return;
		}
		var r, px, py, no;
		while (1) {
			r = Math.floor(Math.random() * UDLR.length);
			px = getCol(blank) + UDLR[r][0];
			py = getRow(blank) + UDLR[r][1];
			if (px < 0 || px >= COL_COUNT) continue;
			if (py < 0 || py >= ROW_COUNT) continue;
			no = getIndex(px, py);
			break;
		}
		blocks[blank] = blocks[no]
		blocks[no] = -1;
		blank = no;
		drawPuzzle();
		setTimeout(shuffle, 2);
	};
	shuffle();
}
// パズルの画面を描画する
function drawPuzzle() {
	for (var i = 0; i < NUM_BLOCKS; i++) {
		// 描画先座標を計算
		var dx = (i % COL_COUNT) * BLOCK_W;
		var dy = Math.floor(i / COL_COUNT) * BLOCK_H;
		// 描画元座標を計算
		var no = blocks[i];
		if (no < 0) {	// 空きブロック
			context.fillStyle = "#0000FF";
			context.fillRect(dx, dy, BLOCK_W, BLOCK_H);
		} else {
			var sx = (no % COL_COUNT) * BLOCK_W;
			var sy = Math.floor(no / COL_COUNT) * BLOCK_H;
			// 画像の一部を切り取って描画
			context.drawImage(image, sx, sy, BLOCK_W, BLOCK_H, dx, dy, BLOCK_W, BLOCK_H);
		}
		// 描画の枠を表示
		context.beginPath();
		context.strokeStyle = "white";
		context.lineWidth = 3;
		context.rect(dx, dy, BLOCK_W, BLOCK_H);
		context.stroke();
		context.closePath();
		// ブロック番号を描画する
		context.fillStyle = "rgba(255, 255, 255, 0.8)";
		context.font = "bold 48px Arial";
		var cx = dx + (BLOCK_W - 40) / 2;
		var cy = dy + BLOCK_H /2;
		if (no != -1){
			context.fillText((no+1), cx, cy);
			context.strokeStyle = "black";
			context.strokeText((no+1), cx, cy);
		}
	}
}
// マウスで移動先をクリックした時の処理
function mouseHandler(t) {
	if (isLock) return;
	if (selFlag) {	// ----- MENU のマウス処理 -----
		// タッチ座標の取得
		var px = t.offsetX, py = t.offsetY;
		if (px == undefined) {	// FireFox対策
			var p = t.currentTarget;
			px = t.layerX - p.offsetLeft;
			py = t.layerY - p.offsetTop;
		}
		// 何番目の画像をクリックしたのか計算する
		var px2 = Math.floor(px / BLOCK_W);
		var py2 = Math.floor(py / BLOCK_H);
		var selNo = getIndex(px2, py2);
		PICTURE_URL = PICTURES[selNo].fname;
		PICTURE_TITLE = PICTURES[selNo].title;
		PICTURE_TXT =	PICTURES[selNo].txt;	// 選択した写真の説明を変数にセット
		// document.getElementById('pict_title').innerHTML = PICTURE_TITLE;	// 写真タイトルを表示(確認用)
		// document.getElementById('pict_txt').innerHTML = PICTURE_TXT;	// 写真説明を表示(確認用)
		selFlag = false;
		gameStart();
	}else{
		if (clearFlag) {	// ----- CLEAR 時の処理 -----
			clearFlag = false;
			document.getElementById('pict_title').innerHTML = "";	// 写真タイトルを消去
			document.getElementById('pict_txt').innerHTML = "";	// 写真説明を消去
			selectImage();	// 再度ゲームを実行
		}else{	// ----- PUZZLE プレイ中のマウス処理 -----
			// タッチ座標の取得
			var px = t.offsetX, py = t.offsetY;
			if (px == undefined) {	// FireFox対策
				var p = t.currentTarget;
				px = t.layerX - p.offsetLeft;
				py = t.layerY - p.offsetTop;
			}
			// 何番目のピースを動かしたいのか計算する
			var px2 = Math.floor(px / BLOCK_W);
			var py2 = Math.floor(py / BLOCK_H);
			var no = getIndex(px2, py2);
			// 空白ブロックなら動かせない
			if (blocks[no] == -1) return;
			// 上下左右に動かせるブロックがあるか確認
			for (var i = 0; i < UDLR.length; i++) {
				var pt = UDLR[i];
				var xx = px2 + pt[0];
				var yy = py2 + pt[1];
				var no = getIndex(xx, yy);
				if (xx < 0 || xx >= COL_COUNT) continue;
				if (yy < 0 || yy >= ROW_COUNT) continue;
				if (blocks[no] == -1) {	// 移動可能か
					blocks[no] = blocks[getIndex(px2,py2)];
					blocks[getIndex(px2,py2)] = -1;
					drawPuzzle();
					checkClear();
					break;
				}
			}
		}
	}
}
// クリアしたかどうかチェックする
function checkClear() {
	var flag = true;
	for (var i = 0; i < (NUM_BLOCKS -1); i++) {
		if (blocks[i] != i) { flag = false; break; }
	}
	if (flag) {
		document.getElementById('top_title').innerHTML = clear_msg;
		context.drawImage(image, 0, 0);	// 元画像を描画する
		document.getElementById('pict_title').innerHTML = PICTURE_TITLE;	// 写真タイトルを表示
		document.getElementById('pict_txt').innerHTML = PICTURE_TXT;	// 写真説明を表示
		clearFlag = true;
	}
}
// 列と行からブロック番号を調べる関数
function getIndex(col, row) {
	return row * COL_COUNT + col;
}
function getCol(no) { return no % COL_COUNT; }
function getRow(no) {
	return Math.floor(no / COL_COUNT);
}

* {
	padding:0;
	margin:0;
	text-align:center;
}

h1 {
	background-color:blue;
	color:white;
	font-size:20px;
	padding:4px;
}

#pict_title {
	max-width: 600px;
	margin: 0 auto;
	text-align: left;
	font-size: 1.2em;
	font-weight: 600;
}

#pict_txt {
	max-width: 600px;
	margin: 0 auto;
	text-align: left;
	line-height: 1.4em;
}