123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- import { Ball } from "./Ball.js";
- import { Slot } from "./Slot.js";
- import { Point } from "../libraries/spatial/Point.js";
- import { Rectangle } from "../libraries/spatial/Rectangle.js";
- export class Board {
- constructor() {
- this.slots = [];
- this.balls = [];
- /*
- Design and color pallet by @kateradeg
- */
- this.heldBall = null;
- this.removedFromSlot = null;
- this.game = null;
- this.levelData = "";
- this.canvasBounds = null;
- }
- init(game) {
- this.game = game;
- this.reset();
- }
- reset() {
- this.loadLevel();
- // this.generateRandomLevel();
-
- }
- generateRandomLevel() {
- this.balls = [];
- this.slots = [];
- let slotCount = 2;
- let level = this.game.playerData.current;
- switch(level) {
- case 1:
- case 2:
- slotCount = 2;
- break;
- case 3:
- case 4:
- case 5:
- case 6:
- slotCount = 4;
- break;
- case 7:
- case 8:
- case 9:
- case 10:
- case 11:
- slotCount = 6;
- break;
- case 12:
- case 13:
- case 14:
- case 15:
- case 16:
- slotCount = 8;
- break;
- case 17:
- case 18:
- case 19:
- case 20:
- case 21:
- case 22:
- slotCount = 10;
- break;
- default:
- slotCount = 12;
- break;
- }
- for(let i = 0; i < slotCount; i++){
- for(let j = 0; j < 4; j++) {
- this.balls.push(new Ball(i));
- }
- }
- this.balls = this.shuffle(this.balls);
- for(let i = 0; i < slotCount; i++){
- let slot = new Slot(i);
- for(let j = 0; j < 4; j++) {
- slot.addBall(this.balls[4*i+j]);
- }
- this.slots.push(slot);
- }
- this.slots.push(new Slot(slotCount)); //two empties
- this.slots.push(new Slot(slotCount+1));
- //this.levelData += "\t" + JSON.stringify({slots: this.slots.length, balls:this.balls.map(b => b.colorId)}) +",\n";
- }
- shuffle(a) {
- var j, x, i;
- for (i = a.length - 1; i > 0; i--) {
- j = Math.floor(Math.random() * (i + 1));
- x = a[i];
- a[i] = a[j];
- a[j] = x;
- }
- return a;
- }
- loadLevel() {
- this.balls = [];
- this.slots = [];
- let level = this.game.playerData.current;
- let levelData = this.game.getLevel(level);
- if(!levelData) {
- this.generateRandomLevel();
- return;
- }
- this.balls = levelData.balls.map(colorId => new Ball(colorId));
- for(let i = 0; i < levelData.slots-2; i++){
- let slot = new Slot(i);
- for(let j = 0; j < 4; j++) {
- slot.addBall(this.balls[4*i+j]);
- }
- this.slots.push(slot);
- }
- this.slots.push(new Slot(levelData.slots-2));
- this.slots.push(new Slot(levelData.slots-1));
- }
- draw(ctx, scaledCanvas) {
- this.canvasBounds = scaledCanvas.bounds;
- ctx.strokeStyle = "rgba(255,255,255,0.5)";
- ctx.fillStyle = "rgba(255,255,255,0.3)";
- ctx.lineWidth = 3;
- for(let i = 0; i < this.slots.length; i++) {
- let slotBounds = this.getSlotBounds(this.slots[i]);
- ctx.save();
- ctx.translate(slotBounds.x, slotBounds.y);
- this.slots[i].draw(ctx, scaledCanvas);
- ctx.restore();
- }
- if(this.heldBall) {
- let bounds = this.getSlotBounds(this.removedFromSlot);
- ctx.save();
- let radiusPadding = Ball.radius + Ball.radiusPadding;
- ctx.translate(bounds.x + Slot.width / 2, bounds.y - radiusPadding);
- this.heldBall.draw(ctx, scaledCanvas);
- ctx.restore();
- }
- }
- update(delta) {
- }
- mouseDown(event) {
- let mousePoint = new Point(event.clientX, event.clientY);
- for(let i = 0; i < this.slots.length; i++) {
- let slot = this.slots[i];
- if(this.getSlotBounds(slot).pointWithin(mousePoint)) {
- if(!this.heldBall) {
- this.heldBall = slot.removeBall();
- this.removedFromSlot = slot;
- } else {
- if(slot.canAddBall(this.heldBall) || slot == this.removedFromSlot) {
- this.game.trackMove(this.removedFromSlot, slot);
- this.placeHeldBallInSlot(slot);
- this.checkForWin();
- }
- }
- }
- }
- }
- mouseMove(event) {
- let mousePoint = new Point(event.clientX, event.clientY);
- for(let i = 0; i < this.slots.length; i++) {
- let slot = this.slots[i];
- if(this.getSlotBounds(slot).pointWithin(mousePoint)) {
- document.body.style.cursor = "pointer";
- }
- }
- }
- placeHeldBallInSlot(slot) {
- slot.addBall(this.heldBall);
- this.heldBall = null;
- this.removedFromSlot = null;
- }
- getSlotBounds(slot) {
- let widthPadding = Slot.width + Slot.widthPadding;
- let heightPadding = Slot.height + Slot.heightPadding;
- let radiusPadding = Ball.radius + Ball.radiusPadding;
- let maxSlotsPerRow = Math.floor((this.canvasBounds.width - 40) / widthPadding);
- let slotsInFirstRow = Math.min(this.slots.length, maxSlotsPerRow);
- if(slotsInFirstRow < this.slots.length) {
- slotsInFirstRow = this.slots.length / 2;
- }
- let slotsTotalWidth = slotsInFirstRow * widthPadding;
- let offsetX = (this.canvasBounds.width - slotsTotalWidth - 40 + widthPadding) / 2
- return new Rectangle(
- offsetX + (slot.id % slotsInFirstRow) * widthPadding,
- Math.floor(slot.id / slotsInFirstRow) * heightPadding + Math.max((2 * radiusPadding), this.canvasBounds.height < 660 ? 10 : this.canvasBounds.height / 4),
- Slot.width,
- Slot.height + radiusPadding,
- );
- }
- checkForWin() {
- if(this.hasWon()) {
- this.game.win();
- }
- }
- hasWon() {
- for(let i = 0; i < this.slots.length; i++) {
- let slot = this.slots[i];
- if(!slot.colorsAllMatch()) {
- return false;
- }
- }
- return true;
- }
- initDemo() {
- //this.levelData = "[\n";
- //for(let i = 1; i< 256; i++) {
- this.game = {playerData: {current: 15}};
- this.generateRandomLevel();
- //}
- //this.levelData += "]\n";
- //console.log(this.levelData);
- }
- drawDemo(ctx, scaledCanvas) {
- this.draw(ctx,scaledCanvas);
- }
-
- getBounds() {
- let firstSlotBounds = this.getSlotBounds(this.slots[0]);
- let lastSlotBounds = this.getSlotBounds(this.slots[this.slots.length - 1]);
- return new Rectangle(
- firstSlotBounds.x,
- firstSlotBounds.y,
- lastSlotBounds.x - firstSlotBounds.x + lastSlotBounds.width,
- lastSlotBounds.y - firstSlotBounds.y + lastSlotBounds.height,
- )
- }
- }
|