2 ****PCD-2013 GameScriptCoreLibrary****
3 Tokyo Gakugei University Senior High School.
14 document.getElementById("main").style.display = "none";
15 (mainというIDが振られている要素の表示を消す)
16 this.effectSound.pause();
17 this.effectSound.currentTime = 0;
18 this.effectSound.play();
19 this.backgroundImage = new Image();
20 this.backgroundMusic = document.getElementById('BGM006');
21 this.effectSound = document.getElementById('SE_Select');
23 this.backgroundImage.manager = this;
24 this.backgroundImage.onload = this.backgroundLoaded;
25 this.backgroundImage.src = "title.gif";
28 this.backgroundMusic.loop = true;
29 this.backgroundMusic.play();
31 MicrosoftInternetExplorerでは、ローカル変数でparentを使うとappendChildが使えなくなる…。
33 IEではXMLHTTPRequest.onreadystatechangeのthisの値が他と異なるようだ。
35 request.onreadystatechange = function(){
36 と無名関数で書いて、内部でrequestインスタンスを参照
44 var URL_PCD_Root = "http://192.168.6.242/pcd2013dev/www/";
45 //var URL_PCD_Root = "http://192.168.0.8/PCD2013GSCL/www/";
46 var URL_PCD_Auth = URL_PCD_Root + "auth.php";
47 var URL_PCD_Stage = URL_PCD_Root + "stage/";
48 var URL_PCD_Stage_Local = "stage/";
54 function GameManager(){
60 this.networkManager = new NetworkManager();
61 //必要最低限のCanvasとコンテキストの設定
62 this.mainCanvas = createCanvas("MainCanvas", 640, 480, 0, 0, 1, "MainArea");
63 this.mainCanvas.style.border = "solid 1px";
64 this.debugCanvas = createCanvas("DebugCanvas", 640, 480, 0, 480, 2, "MainArea");
65 this.mainContext = this.mainCanvas.getContext('2d');
66 this.debugContext = this.debugCanvas.getContext('2d');
67 this.debugText = document.getElementById('DebugText');
68 //実行中のGameStageオブジェクトを格納
69 this.runningStage = null;
74 this.tickPerSecond = 60;
75 this.updateIntervalMs = 250;
76 //キーボード状態を格納するプロパティの設定
77 this.keyState = new Object();
78 this.keyState.upArrow = false;
79 this.keyState.downArrow = false;
80 this.keyState.leftArrow = false;
81 this.keyState.rightArrow = false;
83 //**描画コンテキスト取得、設定・HTML5対応チェック**
84 if(!this.mainCanvas || !this.mainCanvas.getContext){
86 alert("このゲームを遊ぶためには、HTML5に対応しているブラウザでアクセスしてください...。");
90 //**Canvas描画コンテキストの初期設定**
92 this.mainContext.fillStyle = "rgba(200,255,200,0.5)";
93 this.mainContext.strokeStyle = "rgba(0, 0, 0, 0.5)";
95 this.debugContext.fillStyle = "rgb(255,255,255)";
96 this.debugContext.strokeStyle = "rgb(0, 0, 0)";
97 this.debugContext.font = "normal 20px sans-serif";
100 //コールバックを行うために、イベントリスナーのmanagerプロパティにGameManagerのインスタンスを代入する。
102 keyDownEventListener.manager = this;
103 window.addEventListener('keydown', keyDownEventListener, true);
105 keyUpEventListener.manager = this;
106 window.addEventListener('keyup', keyUpEventListener, true);
108 timerTickEventListener.manager = this;
109 window.setInterval(timerTickEventListener, 1000/this.tickPerSecond);
110 timeStampTimerTickEventListener.manager = this;
111 window.setInterval(timeStampTimerTickEventListener, this.updateIntervalMs);
113 GameManager.prototype = {
115 //prototype以下のプロパティは、新規インスタンスに参照が引き継がれる。
116 keyDown: function(event){
118 //コールバックではなくコールバック関数(keyDownEventListener)から呼び出されるので、thisはGameManagerのインスタンスとなる。
119 keyCode = event.keyCode;
120 switch(event.keyCode){
123 this.keyState.upArrow = true;
124 event.preventDefault();
128 this.keyState.downArrow = true;
129 event.preventDefault();
133 this.keyState.leftArrow = true;
134 event.preventDefault();
138 this.keyState.rightArrow = true;
139 event.preventDefault();
143 this.debugOut("keyDw:" + keyCode + "\n");
145 if(this.runningStage){
146 this.runningStage.keyDown(event);
149 keyUp: function(event){
151 //コールバックではなくコールバック関数(keyUpEventListener)から呼び出されるので、thisはGameManagerのインスタンスとなる。
152 keyCode = event.keyCode;
153 switch(event.keyCode){
156 this.keyState.upArrow = false;
160 this.keyState.downArrow = false;
164 this.keyState.leftArrow = false;
168 this.keyState.rightArrow = false;
172 this.debugOut("keyUp:" + keyCode + "\n");
174 if(this.runningStage){
175 this.runningStage.keyUp(event);
178 timerTick: function(){
182 if(this.runningStage){
183 this.runningStage.timerTick();
184 this.runningStage.draw();
187 timeStampTimerTick: function(){
190 this.timeStamp += this.updateIntervalMs;
191 drawText(this.debugContext, " timeStamp:" + this.timeStamp, 0, 40);
194 if(this.userID != 0){
195 request = this.networkManager.CreateRequestObject();
196 request.onreadystatechange = function(){
197 //requestコールバックなのでthisはrequest!
198 //onloadedはステージプリロード用
199 switch(request.readyState){
201 //console.log("XMLHttpRequest created.");
204 //console.log("open() called.");
207 //console.log("Response header received.");
210 //console.log("Response body receiving.");
213 //mainManager.debugOut("send() compleated.\n");
214 //mainManager.debugOut("status:" + this.status + ":" + this.statusText + "\n");
215 if(request.status == 0){
216 //alert("ネットワークにアクセスできません。" + this.status + ":" + this.statusText);
217 }else if((200 <= request.status && request.status < 300) || (request.status == 304)){
218 //console.log("ACK");
219 var res = request.responseText
220 this.timeStamp = eval(res);
221 drawText(mainManager.debugContext, "ServertimeStamp:" + res.toString(), 0, 80);
223 //alert("サーバーがエラーを返しました。" + this.status + ":" + this.statusText);
228 request.open('GET', URL_PCD_Root + "update.php?uid=" + this.userID);
229 this.networkManager.RequestObjectDisableCache(request);
233 runStage: function(stage){
234 //****新たなステージを開始する****
235 //実行中のステージがあれば終了処理を行わせる。
236 if(this.runningStage){
239 //**新たに開始するステージの初期化**
240 //GameManager側の情報をGameStageに渡す。
241 stage.manager = this;
242 stage.mainCanvas = this.mainCanvas
243 stage.debugCanvas = this.debugCanvas
244 stage.mainContext = this.mainContext
245 stage.debugContext = this.debugContext
246 //GameStage側の初期化処理を行わせる。
248 //runningStageに登録することで、イベントの通知が開始され、GameStageは実行状態に入る。
249 this.runningStage = stage;
251 stopStage: function(){
252 //****現在実行中のステージを終了する****
253 if(this.runningStage){
254 //runningStageから解除することで、イベントの通知は行われなくなる。
255 var aGameStage = this.runningStage;
256 this.runningStage = null;
257 //GameStage側の終了処理を行わせる。
258 aGameStage.stopStage();
259 //GameStageインスタンスからGameManagerの情報を削除する。
260 aGameStage.manager = null;
261 aGameStage.mainCanvas = null;
262 aGameStage.debugCanvas = null;
263 aGameStage.mainContext = null;
264 aGameStage.debugContext = null;
267 loadStageFromLocal: function(code, onLoaded){
268 var ____stage = eval(code);
269 mainManager.runStage(____stage);
271 loadStageFromNetwork: function(name, onLoaded){
272 //urlに存在するjavascriptファイルを利用してステージを作成する。
273 request = this.networkManager.CreateRequestObject();
274 request.onreadystatechange = function(){
275 //requestコールバックなのでthisはrequest!とは限らない(IE)
276 console.log("state:" + request.readyState);
277 switch(request.readyState){
279 //console.log("XMLHttpRequest created.");
282 //console.log("open() called.");
285 //console.log("Response header received.");
288 //console.log("Response body receiving.");
291 //mainManager.debugOut("send() compleated.\n");
292 //mainManager.debugOut("status:" + this.status + ":" + this.statusText + "\n");
293 if(request.status == 0){
294 alert("ネットワークにアクセスできません。" + request.status + ":" + request.statusText);
295 }else if((200 <= request.status && request.status < 300) || (request.status == 304)){
296 //console.log("ACK");
297 var stage = eval(request.responseText);
298 mainManager.runStage(stage);
300 alert("サーバーがエラーを返しました。" + request.status + ":" + request.statusText);
305 request.open('GET', URL_PCD_Stage + name + ".js");
306 this.networkManager.RequestObjectDisableCache(request);
308 //console.log("reqObject:" + request.toString());
311 debugOut: function(str){
312 if(!/*@cc_on!@*/false)
314 this.debugText.value = str.replace(/\n/g,"\r\n") + this.debugText.value;
318 this.debugText.innerHTML = str + this.debugText.value;
330 function Point2D(x, y){
334 Point2D.prototype = {
338 function Rectangle(x, y, width, height){
339 this.origin = new Point2D(x,y);
340 this.size = new Point2D(width,height);
342 Rectangle.prototype = {
346 function ResourceManager(){
348 this.resourceObjectList = new Array();
350 this.ResourceTag.prototype = {
354 ResourceManager.prototype = {
356 addAudioResource: function(id, src){
357 dobj = document.createElement("audio");
358 parent = document.getElementById("Resources");
360 parent.appendChild(dobj);
362 this.resourceObjectList.push(dobj);
364 dobj.isLoaded = false;
365 dobj.onload = this.resourceLoaded;
368 resourceLoaded: function(){
369 //コールバック関数のthisはコールバック関数の設定先オブジェクト(DOMObject)となる。
370 this.isLoaded = true;
372 waitForLoadResource: function(){
374 for(i = 0; i < resourceObjectList.length; i++){
375 if(!resourceObjectList[i].isLoaded){
380 if(i == resourceObjectList.length){
387 function NetworkManager(){
390 NetworkManager.prototype = {
391 //from http://hakuhin.jp/js/xmlhttprequest.html
392 CreateRequestObject: function(){
396 // XMLHttpRequest オブジェクトを作成
397 rq = new XMLHttpRequest();
401 rq = new ActiveXObject('MSXML2.XMLHTTP.6.0');
404 rq = new ActiveXObject('MSXML2.XMLHTTP.3.0');
407 rq = new ActiveXObject('MSXML2.XMLHTTP');
414 RequestObjectDisableCache: function(rq){
415 //call after open request.
417 //http://vird2002.s8.xrea.com/javascript/XMLHttpRequest.html
418 rq.setRequestHeader('Pragma', 'no-cache'); // HTTP/1.0 における汎用のヘッダフィールド
419 rq.setRequestHeader('Cache-Control', 'no-cache'); // HTTP/1.1 におけるキャッシュ制御のヘッダフィールド
420 rq.setRequestHeader('If-Modified-Since', 'Thu, 01 Jun 1970 00:00:00 GMT');
429 function createCanvas(id, width, height, x, y, z, parent)
432 //width * heightの大きさのCanvasを
434 //parentには、Canvasタグを包含することになるDOMオブジェクトのidを指定する。
435 canvas = document.createElement("canvas");
436 parent = document.getElementById(parent);
440 parent.appendChild(canvas);
442 canvas.style.position = "absolute";
443 canvas.style.top = y + "px";
444 canvas.style.left = x + "px";
445 canvas.style.zIndex = z;
447 canvas.width = width;
448 canvas.height = height;
453 function createDOMObject(typestr, idstr, parentidstr)
455 dobj = document.createElement(typestr);
456 parentObj = document.getElementById(parentidstr);
459 parentObj.appendChild(dobj);
464 function destroyDOMObjectByID(id)
466 //識別名idのDOMオブジェクトを破棄する。
467 object = document.getElementById(id);
468 parentObj = object.parentNode;
470 parentObj.removeChild(object);
473 function removeObjectFromArray(anArray, anObject)
475 //anArray中にある全てのanObjectを削除し、空いた部分は前につめる。
476 for(i = 0; i < anArray.length; i++){
477 if(anArray[i] == anObject){
478 anArray.splice(i, 1);
486 //イベントリスナーにおけるthisは、イベントリスナーを登録したオブジェクトになり、通常とは異なるので注意。
488 function keyDownEventListener(event)
490 keyDownEventListener.manager.keyDown(event);
493 function keyUpEventListener(event)
495 keyUpEventListener.manager.keyUp(event);
496 event.preventDefault();
499 function timerTickEventListener(event)
501 timerTickEventListener.manager.timerTick(event);
504 function timeStampTimerTickEventListener(event)
506 timerTickEventListener.manager.timeStampTimerTick(event);
513 function drawText(gcontext, text, x, y)
516 //前景をstrokeStyleで塗りつぶした文字列を描画する
518 //fillTextの座標は文字列の左下!
519 textsize = gcontext.measureText(text);
520 gcontext.fillRect(x, y, textsize.width, 20);
522 gcontext.fillStyle = gcontext.strokeStyle;
523 gcontext.fillText(text, x, y + 20 - 1);
527 function drawArcDegree(gcontext, radius, startAngleDegree, endAngleDegree, x, y, anticlockwise)
529 //半径radius, 中心座標(x,y)の円弧の、
530 //startAngleDegreeからendAngleDegreeまでの範囲を、
531 //(!anticlockwise)=時計回り
532 //(anticlockwise) =反時計回り
535 startAngleRadian = startAngleDegree * Math.PI / 180;
536 endAngleRadian = endAngleDegree * Math.PI / 180;
538 gcontext.beginPath();
539 gcontext.arc(drawCoordinatesInInteger(x), drawCoordinatesInInteger(y), drawCoordinatesInInteger(radius), startAngleRadian, endAngleRadian, anticlockwise);
542 gcontext.closePath();
545 function fillRect(gContext, x, y, w, h)
547 gContext.fillRect(drawCoordinatesInInteger(x), drawCoordinatesInInteger(y), drawCoordinatesInInteger(w), drawCoordinatesInInteger(h));
550 function strokeRect(gContext, x, y, w, h)
552 gContext.strokeRect(drawCoordinatesInInteger(x), drawCoordinatesInInteger(y), drawCoordinatesInInteger(w), drawCoordinatesInInteger(h));
555 function drawCoordinatesInInteger(coordinateElement)
557 //from http://www.html5rocks.com/ja/tutorials/canvas/performance/
558 // With a bitwise or.
559 return ((0.5 + coordinateElement) | 0);