| 情報学部 | 菅沼ホーム | JavaScript 目次 | 索引 |
<!DOCTYPE HTML> <HTML> <HEAD> <TITLE>シューティングゲーム:ステップ1</TITLE> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8"> <META NAME=viewport CONTENT="width=device-width, initial-scale=1"> <LINK REL="stylesheet" TYPE="text/css" HREF="../../../master.css"> <SCRIPT TYPE="text/javascript" SRC="main/MainPanel.js"></SCRIPT> <SCRIPT TYPE="text/javascript" SRC="start/StartPanel.js"></SCRIPT> <SCRIPT TYPE="text/javascript" SRC="game/GamePanel.js"></SCRIPT> <SCRIPT TYPE="text/javascript" SRC="clear/GameClearPanel.js"></SCRIPT> <SCRIPT TYPE="text/javascript" SRC="over/GameOverPanel.js"></SCRIPT> </HEAD> <BODY CLASS="eeffee" onLoad="mp_start()"> <H1>シューティングゲーム:ステップ1</H1> <CANVAS ID="canvas_e" STYLE="background-color: #ffffff;" WIDTH="500" HEIGHT="500" TABINDEX="1"></CANVAS><BR> <A HREF="method.htm" TARGET="method"><BUTTON ID="method" CLASS="std">遊び方</BUTTON></A> <BUTTON ID="start" CLASS="std" onClick="gp_start()">ゲーム開始</BUTTON> <BUTTON ID="first" CLASS="std" onClick="st_start()">最初から再開</BUTTON> <BUTTON ID="finish" CLASS="std" onClick="mp.finish()">ゲーム終了</BUTTON> <BUTTON ID="clear" CLASS="std" onClick="gp.next(0)">ゲームクリア</BUTTON> <BUTTON ID="over" CLASS="std" onClick="gp.next(1)">ゲームオーバー</BUTTON> </BODY> </HTML>
01 mp = null; // MainPanel オブジェクト
02
03 //
04 // MainPanel の開始
05 //
06 function mp_start()
07 {
08 // キャンバス情報
09 let canvas = document.getElementById('canvas_e'); // キャンバス要素の取得
10 let ctx = canvas.getContext('2d'); // キャンバスからコンテキストを取得
11 // MainPanel オブジェクト
12 mp = new MainPanel(canvas, ctx);
13 // StartPanel の表示
14 st_start();
15 }
16 //
17 // MainPanel オブジェクト(プロパティ)
18 //
19 function MainPanel(canvas, ctx)
20 {
21 this.canvas = canvas; // キャンバス要素
22 this.ctx = ctx; // キャンバスのコンテキスト
23 this.level = 1; // ゲームレベル
24 return this;
25 }
26 //
27 // MainPanel オブジェクト(メソッド)
28 //
29 MainPanel.prototype.finish = function()
30 {
31 // キャンバスのクリア
32 mp.ctx.clearRect(0, 0, mp.canvas.width, mp.canvas.height);
33 // ボタンを非表示
34 document.getElementById('method').style.display = "none";
35 document.getElementById('start').style.display = "none";
36 document.getElementById('first').style.display = "none";
37 document.getElementById('finish').style.display = "none";
38 document.getElementById('clear').style.display = "none";
39 document.getElementById('over').style.display = "none";
40 }
//
// StartPanel の開始
//
function st_start()
{
mp.level = 1; // ゲームレベルの設定
// キャンバスのクリア
mp.ctx.clearRect(0, 0, mp.canvas.width, mp.canvas.height);
// ゲームタイトルの表示
mp.ctx.font = "40px 'MS ゴシック'";
mp.ctx.textBaseline = "middle";
mp.ctx.textAlign = "center";
mp.ctx.fillStyle = "rgb(0, 0, 0)";
mp.ctx.fillText("シューティングゲーム", mp.canvas.width/2, mp.canvas.height/2);
// ボタンの表示制御
document.getElementById('method').style.display = "";
document.getElementById('start').style.display = "";
document.getElementById('first').style.display = "none";
document.getElementById('finish').style.display = "none";
document.getElementById('start').innerHTML = "ゲーム開始";
document.getElementById('clear').style.display = "none";
document.getElementById('over').style.display = "none";
}
001 gp = null; // GamePanel オブジェクト
002
003 //
004 // GamePanel の開始
005 //
006 function gp_start()
007 {
008 // GamePanel オブジェクト
009 gp = new GamePanel();
010 // タイマーのスタート
011 gp.timerID = setInterval('gp.timer()', 10);
012 // ボタンの表示制御
013 document.getElementById('method').style.display = "none";
014 document.getElementById('start').style.display = "none";
015 document.getElementById('first').style.display = "none";
016 document.getElementById('finish').style.display = "none";
017 document.getElementById('clear').style.display = "";
018 document.getElementById('over').style.display = "";
019 }
020 //
021 // GamePanel オブジェクト(プロパティ)
022 //
023 function GamePanel()
024 {
025 this.timerID = -1;
026 this.ct = 0; // カウンター
027 this.my = new My(); // 自機
028 this.bs = new Boss(); // ボス
029 this.no = 2; // 敵機の数
030 this.em = new Array(); // 敵機
031 this.em[0] = new Enemy(0, this.bs);
032 this.em[1] = new Enemy(1, this.bs);
033 // 敵機の存在
034 this.ex = new Array();
035 if (mp.level == 1) {
036 this.ex[0] = false;
037 this.ex[1] = false;
038 }
039 else {
040 this.ex[0] = true;
041 this.ex[1] = true;
042 }
043 return this;
044 }
045 //
046 // GamePanel オブジェクト(メソッド timer)
047 //
048 GamePanel.prototype.timer = function()
049 {
050 // 描画
051 gp.draw();
052 // カウントアップ
053 gp.ct = (gp.ct + 1) % 300;
054 }
055 //
056 // GamePanel オブジェクト(メソッド draw)
057 //
058 GamePanel.prototype.draw = function()
059 {
060 // キャンバスのクリア
061 mp.ctx.clearRect(0, 0, mp.canvas.width, mp.canvas.height);
062 // 描画
063 mp.ctx.drawImage(gp.my.image, gp.my.x, gp.my.y);
064 mp.ctx.drawImage(gp.bs.image, gp.bs.x, gp.bs.y);
065 for (let i1 = 0; i1 < gp.no; i1++) {
066 if (gp.ex[i1])
067 mp.ctx.drawImage(gp.em[i1].image, gp.em[i1].x, gp.em[i1].y);
068 }
069 }
070 //
071 // My オブジェクト(プロパティ)
072 //
073 function My()
074 {
075 this.image = new Image(); // 自機の画像
076 this.image.src = "image/my.gif";
077 this.width = 50; // 自機の幅
078 this.height = 51; // 自機の高さ
079 this.x = mp.canvas.width / 2 - this.width / 2; // 自機の位置(横)
080 this.y = mp.canvas.height - this.height - 10; // 自機の位置(縦)
081 return this;
082 }
083 //
084 // Boss オブジェクト(プロパティ)
085 //
086 function Boss()
087 {
088 this.image = new Image(); // ボス画像
089 this.image.src = "image/boss.gif";
090 this.width = 66; // ボスの幅
091 this.height = 95; // ボスの高さ
092 let a = 100 + Math.floor((mp.canvas.width - 200 - this.width) * Math.random());
093 this.x = a; // ボスの位置(横)
094 let b = 10 + Math.floor(20 * Math.random());
095 this.y = b; // ボスの位置(縦)
096 return this;
097 }
098 //
099 // Enemy オブジェクト(プロパティ)
100 //
101 function Enemy(sw, bs)
102 {
103 this.image = new Image(); // 敵機画像
104 this.image.src = "image/enemy.gif";
105 this.width = 27; // 敵機の幅
106 this.height = 41; // 敵機の高さ
107 this.x; // 敵機の位置(横)
108 this.y; // 敵機の位置(縦)
109 // 敵機の初期位置
110 if (sw == 0) {
111 this.x = bs.x - 150 + Math.floor(100 * Math.random());
112 this.y = bs.y + bs.height - 80 + Math.floor(100 * Math.random());
113 }
114 else {
115 this.x = bs.x + bs.width + 50 + Math.floor(100 * Math.random());
116 this.y = bs.y + bs.height - 80 + Math.floor(100 * Math.random());
117 }
118 return this;
119 }
120 //
121 // GamePanel オブジェクト(メソッド next)
122 //
123 GamePanel.prototype.next = function(sw)
124 {
125 clearInterval(gp.timerID); // タイマーの停止
126 if (sw == 0)
127 gcp_start(); // ゲームクリア
128 else
129 gop_start(); // ゲームオーバー
130 }
//
// GameClearPanel の開始
//
function gcp_start()
{
// キャンバスのクリア
mp.ctx.clearRect(0, 0, mp.canvas.width, mp.canvas.height);
// タイトルの表示
mp.ctx.font = "40px 'MS ゴシック'";
mp.ctx.textBaseline = "middle";
mp.ctx.textAlign = "center";
mp.ctx.fillStyle = "rgb(0, 0, 0)";
mp.ctx.fillText("Game Clear!", mp.canvas.width/2, mp.canvas.height/2);
// ボタンの表示制御
document.getElementById('method').style.display = "none";
if (mp.level > 1) { // 最初からゲーム再開
document.getElementById('start').style.display = "none";
document.getElementById('first').style.display = "";
}
else { // レベルアップ
mp.level++;
document.getElementById('start').style.display = "";
document.getElementById('first').style.display = "none";
document.getElementById('start').innerHTML = "次のレベル";
}
document.getElementById('finish').style.display = "";
document.getElementById('clear').style.display = "none";
document.getElementById('over').style.display = "none";
}
//
// GameOverPanel の開始
//
function gop_start()
{
// キャンバスのクリア
mp.ctx.clearRect(0, 0, mp.canvas.width, mp.canvas.height);
// タイトルの表示
mp.ctx.font = "40px 'MS ゴシック'";
mp.ctx.textBaseline = "middle";
mp.ctx.textAlign = "center";
mp.ctx.fillStyle = "rgb(0, 0, 0)";
mp.ctx.fillText("Game Over!", mp.canvas.width/2, mp.canvas.height/2);
// ボタンの表示制御
document.getElementById('method').style.display = "none";
document.getElementById('start').style.display = "";
document.getElementById('first').style.display = "";
document.getElementById('finish').style.display = "";
document.getElementById('start').innerHTML = "現レベルで再開";
document.getElementById('clear').style.display = "none";
document.getElementById('over').style.display = "none";
}
001 gp = null; // GamePanel オブジェクト
002
003 //
004 // GamePanel の開始
005 //
006 function gp_start()
007 {
008 // GamePanel オブジェクト
009 gp = new GamePanel();
010 // タイマーのスタート
011 gp.timerID = setInterval('gp.timer()', 10);
012 // キーリスナの追加(キーが押された時)
013 mp.canvas.addEventListener("keydown", gp.onKeyDown, false);
014 mp.canvas.focus();
015 // ボタンの表示制御
016 document.getElementById('method').style.display = "none";
017 document.getElementById('start').style.display = "none";
018 document.getElementById('first').style.display = "none";
019 document.getElementById('finish').style.display = "none";
020 document.getElementById('clear').style.display = "";
021 document.getElementById('over').style.display = "";
022 }
023 //
024 // GamePanel オブジェクト(プロパティ)
025 //
026 function GamePanel()
027 {
028 this.timerID = -1;
029 this.ct = 0; // カウンター
030 this.my = new My(); // 自機
031 this.bs = new Boss(); // ボス
032 this.no = 2; // 敵機の数
033 this.em = new Array(); // 敵機
034 this.em[0] = new Enemy(0, this.bs);
035 this.em[1] = new Enemy(1, this.bs);
036 // 敵機の存在
037 this.ex = new Array();
038 if (mp.level == 1) {
039 this.ex[0] = false;
040 this.ex[1] = false;
041 }
042 else {
043 this.ex[0] = true;
044 this.ex[1] = true;
045 }
046 return this;
047 }
048 //
049 // GamePanel オブジェクト(メソッド timer)
050 //
051 GamePanel.prototype.timer = function()
052 {
053 // 描画
054 gp.draw();
055 // カウントアップ
056 gp.ct = (gp.ct + 1) % 300;
057 }
058 //
059 // GamePanel オブジェクト(メソッド draw)
060 //
061 GamePanel.prototype.draw = function()
062 {
063 // キャンバスのクリア
064 mp.ctx.clearRect(0, 0, mp.canvas.width, mp.canvas.height);
065 // 描画
066 mp.ctx.drawImage(gp.my.image, gp.my.x, gp.my.y);
067 mp.ctx.drawImage(gp.bs.image, gp.bs.x, gp.bs.y);
068 for (let i1 = 0; i1 < gp.no; i1++) {
069 if (gp.ex[i1])
070 mp.ctx.drawImage(gp.em[i1].image, gp.em[i1].x, gp.em[i1].y);
071 }
072 }
073 //
074 // GamePanel オブジェクト(メソッド onKeyDown)
075 //
076 GamePanel.prototype.onKeyDown = function(event)
077 {
078 if (event.keyCode == 38) // 「↑」キー
079 gp.my.y -= gp.my.v;
080 else if (event.keyCode == 40) // 「↓」キー
081 gp.my.y += gp.my.v;
082 else if (event.keyCode == 37) // 「←」キー
083 gp.my.x -= gp.my.v;
084 else if (event.keyCode == 39) // 「→」キー
085 gp.my.x += gp.my.v;
086 }
087 //
088 // My オブジェクト(プロパティ)
089 //
090 function My()
091 {
092 this.image = new Image(); // 自機の画像
093 this.image.src = "image/my.gif";
094 this.width = 50; // 自機の幅
095 this.height = 51; // 自機の高さ
096 this.x = mp.canvas.width / 2 - this.width / 2; // 自機の位置(横)
097 this.y = mp.canvas.height - this.height - 10; // 自機の位置(縦)
098 this.v = 20; // 移動キーが押されたときの移動量
099 return this;
100 }
101 //
102 // Boss オブジェクト(プロパティ)
103 //
104 function Boss()
105 {
106 this.image = new Image(); // ボス画像
107 this.image.src = "image/boss.gif";
108 this.width = 66; // ボスの幅
109 this.height = 95; // ボスの高さ
110 let a = 100 + Math.floor((mp.canvas.width - 200 - this.width) * Math.random());
111 this.x = a; // ボスの位置(横)
112 let b = 10 + Math.floor(20 * Math.random());
113 this.y = b; // ボスの位置(縦)
114 return this;
115 }
116 //
117 // Enemy オブジェクト(プロパティ)
118 //
119 function Enemy(sw, bs)
120 {
121 this.image = new Image(); // 敵機画像
122 this.image.src = "image/enemy.gif";
123 this.width = 27; // 敵機の幅
124 this.height = 41; // 敵機の高さ
125 this.x; // 敵機の位置(横)
126 this.y; // 敵機の位置(縦)
127 // 敵機の初期位置
128 if (sw == 0) {
129 this.x = bs.x - 150 + Math.floor(100 * Math.random());
130 this.y = bs.y + bs.height - 80 + Math.floor(100 * Math.random());
131 }
132 else {
133 this.x = bs.x + bs.width + 50 + Math.floor(100 * Math.random());
134 this.y = bs.y + bs.height - 80 + Math.floor(100 * Math.random());
135 }
136 return this;
137 }
138 //
139 // GamePanel オブジェクト(メソッド next)
140 //
141 GamePanel.prototype.next = function(sw)
142 {
143 clearInterval(gp.timerID); // タイマーの停止
144 if (sw == 0)
145 gcp_start();
146 else
147 gop_start();
148 }
001 gp = null; // GamePanel オブジェクト
002
003 //
004 // GamePanel の開始
005 //
006 function gp_start()
007 {
008 // GamePanel オブジェクト
009 gp = new GamePanel();
010 // タイマーのスタート
011 gp.timerID = setInterval('gp.timer()', 10);
012 // キーリスナの追加(キーが押された時)
013 mp.canvas.addEventListener("keydown", gp.onKeyDown, false);
014 mp.canvas.focus();
015 // ボタンの表示制御
016 document.getElementById('method').style.display = "none";
017 document.getElementById('start').style.display = "none";
018 document.getElementById('first').style.display = "none";
019 document.getElementById('finish').style.display = "none";
020 document.getElementById('clear').style.display = "";
021 document.getElementById('over').style.display = "";
022 }
023 //
024 // GamePanel オブジェクト(プロパティ)
025 //
026 function GamePanel()
027 {
028 this.timerID = -1;
029 this.ct = 0; // カウンタ
030 this.my = new My(); // 自機
031 this.bs = new Boss(); // ボス
032 this.no = 2; // 敵機の数
033 this.em = new Array(); // 敵機
034 this.em[0] = new Enemy(0, this.bs);
035 this.em[1] = new Enemy(1, this.bs);
036 // 敵機の存在
037 this.ex = new Array();
038 if (mp.level == 1) {
039 this.ex[0] = false;
040 this.ex[1] = false;
041 }
042 else {
043 this.ex[0] = true;
044 this.ex[1] = true;
045 }
046 return this;
047 }
048 //
049 // GamePanel オブジェクト(メソッド timer)
050 //
051 GamePanel.prototype.timer = function()
052 {
053 // 描画
054 gp.draw();
055 // 移動処理
056 if (gp.ct%5 == 0)
057 gp.bs.move();
058 // カウントアップ
059 gp.ct = (gp.ct + 1) % 300;
060 }
061 //
062 // GamePanel オブジェクト(メソッド draw)
063 //
064 GamePanel.prototype.draw = function()
065 {
066 // キャンバスのクリア
067 mp.ctx.clearRect(0, 0, mp.canvas.width, mp.canvas.height);
068 // 描画
069 mp.ctx.drawImage(gp.my.image, gp.my.x, gp.my.y);
070 mp.ctx.drawImage(gp.bs.image, gp.bs.x, gp.bs.y);
071 for (let i1 = 0; i1 < gp.no; i1++) {
072 if (gp.ex[i1])
073 mp.ctx.drawImage(gp.em[i1].image, gp.em[i1].x, gp.em[i1].y);
074 }
075 }
076 //
077 // GamePanel オブジェクト(メソッド onKeyDown)
078 //
079 GamePanel.prototype.onKeyDown = function(event)
080 {
081 if (event.keyCode == 38) // 「↑」キー
082 gp.my.y -= gp.my.v;
083 else if (event.keyCode == 40) // 「↓」キー
084 gp.my.y += gp.my.v;
085 else if (event.keyCode == 37) // 「←」キー
086 gp.my.x -= gp.my.v;
087 else if (event.keyCode == 39) // 「→」キー
088 gp.my.x += gp.my.v;
089 }
090 //
091 // My オブジェクト(プロパティ)
092 //
093 function My()
094 {
095 this.image = new Image(); // 自機の画像
096 this.image.src = "image/my.gif";
097 this.width = 50; // 自機の幅
098 this.height = 51; // 自機の高さ
099 this.x = mp.canvas.width / 2 - this.width / 2; // 自機の位置(横)
100 this.y = mp.canvas.height - this.height - 10; // 自機の位置(縦)
101 this.v = 20; // 移動キーが押されたときの移動量
102 return this;
103 }
104 //
105 // Boss オブジェクト(プロパティ)
106 //
107 function Boss()
108 {
109 this.image = new Image(); // ボス画像
110 this.image.src = "image/boss.gif";
111 this.width = 66; // ボスの幅
112 this.height = 95; // ボスの高さ
113 let a = 100 + Math.floor((mp.canvas.width - 200 - this.width) * Math.random());
114 this.x = a; // ボスの位置(横)
115 let b = 10 + Math.floor(20 * Math.random());
116 this.y = b; // ボスの位置(縦)
117 // 行動パターンの設定
118 this.ct = 1;
119 this.ptn1 = new Array();
120 this.ptn1[0] = new Array(-5, 0, 50);
121 this.ptn1[1] = new Array(0, 20, 55);
122 this.ptn1[2] = new Array(5, 0, 105);
123 this.ptn1[3] = new Array(0, -20, 110);
124 this.ptn2 = new Array();
125 this.ptn2[0] = new Array(5, 0, 50);
126 this.ptn2[1] = new Array(0, 20, 55);
127 this.ptn2[2] = new Array(-5, 0, 105);
128 this.ptn2[3] = new Array(0, -20, 110);
129 this.ptn = new Array();
130 if (this.x > mp.canvas.width/2-this.width/2)
131 this.ptn = this.ptn1;
132 else
133 this.ptn = this.ptn2;
134 return this;
135 }
136 //
137 // Boss オブジェクト(メソッド move)
138 //
139 Boss.prototype.move = function()
140 {
141 // 移動
142 gp.bs.ct++;
143 if (gp.bs.ct > 110)
144 gp.bs.ct = 1;
145 // ボスの位置
146 let k = -1;
147 for (let i1 = 0; i1 < gp.bs.ptn.length-1 && k < 0; i1++) {
148 if (gp.bs.ct <= gp.bs.ptn[i1][2])
149 k = i1;
150 }
151 if (k < 0)
152 k = gp.bs.ptn.length - 1;
153 gp.bs.x += gp.bs.ptn[k][0];
154 gp.bs.y += gp.bs.ptn[k][1];
155 // 敵機の位置
156 if (gp.ex[0]) {
157 gp.em[0].x += gp.bs.ptn[k][0];
158 gp.em[0].y += gp.bs.ptn[k][1];
159 }
160 if (gp.ex[1]) {
161 gp.em[1].x += gp.bs.ptn[k][0];
162 gp.em[1].y += gp.bs.ptn[k][1];
163 }
164 }
165 //
166 // Enemy オブジェクト(プロパティ)
167 //
168 function Enemy(sw, bs)
169 {
170 this.image = new Image(); // 敵機画像
171 this.image.src = "image/enemy.gif";
172 this.width = 27; // 敵機の幅
173 this.height = 41; // 敵機の高さ
174 this.x; // 敵機の位置(横)
175 this.y; // 敵機の位置(縦)
176 // 敵機の初期位置
177 if (sw == 0) {
178 this.x = bs.x - 150 + Math.floor(100 * Math.random());
179 this.y = bs.y + bs.height - 80 + Math.floor(100 * Math.random());
180 }
181 else {
182 this.x = bs.x + bs.width + 50 + Math.floor(100 * Math.random());
183 this.y = bs.y + bs.height - 80 + Math.floor(100 * Math.random());
184 }
185 return this;
186 }
187 //
188 // GamePanel オブジェクト(メソッド next)
189 //
190 GamePanel.prototype.next = function(sw)
191 {
192 clearInterval(gp.timerID); // タイマーの停止
193 if (sw == 0)
194 gcp_start();
195 else
196 gop_start();
197 }
let a = new Array(2); // let a = new Array(); でも可 for (let i1 = 0; i1 < 2; i1++) a[i1] = new Array(3);
let a = new Array(2); // let a = new Array(); でも可 a[0] = new Array(1, 2, 3); a[1] = new Array(4, 5, 6);
(-5, 0, 50) : ct の値が 1 ~ 50 の間は x 座標は 5 ピクセルずつ減らし,y 座標は変化させない (0, 20, 55) : ct の値が 51 ~ 55 の間は x 座標は変化させず,y 座標は 20 ピクセルずつ増やす ・・・・・
001 gp = null; // GamePanel オブジェクト
002
003 //
004 // GamePanel の開始
005 //
006 function gp_start()
007 {
008 // GamePanel オブジェクト
009 gp = new GamePanel();
010 // タイマーのスタート
011 gp.timerID = setInterval('gp.timer()', 10);
012 // キーリスナの追加(キーが押された時)
013 mp.canvas.addEventListener("keydown", gp.onKeyDown, false);
014 mp.canvas.focus();
015 // ボタンの表示制御
016 document.getElementById('method').style.display = "none";
017 document.getElementById('start').style.display = "none";
018 document.getElementById('first').style.display = "none";
019 document.getElementById('finish').style.display = "none";
020 document.getElementById('clear').style.display = "";
021 document.getElementById('over').style.display = "";
022 }
023 //
024 // GamePanel オブジェクト(プロパティ)
025 //
026 function GamePanel()
027 {
028 this.timerID = -1;
029 this.ct = 0; // カウンタ
030 this.my = new My(); // 自機
031 this.bs = new Boss(); // ボス
032 this.no = 2; // 敵機の数
033 this.em = new Array(); // 敵機
034 this.em[0] = new Enemy(0, this.bs);
035 this.em[1] = new Enemy(1, this.bs);
036 // 敵機の存在
037 this.ex = new Array();
038 if (mp.level == 1) {
039 this.ex[0] = false;
040 this.ex[1] = false;
041 }
042 else {
043 this.ex[0] = true;
044 this.ex[1] = true;
045 }
046 return this;
047 }
048 //
049 // GamePanel オブジェクト(メソッド timer)
050 //
051 GamePanel.prototype.timer = function()
052 {
053 // 描画
054 gp.draw();
055 // 移動処理
056 if (gp.ct%3 == 0)
057 gp.my.bl.move(); // 自機の弾
058 if (gp.ct%5 == 0)
059 gp.bs.move(); // ボスの移動
060 // カウントアップ
061 gp.ct = (gp.ct + 1) % 300;
062 }
063 //
064 // GamePanel オブジェクト(メソッド draw)
065 //
066 GamePanel.prototype.draw = function()
067 {
068 // キャンバスのクリア
069 mp.ctx.clearRect(0, 0, mp.canvas.width, mp.canvas.height);
070 // 描画
071 // 自機と弾
072 mp.ctx.drawImage(gp.my.image, gp.my.x, gp.my.y);
073 for (let i1 = 0; i1 < gp.my.bl.no; i1++) {
074 if (gp.my.bl.ex[i1]) {
075 mp.ctx.beginPath();
076 mp.ctx.fillStyle = "rgb(0, 255, 0)";
077 mp.ctx.arc(gp.my.bl.x[i1], gp.my.bl.y[i1], gp.my.bl.r, 0, 2*Math.PI);
078 mp.ctx.fill();
079 }
080 }
081 // ボス
082 mp.ctx.drawImage(gp.bs.image, gp.bs.x, gp.bs.y);
083 // 敵機
084 for (let i1 = 0; i1 < gp.no; i1++) {
085 if (gp.ex[i1])
086 mp.ctx.drawImage(gp.em[i1].image, gp.em[i1].x, gp.em[i1].y);
087 }
088 }
089 //
090 // GamePanel オブジェクト(メソッド onKeyDown)
091 //
092 GamePanel.prototype.onKeyDown = function(event)
093 {
094 if (event.keyCode == 38) // 「↑」キー
095 gp.my.y -= gp.my.v;
096 else if (event.keyCode == 40) // 「↓」キー
097 gp.my.y += gp.my.v;
098 else if (event.keyCode == 37) // 「←」キー
099 gp.my.x -= gp.my.v;
100 else if (event.keyCode == 39) // 「→」キー
101 gp.my.x += gp.my.v;
102 else if (event.keyCode == 32) // 「スペース」キー
103 gp.my.bl.shoot();
104 }
105 //
106 // My オブジェクト(プロパティ)
107 //
108 function My()
109 {
110 this.image = new Image(); // 自機の画像
111 this.image.src = "image/my.gif";
112 this.width = 50; // 自機の幅
113 this.height = 51; // 自機の高さ
114 this.x = mp.canvas.width / 2 - this.width / 2; // 自機の位置(横)
115 this.y = mp.canvas.height - this.height - 10; // 自機の位置(縦)
116 this.v = 20; // 移動キーが押されたときの移動量
117 this.bl = new Bullet(); // 弾
118 return this;
119 }
120 //
121 // Bullet オブジェクト(プロパティ)
122 //
123 function Bullet()
124 {
125 this.r = 12; // 弾の半径
126 this.no = 15; // 弾の全数
127 this.no_1 = 5; // 一度に撃てる弾数
128 this.ct = 0; // 現在の弾の数
129 this.x = new Array(); // 弾の位置(横)
130 this.y = new Array(); // 弾の位置(縦)
131 this.v = 30; // 弾の速さ
132 this.fire = false; // 弾を発射中か否か
133 this.ex = new Array(); // 弾の存在
134 for (let i1 = 0; i1 < this.no; i1++)
135 this.ex[i1] = false;
136 }
137 //
138 // Bullet オブジェクト(メソッド move)
139 //
140 Bullet.prototype.move = function()
141 {
142 // 弾の移動
143 for (let i1 = 0; i1 < gp.my.bl.no; i1++) {
144 if (gp.my.bl.ex[i1]) {
145 gp.my.bl.y[i1] -= gp.my.bl.v;
146 if (gp.my.bl.y[i1] < -gp.my.bl.r)
147 gp.my.bl.ex[i1] = false;
148 }
149 }
150 // 次の弾の発射
151 if (gp.my.bl.fire) {
152 if (gp.my.bl.ct < gp.my.bl.no_1) {
153 let sw = true;
154 for (let i1 = 0; i1 < gp.my.bl.no && sw; i1++) {
155 if (!gp.my.bl.ex[i1]) {
156 gp.my.bl.x[i1] = gp.my.x + gp.my.width / 2;
157 gp.my.bl.y[i1] = gp.my.y - gp.my.bl.r;
158 gp.my.bl.ex[i1] = true;
159 sw = false;
160 }
161 }
162 gp.my.bl.ct++;
163 if (gp.my.bl.ct >= gp.my.bl.no_1) {
164 gp.my.bl.fire = false;
165 gp.my.bl.ct = 0;
166 }
167 }
168 }
169 }
170 //
171 // Bullet オブジェクト(メソッド shoot,最初の弾の発射)
172 //
173 Bullet.prototype.shoot = function()
174 {
175 if (!gp.my.bl.fire) {
176 gp.my.bl.fire = true;
177 gp.my.bl.ct = 1;
178 let sw = true;
179 for (let i1 = 0; i1 < gp.my.bl.no && sw; i1++) {
180 if (!gp.my.bl.ex[i1]) {
181 gp.my.bl.x[i1] = gp.my.x + gp.my.width / 2;
182 gp.my.bl.y[i1] = gp.my.y - gp.my.bl.r;
183 gp.my.bl.ex[i1] = true;
184 sw = false;
185 }
186 }
187 }
188 }
189 //
190 // Boss オブジェクト(プロパティ)
191 //
192 function Boss()
193 {
194 this.image = new Image(); // ボス画像
195 this.image.src = "image/boss.gif";
196 this.width = 66; // ボスの幅
197 this.height = 95; // ボスの高さ
198 let a = 100 + Math.floor((mp.canvas.width - 200 - this.width) * Math.random());
199 this.x = a; // ボスの位置(横)
200 let b = 10 + Math.floor(20 * Math.random());
201 this.y = b; // ボスの位置(縦)
202 // 行動パターンの設定
203 this.ct = 1;
204 this.ptn1 = new Array();
205 this.ptn1[0] = new Array(-5, 0, 50);
206 this.ptn1[1] = new Array(0, 20, 55);
207 this.ptn1[2] = new Array(5, 0, 105);
208 this.ptn1[3] = new Array(0, -20, 110);
209 this.ptn2 = new Array();
210 this.ptn2[0] = new Array(5, 0, 50);
211 this.ptn2[1] = new Array(0, 20, 55);
212 this.ptn2[2] = new Array(-5, 0, 105);
213 this.ptn2[3] = new Array(0, -20, 110);
214 this.ptn = new Array();
215 if (this.x > mp.canvas.width/2-this.width/2)
216 this.ptn = this.ptn1;
217 else
218 this.ptn = this.ptn2;
219 return this;
220 }
221 //
222 // Boss オブジェクト(メソッド move)
223 //
224 Boss.prototype.move = function()
225 {
226 // 移動
227 gp.bs.ct++;
228 if (gp.bs.ct > 110)
229 gp.bs.ct = 1;
230 // ボスの位置
231 let k = -1;
232 for (let i1 = 0; i1 < gp.bs.ptn.length-1 && k < 0; i1++) {
233 if (gp.bs.ct <= gp.bs.ptn[i1][2])
234 k = i1;
235 }
236 if (k < 0)
237 k = gp.bs.ptn.length - 1;
238 gp.bs.x += gp.bs.ptn[k][0];
239 gp.bs.y += gp.bs.ptn[k][1];
240 // 敵機の位置
241 if (gp.ex[0]) {
242 gp.em[0].x += gp.bs.ptn[k][0];
243 gp.em[0].y += gp.bs.ptn[k][1];
244 }
245 if (gp.ex[1]) {
246 gp.em[1].x += gp.bs.ptn[k][0];
247 gp.em[1].y += gp.bs.ptn[k][1];
248 }
249 }
250 //
251 // Enemy オブジェクト(プロパティ)
252 //
253 function Enemy(sw, bs)
254 {
255 this.image = new Image(); // 敵機画像
256 this.image.src = "image/enemy.gif";
257 this.width = 27; // 敵機の幅
258 this.height = 41; // 敵機の高さ
259 this.x; // 敵機の位置(横)
260 this.y; // 敵機の位置(縦)
261 // 敵機の初期位置
262 if (sw == 0) {
263 this.x = bs.x - 150 + Math.floor(100 * Math.random());
264 this.y = bs.y + bs.height - 80 + Math.floor(100 * Math.random());
265 }
266 else {
267 this.x = bs.x + bs.width + 50 + Math.floor(100 * Math.random());
268 this.y = bs.y + bs.height - 80 + Math.floor(100 * Math.random());
269 }
270 return this;
271 }
272 //
273 // GamePanel オブジェクト(メソッド next)
274 //
275 GamePanel.prototype.next = function(sw)
276 {
277 clearInterval(gp.timerID); // タイマーの停止
278 if (sw == 0)
279 gcp_start();
280 else
281 gop_start();
282 }
001 gp = null; // GamePanel オブジェクト
002
003 //
004 // GamePanel の開始
005 //
006 function gp_start()
007 {
008 // GamePanel オブジェクト
009 gp = new GamePanel();
010 // タイマーのスタート
011 gp.timerID = setInterval('gp.timer()', 10);
012 // キーリスナの追加(キーが押された時)
013 mp.canvas.addEventListener("keydown", gp.onKeyDown, false);
014 mp.canvas.focus();
015 // ボタンの表示制御
016 document.getElementById('method').style.display = "none";
017 document.getElementById('start').style.display = "none";
018 document.getElementById('first').style.display = "none";
019 document.getElementById('finish').style.display = "none";
020 document.getElementById('clear').style.display = "";
021 document.getElementById('over').style.display = "";
022 }
023 //
024 // GamePanel オブジェクト(プロパティ)
025 //
026 function GamePanel()
027 {
028 this.timerID = -1;
029 this.ct = 0; // カウンタ
030 this.my = new My(); // 自機
031 this.bs = new Boss(); // ボス
032 this.no = 2; // 敵機の数
033 this.em = new Array(); // 敵機
034 this.em[0] = new Enemy(0, this.bs);
035 this.em[1] = new Enemy(1, this.bs);
036 // 敵機の存在
037 this.ex = new Array();
038 if (mp.level == 1) {
039 this.ex[0] = false;
040 this.ex[1] = false;
041 }
042 else {
043 this.ex[0] = true;
044 this.ex[1] = true;
045 }
046 return this;
047 }
048 //
049 // GamePanel オブジェクト(メソッド timer)
050 //
051 GamePanel.prototype.timer = function()
052 {
053 // 描画
054 gp.draw();
055 // 移動処理
056 if (gp.ct%3 == 0)
057 gp.my.bl.move(); // 自機の弾
058 if (gp.ct%5 == 0) {
059 gp.bs.move(); // ボスと敵機の移動
060 for (let i1 = 0; i1 < gp.no; i1++) { // 敵機の弾
061 if (gp.ex[i1])
062 gp.em[i1].bl.move(gp.em[i1]);
063 }
064 }
065 if (gp.ct%10 == 0)
066 gp.bs.bl.move(); // ボスの弾
067 // カウントアップ
068 gp.ct = (gp.ct + 1) % 300;
069 }
070 //
071 // GamePanel オブジェクト(メソッド draw)
072 //
073 GamePanel.prototype.draw = function()
074 {
075 // キャンバスのクリア
076 mp.ctx.clearRect(0, 0, mp.canvas.width, mp.canvas.height);
077 // 描画
078 // 自機と弾
079 mp.ctx.drawImage(gp.my.image, gp.my.x, gp.my.y);
080 for (let i1 = 0; i1 < gp.my.bl.no; i1++) {
081 if (gp.my.bl.ex[i1]) {
082 mp.ctx.beginPath();
083 mp.ctx.fillStyle = "rgb(0, 255, 0)";
084 mp.ctx.arc(gp.my.bl.x[i1], gp.my.bl.y[i1], gp.my.bl.r, 0, 2*Math.PI);
085 mp.ctx.fill();
086 }
087 }
088 // ボスと弾
089 mp.ctx.drawImage(gp.bs.image, gp.bs.x, gp.bs.y);
090 for (let i1 = 0; i1 < gp.bs.bl.no; i1++) {
091 if (gp.bs.bl.ex[i1]) {
092 mp.ctx.beginPath();
093 mp.ctx.fillStyle = "rgb(255, 165, 0)";
094 mp.ctx.arc(gp.bs.bl.x[i1], gp.bs.bl.y[i1], gp.bs.bl.r, 0, 2*Math.PI);
095 mp.ctx.fill();
096 }
097 }
098 // 敵機と弾
099 for (let i1 = 0; i1 < gp.no; i1++) {
100 if (gp.ex[i1]) {
101 mp.ctx.drawImage(gp.em[i1].image, gp.em[i1].x, gp.em[i1].y);
102 for (let i2 = 0; i2 < gp.em[i1].bl.no; i2++) {
103 if (gp.em[i1].bl.ex[i2]) {
104 mp.ctx.beginPath();
105 mp.ctx.fillStyle = "rgb(255, 0, 0)";
106 mp.ctx.arc(gp.em[i1].bl.x[i2], gp.em[i1].bl.y[i2], gp.em[i1].bl.r, 0, 2*Math.PI);
107 mp.ctx.fill();
108 }
109 }
110 }
111 }
112 }
113 //
114 // GamePanel オブジェクト(メソッド onKeyDown)
115 //
116 GamePanel.prototype.onKeyDown = function(event)
117 {
118 if (event.keyCode == 38) // 「↑」キー
119 gp.my.y -= gp.my.v;
120 else if (event.keyCode == 40) // 「↓」キー
121 gp.my.y += gp.my.v;
122 else if (event.keyCode == 37) // 「←」キー
123 gp.my.x -= gp.my.v;
124 else if (event.keyCode == 39) // 「→」キー
125 gp.my.x += gp.my.v;
126 else if (event.keyCode == 32) // 「スペース」キー
127 gp.my.bl.shoot();
128 }
129 //
130 // My オブジェクト(プロパティ)
131 //
132 function My()
133 {
134 this.image = new Image(); // 自機の画像
135 this.image.src = "image/my.gif";
136 this.width = 50; // 自機の幅
137 this.height = 51; // 自機の高さ
138 this.x = mp.canvas.width / 2 - this.width / 2; // 自機の位置(横)
139 this.y = mp.canvas.height - this.height - 10; // 自機の位置(縦)
140 this.v = 20; // 移動キーが押されたときの移動量
141 this.bl = new Bullet(); // 弾
142 return this;
143 }
144 //
145 // Bullet オブジェクト(プロパティ)
146 //
147 function Bullet()
148 {
149 this.r = 12; // 弾の半径
150 this.no = 15; // 弾の全数
151 this.no_1 = 5; // 一度に撃てる弾数
152 this.ct = 0; // 現在の弾の数
153 this.x = new Array(); // 弾の位置(横)
154 this.y = new Array(); // 弾の位置(縦)
155 this.v = 30; // 弾の速さ
156 this.fire = false; // 弾を発射中か否か
157 this.ex = new Array(); // 弾の存在
158 for (let i1 = 0; i1 < this.no; i1++)
159 this.ex[i1] = false;
160 }
161 //
162 // Bullet オブジェクト(メソッド move)
163 //
164 Bullet.prototype.move = function()
165 {
166 // 弾の移動
167 for (let i1 = 0; i1 < gp.my.bl.no; i1++) {
168 if (gp.my.bl.ex[i1]) {
169 gp.my.bl.y[i1] -= gp.my.bl.v;
170 if (gp.my.bl.y[i1] < -gp.my.bl.r)
171 gp.my.bl.ex[i1] = false;
172 }
173 }
174 // 次の弾の発射
175 if (gp.my.bl.fire) {
176 if (gp.my.bl.ct < gp.my.bl.no_1) {
177 let sw = true;
178 for (let i1 = 0; i1 < gp.my.bl.no && sw; i1++) {
179 if (!gp.my.bl.ex[i1]) {
180 gp.my.bl.x[i1] = gp.my.x + gp.my.width / 2;
181 gp.my.bl.y[i1] = gp.my.y - gp.my.bl.r;
182 gp.my.bl.ex[i1] = true;
183 sw = false;
184 }
185 }
186 gp.my.bl.ct++;
187 if (gp.my.bl.ct >= gp.my.bl.no_1) {
188 gp.my.bl.fire = false;
189 gp.my.bl.ct = 0;
190 }
191 }
192 }
193 }
194 //
195 // Bullet オブジェクト(メソッド shoot,最初の弾の発射)
196 //
197 Bullet.prototype.shoot = function()
198 {
199 if (!gp.my.bl.fire) {
200 gp.my.bl.fire = true;
201 gp.my.bl.ct = 1;
202 let sw = true;
203 for (let i1 = 0; i1 < gp.my.bl.no && sw; i1++) {
204 if (!gp.my.bl.ex[i1]) {
205 gp.my.bl.x[i1] = gp.my.x + gp.my.width / 2;
206 gp.my.bl.y[i1] = gp.my.y - gp.my.bl.r;
207 gp.my.bl.ex[i1] = true;
208 sw = false;
209 }
210 }
211 }
212 }
213 //
214 // Boss オブジェクト(プロパティ)
215 //
216 function Boss()
217 {
218 this.image = new Image(); // ボス画像
219 this.image.src = "image/boss.gif";
220 this.width = 66; // ボスの幅
221 this.height = 95; // ボスの高さ
222 let a = 100 + Math.floor((mp.canvas.width - 200 - this.width) * Math.random());
223 this.x = a; // ボスの位置(横)
224 let b = 10 + Math.floor(20 * Math.random());
225 this.y = b; // ボスの位置(縦)
226 this.bl = new Bullet_b(); // 弾
227 // 行動パターンの設定
228 this.ct = 1;
229 this.ptn1 = new Array();
230 this.ptn1[0] = new Array(-5, 0, 50);
231 this.ptn1[1] = new Array(0, 20, 55);
232 this.ptn1[2] = new Array(5, 0, 105);
233 this.ptn1[3] = new Array(0, -20, 110);
234 this.ptn2 = new Array();
235 this.ptn2[0] = new Array(5, 0, 50);
236 this.ptn2[1] = new Array(0, 20, 55);
237 this.ptn2[2] = new Array(-5, 0, 105);
238 this.ptn2[3] = new Array(0, -20, 110);
239 this.ptn = new Array();
240 if (this.x > mp.canvas.width/2-this.width/2)
241 this.ptn = this.ptn1;
242 else
243 this.ptn = this.ptn2;
244 return this;
245 }
246 //
247 // Boss オブジェクト(メソッド move)
248 //
249 Boss.prototype.move = function()
250 {
251 // 移動
252 gp.bs.ct++;
253 if (gp.bs.ct > 110)
254 gp.bs.ct = 1;
255 // ボスの位置
256 let k = -1;
257 for (let i1 = 0; i1 < gp.bs.ptn.length-1 && k < 0; i1++) {
258 if (gp.bs.ct <= gp.bs.ptn[i1][2])
259 k = i1;
260 }
261 if (k < 0)
262 k = gp.bs.ptn.length - 1;
263 gp.bs.x += gp.bs.ptn[k][0];
264 gp.bs.y += gp.bs.ptn[k][1];
265 // 敵機の位置
266 if (gp.ex[0]) {
267 gp.em[0].x += gp.bs.ptn[k][0];
268 gp.em[0].y += gp.bs.ptn[k][1];
269 }
270 if (gp.ex[1]) {
271 gp.em[1].x += gp.bs.ptn[k][0];
272 gp.em[1].y += gp.bs.ptn[k][1];
273 }
274 }
275 //
276 // Bullet_b オブジェクト(プロパティ)
277 //
278 function Bullet_b()
279 {
280 this.r = 12; // 弾の幅
281 this.no = 15; // 弾の全数
282 this.x = new Array(); // 弾の位置(横)
283 this.y = new Array(); // 弾の位置(縦)
284 this.v = 30; // 弾の速さ
285 this.vx = new Array(); // 横方向の弾の速さ
286 this.vy = new Array(); // 縦方向の弾の速さ
287 this.pr = 5; // 弾の発射間隔
288 this.ct = 0;
289 this.ex = new Array(); // 弾の存在
290 for (let i1 = 0; i1 < this.no; i1++)
291 this.ex[i1] = false;
292 }
293 //
294 // Bullet_b オブジェクト(メソッド move)
295 //
296 Bullet_b.prototype.move = function()
297 {
298 // 弾の移動
299 for (let i1 = 0; i1 < gp.bs.bl.no; i1++) {
300 if (gp.bs.bl.ex[i1]) {
301 gp.bs.bl.x[i1] += gp.bs.bl.vx[i1];
302 gp.bs.bl.y[i1] += gp.bs.bl.vy[i1];
303 if (gp.bs.bl.x[i1] < -gp.bs.bl.r ||
304 gp.bs.bl.x[i1] > mp.canvas.width+gp.bs.bl.r ||
305 gp.bs.bl.y[i1] > mp.canvas.height+gp.bs.bl.r)
306 gp.bs.bl.ex[i1] = false;
307 }
308 }
309 // 次の弾の発射
310 gp.bs.bl.ct = (gp.bs.bl.ct + 1) % gp.bs.bl.pr;
311 if (gp.bs.bl.ct == 0)
312 gp.bs.bl.shoot();
313 }
314 //
315 // Bullet_b オブジェクト(メソッド shoot,弾の発射)
316 //
317 Bullet_b.prototype.shoot = function()
318 {
319 let sw = true;
320 for (let i1 = 1; i1 < gp.bs.bl.no && sw; i1++) {
321 if (!gp.bs.bl.ex[i1]) {
322 sw = false;
323 gp.bs.bl.ex[i1] = true;
324 gp.bs.bl.x[i1] = gp.bs.x + gp.bs.width / 2;
325 gp.bs.bl.y[i1] = gp.bs.y + gp.bs.height + gp.bs.bl.r;
326 let yt = gp.my.y + gp.my.height / 2 - gp.bs.bl.y[i1];
327 let xt = gp.my.x + gp.my.width / 2 - gp.bs.bl.x[i1];
328 let ang = Math.atan2(yt, xt);
329 gp.bs.bl.vx[i1] = Math.floor(gp.bs.bl.v * Math.cos(ang) + 0.5);
330 gp.bs.bl.vy[i1] = Math.floor(gp.bs.bl.v * Math.sin(ang) + 0.5);
331 }
332 }
333 }
334 //
335 // Enemy オブジェクト(プロパティ)
336 //
337 function Enemy(sw, bs)
338 {
339 this.image = new Image(); // 敵機画像
340 this.image.src = "image/enemy.gif";
341 this.width = 27; // 敵機の幅
342 this.height = 41; // 敵機の高さ
343 this.x; // 敵機の位置(横)
344 this.y; // 敵機の位置(縦)
345 this.bl = new Bullet_e(); // 弾
346 // 敵機の初期位置
347 if (sw == 0) {
348 this.x = bs.x - 150 + Math.floor(100 * Math.random());
349 this.y = bs.y + bs.height - 80 + Math.floor(100 * Math.random());
350 }
351 else {
352 this.x = bs.x + bs.width + 50 + Math.floor(100 * Math.random());
353 this.y = bs.y + bs.height - 80 + Math.floor(100 * Math.random());
354 }
355 return this;
356 }
357 //
358 // Bullet_e オブジェクト(プロパティ)
359 //
360 function Bullet_e()
361 {
362 this.r = 7; // 弾の幅
363 this.no = 5; // 弾の全数
364 this.ct = 0; // 現在の弾の数
365 this.x = new Array(); // 弾の位置(横)
366 this.y = new Array(); // 弾の位置(縦)
367 this.v = 30; // 弾の速さ
368 this.vx = new Array(); // 横方向の弾の速さ
369 this.vy = new Array(); // 縦方向の弾の速さ
370 this.ex = new Array(); // 弾の存在
371 for (let i1 = 0; i1 < this.no; i1++)
372 this.ex[i1] = false;
373 }
374 //
375 // Bullet_e オブジェクト(メソッド move)
376 //
377 Bullet_e.prototype.move = function(em)
378 {
379 if (em.bl.ct < em.bl.no)
380 em.bl.ct++;
381 // 弾の移動
382 let sw = false;
383 for (let i1 = 0; i1 < em.bl.no; i1++) {
384 if (em.bl.ex[i1]) {
385 em.bl.x[i1] += em.bl.vx;
386 em.bl.y[i1] += em.bl.vy;
387 if (em.bl.x[i1] < -em.bl.r || em.bl.x[i1] > mp.canvas.width+em.bl.r ||
388 em.bl.y[i1] > mp.canvas.height+em.bl.r)
389 em.bl.ex[i1] = false;
390 else
391 sw = true;
392 }
393 }
394 // 最初の弾の発射
395 if (!sw)
396 em.bl.shoot(em);
397 // 次の弾の発射
398 else {
399 if (em.bl.ct < em.bl.no) {
400 em.bl.x[em.bl.ct] = em.x + em.width / 2;
401 em.bl.y[em.bl.ct] = em.y + em.height + em.bl.r;
402 em.bl.ex[em.bl.ct] = true;
403 }
404 }
405 }
406 //
407 // Bullet_e オブジェクト(メソッド shoot,弾の発射)
408 //
409 Bullet_e.prototype.shoot = function(em)
410 {
411 em.bl.ct = 0;
412 em.bl.ex[0] = true;
413 for (let i1 = 1; i1 < em.bl.no; i1++)
414 em.bl.ex[i1] = false;
415 let ang = 0.25 * Math.PI + 0.5 * Math.PI * Math.random();
416 em.bl.vx = Math.floor(em.bl.v * Math.cos(ang) + 0.5);
417 em.bl.vy = Math.floor(em.bl.v * Math.sin(ang) + 0.5);
418 em.bl.x[0] = em.x + em.width / 2;
419 em.bl.y[0] = em.y + em.height + em.bl.r;
420 }
421 //
422 // GamePanel オブジェクト(メソッド next)
423 //
424 GamePanel.prototype.next = function(sw)
425 {
426 clearInterval(gp.timerID); // タイマーの停止
427 if (sw == 0)
428 gcp_start();
429 else
430 gop_start();
431 }
001 gp = null; // GamePanel オブジェクト
002
003 //
004 // GamePanel の開始
005 //
006 function gp_start()
007 {
008 // GamePanel オブジェクト
009 gp = new GamePanel();
010 // タイマーのスタート
011 gp.timerID = setInterval('gp.timer()', 10);
012 // キーリスナの追加(キーが押された時)
013 mp.canvas.addEventListener("keydown", gp.onKeyDown, false);
014 mp.canvas.focus();
015 // ボタンの表示制御
016 document.getElementById('method').style.display = "none";
017 document.getElementById('start').style.display = "none";
018 document.getElementById('first').style.display = "none";
019 document.getElementById('finish').style.display = "none";
020 }
021 //
022 // GamePanel オブジェクト(プロパティ)
023 //
024 function GamePanel()
025 {
026 this.timerID = -1;
027 this.ct = 0; // カウンタ
028 this.my = new My(); // 自機
029 this.bs = new Boss(); // ボス
030 this.no = 2; // 敵機の数
031 this.em = new Array(); // 敵機
032 this.em[0] = new Enemy(0, this.bs);
033 this.em[1] = new Enemy(1, this.bs);
034 // 敵機の存在
035 this.ex = new Array();
036 if (mp.level == 1) {
037 this.ex[0] = false;
038 this.ex[1] = false;
039 }
040 else {
041 this.ex[0] = true;
042 this.ex[1] = true;
043 }
044 return this;
045 }
046 //
047 // GamePanel オブジェクト(メソッド timer)
048 //
049 GamePanel.prototype.timer = function()
050 {
051 // 描画
052 gp.draw();
053 // 移動処理
054 if (gp.ct%3 == 0)
055 gp.my.bl.move(); // 自機の弾
056 if (gp.ct%5 == 0) {
057 gp.bs.move(); // ボスと敵機の移動
058 for (let i1 = 0; i1 < gp.no; i1++) { // 敵機の弾
059 if (gp.ex[i1])
060 gp.em[i1].bl.move(gp.em[i1]);
061 }
062 }
063 if (gp.ct%10 == 0)
064 gp.bs.bl.move(); // ボスの弾
065 // 自機の弾による命中判定
066 let hit = false;
067 // ボスに対して
068 for (let i1 = 0; i1 < gp.my.bl.no && !hit; i1++) {
069 if (gp.my.bl.ex[i1]) {
070 let xb = gp.my.bl.x[i1];
071 let yb = gp.my.bl.y[i1];
072 let w = gp.bs.width / 2 + gp.my.bl.r;
073 let h = gp.bs.height / 2 + gp.my.bl.r;
074 let xt = gp.bs.x + gp.bs.width / 2;
075 let yt = gp.bs.y + gp.bs.height / 2;
076 if (xb > xt-w && xb < xt+w && yb > yt-h && yb < yt+h) {
077 gp.my.bl.ex[i1] = false;
078 gp.bs.h_ct++;
079 if (gp.bs.h_ct > gp.bs.h_max) {
080 hit = true;
081 clearInterval(gp.timerID); // タイマーの停止
082 gcp_start(); // ゲームクリア
083 }
084 }
085 }
086 }
087 // 敵機に対して
088 if (!hit) {
089 for (let i1 = 0; i1 < gp.no && !hit; i1++) {
090 if (gp.ex[i1]) {
091 for (let i2 = 0; i2 < gp.my.bl.no && !hit; i2++) {
092 if (gp.my.bl.ex[i2]) {
093 let xb = gp.my.bl.x[i2];
094 let yb = gp.my.bl.y[i2];
095 let w = gp.em[i1].width / 2 + gp.my.bl.r;
096 let h = gp.em[i1].height / 2 + gp.my.bl.r;
097 let xt = gp.em[i1].x + gp.em[i1].width / 2;
098 let yt = gp.em[i1].y + gp.em[i1].height / 2;
099 if (xb > xt-w && xb < xt+w && yb > yt-h && yb < yt+h) {
100 hit = true;
101 gp.ex[i1] = false;
102 gp.my.bl.ex[i2] = false;
103 }
104 }
105 }
106 }
107 }
108 }
109 // ボスの弾による命中判定
110 if (!hit) {
111 for (let i1 = 0; i1 < gp.bs.bl.no && !hit; i1++) {
112 if (gp.bs.bl.ex[i1]) {
113 xb = gp.bs.bl.x[i1];
114 yb = gp.bs.bl.y[i1];
115 w = gp.my.width / 2;
116 h = gp.my.width / 2;
117 xt = gp.my.x + w;
118 yt = gp.my.y + h;
119 if (xb > xt-w && xb < xt+w && yb > yt-h && yb < yt+h) {
120 hit = true;
121 clearInterval(gp.timerID); // タイマーの停止
122 gop_start(); // ゲームオーバー
123 }
124 }
125 }
126 }
127 // 敵機の弾による命中判定
128 if (!hit) {
129 for (let i1 = 0; i1 < gp.no && !hit; i1++) {
130 if (gp.ex[i1]) {
131 for (let i2 = 0; i2 < gp.em[i1].bl.no && !hit; i2++) {
132 if (gp.em[i1].bl.ex[i2]) {
133 let xb = gp.em[i1].bl.x[i2];
134 let yb = gp.em[i1].bl.y[i2];
135 let w = gp.my.width / 2;
136 let h = gp.my.width / 2;
137 let xt = gp.my.x + w;
138 let yt = gp.my.y + h;
139 if (xb > xt-w && xb < xt+w && yb > yt-h && yb < yt+h) {
140 hit = true;
141 clearInterval(gp.timerID); // タイマーの停止
142 gop_start(); // ゲームオーバー
143 }
144 }
145 }
146 }
147 }
148 }
149 // カウントアップ
150 gp.ct = (gp.ct + 1) % 300;
151 }
152 //
153 // GamePanel オブジェクト(メソッド draw)
154 //
155 GamePanel.prototype.draw = function()
156 {
157 // キャンバスのクリア
158 mp.ctx.clearRect(0, 0, mp.canvas.width, mp.canvas.height);
159 // 描画
160 // 自機と弾
161 mp.ctx.drawImage(gp.my.image, gp.my.x, gp.my.y);
162 for (let i1 = 0; i1 < gp.my.bl.no; i1++) {
163 if (gp.my.bl.ex[i1]) {
164 mp.ctx.beginPath();
165 mp.ctx.fillStyle = "rgb(0, 255, 0)";
166 mp.ctx.arc(gp.my.bl.x[i1], gp.my.bl.y[i1], gp.my.bl.r, 0, 2*Math.PI);
167 mp.ctx.fill();
168 }
169 }
170 // ボスと弾
171 mp.ctx.drawImage(gp.bs.image, gp.bs.x, gp.bs.y);
172 for (let i1 = 0; i1 < gp.bs.bl.no; i1++) {
173 if (gp.bs.bl.ex[i1]) {
174 mp.ctx.beginPath();
175 mp.ctx.fillStyle = "rgb(255, 165, 0)";
176 mp.ctx.arc(gp.bs.bl.x[i1], gp.bs.bl.y[i1], gp.bs.bl.r, 0, 2*Math.PI);
177 mp.ctx.fill();
178 }
179 }
180 // 敵機と弾
181 for (let i1 = 0; i1 < gp.no; i1++) {
182 if (gp.ex[i1]) {
183 mp.ctx.drawImage(gp.em[i1].image, gp.em[i1].x, gp.em[i1].y);
184 for (let i2 = 0; i2 < gp.em[i1].bl.no; i2++) {
185 if (gp.em[i1].bl.ex[i2]) {
186 mp.ctx.beginPath();
187 mp.ctx.fillStyle = "rgb(255, 0, 0)";
188 mp.ctx.arc(gp.em[i1].bl.x[i2], gp.em[i1].bl.y[i2], gp.em[i1].bl.r, 0, 2*Math.PI);
189 mp.ctx.fill();
190 }
191 }
192 }
193 }
194 }
195 //
196 // GamePanel オブジェクト(メソッド onKeyDown)
197 //
198 GamePanel.prototype.onKeyDown = function(event)
199 {
200 if (event.keyCode == 38) // 「↑」キー
201 gp.my.y -= gp.my.v;
202 else if (event.keyCode == 40) // 「↓」キー
203 gp.my.y += gp.my.v;
204 else if (event.keyCode == 37) // 「←」キー
205 gp.my.x -= gp.my.v;
206 else if (event.keyCode == 39) // 「→」キー
207 gp.my.x += gp.my.v;
208 else if (event.keyCode == 32) // 「スペース」キー
209 gp.my.bl.shoot();
210 }
211 //
212 // My オブジェクト(プロパティ)
213 //
214 function My()
215 {
216 this.image = new Image(); // 自機の画像
217 this.image.src = "image/my.gif";
218 this.width = 50; // 自機の幅
219 this.height = 51; // 自機の高さ
220 this.x = mp.canvas.width / 2 - this.width / 2; // 自機の位置(横)
221 this.y = mp.canvas.height - this.height - 10; // 自機の位置(縦)
222 this.v = 20; // 移動キーが押されたときの移動量
223 this.bl = new Bullet(); // 弾
224 return this;
225 }
226 //
227 // Bullet オブジェクト(プロパティ)
228 //
229 function Bullet()
230 {
231 this.r = 12; // 弾の半径
232 this.no = 15; // 弾の全数
233 this.no_1 = 5; // 一度に撃てる弾数
234 this.ct = 0; // 現在の弾の数
235 this.x = new Array(); // 弾の位置(横)
236 this.y = new Array(); // 弾の位置(縦)
237 this.v = 30; // 弾の速さ
238 this.fire = false; // 弾を発射中か否か
239 this.ex = new Array(); // 弾の存在
240 for (let i1 = 0; i1 < this.no; i1++)
241 this.ex[i1] = false;
242 }
243 //
244 // Bullet オブジェクト(メソッド move)
245 //
246 Bullet.prototype.move = function()
247 {
248 // 弾の移動
249 for (let i1 = 0; i1 < gp.my.bl.no; i1++) {
250 if (gp.my.bl.ex[i1]) {
251 gp.my.bl.y[i1] -= gp.my.bl.v;
252 if (gp.my.bl.y[i1] < -gp.my.bl.r)
253 gp.my.bl.ex[i1] = false;
254 }
255 }
256 // 次の弾の発射
257 if (gp.my.bl.fire) {
258 if (gp.my.bl.ct < gp.my.bl.no_1) {
259 let sw = true;
260 for (let i1 = 0; i1 < gp.my.bl.no && sw; i1++) {
261 if (!gp.my.bl.ex[i1]) {
262 gp.my.bl.x[i1] = gp.my.x + gp.my.width / 2;
263 gp.my.bl.y[i1] = gp.my.y - gp.my.bl.r;
264 gp.my.bl.ex[i1] = true;
265 sw = false;
266 }
267 }
268 gp.my.bl.ct++;
269 if (gp.my.bl.ct >= gp.my.bl.no_1) {
270 gp.my.bl.fire = false;
271 gp.my.bl.ct = 0;
272 }
273 }
274 }
275 }
276 //
277 // Bullet オブジェクト(メソッド shoot,最初の弾の発射)
278 //
279 Bullet.prototype.shoot = function()
280 {
281 if (!gp.my.bl.fire) {
282 gp.my.bl.fire = true;
283 gp.my.bl.ct = 1;
284 let sw = true;
285 for (let i1 = 0; i1 < gp.my.bl.no && sw; i1++) {
286 if (!gp.my.bl.ex[i1]) {
287 gp.my.bl.x[i1] = gp.my.x + gp.my.width / 2;
288 gp.my.bl.y[i1] = gp.my.y - gp.my.bl.r;
289 gp.my.bl.ex[i1] = true;
290 sw = false;
291 }
292 }
293 }
294 }
295 //
296 // Boss オブジェクト(プロパティ)
297 //
298 function Boss()
299 {
300 this.image = new Image(); // ボス画像
301 this.image.src = "image/boss.gif";
302 this.width = 66; // ボスの幅
303 this.height = 95; // ボスの高さ
304 let a = 100 + Math.floor((mp.canvas.width - 200 - this.width) * Math.random());
305 this.x = a; // ボスの位置(横)
306 let b = 10 + Math.floor(20 * Math.random());
307 this.y = b; // ボスの位置(縦)
308 this.bl = new Bullet_b(); // 弾
309 this.h_ct = 0; // 命中した弾の数
310 this.h_max = 5; // 耐えうる命中した弾の数
311 // 行動パターンの設定
312 this.ct = 1;
313 this.ptn1 = new Array();
314 this.ptn1[0] = new Array(-5, 0, 50);
315 this.ptn1[1] = new Array(0, 20, 55);
316 this.ptn1[2] = new Array(5, 0, 105);
317 this.ptn1[3] = new Array(0, -20, 110);
318 this.ptn2 = new Array();
319 this.ptn2[0] = new Array(5, 0, 50);
320 this.ptn2[1] = new Array(0, 20, 55);
321 this.ptn2[2] = new Array(-5, 0, 105);
322 this.ptn2[3] = new Array(0, -20, 110);
323 this.ptn = new Array();
324 if (this.x > mp.canvas.width/2-this.width/2)
325 this.ptn = this.ptn1;
326 else
327 this.ptn = this.ptn2;
328 return this;
329 }
330 //
331 // Boss オブジェクト(メソッド move)
332 //
333 Boss.prototype.move = function()
334 {
335 // 移動
336 gp.bs.ct++;
337 if (gp.bs.ct > 110)
338 gp.bs.ct = 1;
339 // ボスの位置
340 let k = -1;
341 for (let i1 = 0; i1 < gp.bs.ptn.length-1 && k < 0; i1++) {
342 if (gp.bs.ct <= gp.bs.ptn[i1][2])
343 k = i1;
344 }
345 if (k < 0)
346 k = gp.bs.ptn.length - 1;
347 gp.bs.x += gp.bs.ptn[k][0];
348 gp.bs.y += gp.bs.ptn[k][1];
349 // 敵機の位置
350 if (gp.ex[0]) {
351 gp.em[0].x += gp.bs.ptn[k][0];
352 gp.em[0].y += gp.bs.ptn[k][1];
353 }
354 if (gp.ex[1]) {
355 gp.em[1].x += gp.bs.ptn[k][0];
356 gp.em[1].y += gp.bs.ptn[k][1];
357 }
358 }
359 //
360 // Bullet_b オブジェクト(プロパティ)
361 //
362 function Bullet_b()
363 {
364 this.r = 12; // 弾の幅
365 this.no = 15; // 弾の全数
366 this.x = new Array(); // 弾の位置(横)
367 this.y = new Array(); // 弾の位置(縦)
368 this.v = 30; // 弾の速さ
369 this.vx = new Array(); // 横方向の弾の速さ
370 this.vy = new Array(); // 縦方向の弾の速さ
371 this.pr = 5; // 弾の発射間隔
372 this.ct = 0;
373 this.ex = new Array(); // 弾の存在
374 for (let i1 = 0; i1 < this.no; i1++)
375 this.ex[i1] = false;
376 }
377 //
378 // Bullet_b オブジェクト(メソッド move)
379 //
380 Bullet_b.prototype.move = function()
381 {
382 // 弾の移動
383 for (let i1 = 0; i1 < gp.bs.bl.no; i1++) {
384 if (gp.bs.bl.ex[i1]) {
385 gp.bs.bl.x[i1] += gp.bs.bl.vx[i1];
386 gp.bs.bl.y[i1] += gp.bs.bl.vy[i1];
387 if (gp.bs.bl.x[i1] < -gp.bs.bl.r ||
388 gp.bs.bl.x[i1] > mp.canvas.width+gp.bs.bl.r ||
389 gp.bs.bl.y[i1] > mp.canvas.height+gp.bs.bl.r)
390 gp.bs.bl.ex[i1] = false;
391 }
392 }
393 // 次の弾の発射
394 gp.bs.bl.ct = (gp.bs.bl.ct + 1) % gp.bs.bl.pr;
395 if (gp.bs.bl.ct == 0)
396 gp.bs.bl.shoot();
397 }
398 //
399 // Bullet_b オブジェクト(メソッド shoot,弾の発射)
400 //
401 Bullet_b.prototype.shoot = function()
402 {
403 let sw = true;
404 for (let i1 = 1; i1 < gp.bs.bl.no && sw; i1++) {
405 if (!gp.bs.bl.ex[i1]) {
406 sw = false;
407 gp.bs.bl.ex[i1] = true;
408 gp.bs.bl.x[i1] = gp.bs.x + gp.bs.width / 2;
409 gp.bs.bl.y[i1] = gp.bs.y + gp.bs.height + gp.bs.bl.r;
410 let yt = gp.my.y + gp.my.height / 2 - gp.bs.bl.y[i1];
411 let xt = gp.my.x + gp.my.width / 2 - gp.bs.bl.x[i1];
412 let ang = Math.atan2(yt, xt);
413 gp.bs.bl.vx[i1] = Math.floor(gp.bs.bl.v * Math.cos(ang) + 0.5);
414 gp.bs.bl.vy[i1] = Math.floor(gp.bs.bl.v * Math.sin(ang) + 0.5);
415 }
416 }
417 }
418 //
419 // Enemy オブジェクト(プロパティ)
420 //
421 function Enemy(sw, bs)
422 {
423 this.image = new Image(); // 敵機画像
424 this.image.src = "image/enemy.gif";
425 this.width = 27; // 敵機の幅
426 this.height = 41; // 敵機の高さ
427 this.x; // 敵機の位置(横)
428 this.y; // 敵機の位置(縦)
429 this.bl = new Bullet_e(); // 弾
430 // 敵機の初期位置
431 if (sw == 0) {
432 this.x = bs.x - 150 + Math.floor(100 * Math.random());
433 this.y = bs.y + bs.height - 80 + Math.floor(100 * Math.random());
434 }
435 else {
436 this.x = bs.x + bs.width + 50 + Math.floor(100 * Math.random());
437 this.y = bs.y + bs.height - 80 + Math.floor(100 * Math.random());
438 }
439 return this;
440 }
441 //
442 // Bullet_e オブジェクト(プロパティ)
443 //
444 function Bullet_e()
445 {
446 this.r = 7; // 弾の幅
447 this.no = 5; // 弾の全数
448 this.ct = 0; // 現在の弾の数
449 this.x = new Array(); // 弾の位置(横)
450 this.y = new Array(); // 弾の位置(縦)
451 this.v = 30; // 弾の速さ
452 this.vx = new Array(); // 横方向の弾の速さ
453 this.vy = new Array(); // 縦方向の弾の速さ
454 this.ex = new Array(); // 弾の存在
455 for (let i1 = 0; i1 < this.no; i1++)
456 this.ex[i1] = false;
457 }
458 //
459 // Bullet_e オブジェクト(メソッド move)
460 //
461 Bullet_e.prototype.move = function(em)
462 {
463 if (em.bl.ct < em.bl.no)
464 em.bl.ct++;
465 // 弾の移動
466 let sw = false;
467 for (let i1 = 0; i1 < em.bl.no; i1++) {
468 if (em.bl.ex[i1]) {
469 em.bl.x[i1] += em.bl.vx;
470 em.bl.y[i1] += em.bl.vy;
471 if (em.bl.x[i1] < -em.bl.r || em.bl.x[i1] > mp.canvas.width+em.bl.r ||
472 em.bl.y[i1] > mp.canvas.height+em.bl.r)
473 em.bl.ex[i1] = false;
474 else
475 sw = true;
476 }
477 }
478 // 最初の弾の発射
479 if (!sw)
480 em.bl.shoot(em);
481 // 次の弾の発射
482 else {
483 if (em.bl.ct < em.bl.no) {
484 em.bl.x[em.bl.ct] = em.x + em.width / 2;
485 em.bl.y[em.bl.ct] = em.y + em.height + em.bl.r;
486 em.bl.ex[em.bl.ct] = true;
487 }
488 }
489 }
490 //
491 // Bullet_e オブジェクト(メソッド shoot,弾の発射)
492 //
493 Bullet_e.prototype.shoot = function(em)
494 {
495 em.bl.ct = 0;
496 em.bl.ex[0] = true;
497 for (let i1 = 1; i1 < em.bl.no; i1++)
498 em.bl.ex[i1] = false;
499 let ang = 0.25 * Math.PI + 0.5 * Math.PI * Math.random();
500 em.bl.vx = Math.floor(em.bl.v * Math.cos(ang) + 0.5);
501 em.bl.vy = Math.floor(em.bl.v * Math.sin(ang) + 0.5);
502 em.bl.x[0] = em.x + em.width / 2;
503 em.bl.y[0] = em.y + em.height + em.bl.r;
504 }
01 <!DOCTYPE HTML>
02 <HTML>
03 <HEAD>
04 <TITLE>シューティングゲーム:ステップ6(完成)</TITLE>
05 <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
06 <LINK REL="stylesheet" TYPE="text/css" HREF="../../../master.css">
07 <SCRIPT TYPE="text/javascript" SRC="main/MainPanel.js"></SCRIPT>
08 <SCRIPT TYPE="text/javascript" SRC="start/StartPanel.js"></SCRIPT>
09 <SCRIPT TYPE="text/javascript" SRC="game/GamePanel.js"></SCRIPT>
10 <SCRIPT TYPE="text/javascript" SRC="clear/GameClearPanel.js"></SCRIPT>
11 <SCRIPT TYPE="text/javascript" SRC="over/GameOverPanel.js"></SCRIPT>
12 </HEAD>
13 <BODY CLASS="eeffee" onLoad="mp_start()">
14 <H1>シューティングゲーム:ステップ6(完成)</H1>
15 <CANVAS ID="canvas_e" STYLE="background-color: #ffffff;" WIDTH="500" HEIGHT="500" TABINDEX="1"></CANVAS><BR>
16 <A HREF="method.htm" TARGET="method"><BUTTON ID="method" CLASS="std">遊び方</BUTTON></A>
17 <BUTTON ID="start" CLASS="std" onClick="gp_start()">ゲーム開始</BUTTON>
18 <BUTTON ID="first" CLASS="std" onClick="st_start()">最初から再開</BUTTON>
19 <BUTTON ID="finish" CLASS="std" onClick="mp.finish()">ゲーム終了</BUTTON>
20 <AUDIO ID="BGM" LOOP SRC="Shoot_BGM.mp3"></AUDIO> <!-- BGMのために追加 -->
21 </BODY>
22 </HTML>
001 gp = null; // GamePanel オブジェクト
002
003 //
004 // GamePanel の開始
005 //
006 function gp_start()
007 {
008 // BGM の再生
009 document.getElementById('BGM').volume = 0.5;
010 document.getElementById('BGM').play();
011 document.getElementById('BGM').currentTime = 0.5; // 約0.5秒の空白をスキップ
012 // GamePanel オブジェクト
013 gp = new GamePanel();
014 // タイマーのスタート
015 gp.timerID = setInterval('gp.timer()', 10);
016 // キーリスナの追加(キーが押された時)
017 mp.canvas.addEventListener("keydown", gp.onKeyDown, false);
018 mp.canvas.focus();
019 // ボタンの表示制御
020 document.getElementById('method').style.display = "none";
021 document.getElementById('start').style.display = "none";
022 document.getElementById('first').style.display = "none";
023 document.getElementById('finish').style.display = "none";
024 }
025 //
026 // GamePanel オブジェクト(プロパティ)
027 //
028 function GamePanel()
029 {
030 this.timerID = -1;
031 this.ct = 0; // カウンター
032 this.my = new My(); // 自機
033 this.bs = new Boss(); // ボス
034 this.no = 2; // 敵機の数
035 this.em = new Array(); // 敵機
036 this.em[0] = new Enemy(0, this.bs);
037 this.em[1] = new Enemy(1, this.bs);
038 // 敵機の存在
039 this.ex = new Array();
040 if (mp.level == 1) {
041 this.ex[0] = false;
042 this.ex[1] = false;
043 }
044 else {
045 this.ex[0] = true;
046 this.ex[1] = true;
047 }
048 return this;
049 }
050 //
051 // GamePanel オブジェクト(メソッド timer)
052 //
053 GamePanel.prototype.timer = function()
054 {
055 // 描画
056 gp.draw();
057 // 移動処理
058 if (gp.ct%3 == 0)
059 gp.my.bl.move(); // 自機の弾
060 if (gp.ct%5 == 0) {
061 gp.bs.move(); // ボスと敵機の移動
062 for (let i1 = 0; i1 < gp.no; i1++) { // 敵機の弾
063 if (gp.ex[i1])
064 gp.em[i1].bl.move(gp.em[i1]);
065 }
066 }
067 if (gp.ct%10 == 0)
068 gp.bs.bl.move(); // ボスの弾
069 // 自機の弾による命中判定
070 let hit = false;
071 // ボスに対して
072 for (let i1 = 0; i1 < gp.my.bl.no && !hit; i1++) {
073 if (gp.my.bl.ex[i1]) {
074 let xb = gp.my.bl.x[i1];
075 let yb = gp.my.bl.y[i1];
076 let w = gp.bs.width / 2 + gp.my.bl.r;
077 let h = gp.bs.height / 2 + gp.my.bl.r;
078 let xt = gp.bs.x + gp.bs.width / 2;
079 let yt = gp.bs.y + gp.bs.height / 2;
080 if (xb > xt-w && xb < xt+w && yb > yt-h && yb < yt+h) {
081 gp.my.bl.ex[i1] = false;
082 gp.bs.h_ct++;
083 if (gp.bs.h_ct > gp.bs.h_max) {
084 document.getElementById('BGM').pause(); // BGMのために追加
085 document.getElementById('BGM').load(); // BGMのために追加
086 hit = true;
087 clearInterval(gp.timerID); // タイマーの停止
088 gcp_start(); // ゲームクリア
089 }
090 }
091 }
092 }
093 // 敵機に対して
094 if (!hit) {
095 for (let i1 = 0; i1 < gp.no && !hit; i1++) {
096 if (gp.ex[i1]) {
097 for (let i2 = 0; i2 < gp.my.bl.no && !hit; i2++) {
098 if (gp.my.bl.ex[i2]) {
099 let xb = gp.my.bl.x[i2];
100 let yb = gp.my.bl.y[i2];
101 let w = gp.em[i1].width / 2 + gp.my.bl.r;
102 let h = gp.em[i1].height / 2 + gp.my.bl.r;
103 let xt = gp.em[i1].x + gp.em[i1].width / 2;
104 let yt = gp.em[i1].y + gp.em[i1].height / 2;
105 if (xb > xt-w && xb < xt+w && yb > yt-h && yb < yt+h) {
106 hit = true;
107 gp.ex[i1] = false;
108 gp.my.bl.ex[i2] = false;
109 }
110 }
111 }
112 }
113 }
114 }
115 // ボスの弾による命中判定
116 if (!hit) {
117 for (let i1 = 0; i1 < gp.bs.bl.no && !hit; i1++) {
118 if (gp.bs.bl.ex[i1]) {
119 xb = gp.bs.bl.x[i1];
120 yb = gp.bs.bl.y[i1];
121 w = gp.my.width / 2;
122 h = gp.my.width / 2;
123 xt = gp.my.x + w;
124 yt = gp.my.y + h;
125 if (xb > xt-w && xb < xt+w && yb > yt-h && yb < yt+h) {
126 document.getElementById('BGM').pause(); // BGMのために追加
127 document.getElementById('BGM').load(); // BGMのために追加
128 hit = true;
129 clearInterval(gp.timerID); // タイマーの停止
130 gop_start(); // ゲームオーバー
131 }
132 }
133 }
134 }
135 // 敵機の弾による命中判定
136 if (!hit) {
137 for (let i1 = 0; i1 < gp.no && !hit; i1++) {
138 if (gp.ex[i1]) {
139 for (let i2 = 0; i2 < gp.em[i1].bl.no && !hit; i2++) {
140 if (gp.em[i1].bl.ex[i2]) {
141 let xb = gp.em[i1].bl.x[i2];
142 let yb = gp.em[i1].bl.y[i2];
143 let w = gp.my.width / 2;
144 let h = gp.my.width / 2;
145 let xt = gp.my.x + w;
146 let yt = gp.my.y + h;
147 if (xb > xt-w && xb < xt+w && yb > yt-h && yb < yt+h) {
148 document.getElementById('BGM').pause(); // BGMのために追加
149 document.getElementById('BGM').load(); // BGMのために追加
150 hit = true;
151 clearInterval(gp.timerID); // タイマーの停止
152 gop_start(); // ゲームオーバー
153 }
154 }
155 }
156 }
157 }
158 }
159 // カウントアップ
160 gp.ct = (gp.ct + 1) % 300;
161 }
162 //
163 // GamePanel オブジェクト(メソッド draw)
164 //
165 GamePanel.prototype.draw = function()
166 {
167 // キャンバスのクリア
168 mp.ctx.clearRect(0, 0, mp.canvas.width, mp.canvas.height);
169 // 描画
170 // 自機と弾
171 mp.ctx.drawImage(gp.my.image, gp.my.x, gp.my.y);
172 for (let i1 = 0; i1 < gp.my.bl.no; i1++) {
173 if (gp.my.bl.ex[i1]) {
174 mp.ctx.beginPath();
175 mp.ctx.fillStyle = "rgb(0, 255, 0)";
176 mp.ctx.arc(gp.my.bl.x[i1], gp.my.bl.y[i1], gp.my.bl.r, 0, 2*Math.PI);
177 mp.ctx.fill();
178 }
179 }
180 // ボスと弾
181 mp.ctx.drawImage(gp.bs.image, gp.bs.x, gp.bs.y);
182 for (let i1 = 0; i1 < gp.bs.bl.no; i1++) {
183 if (gp.bs.bl.ex[i1]) {
184 mp.ctx.beginPath();
185 mp.ctx.fillStyle = "rgb(255, 165, 0)";
186 mp.ctx.arc(gp.bs.bl.x[i1], gp.bs.bl.y[i1], gp.bs.bl.r, 0, 2*Math.PI);
187 mp.ctx.fill();
188 }
189 }
190 // 敵機と弾
191 for (let i1 = 0; i1 < gp.no; i1++) {
192 if (gp.ex[i1]) {
193 mp.ctx.drawImage(gp.em[i1].image, gp.em[i1].x, gp.em[i1].y);
194 for (let i2 = 0; i2 < gp.em[i1].bl.no; i2++) {
195 if (gp.em[i1].bl.ex[i2]) {
196 mp.ctx.beginPath();
197 mp.ctx.fillStyle = "rgb(255, 0, 0)";
198 mp.ctx.arc(gp.em[i1].bl.x[i2], gp.em[i1].bl.y[i2], gp.em[i1].bl.r, 0, 2*Math.PI);
199 mp.ctx.fill();
200 }
201 }
202 }
203 }
204 }
205 //
206 // GamePanel オブジェクト(メソッド onKeyDown)
207 //
208 GamePanel.prototype.onKeyDown = function(event)
209 {
210 if (event.keyCode == 38) // 「↑」キー
211 gp.my.y -= gp.my.v;
212 else if (event.keyCode == 40) // 「↓」キー
213 gp.my.y += gp.my.v;
214 else if (event.keyCode == 37) // 「←」キー
215 gp.my.x -= gp.my.v;
216 else if (event.keyCode == 39) // 「→」キー
217 gp.my.x += gp.my.v;
218 else if (event.keyCode == 32) // 「スペース」キー
219 gp.my.bl.shoot();
220 }
221 //
222 // My オブジェクト(プロパティ)
223 //
224 function My()
225 {
226 this.image = new Image(); // 自機の画像
227 this.image.src = "image/my.gif";
228 this.width = 50; // 自機の幅
229 this.height = 51; // 自機の高さ
230 this.x = mp.canvas.width / 2 - this.width / 2; // 自機の位置(横)
231 this.y = mp.canvas.height - this.height - 10; // 自機の位置(縦)
232 this.v = 20; // 移動キーが押されたときの移動量
233 this.bl = new Bullet(); // 弾
234 return this;
235 }
236 //
237 // Bullet オブジェクト(プロパティ)
238 //
239 function Bullet()
240 {
241 this.r = 12; // 弾の半径
242 this.no = 15; // 弾の全数
243 this.no_1 = 5; // 一度に撃てる弾数
244 this.ct = 0; // 現在の弾の数
245 this.x = new Array(); // 弾の位置(横)
246 this.y = new Array(); // 弾の位置(縦)
247 this.v = 30; // 弾の速さ
248 this.fire = false; // 弾を発射中か否か
249 this.ex = new Array(); // 弾の存在
250 for (let i1 = 0; i1 < this.no; i1++)
251 this.ex[i1] = false;
252 }
253 //
254 // Bullet オブジェクト(メソッド move)
255 //
256 Bullet.prototype.move = function()
257 {
258 // 弾の移動
259 for (let i1 = 0; i1 < gp.my.bl.no; i1++) {
260 if (gp.my.bl.ex[i1]) {
261 gp.my.bl.y[i1] -= gp.my.bl.v;
262 if (gp.my.bl.y[i1] < -gp.my.bl.r)
263 gp.my.bl.ex[i1] = false;
264 }
265 }
266 // 次の弾の発射
267 if (gp.my.bl.fire) {
268 if (gp.my.bl.ct < gp.my.bl.no_1) {
269 let sw = true;
270 for (let i1 = 0; i1 < gp.my.bl.no && sw; i1++) {
271 if (!gp.my.bl.ex[i1]) {
272 gp.my.bl.x[i1] = gp.my.x + gp.my.width / 2;
273 gp.my.bl.y[i1] = gp.my.y - gp.my.bl.r;
274 gp.my.bl.ex[i1] = true;
275 sw = false;
276 }
277 }
278 gp.my.bl.ct++;
279 if (gp.my.bl.ct >= gp.my.bl.no_1) {
280 gp.my.bl.fire = false;
281 gp.my.bl.ct = 0;
282 }
283 }
284 }
285 }
286 //
287 // Bullet オブジェクト(メソッド shoot,最初の弾の発射)
288 //
289 Bullet.prototype.shoot = function()
290 {
291 if (!gp.my.bl.fire) {
292 gp.my.bl.fire = true;
293 gp.my.bl.ct = 1;
294 let sw = true;
295 for (let i1 = 0; i1 < gp.my.bl.no && sw; i1++) {
296 if (!gp.my.bl.ex[i1]) {
297 gp.my.bl.x[i1] = gp.my.x + gp.my.width / 2;
298 gp.my.bl.y[i1] = gp.my.y - gp.my.bl.r;
299 gp.my.bl.ex[i1] = true;
300 sw = false;
301 }
302 }
303 }
304 }
305 //
306 // Boss オブジェクト(プロパティ)
307 //
308 function Boss()
309 {
310 this.image = new Image(); // ボス画像
311 this.image.src = "image/boss.gif";
312 this.width = 66; // ボスの幅
313 this.height = 95; // ボスの高さ
314 let a = 100 + Math.floor((mp.canvas.width - 200 - this.width) * Math.random());
315 this.x = a; // ボスの位置(横)
316 let b = 10 + Math.floor(20 * Math.random());
317 this.y = b; // ボスの位置(縦)
318 this.bl = new Bullet_b(); // 弾
319 this.h_ct = 0; // 命中した弾の数
320 this.h_max = 5; // 耐えうる命中した弾の数
321 // 行動パターンの設定
322 this.ct = 1;
323 this.ptn1 = new Array();
324 this.ptn1[0] = new Array(-5, 0, 50);
325 this.ptn1[1] = new Array(0, 20, 55);
326 this.ptn1[2] = new Array(5, 0, 105);
327 this.ptn1[3] = new Array(0, -20, 110);
328 this.ptn2 = new Array();
329 this.ptn2[0] = new Array(5, 0, 50);
330 this.ptn2[1] = new Array(0, 20, 55);
331 this.ptn2[2] = new Array(-5, 0, 105);
332 this.ptn2[3] = new Array(0, -20, 110);
333 this.ptn = new Array();
334 if (this.x > mp.canvas.width/2-this.width/2)
335 this.ptn = this.ptn1;
336 else
337 this.ptn = this.ptn2;
338 return this;
339 }
340 //
341 // Boss オブジェクト(メソッド move)
342 //
343 Boss.prototype.move = function()
344 {
345 // 移動
346 gp.bs.ct++;
347 if (gp.bs.ct > 110)
348 gp.bs.ct = 1;
349 // ボスの位置
350 let k = -1;
351 for (let i1 = 0; i1 < gp.bs.ptn.length-1 && k < 0; i1++) {
352 if (gp.bs.ct <= gp.bs.ptn[i1][2])
353 k = i1;
354 }
355 if (k < 0)
356 k = gp.bs.ptn.length - 1;
357 gp.bs.x += gp.bs.ptn[k][0];
358 gp.bs.y += gp.bs.ptn[k][1];
359 // 敵機の位置
360 if (gp.ex[0]) {
361 gp.em[0].x += gp.bs.ptn[k][0];
362 gp.em[0].y += gp.bs.ptn[k][1];
363 }
364 if (gp.ex[1]) {
365 gp.em[1].x += gp.bs.ptn[k][0];
366 gp.em[1].y += gp.bs.ptn[k][1];
367 }
368 }
369 //
370 // Bullet_b オブジェクト(プロパティ)
371 //
372 function Bullet_b()
373 {
374 this.r = 12; // 弾の幅
375 this.no = 15; // 弾の全数
376 this.x = new Array(); // 弾の位置(横)
377 this.y = new Array(); // 弾の位置(縦)
378 this.v = 30; // 弾の速さ
379 this.vx = new Array(); // 横方向の弾の速さ
380 this.vy = new Array(); // 縦方向の弾の速さ
381 this.pr = 5; // 弾の発射間隔
382 this.ct = 0;
383 this.ex = new Array(); // 弾の存在
384 for (let i1 = 0; i1 < this.no; i1++)
385 this.ex[i1] = false;
386 }
387 //
388 // Bullet_b オブジェクト(メソッド move)
389 //
390 Bullet_b.prototype.move = function()
391 {
392 // 弾の移動
393 for (let i1 = 0; i1 < gp.bs.bl.no; i1++) {
394 if (gp.bs.bl.ex[i1]) {
395 gp.bs.bl.x[i1] += gp.bs.bl.vx[i1];
396 gp.bs.bl.y[i1] += gp.bs.bl.vy[i1];
397 if (gp.bs.bl.x[i1] < -gp.bs.bl.r ||
398 gp.bs.bl.x[i1] > mp.canvas.width+gp.bs.bl.r ||
399 gp.bs.bl.y[i1] > mp.canvas.height+gp.bs.bl.r)
400 gp.bs.bl.ex[i1] = false;
401 }
402 }
403 // 次の弾の発射
404 gp.bs.bl.ct = (gp.bs.bl.ct + 1) % gp.bs.bl.pr;
405 if (gp.bs.bl.ct == 0)
406 gp.bs.bl.shoot();
407 }
408 //
409 // Bullet_b オブジェクト(メソッド shoot,弾の発射)
410 //
411 Bullet_b.prototype.shoot = function()
412 {
413 let sw = true;
414 for (let i1 = 1; i1 < gp.bs.bl.no && sw; i1++) {
415 if (!gp.bs.bl.ex[i1]) {
416 sw = false;
417 gp.bs.bl.ex[i1] = true;
418 gp.bs.bl.x[i1] = gp.bs.x + gp.bs.width / 2;
419 gp.bs.bl.y[i1] = gp.bs.y + gp.bs.height + gp.bs.bl.r;
420 let yt = gp.my.y + gp.my.height / 2 - gp.bs.bl.y[i1];
421 let xt = gp.my.x + gp.my.width / 2 - gp.bs.bl.x[i1];
422 let ang = Math.atan2(yt, xt);
423 gp.bs.bl.vx[i1] = Math.floor(gp.bs.bl.v * Math.cos(ang) + 0.5);
424 gp.bs.bl.vy[i1] = Math.floor(gp.bs.bl.v * Math.sin(ang) + 0.5);
425 }
426 }
427 }
428 //
429 // Enemy オブジェクト(プロパティ)
430 //
431 function Enemy(sw, bs)
432 {
433 this.image = new Image(); // 敵機画像
434 this.image.src = "image/enemy.gif";
435 this.width = 27; // 敵機の幅
436 this.height = 41; // 敵機の高さ
437 this.x; // 敵機の位置(横)
438 this.y; // 敵機の位置(縦)
439 this.bl = new Bullet_e(); // 弾
440 // 敵機の初期位置
441 if (sw == 0) {
442 this.x = bs.x - 150 + Math.floor(100 * Math.random());
443 this.y = bs.y + bs.height - 80 + Math.floor(100 * Math.random());
444 }
445 else {
446 this.x = bs.x + bs.width + 50 + Math.floor(100 * Math.random());
447 this.y = bs.y + bs.height - 80 + Math.floor(100 * Math.random());
448 }
449 return this;
450 }
451 //
452 // Bullet_e オブジェクト(プロパティ)
453 //
454 function Bullet_e()
455 {
456 this.r = 7; // 弾の幅
457 this.no = 5; // 弾の全数
458 this.ct = 0; // 現在の弾の数
459 this.x = new Array(); // 弾の位置(横)
460 this.y = new Array(); // 弾の位置(縦)
461 this.v = 30; // 弾の速さ
462 this.vx = new Array(); // 横方向の弾の速さ
463 this.vy = new Array(); // 縦方向の弾の速さ
464 this.ex = new Array(); // 弾の存在
465 for (let i1 = 0; i1 < this.no; i1++)
466 this.ex[i1] = false;
467 }
468 //
469 // Bullet_e オブジェクト(メソッド move)
470 //
471 Bullet_e.prototype.move = function(em)
472 {
473 if (em.bl.ct < em.bl.no)
474 em.bl.ct++;
475 // 弾の移動
476 let sw = false;
477 for (let i1 = 0; i1 < em.bl.no; i1++) {
478 if (em.bl.ex[i1]) {
479 em.bl.x[i1] += em.bl.vx;
480 em.bl.y[i1] += em.bl.vy;
481 if (em.bl.x[i1] < -em.bl.r || em.bl.x[i1] > mp.canvas.width+em.bl.r ||
482 em.bl.y[i1] > mp.canvas.height+em.bl.r)
483 em.bl.ex[i1] = false;
484 else
485 sw = true;
486 }
487 }
488 // 最初の弾の発射
489 if (!sw)
490 em.bl.shoot(em);
491 // 次の弾の発射
492 else {
493 if (em.bl.ct < em.bl.no) {
494 em.bl.x[em.bl.ct] = em.x + em.width / 2;
495 em.bl.y[em.bl.ct] = em.y + em.height + em.bl.r;
496 em.bl.ex[em.bl.ct] = true;
497 }
498 }
499 }
500 //
501 // Bullet_e オブジェクト(メソッド shoot,弾の発射)
502 //
503 Bullet_e.prototype.shoot = function(em)
504 {
505 em.bl.ct = 0;
506 em.bl.ex[0] = true;
507 for (let i1 = 1; i1 < em.bl.no; i1++)
508 em.bl.ex[i1] = false;
509 let ang = 0.25 * Math.PI + 0.5 * Math.PI * Math.random();
510 em.bl.vx = Math.floor(em.bl.v * Math.cos(ang) + 0.5);
511 em.bl.vy = Math.floor(em.bl.v * Math.sin(ang) + 0.5);
512 em.bl.x[0] = em.x + em.width / 2;
513 em.bl.y[0] = em.y + em.height + em.bl.r;
514 }
| 情報学部 | 菅沼ホーム | JavaScript 目次 | 索引 |