質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

736閲覧

JavaScript Canvasでのゲーム開発

jirosian

総合スコア7

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2020/03/23 23:06

編集2020/03/23 23:10

JavaScriptのキャンバスを使ってゲーム開発の課題をしているのですが、
プレイヤーがプレイヤーの子供と同じポジションに行くたびにスコアを増やしていく
設定にしたのですが、スコアが更新されずにいます。
コードでは、プレイヤーとその子供のx,yが同じであったら、score++という形でスコアを更新していこうとしたのですが、効果はありませんでした。

プレイヤーが子供のポジションと重なるたびにスコアを増やしていくようにするには
どうしたらいいでしょうか。
HTMLのページとJSのページで分けて添付させていただいてます。

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Project part1</title> <script src="game.js" type="text/javascript"></script> </head> <body onload="setup()"> <h1>Project part1</h1> <canvas id="gameCanvas" width="500" height="500" style="border:solid black"></canvas> <br> <p id="scoreOutput"></p> <button id="reset" type="button" name="button">Reset</button> </body> </html>
"use strict"; let ctx; let sx; let sy; let gx; let gy; let ex; let ey; let wx; let wy; let count; function setup() { ctx = document.getElementById("gameCanvas").getContext("2d"); sx = 31.25; sy = 31.25; gx = randomNumber(); gy = randomNumber(); ex = randomNumber(); ey = randomNumber(); count = 0; //wx = randomNumber(); //wy = randomNumber(); draw(); } function drawWall(x,y){ ctx.save(); ctx.translate(0,0); ctx.fillStyle = "black"; ctx.rect(x,y,125,62.5); ctx.fill(); ctx.restore(); } function randomNumber() { let locNum=31.25; let locArray = [] for(let i=0;locNum<500;i++) { locArray[i] = locNum; locNum+=62.5; } return locArray[Math.floor(Math.random()*locArray.length)]; } function draw() { ctx.clearRect(0, 0, 500, 500); drawGoal(gx,gy); drawPlayer(sx,sy); drawEnemy(ex,ey); makeGrid(); let x=187.5; let y=62.5; //for(let i=0;i<5;i++){ //drawWall(x,y); //y+=62.5 //} } function makeGrid() { ctx.save(); ctx.translate(0,0); let x = 62.5; let y = 0; for (let j = 0;j < 8;j++) { ctx.beginPath(); ctx.strokeStyle = "DarkSalmon"; ctx.moveTo(x,y); ctx.lineTo(x,y+500); ctx.stroke(); x+=62.5; } x = 0; y = 62.5; for (let i =0;i<8;i++) { ctx.beginPath(); ctx.strokeStyle = "DarkSalmon"; ctx.moveTo(x,y); ctx.lineTo(x+500,y); ctx.stroke(); y+=62.5; } ctx.restore(); } function drawGoal(x,y) { ctx.save(); //drawing arms and legs ctx.beginPath(); ctx.strokeStyle = "black" ctx.moveTo(x-10,y+10); ctx.lineTo(x-20,y-5); ctx.moveTo(x+10,y+10); ctx.lineTo(x+20,y-5); /* ctx.moveTo(x-10,y+30); ctx.lineTo(x-20,y+35); ctx.moveTo(x+10,y+30); ctx.lineTo(x+20,y+35); */ ctx.stroke(); //face ctx.beginPath(); ctx.fillStyle= "yellow"; ctx.arc(x,y, 10,0, 2*Math.PI) ctx.fill(); //left eye ctx.beginPath(); ctx.fillStyle = "black" ctx.arc(x-10,y, 2,0, 2*Math.PI) ctx.fill(); //right eye ctx.beginPath(); ctx.fillStyle = "black" ctx.arc(x+10,y, 2,0, 2*Math.PI) ctx.fill(); //mouth ctx.beginPath(); ctx.fillStyle = "brown" ctx.arc(x,y+8, 6,0, 2*Math.PI) ctx.fill(); //mouth line ctx.beginPath(); ctx.lineTo(x-6,y+8); ctx.lineTo(x+6,y+8); ctx.stroke(); //body ctx.beginPath(); ctx.lineWidth = "20"; ctx.strokeStyle = "yellow" ctx.lineTo(x,y+15); ctx.lineTo(x,y+20); ctx.stroke(); ctx.restore(); } function drawPlayer(x,y) { ctx.save(); ctx.beginPath(); ctx.fillStyle= "yellow"; ctx.arc(x,y, 25,0, 2*Math.PI) ctx.fill(); ctx.beginPath(); ctx.fillStyle = "black" ctx.arc(x-15,y-5, 4,0, 2*Math.PI) ctx.fill(); ctx.beginPath(); ctx.fillStyle = "black" ctx.arc(x+15,y-5, 4,0, 2*Math.PI) ctx.fill(); ctx.beginPath(); ctx.fillStyle = "brown" ctx.arc(x,y+8, 10,0, 2*Math.PI) ctx.fill(); ctx.beginPath(); ctx.moveTo(x-10,y+8); ctx.lineTo(x+10,y+8); ctx.stroke(); ctx.restore(); } function drawEnemy(x,y) { ctx.save(); ctx.translate(x,y); //body ctx.beginPath(); ctx.fillStyle = "CadetBlue" ctx.rect(-20,-24,40,50); ctx.fill(); //eyes ctx.beginPath(); ctx.fillStyle = "AliceBlue" ctx.rect(-15,-10,9,5); ctx.rect(7,-10,9,5); ctx.fill(); //mouth ctx.beginPath(); ctx.fillStyle = "DarkRed" ctx.arc(0, 3, 20, 0, Math.PI, false); ctx.fill(); //ctx.strokeText("Mr.Enemy",-20,-15); ctx.restore(); } addEventListener("keydown",function(event) { if(event.key == "ArrowUp") { sy-=62.5; }else if(event.key =="ArrowDown") { sy+=62.5; }else if(event.key == "ArrowLeft") { sx-=62.5; }else if(event.key == "ArrowRight") { sx+=62.5; } let count =0; while(sx==gx&&sy==gy) { gx=undefined; gy=undefined; gx=randomNumber(); gy=randomNumber(); count++; } draw(); });

問題のjsのファンクション

addEventListener("keydown",function(event) { if(event.key == "ArrowUp") { sy-=62.5; }else if(event.key =="ArrowDown") { sy+=62.5; }else if(event.key == "ArrowLeft") { sx-=62.5; }else if(event.key == "ArrowRight") { sx+=62.5; } let count =0; while(sx==gx&&sy==gy) { gx=undefined; gy=undefined; gx=randomNumber(); gy=randomNumber(); count++; } draw(); });

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2020/03/23 23:27

面白そうな内容なんですが「課題」なんですよね? 赤の他人より先に相談する人がいるのでは?
miyabi_takatsuk

2020/03/24 00:41

> 効果はありませんでした。 どういうことでしょうか? canvasの画面の描画が更新されなかった、ということでしょうか? あと、m.ts10806さんの仰る通り、課題ならばしかるべきところに相談したほうがいいかと・・・。
jirosian

2020/03/24 00:47

数が更新されなかったという意味ですよ? 然るべき場所で既に相談した後にそれでも解決できなかったので こちらで質問させていただいてることの何が問題でしょうか? きちんと解決を教えてくださる方のみご回答ください。 上記の方々のように解決の糸口にならない投稿は控えてください。
m.ts10806

2020/03/24 01:02

↓のようなガイドラインがなければわざわざこんな指摘しませんよ。 https://teratail.com/help/avoid-asking 何かを作りたいのでコードを書いてほしい、学校の課題を解いてほしい等の質問は、具体的にプログラミングで困っている質問ではないと考え、推奨していません。 -------- せめてその「然るべきところで質問した」ことが具体的に質問本文に書いてあるのでしたらまだ良いのですけど。書かれてないので誰にも伝わってません。 お言葉借りるようになりますが、ガイドラインに則ってない投稿は控えてください。
miyabi_takatsuk

2020/03/24 01:05

わかりました。 <p id="scoreOutput"></p> にスコアを表示したい、ということでしょうか? それとも、プレイの状態に関わらず、スコアの変数(count、という名前の変数?)の更新自体ができない、ということしょうか?
jirosian

2020/03/24 01:07

学校の課題を解いてほしいという内容ではございません。 何が問題で何が解決の糸口かと質問しております。 回答者様もこちらから何も聞いていないで然るべきで質問していないまま このサイトで質問していると決めつけて投稿するのはやめたほうが良いのでは? 繰り返しになりますが、コードに関する問題の指摘、問題解決へのヒント以外 の投稿はやめてください。 それ以外の必要な修正なら受け付けます。
m.ts10806

2020/03/24 01:15

書いてなければ本当に調べず試さず丸投げする人との区別は他人には不可能ですよ。あくまで書いてあることが全てです。決めつけでもなんでもなく他人だからそこまで推し量れというのは横暴です。 ですからガイドライン(質問するときのヒント)にも「調べてみて分からなければどこがどう分からないか提示して質問してみましょう」といった旨の記載があります。 ですので追記修正依頼をしてます。あくまで質問内容の不備の指摘です。 調べたことを具体的に記載してください。 調べ方の方向性や中身の理解の問題であればそこのアドバイスだけで自己解決にも繋がります。 自分で出来れば一番早いですよね(そう思わないのが「丸投げ」です)。
jirosian

2020/03/24 01:19

>miyabi_takatsuk様 そうです。 ゲームが始まった時点ではRescue:0と表示されるはずです。 そしてプレイヤーが子供(オブジェクト1)のポジションへ行くとレスキューしたということになりスコアが1個づつ増えていくようにするのが今の課題です。子供はレスキューされると、場所が違うところにまた出現するのでそれをどんどんレスキューしていくというゲームです。 今の説明が分かりませんでしたら教えてください。
m.ts10806

2020/03/24 01:23 編集

一番始めに書いたようにやってること自体は面白いと感じてます。 けど、調べたことがあるならそれをきちんと書いてほしい(じゃないと調べたかどうか分からない) ということです。「課題」という文言に多少敏感になるのはteratailで回答者してると致し方ない部分はあります。 「推奨していない質問」のページを提示しましたが、こちらよりもひどい課題完全丸投げが日々繰り返されてますので(どんなに非推奨や指摘や低評価してもなくならないしそもそも説明書読まない人が多すぎる)。
kyoya0819

2020/03/24 01:39 編集

m.ts10806さん、別に良いのでは? 自ら、 「利用規約とかガイドを読みませ〜ん!」 と威張っているのですから。 そんなお方に時間を割く必要はないと思います。
m.ts10806

2020/03/24 01:41

asuchi0819さん そうですね。低評価だけで伝わればいいんですけど。
guest

回答1

0

ベストアンサー

何点か。

  • addEventListener("keydown")がどのオブジェクトにも割り当てられておらず、機能していない。

window.addEventListenerというように、windowオブジェクトに割り当てれば、キーを押した時のイベントとなります。

  • let count =0;としているため、ローカル変数のため、そこでいくら更新しても、どこにも反映されない。

つまり、addEventListener("keydown", function(event){内で、let countを宣言しなければ、グローバルで宣言しているcount変数にアクセスできます。現在は、count変数が、そのfunction内のローカル変数として宣言されてしまっているため、そのfunctionの領域外では使うことができません。
ここら辺は、**スコープ(参照)**に関しての知識が必要不可欠なので、よくよく勉強されるといいかと。

  • <p id="scoreOutput"></p>に出力に関しては、HTML JavaScript テキスト変更とかのキーワードで再度調査されるといいかと。

また、そのHTMLの更新の構文を、addEventListener("keydown", function(event){内で(window.を先頭に必ずつける)実行するといいかと。

投稿2020/03/24 01:27

miyabi_takatsuk

総合スコア9528

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jirosian

2020/03/24 01:37

解決できました! 問題は回答者様のおっしゃる通りファンクション内で変数を定義していたことでした。 関数で定義している変数を消してグローバル変数だけ定義すると、 プレイヤーがレスキューする度にスコアの更新ができるようになりました。 生産性のある回答ありがとうございました。
kyoya0819

2020/03/24 01:41

m.ts10806さんの指摘も十分生産性があると思います。
miyabi_takatsuk

2020/03/24 01:41

解決できてよかったです。 変数のスコープに関しては、基本中の基本であるうえ、規模が大きくなればなるほど、ぶつかる壁になるので、 今のうちに、よくよく勉強して、いっぱい書いて、動きや仕様の把握をしていかれるといいかと。
miyabi_takatsuk

2020/03/24 01:46

jirosianさん > asuchi0819さんの仰る通り、質問する上で、非常に重要な指摘を、m.ts10806さんはされていますので、 どうか、ジャケにせず、次質問する時のポイントとしていってください。 (また、teratailに限らず誰かに質問する時に生かせると思う)
jirosian

2020/03/24 01:47

miyabi_takatsuk様 そうですか、外国の学校の為変数のスコープという言葉は初めて聞きましたのでよく調べてみます。 suchi0819様 誰よりも生産性のない投稿をするのは控えてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問