ソースを参照

getting spawn in and cascade built

Justin Gilman 1 年間 前
コミット
4a3c0d36b5
2 ファイル変更93 行追加24 行削除
  1. 43 6
      js/libraries/ActionQueue.js
  2. 50 18
      js/libraries/components/matchthree/Board.js

+ 43 - 6
js/libraries/ActionQueue.js

@@ -9,10 +9,10 @@ export class ActionQueue {
         this.pendingActions.push(action)
     }
 
-    execute(actionType, isAllowedCallback = () => true) {
+    execute(actionType, eachCallback = () => true) {
         return new Promise((resolve, reject) => {
             const actionsToRun = this.pendingActions.filter((action) => action instanceof actionType)
-            const pending = actionsToRun.map((action) => action.execute(isAllowedCallback))
+            const pending = actionsToRun.map((action) => action.execute(eachCallback))
             Promise.all(pending).then(() => {
                 this.pendingActions = this.pendingActions.filter((action) => !(action instanceof actionType))
                 resolve()
@@ -32,9 +32,9 @@ export class SwapTileAction {
         this.tweens = []
     }
 
-    execute(isAllowedCallback = () => true) {
+    execute(eachCallback = () => true) {
         return new Promise((resolve, reject) => {
-            if(!isAllowedCallback()) {
+            if(!eachCallback()) {
                  reject()
                  return
             }
@@ -55,9 +55,9 @@ export class MatchTilesAction {
         this.tweens = []
     }
 
-    execute(isAllowedCallback = () => true) {
+    execute(eachCallback = () => true) {
         return new Promise((resolve, reject) => {
-            if(!isAllowedCallback()) {
+            if(!eachCallback()) {
                  reject()
                  return
             }
@@ -71,4 +71,41 @@ export class MatchTilesAction {
             })
         })
     }
+}
+
+export class TileFallAction {
+    constructor(tile, bottom) {
+        this.tile = tile
+        this.bottom = bottom
+    }
+    execute(eachCallback = () => true) {
+        return new Promise((resolve, reject) => {
+            const promiseData = AsyncTween.create(this.tile, {position: {y: this.bottom}}, 800, Easing.Bounce.EaseOut)
+            promiseData.promise.then(() => {
+                resolve()
+            })
+        })
+    }
+}
+
+export class SpawnTileAction {
+    constructor(column, numberToSpawn) {
+        this.column = column
+        this.numberToSpawn = numberToSpawn
+        this.tweens = []
+    }
+    execute(eachCallback = () => true) {
+        return new Promise((resolve, reject) => {
+            this.tweens = []
+            for(let i = 0; i < this.numberToSpawn; i++) {
+                const newTile = eachCallback(this.column, -i - 1)
+                newTile.scale = 0
+                this.tweens.push(AsyncTween.create(newTile, {scale: 1}, 300, Easing.Quadratic.EaseInOut))
+            }
+            Promise.all(this.tweens.map((tween) => tween.promise)).then(() => {
+                resolve()
+                this.tweens = []
+            })
+        })
+    }
 }

+ 50 - 18
js/libraries/components/matchthree/Board.js

@@ -3,7 +3,7 @@ import Tile2 from "./Tile2.js"
 import AsyncTween from "../../AsyncTween.js"
 import { Easing } from "../../Easing.js"
 import { Point } from "../../spatial/Point.js"
-import { ActionQueue, MatchTilesAction, SwapTileAction } from "../../ActionQueue.js"
+import { ActionQueue, MatchTilesAction, SpawnTileAction, SwapTileAction, TileFallAction } from "../../ActionQueue.js"
 
 class Board {
     constructor() {
@@ -16,16 +16,19 @@ class Board {
         this.boardSize = { x: 7, y: 7 }
         for (let y = 0; y < this.boardSize.y; y++) {
             for (let x = 0; x < this.boardSize.x; x++) {
-                const tileType = Math.floor(Math.random() * Object.values(Theme.Colors.TileColors).length)
-                this.tiles.push(new Tile2(this, x, y, tileType))
-                // setTimeout(() => {
-                //     AsyncTween.create(this.tiles[y][x], {scale: 0}, 500, Easing.Quadratic.EaseIn)
-                // }, 10000 * Math.random() + 3000)
+                this.spawnTile(x, y)
             }
         }
 
         this.onResize(scaledCanvas.bounds)
     }
+
+    spawnTile(x, y) {
+        const tileType = Math.floor(Math.random() * Object.values(Theme.Colors.TileColors).length)
+        const newTile = new Tile2(this, x, y, tileType)
+        this.tiles.push(newTile)
+        return newTile
+    }
     draw(ctx) {
         ctx.save()
         ctx.translate(-this.position.x, -this.position.y)
@@ -56,10 +59,10 @@ class Board {
         Board.TILE_SIZE = Math.min(64, Math.max(40, Math.floor((narrowest - this.boardSize.x * 4) / this.boardSize.x)))
 
         const offset = new Point(
-           0,
-           -(canvasBounds.height / 2) + (10 * (Board.TILE_PADDING + Board.TILE_SIZE)) / 2
+            0,
+            -(canvasBounds.height / 2) + (10 * (Board.TILE_PADDING + Board.TILE_SIZE)) / 2
         )
-        if(!isVertical) {
+        if (!isVertical) {
             offset.x = (7 * (Board.TILE_PADDING + Board.TILE_SIZE)) / 2
             offset.y = 0
         }
@@ -143,11 +146,11 @@ class Board {
         //5 in an L shape
         //three in a row horizontal
         this.tiles.forEach((tile, index, array) => {
-            if(tilesToPop.includes(tile)) {
+            if (tilesToPop.includes(tile)) {
                 return
             }
             const validTiles = this.tiles.filter((checkedTile) => tile != checkedTile && tile.type == checkedTile.type && checkedTile.position.y == tile.position.y && (checkedTile.position.x == tile.position.x + 1 || checkedTile.position.x == tile.position.x - 1))
-            if(validTiles.length == 2) {
+            if (validTiles.length == 2) {
                 tilesToPop.push(tile, ...validTiles)
                 this.actionQueue.push(new MatchTilesAction([tile, ...validTiles]))
                 return
@@ -155,11 +158,11 @@ class Board {
         })
         //three in a row vertical
         this.tiles.forEach((tile, index, array) => {
-            if(tilesToPop.includes(tile)) {
+            if (tilesToPop.includes(tile)) {
                 return
             }
             const validTiles = this.tiles.filter((checkedTile) => tile != checkedTile && tile.type == checkedTile.type && checkedTile.position.x == tile.position.x && (checkedTile.position.y == tile.position.y + 1 || checkedTile.position.y == tile.position.y - 1))
-            if(validTiles.length == 2) {
+            if (validTiles.length == 2) {
                 tilesToPop.push(tile, ...validTiles)
                 this.actionQueue.push(new MatchTilesAction([tile, ...validTiles]))
                 return
@@ -170,16 +173,45 @@ class Board {
             tile.isSelected = true
         })
 
+        if (tilesToPop.length == 0) {
+            return
+        }
         this.actionQueue.execute(MatchTilesAction).then(() => {
-            this.cascade()
             this.tiles = this.tiles.filter((tile) => !tilesToPop.includes(tile))
+            this.spawnAndCascade()
         })
-        //push matches into poplist
-
-        // this.popAndCascade(tilesToPop)
     }
 
-    cascade() {
+    spawnAndCascade() {
+        for (let x = 0; x < this.boardSize.x; x++) {
+            const columnTiles = this.tiles.filter((tile) => tile.position.x == x)
+            if (columnTiles.length == this.boardSize.y) {
+                continue
+            }
+            if (columnTiles.length != this.boardSize.y) {
+                this.actionQueue.push(new SpawnTileAction(x, this.boardSize.y - columnTiles.length))
+            }
+        }
+
+        this.actionQueue.execute(SpawnTileAction, (x, y) => this.spawnTile(x, y)).then(() => {
+            for (let x = 0; x < this.boardSize.x; x++) {
+                const columnTiles = this.tiles.filter((tile) => tile.position.x == x).sort((tileA, tileB) => tileA.position.y < tileB.position.y)
+
+                let bottom = this.boardSize.y
+                columnTiles.forEach((tile, index) => {
+                    if (tile.position.y < bottom) {
+                        bottom -= 1
+                        this.actionQueue.push(new TileFallAction(tile, bottom))
+
+                    }
+                })
+            }
+
+            this.actionQueue.execute(TileFallAction).then(() => {
+                this.checkForMatches()
+            })
+        })
+       
 
     }
 }