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

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

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

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

JavaScript

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

Q&A

解決済

2回答

1216閲覧

Javascript 2つの同一色のブロックを消した際、その上に乗っていたブロックを落下

OG.

総合スコア7

canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

JavaScript

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

0グッド

0クリップ

投稿2020/07/15 05:26

前提・実現したいこと

CANVAS APIにてJavascriptの学習を行っております。
上の記述で消した2つの四角の上にも、まだブロックがある場合
(空中に浮いている状態になっているもの)をy += gravity して下のブロックがある箇所or地面まで持っていきたいと思っているのですが、思い詰まっています。

前回に引き続きですが、考え方・記述等ご助力頂ければ幸いです。

該当のソースコード(必要そうな個所を記載)

Javascript

1 let canvas = $("maingame"); 2 let ctx = canvas.get(0).getContext("2d"); //決まり文句 3 4 let canvasWidth = canvas.width(); 5 let canvasHeight = canvas.height(); 6 7 let playGame; 8 9 let playAnimation = false; 10 11 let score = 0; 12 let koWidth = 80; 13 let koHeight = 100; 14 15 let colors = ["rgb(240,255,240)", "rgb(81, 102, 107)", "rgb(92, 66, 123)", "rgb(39, 125, 160)"]; 16 17 18 let title = $("#title"); 19 let startButton = $("#startAnimation"); 20 let gameover = $("#gameover"); 21 let restart = $("#restart"); 22 let titleback = $("#titleback"); 23 24 //抽象化 25 function Shape(x, y, width, height, gravity, boxColor) { 26 this.x = x; 27 this.y = y; 28 this.width = width; 29 this.height = height; 30 this.gravity = gravity; 31 this.boxColor = boxColor; 32 33 this.fixed = false; //静止の有無 34 }; 35 36 Shape.prototype.update = function (others) { 37 //地面の設定 38 let ground = { 39 x: 100, 40 y: canvasHeight - 50, 41 width: canvasWidth - 200, 42 height: 0 43 } 44 //地面に触れるor触れないの処理 45 if (!this.fixed && this.collision(ground)) { 46 this.y = canvasHeight - this.height - 50; 47 48 if ((this.y > koHeight && this.x > koWidth && this.x + this.height < 49 canvasWidth - 50 koWidth)) {//エリア内に全て入っていればOK 51 score++; 52 return this.fixed = true; 53 } else {//エリア外に触れてるのでgameover演出 54 gameover.show(); 55 restart.show(); 56 playAnimation = false; 57 58 restart.click(function (e) { 59 location.reload(); 60 }); 61 } 62 } 63 64 if (this.fixed) return; 65 66 others.some(other => { 67 //他のShapeとの衝突確認 68 if (other.fixed && other.collision(this)) { 69 this.y = other.y - this.height; 70 71 if(this.boxColor === other.boxColor ){ 72 //同色が積まれたときに消す記述 73 this.number = 0; 74 this.x = baseX + 1; 75 this.y = baseY + 1; 76 this.width = 0; 77 this.height = 0; 78 79 other.x = baseX + 2; 80 other.y = baseY + 2; 81 other.width = 0; 82 other.height = 0; 83 score++ 84 85 /*if { 86 ここら辺で追記…? 87 88 }*/ 89 90 } 91 92 if (this.y > koHeight && this.x > koWidth && this.x + this.height < 93 canvasWidth - 94 koWidth) { 95 score++; 96 return this.fixed = true; 97 98 } else { 99 gameover.show(); 100 restart.show(); 101 playAnimation = false; //gameover演出 102 103 restart.click(function (e) { 104 location.reload(); 105 }); 106 } 107 } 108 }); 109 110 if (!this.fixed) { 111 this.y += this.gravity; 112 //1コマごとの変化の記述はここで 113 } 114 } 115 116 Shape.prototype.render = function (ctx) { 117 ctx.beginPath(); 118 ctx.fillStyle = this.boxColor; //物体の色、場所 119 ctx.rect(this.x, this.y, this.width, this.height); 120 ctx.fill(); 121 122 ctx.strokeStyle = "rgba(5, 5, 5, 0.9)"; 123 ctx.lineWidth = 1; 124 ctx.stroke(); 125 } 126 127 Shape.prototype.collision = function (shape) { 128 let rect1 = this, 129 rect2 = shape; 130 return rect1.x < rect2.x + rect2.width && 131 rect1.x + rect1.width > rect2.x && 132 rect1.y < rect2.y + rect2.height && 133 rect1.height + rect1.y > rect2.y; //衝突判定 134 } 135 /*ここから初期位置配置*/ 136 let shapes = new Array(); 137 138 function onClick() { //出現させるブロックの位置、大きさ、落ちる速度 139 let width = height = Math.floor(Math.random() * 80 + 30); 140 let x = event.clientX - blockP.offsetLeft - width / 2; 141 let y = 10; 142 let gravity = 5; 143 let boxColor = colors[Math.floor(Math.random() * colors.length)]; 144 145 shapes.push(new Shape(x, y, width, height, gravity, boxColor)); 146 } 147 148 shapes.addEventListener('click', onClick, false); 149 /*ここまで*/ 150 151 function animate() { 152 ctx.clearRect(0, 0, canvasWidth, canvasHeight); 153 ctx.drawImage(img, 100, 648, 400, 60); //土台 154 155 for (let shape of shapes) { 156 shape.update(shapes); 157 shape.render(ctx); 158 } 159 160 if (playAnimation === true) { 161 setTimeout(animate, 33); 162 }; 163 }; 164 165 animate();

試したこと

ここらへんで記載するのかなとは思ってます。(コメントアウトしてる部分)
othersがfixedになっていて、かつcollisionがふれていない対象を取れれば実装できるかと考えているのですが、
コメントアウトの部分だとothers.collisionがfunctionになっていない為エラーが発生してしまいました。

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

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

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

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

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

guest

回答2

0

ベストアンサー

64行目 if (this.fixed) return;を消して、
66行目 others.some(other => {
this.fixed=others.some(other => {とし、{}内で停止するときだけtrueを返すようにすれば、fixedの更新と停止判定が同時にできるようになります。

質問と関係ないけど92行目

if (this.y > koHeight && this.x > koWidth && this.x + this.height < canvasWidth - koWidth) {

x + heightwidthと比較してるけど、あってるのかな?

投稿2020/07/15 13:52

Kaleidoscope

総合スコア257

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

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

OG.

2020/07/16 01:06

回答ありがとうございます。 すみません。64行目を消し、66行目のものに変更をかけたのですが最初のブロックが地面に接した時点でブロックが消失するようになってしまいました… これは更に別途some内に記述が必要なのでしょうか?
Kaleidoscope

2020/07/16 11:12

//地面に触れるor触れないの処理 の部分をothers.some()のブロックの下に持っていったほうが良いかもです。 地面に衝突したあと、下にブロックが無いのでそのまま落下してるかもしれません。 もう一つはshapesの自分自身との衝突判定を除外しないと、落下が止まった瞬間自分自身と衝突して消えてしまってるかもしれません。 `this===other`で除外できればいいですが、うまく動かないのであれば、x,yが同じ値のshapesはないと仮定して`this.x==other.x && this.y==other.y`で判定するくらいですかね。 単純にsomeの中に追加してしまうとshapes数×shapes数 回、地面との判定をすることになるのでちょっと無駄が多いです。(shapes数 回あれば十分) ground自体を特別なshapesとして追加してしまうのは一つの手です。`isErasable`等の属性を追加して、消滅判定はスキップしたり。
OG.

2020/07/20 01:38

評価が遅くなり大変申し訳ございません。 カレイドスコープさんのコメントを参考に色々模索してみたのですが、今度は地面上でビタビタと振動を続けたり逆方向に飛んで行くようになってしまい… 恐らく大きく修正が必要だと判断したため、Javascriptのロジックの勉強がもう少しじっくりと時間をかけて行って実装しようと思います。 ご丁寧にご説明頂きありがとうございます!
guest

0

this.fixed を変更する条件を考えてみましょう。

現状は、他のShapeと接触したら、update() しても値が変わらないようにするためのフラグになっているはずです。

投稿2020/07/15 06:02

AkitoshiManabe

総合スコア5432

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

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

OG.

2020/07/15 08:41

回答ありがとうございます。 原因としては some()での衝突有無の検出でtrue or false仕分け→衝突した時点でreturn文でthis.fixed = trueにしてしまっているのでそれ以降はtrueのままになってしまっている。 なので下のものが消えてしまってもtrue状態を抜けずに物体が浮いてしまっている。 って感じでしょうか? つまりreturn文を改修する必要があるってことですかね…(場所的にはコメントアウトした上のreturn付近…?)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問