1 /* 2 * Copyright (C) 2012-2013 たかはしのんき. All rights reserved. 3 * 4 * History: 5 * 0.3 2013-06-15 JsDoc Toolkit対応。メソッド showScore の作成。 6 * 0.2 2013-04-26 バージョンの変更。 7 * 0.1 2013-04-07 碁盤プログラム goban06.js を元に新規作成。 8 */ 9 10 /** 11 * @fileOverview Simulator - 囲碁対局シミュレータ 12 * @name simulator03.js 13 * @version 0.3 14 * @author たかはしのんき 15 * 16 */ 17 18 // 共通に使う定数と変数 19 var BLACK = 1; 20 var WHITE = 2; 21 var PX_BOWL = 134; // 碁笥の直径 [ピクセル] 22 var Z2_BOWL = 20; // 碁笥の高さ / 2 [ピクセル] 23 var PX_LID = 110; // 碁笥の蓋の直径 [ピクセル] 24 var Z2_LID = 8; // 碁笥の蓋の高さ / 2 [ピクセル] 25 var PX_STONE = 22; // 碁石の直径 [ピクセル] 26 var Z2_STONE = 2; // 碁石の高さ / 2 [ピクセル] 27 var PX_STAR = 5; // 星の直径 [ピクセル] 28 var PX_CHAR = 24; // 文字の高さ [ピクセル] 29 var Z2_BOARD = 6; // 碁盤の高さ / 2 [ピクセル] 30 31 // キャッシュにイメージを読み込んでおく 32 var imgbb = new Image(PX_BOWL, PX_BOWL); // 黒の碁笥 (black bowl) 33 imgbb.src = "img/blackbowl134.png"; 34 var imgwb = new Image(PX_BOWL, PX_BOWL); // 白の碁笥 (white bowl) 35 imgwb.src = "img/whitebowl134.png"; 36 var imgl = new Image(PX_LID, PX_LID); // 碁笥の蓋 (lid) 37 imgl.src = "img/lid110.png"; 38 var imgb = new Image(PX_STONE, PX_STONE); // 黒石 (white stone) 39 imgb.src = "img/black22.png"; 40 var imgw = new Image(PX_STONE, PX_STONE); // 白石 (black stone) 41 imgw.src = "img/white22.png"; 42 var imgs = new Image(PX_STAR, PX_STAR); // 星 (star) 43 imgs.src = "img/star5.png"; 44 45 // キャッシュに効果音を読み込んでおく 46 var ext = audioExt(); 47 var auClick = new Audio("se/button6." + ext); 48 var auSwitch = new Audio("se/se_sad05." + ext); 49 var auError = new Audio("se/se_sad08." + ext); 50 51 var ro = 9; // 路数 52 var context3; // 碁石レイヤーのキャンバスのコンテキスト 53 var context2; // 影レイヤーのキャンバスのコンテキスト 54 var passButton = new Array(2); // [パス]ボタン 55 var brd; // 碁盤オブジェクト 56 var offsetBLid = new Object(); // 黒の碁笥の蓋のオフセット 57 var offsetWLid = new Object(); // 白の碁笥の蓋のオフセット 58 59 /** 60 * ロード時に碁盤イメージを描画します。 61 */ 62 window.onload = function() { 63 // 黒石の <input id="black"> 取得 64 passButton[BLACK] = document.getElementById('black'); 65 // 白石の <input id="white"> 取得 66 passButton[WHITE] = document.getElementById('white'); 67 68 // キャンバスとコンテキスト取得 69 var canvas = document.querySelector('#table'); 70 var context = canvas.getContext('2d'); 71 var canvas3 = document.querySelector('#stones'); 72 context3 = canvas3.getContext('2d'); 73 var canvas2 = document.querySelector('#shadow'); 74 context2 = canvas2.getContext('2d'); 75 // 座標 (270, 50) にタイトルを表示 76 context.fillStyle = "white"; 77 context.font = "bold 24px Arial"; 78 var title = "Simulator 0.3"; 79 var x = context.canvas.width / 2 - 80 PX_CHAR / 1.8 * title.length / 2; 81 var y = PX_CHAR * 2; 82 context.fillText(title, x, y); 83 // 机の中央に 碁盤を表示 84 brd = new Board(ro, context); 85 // 碁盤の左に白の碁笥の蓋のイメージを表示 86 offsetWLid.x = Math.floor((brd.boardOffset.x - PX_LID) / 2); 87 offsetWLid.y = brd.boardOffset.y + 88 Math.floor((brd.boardSize.height - PX_LID) / 2); 89 drawObject(offsetWLid.x, offsetWLid.y, Z2_LID, imgl, context, context); 90 // 左上に白の碁笥のイメージを表示 91 var xb = offsetWLid.x - Math.floor((PX_BOWL - PX_LID) / 2); 92 var yb = offsetWLid.y - PX_BOWL - Z2_BOWL; 93 drawObject(xb, yb, Z2_BOWL, imgwb, context, context); 94 // 碁盤の右に黒の碁笥の蓋のイメージを表示 95 offsetBLid.x = offsetWLid.x + brd.boardOffset.x + brd.boardSize.width; 96 offsetBLid.y = offsetWLid.y; 97 drawObject(offsetBLid.x, offsetBLid.y, Z2_LID, imgl, context, context); 98 // 右下に黒の碁笥のイメージを表示 99 xb = offsetBLid.x - Math.floor((PX_BOWL - PX_LID) / 2); 100 yb = offsetBLid.y + PX_LID + Z2_BOWL; 101 drawObject(xb, yb, Z2_BOWL, imgbb, context, context); 102 // 碁盤を表示 103 brd.drawBoard(Z2_BOARD, context); 104 // 黒番から 105 passButton[WHITE].disabled = true; 106 // クリックイベント登録 107 canvas3.addEventListener("click", onClick, false); 108 }; 109 110 /** 111 * アゲハマの表示 112 * @param stone 石の色 113 * @param prisoner アゲハマの数 114 * @since 0.1 115 */ 116 function showPrisoner(stone, prisoner) { 117 if (stone == BLACK) { 118 var p = document.getElementById('pb'); 119 } else { 120 var p = document.getElementById('pw'); 121 } 122 p.firstChild.nodeValue = prisoner; 123 } 124 125 /** 126 * 得点の表示 127 * @param stone 石の色 128 * @param score 得点 129 * @since 0.3 130 */ 131 function showScore(stone, score) { 132 if (stone == BLACK) { 133 var p = document.getElementById('sb'); 134 } else { 135 var p = document.getElementById('sw'); 136 } 137 p.firstChild.nodeValue = score; 138 } 139 140 /** 141 * マウスイベントハンドラー 142 * 碁石を置きます。 143 * @since 0.1 144 */ 145 function onClick() { 146 var event = arguments[0]; 147 var mx = event.pageX - this.parentNode.offsetLeft; 148 var my = event.pageY - this.parentNode.offsetTop; 149 var mv = brd.offsetToMove(mx, my); 150 if (mv.onBoard) { 151 brd.move(mv.col, mv.row, context3, context2); 152 } else { 153 if (brd.p.turn == BLACK) 154 drawObject(mx - (PX_STONE / 2), my - (PX_STONE / 2), Z2_STONE, imgb, context2, context2); 155 else 156 drawObject(mx - (PX_STONE / 2), my - (PX_STONE / 2), Z2_STONE, imgw, context2, context2); 157 auError.play(); 158 } 159 } 160 161 162 /** 163 * [パス]ボタンの処理 164 * @since 0.1 165 */ 166 function pass() { 167 // ボタンの音を鳴らす。 168 auSwitch.play(); 169 var col = PASS(ro); 170 var row = PASS(ro); 171 brd.move(col, row, context3, context2); 172 } 173 174 /** 175 * [はじめから]ボタンの処理 176 * @since 0.1 177 */ 178 function restart() { 179 // ボタンの音を鳴らす。 180 auSwitch.play(); 181 // 碁石と影のレイヤーをクリア 182 context3.clearRect(0, 0, context3.canvas.width, context3.canvas.height); 183 context2.clearRect(0, 0, context2.canvas.width, context2.canvas.height); 184 // アゲハマのクリア 185 showPrisoner(BLACK, 0); 186 showPrisoner(WHITE, 0); 187 // 得点のクリア 188 showScore(BLACK, 0); 189 showScore(WHITE, 0); 190 // 黒番から 191 brd.clear(); 192 passButton[BLACK].disabled = false; 193 passButton[WHITE].disabled = true; 194 } 195 196 /** 197 * ブラウザで有効なAudioの拡張子を獲得 198 * @since 0.1 199 */ 200 function audioExt() { 201 var ext = ""; 202 var audio = new Audio(); 203 if (audio.canPlayType("audio/ogg") == 'maybe') 204 ext="ogg"; 205 else if (audio.canPlayType("audio/mp3") == 'maybe') 206 ext="mp3"; 207 else if (audio.canPlayType("audio/wav") == 'maybe') 208 ext="wav"; 209 return ext; 210 } 211 212 /** 213 * 円形オブジェクトを描画します。 214 * @param x 左端座標 215 * @param y 上端座標 216 * @param s 影の長さ(高さ/2) 217 * @param img オブジェクトのイメージ 218 * @param context3 描画先のコンテキストを指定します。 219 * @param context2 影用のコンテキストを指定します。 220 * @since 0.1 221 */ 222 function drawObject(x, y, s, img, context3, context2) { 223 var r = img.width / 2; 224 context2.beginPath(); 225 context2.arc(x + r + s, y + r + s, r, 0, 2 * Math.PI); 226 context2.fillStyle = "black"; 227 context2.globalAlpha = 0.5; 228 context2.fill(); 229 context3.globalAlpha = 1.0; 230 context3.drawImage(img, x, y); 231 } 232