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 <About collision checking>(このあたりはまだドラフト)
34 ステージオブジェクトの最小単位を8x8とする。
40 var URL_PCD_Root = "http://192.168.6.242/pcd2013dev/www/";
41 var URL_PCD_Auth = URL_PCD_Root + "auth.php";
42 var URL_PCD_Stage = URL_PCD_Root + "stage/";
43 var URL_PCD_Stage_Local = URL_PCD_Root + "./stage/";
49 function GameManager(){
55 this.networkManager = new NetworkManager();
56 //必要最低限のCanvasとコンテキストの設定
57 this.mainCanvas = createCanvas("MainCanvas", 640, 480, 0, 0, 1, "MainArea");
58 this.mainCanvas.style.border = "solid 1px";
59 this.debugCanvas = createCanvas("DebugCanvas", 640, 480, 0, 480, 2, "MainArea");
60 this.mainContext = this.mainCanvas.getContext('2d');
61 this.debugContext = this.debugCanvas.getContext('2d');
62 this.debugText = document.getElementById('DebugText');
63 //実行中のGameStageオブジェクトを格納
64 this.runningStage = null;
69 this.tickPerSecond = 60;
70 //キーボード状態を格納するプロパティの設定
71 this.keyState = new Object();
72 this.keyState.upArrow = false;
73 this.keyState.downArrow = false;
74 this.keyState.leftArrow = false;
75 this.keyState.rightArrow = false;
77 //**描画コンテキスト取得、設定・HTML5対応チェック**
78 if(!this.mainCanvas || !this.mainCanvas.getContext){
80 alert("このゲームを遊ぶためには、HTML5に対応しているブラウザでアクセスしてください...。");
84 //**Canvas描画コンテキストの初期設定**
86 this.mainContext.fillStyle = "rgba(200,255,200,0.5)";
87 this.mainContext.strokeStyle = "rgba(0, 0, 0, 0.5)";
89 this.debugContext.fillStyle = "rgb(255,255,255)";
90 this.debugContext.strokeStyle = "rgb(0, 0, 0)";
91 this.debugContext.font = "normal 20px sans-serif";
94 //コールバックを行うために、イベントリスナーのmanagerプロパティにGameManagerのインスタンスを代入する。
96 keyDownEventListener.manager = this;
97 window.addEventListener('keydown', keyDownEventListener, true);
99 keyUpEventListener.manager = this;
100 window.addEventListener('keyup', keyUpEventListener, true);
102 timerTickEventListener.manager = this;
103 window.setInterval(timerTickEventListener, 1000/this.tickPerSecond);
104 timeStampTimerTickEventListener.manager = this;
105 window.setInterval(timeStampTimerTickEventListener, 100);
107 GameManager.prototype = {
109 //prototype以下のプロパティは、新規インスタンスに参照が引き継がれる。
110 keyDown: function(event){
112 //コールバックではなくコールバック関数(keyDownEventListener)から呼び出されるので、thisはGameManagerのインスタンスとなる。
113 keyCode = event.keyCode;
114 switch(event.keyCode){
117 this.keyState.upArrow = true;
118 event.preventDefault();
122 this.keyState.downArrow = true;
123 event.preventDefault();
127 this.keyState.leftArrow = true;
128 event.preventDefault();
132 this.keyState.rightArrow = true;
133 event.preventDefault();
137 this.debugOut("keyDw:" + keyCode + "\n");
139 if(this.runningStage){
140 this.runningStage.keyDown(event);
143 keyUp: function(event){
145 //コールバックではなくコールバック関数(keyUpEventListener)から呼び出されるので、thisはGameManagerのインスタンスとなる。
146 keyCode = event.keyCode;
147 switch(event.keyCode){
150 this.keyState.upArrow = false;
154 this.keyState.downArrow = false;
158 this.keyState.leftArrow = false;
162 this.keyState.rightArrow = false;
166 this.debugOut("keyUp:" + keyCode + "\n");
168 if(this.runningStage){
169 this.runningStage.keyUp(event);
172 timerTick: function(){
176 if(this.runningStage){
177 this.runningStage.timerTick();
180 timeStampTimerTick: function(){
183 this.timeStamp += 100;
184 drawText(this.debugContext, "timeStamp:" + this.timeStamp, 0, 40);
186 runStage: function(stage){
187 //****新たなステージを開始する****
188 //実行中のステージがあれば終了処理を行わせる。
189 if(this.runningStage){
192 //**新たに開始するステージの初期化**
193 //GameManager側の情報をGameStageに渡す。
194 stage.manager = this;
195 stage.mainCanvas = this.mainCanvas
196 stage.debugCanvas = this.debugCanvas
197 stage.mainContext = this.mainContext
198 stage.debugContext = this.debugContext
199 //GameStage側の初期化処理を行わせる。
201 //runningStageに登録することで、イベントの通知が開始され、GameStageは実行状態に入る。
202 this.runningStage = stage;
204 stopStage: function(){
205 //****現在実行中のステージを終了する****
206 if(this.runningStage){
207 //runningStageから解除することで、イベントの通知は行われなくなる。
208 var aGameStage = this.runningStage;
209 this.runningStage = null;
210 //GameStage側の終了処理を行わせる。
211 aGameStage.stopStage();
212 //GameStageインスタンスからGameManagerの情報を削除する。
213 aGameStage.manager = null;
214 aGameStage.mainCanvas = null;
215 aGameStage.debugCanvas = null;
216 aGameStage.mainContext = null;
217 aGameStage.debugContext = null;
220 loadStageFromLocal: function(name, onLoaded){
221 var reader = new FileReader();
222 reader.addEventListener('load', function(event){
223 stage = new GameStage();
224 eval(event.target.result);
225 if(onLoaded != null){
228 mainManager.runStage(stage);
231 reader.onload = function(file){
235 reader.ReadAsText(URL_PCD_Stage_Local + name + ".js", "utf-8");
237 loadStageFromNetwork: function(name, onLoaded){
238 //urlに存在するjavascriptファイルを利用してステージを作成する。
239 request = this.networkManager.CreateRequestObject();
240 request.onLoaded = onLoaded;
241 request.onreadystatechange = this.loadStageFromNetwork_HTTPStateChange
242 request.open('GET', URL_PCD_Stage + name + ".js");
245 loadStageFromNetwork_HTTPStateChange: function(){
246 //requestコールバックなのでthisはrequest!
247 switch(this.readyState){
249 //console.log("XMLHttpRequest created.");
252 //console.log("open() called.");
255 //console.log("Response header received.");
258 //console.log("Response body receiving.");
261 //mainManager.debugOut("send() compleated.\n");
262 //mainManager.debugOut("status:" + this.status + ":" + this.statusText + "\n");
263 if(this.status == 0){
264 alert("ネットワークにアクセスできません。" + this.status + ":" + this.statusText);
265 }else if((200 <= this.status && this.status < 300) || (this.status == 304)){
266 //console.log("ACK");
267 stage = new GameStage();
268 eval(this.responseText);
269 if(this.onLoaded != null){
270 this.onLoaded(stage);
272 mainManager.runStage(stage);
275 alert("サーバーがエラーを返しました。" + this.status + ":" + this.statusText);
280 debugOut: function(str){
281 if(!/*@cc_on!@*/false)
283 this.debugText.value = str.replace(/\n/g,"\r\n") + this.debugText.value;
287 this.debugText.innerHTML = str + this.debugText.value;
299 function Point2D(x, y){
303 Point2D.prototype = {
307 function Rectangle(x, y, width, height){
308 this.origin = new Point2D(x,y);
309 this.size = new Point2D(width,height);
311 Rectangle.prototype = {
315 function ResourceManager(){
317 this.resourceObjectList = new Array();
319 this.ResourceTag.prototype = {
323 ResourceManager.prototype = {
325 addAudioResource: function(id, src){
326 dobj = document.createElement("audio");
327 parent = document.getElementById("Resources");
329 parent.appendChild(dobj);
331 this.resourceObjectList.push(dobj);
333 dobj.isLoaded = false;
334 dobj.onload = this.resourceLoaded;
337 resourceLoaded: function(){
338 //コールバック関数のthisはコールバック関数の設定先オブジェクト(DOMObject)となる。
339 this.isLoaded = true;
341 waitForLoadResource: function(){
343 for(i = 0; i < resourceObjectList.length; i++){
344 if(!resourceObjectList[i].isLoaded){
349 if(i == resourceObjectList.length){
356 function NetworkManager(){
359 NetworkManager.prototype = {
360 //from http://hakuhin.jp/js/xmlhttprequest.html
361 CreateRequestObject: function(){
364 // XMLHttpRequest オブジェクトを作成
365 return new XMLHttpRequest();
369 return new ActiveXObject('MSXML2.XMLHTTP.6.0');
372 return new ActiveXObject('MSXML2.XMLHTTP.3.0');
375 return new ActiveXObject('MSXML2.XMLHTTP');
380 HTTPStateChange: function(){
381 //requestコールバックなのでthisはrequest!
382 switch(this.readyState){
384 //console.log("XMLHttpRequest created.");
387 //console.log("open() called.");
390 //console.log("Response header received.");
393 //console.log("Response body receiving.");
396 //console.log("send() compleated.");
397 //console.log("status:" + this.status + ":" + this.statusText);
398 if(this.status == 0){
399 console.log("Error");
400 }else if((200 <= this.status && this.status < 300) || (this.status == 304)){
403 //console.log("NAK");
405 alert(this.responseText);
415 function createCanvas(id, width, height, x, y, z, parent)
418 //width * heightの大きさのCanvasを
420 //parentには、Canvasタグを包含することになるDOMオブジェクトのidを指定する。
421 canvas = document.createElement("canvas");
422 parent = document.getElementById(parent);
426 parent.appendChild(canvas);
428 canvas.style.position = "absolute";
429 canvas.style.top = y + "px";
430 canvas.style.left = x + "px";
431 canvas.style.zIndex = z;
433 canvas.width = width;
434 canvas.height = height;
439 function createCanvas(id, width, height, x, y, z, parent)
442 //width * heightの大きさのCanvasを
444 //parentには、Canvasタグを包含することになるDOMオブジェクトのidを指定する。
445 canvas = document.createElement("canvas");
446 parent = document.getElementById(parent);
450 parent.appendChild(canvas);
452 canvas.style.position = "absolute";
453 canvas.style.top = y + "px";
454 canvas.style.left = x + "px";
455 canvas.style.zIndex = z;
457 canvas.width = width;
458 canvas.height = height;
463 function createDOMObject(typestr, idstr, parentidstr)
465 dobj = document.createElement(typestr);
466 parentObj = document.getElementById(parentidstr);
469 parentObj.appendChild(dobj);
474 function destroyDOMObjectByID(id)
476 //識別名idのDOMオブジェクトを破棄する。
477 object = document.getElementById(id);
478 parentObj = object.parentNode;
480 parentObj.removeChild(object);
483 function removeObjectFromArray(anArray, anObject)
485 //anArray中にある全てのanObjectを削除し、空いた部分は前につめる。
486 for(i = 0; i < anArray.length; i++){
487 if(anArray[i] == anObject){
488 anArray.splice(i, 1);
496 //イベントリスナーにおけるthisは、イベントリスナーを登録したオブジェクトになり、通常とは異なるので注意。
498 function keyDownEventListener(event)
500 keyDownEventListener.manager.keyDown(event);
503 function keyUpEventListener(event)
505 keyUpEventListener.manager.keyUp(event);
506 event.preventDefault();
509 function timerTickEventListener(event)
511 timerTickEventListener.manager.timerTick(event);
514 function timeStampTimerTickEventListener(event)
516 timerTickEventListener.manager.timeStampTimerTick(event);
523 function drawText(gcontext, text, x, y)
526 //前景をstrokeStyleで塗りつぶした文字列を描画する
528 //fillTextの座標は文字列の左下!
529 textsize = gcontext.measureText(text);
530 gcontext.fillRect(x, y, textsize.width, 20);
532 gcontext.fillStyle = gcontext.strokeStyle;
533 gcontext.fillText(text, x, y + 20 - 1);
537 function drawArcDegree(gcontext, radius, startAngleDegree, endAngleDegree, x, y, anticlockwise)
539 //半径radius, 中心座標(x,y)の円弧の、
540 //startAngleDegreeからendAngleDegreeまでの範囲を、
541 //(!anticlockwise)=時計回り
542 //(anticlockwise) =反時計回り
545 startAngleRadian = startAngleDegree * Math.PI / 180;
546 endAngleRadian = endAngleDegree * Math.PI / 180;
548 gcontext.beginPath();
549 gcontext.arc(drawCoordinatesInInteger(x), drawCoordinatesInInteger(y), drawCoordinatesInInteger(radius), startAngleRadian, endAngleRadian, anticlockwise);
552 gcontext.closePath();
555 function fillRect(gContext, x, y, w, h)
557 gContext.fillRect(drawCoordinatesInInteger(x), drawCoordinatesInInteger(y), drawCoordinatesInInteger(w), drawCoordinatesInInteger(h));
560 function strokeRect(gContext, x, y, w, h)
562 gContext.strokeRect(drawCoordinatesInInteger(x), drawCoordinatesInInteger(y), drawCoordinatesInInteger(w), drawCoordinatesInInteger(h));
565 function drawCoordinatesInInteger(coordinateElement)
567 //from http://www.html5rocks.com/ja/tutorials/canvas/performance/
568 // With a bitwise or.
569 return ((0.5 + coordinateElement) | 0);