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

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

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

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

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

Q&A

1回答

1206閲覧

パズルゲームのバグ・不具合を修正したい

nosonosolife

総合スコア42

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

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

0グッド

0クリップ

投稿2021/09/18 08:30

現在ブラウザ向けに、「キャンディークラッシュ」や「ズーキーパー」のように画面上のピースをスライドさせて、3つ以上そろえて消していくマッチ3パズルゲームを制作しています。

以下のページを参考に(というよりコードをほぼそのまま使って)
How to Create a Candy Crush or Bejeweled Game in Phaser
プログラムを組んでみたのですが、ごく稀に以下のバグ・不具合が発生します。

【発生するバグ・不具合】
・マウスイベントに対しての反応が鈍く、スムーズにピースが動かない
・ピースをスライドさせて3つ揃えて消した後に、別のピースが意図しない位置にスライドしてしまう

実際のプログラムは以下の通りです。
(上記のページでは『Phaser』という海外製のゲームエンジンを使用していましたが、こちらでは『phina.js』という日本産のゲームエンジンを使用しています)

javascript

1//"use strict"; 2// 定数定義 3var FPS = 60; 4var SCREEN_WIDTH = 750; 5var SCREEN_HEIGHT = 1106; 6var TILE_SIZE = 100; 7 8//変数定義------------------------------------------------------------ 9var score = 0; 10var activeTile1 = null; 11var activeTile2 = null; 12var canMove = false; 13var tileGrid = [ 14 [null, null, null, null, null, null], 15 [null, null, null, null, null, null], 16 [null, null, null, null, null, null], 17 [null, null, null, null, null, null], 18 [null, null, null, null, null, null], 19 [null, null, null, null, null, null] 20]; 21var startPosX = 0; 22 23var ASSETS = { 24 // 画像 25 image: { 26 "icons": "assets/img/commons/icons.png", 27 }, 28}; 29 30var myscenes = [ 31 { 32 className: 'Main', 33 label: 'main', 34 }, 35]; 36 37phina.globalize(); 38phina.define('Main', { 39 superClass: 'DisplayScene', 40 41 init: function (options) { 42 this.superInit(options); 43 MainScene = this; 44 var self = this; 45 this.glLayer = phina.gl2d.GLLayer(options).addChildTo(this); 46 47 this.initTiles(); 48 }, 49 initTiles: function () { 50 var self = this; 51 for (var i = 0; i < tileGrid.length; i++) { 52 for (var j = 0; j < tileGrid.length; j++) { 53 var tile = this.addTile(i, j); 54 tileGrid[i][j] = tile; 55 tile.addChildTo(this.glLayer); 56 } 57 } 58 this.glLayer.tweener.clear().wait(600).call(function () { 59 self.checkMatch(); 60 }); 61 }, 62 addTile: function (x, y) { 63 var self = this; 64 var tileToAdd = Math.floor(Math.random() * 10); 65 var tile = Tiles(tileToAdd).setPosition((x * TILE_SIZE) + TILE_SIZE / 2, 0); 66 tile.tweener.clear().to({ y: y * TILE_SIZE + (TILE_SIZE / 2) }, 500, "easeInOutElastic") 67 tile.setOrigin(0.5, 0.5); 68 tile.setInteractive(true); 69 tile.tileType = tileToAdd; 70 return tile; 71 }, 72 update: function (app) { 73 var self = this; 74 gameFrame = app.frame; 75 76 if (activeTile1 && !activeTile2) { 77 var pos = app.pointer; 78 var hoverX = pos.x; 79 var hoverY = pos.y; 80 81 var hoverPosX = Math.floor(hoverX / TILE_SIZE); 82 var hoverPosY = Math.floor(hoverY / TILE_SIZE); 83 84 var difX = (hoverPosX - startPosX); 85 var difY = (hoverPosY - startPosY); 86 87 if (!(hoverPosY > tileGrid[0].length - 1 || hoverPosY < 0) && !(hoverPosX > tileGrid.length - 1 || hoverPosX < 0)) { 88 if ((Math.abs(difY) == 1 && difX == 0) || (Math.abs(difX) == 1 && difY == 0)) { 89 canMove = false; 90 activeTile2 = tileGrid[hoverPosX][hoverPosY]; 91 this.swapTiles(); 92 this.glLayer.tweener.clear().wait(500).call(function () { 93 self.checkMatch(); 94 }); 95 } 96 } 97 } 98 }, 99 tileUp: function () { 100 activeTile1 = null; 101 activeTile2 = null; 102 }, 103 swapTiles: function () { 104 var self = this; 105 106 if (activeTile1 && activeTile2) { 107 var tile1Pos = { x: (activeTile1.x - TILE_SIZE / 2) / TILE_SIZE, y: (activeTile1.y - TILE_SIZE / 2) / TILE_SIZE }; 108 var tile2Pos = { x: (activeTile2.x - TILE_SIZE / 2) / TILE_SIZE, y: (activeTile2.y - TILE_SIZE / 2) / TILE_SIZE }; 109 110 tileGrid[tile1Pos.x][tile1Pos.y] = activeTile2; 111 tileGrid[tile2Pos.x][tile2Pos.y] = activeTile1; 112 113 activeTile1.tweener.clear().to({ x: tile2Pos.x * TILE_SIZE + (TILE_SIZE / 2), y: tile2Pos.y * TILE_SIZE + (TILE_SIZE / 2) }, 200, "swing"); 114 activeTile2.tweener.clear().to({ x: tile1Pos.x * TILE_SIZE + (TILE_SIZE / 2), y: tile1Pos.y * TILE_SIZE + (TILE_SIZE / 2) }, 200, "swing"); 115 activeTile1 = tileGrid[tile1Pos.x][tile1Pos.y]; 116 activeTile2 = tileGrid[tile2Pos.x][tile2Pos.y]; 117 } 118 }, 119 checkMatch: function () { 120 var self = this; 121 122 var matches = this.getMatches(tileGrid); 123 if (matches.length > 0) { 124 this.removeTileGroup(matches); 125 this.resetTile(); 126 this.fillTile(); 127 this.glLayer.tweener.clear().wait(500).call(function () { 128 self.tileUp(); 129 }); 130 this.glLayer.tweener.clear().wait(600).call(function () { 131 self.checkMatch(); 132 }); 133 } 134 else { 135 this.swapTiles(); 136 this.glLayer.tweener.clear().wait(500).call(function () { 137 self.tileUp(); 138 canMove = true; 139 }); 140 } 141 }, 142 getMatches: function (tileGrid) { 143 var matches = []; 144 var groups = []; 145 146 for (var i = 0; i < tileGrid.length; i++) { 147 var tempArr = tileGrid[i]; 148 groups = []; 149 for (var j = 0; j < tempArr.length; j++) { 150 if (j < tempArr.length - 2) 151 if (tileGrid[i][j] && tileGrid[i][j + 1] && tileGrid[i][j + 2]) { 152 if (tileGrid[i][j].tileType == tileGrid[i][j + 1].tileType && tileGrid[i][j + 1].tileType == tileGrid[i][j + 2].tileType) { 153 if (groups.length > 0) { 154 if (groups.indexOf(tileGrid[i][j]) == -1) { 155 matches.push(groups); 156 groups = []; 157 } 158 } 159 if (groups.indexOf(tileGrid[i][j]) == -1) { 160 groups.push(tileGrid[i][j]); 161 } 162 if (groups.indexOf(tileGrid[i][j + 1]) == -1) { 163 groups.push(tileGrid[i][j + 1]); 164 } 165 if (groups.indexOf(tileGrid[i][j + 2]) == -1) { 166 groups.push(tileGrid[i][j + 2]); 167 } 168 } 169 } 170 } 171 if (groups.length > 0) matches.push(groups); 172 } 173 174 for (j = 0; j < tileGrid.length; j++) { 175 var tempArr = tileGrid[j]; 176 groups = []; 177 for (i = 0; i < tempArr.length; i++) { 178 if (i < tempArr.length - 2) 179 if (tileGrid[i][j] && tileGrid[i + 1][j] && tileGrid[i + 2][j]) { 180 if (tileGrid[i][j].tileType == tileGrid[i + 1][j].tileType && tileGrid[i + 1][j].tileType == tileGrid[i + 2][j].tileType) { 181 if (groups.length > 0) { 182 if (groups.indexOf(tileGrid[i][j]) == -1) { 183 matches.push(groups); 184 groups = []; 185 } 186 } 187 if (groups.indexOf(tileGrid[i][j]) == -1) { 188 groups.push(tileGrid[i][j]); 189 } 190 if (groups.indexOf(tileGrid[i + 1][j]) == -1) { 191 groups.push(tileGrid[i + 1][j]); 192 } 193 if (groups.indexOf(tileGrid[i + 2][j]) == -1) { 194 groups.push(tileGrid[i + 2][j]); 195 } 196 } 197 } 198 } 199 if (groups.length > 0) matches.push(groups); 200 } 201 return matches; 202 }, 203 removeTileGroup: function (matches) { 204 var self = this; 205 for (var i = 0; i < matches.length; i++) { 206 var tempArr = matches[i]; 207 for (var j = 0; j < tempArr.length; j++) { 208 var tile = tempArr[j]; 209 var tilePos = this.getTilePos(tileGrid, tile); 210 tile.remove(); 211 if (tilePos.x != -1 && tilePos.y != -1) { 212 tileGrid[tilePos.x][tilePos.y] = null; 213 } 214 } 215 } 216 }, 217 getTilePos: function (tileGrid, tile) { 218 var pos = { x: -1, y: -1 }; 219 for (var i = 0; i < tileGrid.length; i++) { 220 for (var j = 0; j < tileGrid[i].length; j++) { 221 if (tile == tileGrid[i][j]) { 222 pos.x = i; 223 pos.y = j; 224 break; 225 } 226 } 227 } 228 return pos; 229 }, 230 resetTile: function () { 231 var self = this; 232 233 for (var i = 0; i < tileGrid.length; i++) { 234 for (var j = tileGrid[i].length - 1; j > 0; j--) { 235 if (tileGrid[i][j] == null && tileGrid[i][j - 1] != null) { 236 var tempTile = tileGrid[i][j - 1]; 237 tileGrid[i][j] = tempTile; 238 tileGrid[i][j - 1] = null; 239 tempTile.tweener.clear().to({ y: (TILE_SIZE * j) + (TILE_SIZE / 2) }, 200, "swing"); 240 j = tileGrid[i].length; 241 } 242 } 243 } 244 }, 245 fillTile: function () { 246 var self = this; 247 248 for (var i = 0; i < tileGrid.length; i++) { 249 for (var j = 0; j < tileGrid.length; j++) { 250 if (tileGrid[i][j] == null) { 251 var tile = this.addTile(i, j); 252 tileGrid[i][j] = tile; 253 tile.addChildTo(this.glLayer); 254 } 255 } 256 } 257 }, 258 createScore: function () { 259 //var self = this; 260 //var scoreFont = "100px Arial"; 261 //me.scoreLabel = me.game.add.text((Math.floor(me.tileGrid[0].length / 2) * me.tileWidth), me.tileGrid.length * me.tileHeight, "0", {font: scoreFont, fill: "#fff"}); 262 //me.scoreLabel.anchor.setTo(0.5, 0); 263 //me.scoreLabel.align = 'center'; 264 }, 265 incrementScore: function () { 266 //var self = this; 267 //me.score += 10; 268 //me.scoreLabel.text = me.score; 269 }, 270 removeTileGroup: function (matches) { 271 var self = this; 272 for (var i = 0; i < matches.length; i++) { 273 var tempArr = matches[i]; 274 for (var j = 0; j < tempArr.length; j++) { 275 var tile = tempArr[j]; 276 var tilePos = this.getTilePos(tileGrid, tile); 277 tile.remove(); 278 this.incrementScore(); 279 if (tilePos.x != -1 && tilePos.y != -1) { 280 tileGrid[tilePos.x][tilePos.y] = null; 281 } 282 } 283 } 284 }, 285}); 286 287phina.define("Tiles", { 288 superClass: 'Sprite', 289 init: function (tileToAdd) { 290 this.superInit("icons"); 291 this.tileType = null; 292 this.setSize(TILE_SIZE, TILE_SIZE); 293 this.setFrameIndex(tileToAdd); 294 this.on('pointstart', this.tileDown); 295 this.on('pointend', this.tileUp); 296 }, 297 tileDown: function () { 298 if (canMove) { 299 activeTile1 = this; 300 startPosX = (this.x - TILE_SIZE / 2) / TILE_SIZE; 301 startPosY = (this.y - TILE_SIZE / 2) / TILE_SIZE; 302 } 303 }, 304 tileUp: function () { 305 activeTile1 = null; 306 activeTile2 = null; 307 }, 308}); 309 310phina.main(function () { 311 var app = phina.game.GameApp({ 312 startLabel: 'main', 313 assets: ASSETS, 314 width: SCREEN_WIDTH, 315 height: SCREEN_HEIGHT, 316 scenes: myscenes, 317 domElement: document.getElementById("main"), 318 }); 319 app.fps = FPS; 320 app.run(); 321});

何卒ご教授よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

仮にタイルの種類が4つという前提ならば

diff

1- var tileToAdd = Math.floor(Math.random() * 10); 2+ var tileToAdd = Math.floor(Math.random() * 4);

ではないですか?

タイル種類が4つ前提のコードなのに、タイル種類選択のところで0~9にしてしまうと
画面上の表示とプログラム上の論理的な位置が異なってしまうと思います。

投稿2021/09/19 10:02

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問