add game logic for fridge
This commit is contained in:
parent
8fc1a7b887
commit
5057de5572
10 changed files with 143 additions and 19 deletions
BIN
src/assets/img/clubmate_grey.png
Normal file
BIN
src/assets/img/clubmate_grey.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 227 KiB |
|
|
@ -30,11 +30,10 @@ function onDragMove(node, event, shift = { x: 0, y: 0 }) {
|
|||
}
|
||||
|
||||
function onDragEnd(node, onDrop) {
|
||||
console.log("drop");
|
||||
node.off("pointerup");
|
||||
node.off("pointerupoutside");
|
||||
node.parent.off("mousemove");
|
||||
onDrop();
|
||||
onDrop(node);
|
||||
}
|
||||
|
||||
function onDragStart(node, onDrop, event) {
|
||||
|
|
@ -58,4 +57,8 @@ function makeDragable(node, onDrop = () => {}) {
|
|||
});
|
||||
}
|
||||
|
||||
export { makeDragable };
|
||||
function makeUnDragable(node, onDrop = () => {}) {
|
||||
node.off("pointerdown");
|
||||
}
|
||||
|
||||
export { makeDragable, makeUnDragable };
|
||||
|
|
|
|||
24
src/common/helpers.js
Normal file
24
src/common/helpers.js
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import { Rectangle } from "pixi.js";
|
||||
|
||||
export function getIntersection(a, b, out = new Rectangle()) {
|
||||
const x1 = Math.max(a.x, b.x);
|
||||
const y1 = Math.max(a.y, b.y);
|
||||
const x2 = Math.min(a.x + a.width, b.x + b.width);
|
||||
const y2 = Math.min(a.y + a.height, b.y + b.height);
|
||||
|
||||
if (x2 <= x1 || y2 <= y1) {
|
||||
// no overlap → empty rect
|
||||
out.x = 0;
|
||||
out.y = 0;
|
||||
out.width = 0;
|
||||
out.height = 0;
|
||||
return out;
|
||||
}
|
||||
|
||||
out.x = x1;
|
||||
out.y = y1;
|
||||
out.width = x2 - x1;
|
||||
out.height = y2 - y1;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
|
@ -1,2 +1,3 @@
|
|||
export { backgroundLayout } from "./layouts";
|
||||
export { makeDragable } from "./dragAndDrop";
|
||||
export { makeDragable, makeUnDragable } from "./dragAndDrop";
|
||||
export { getIntersection } from "./helpers";
|
||||
|
|
|
|||
|
|
@ -1,10 +1,34 @@
|
|||
import { Application, Assets, Container, Sprite } from "pixi.js";
|
||||
import { makeDragable, backgroundLayout } from "../common";
|
||||
import { Application, Assets, Container, Sprite, Rectangle } from "pixi.js";
|
||||
import {
|
||||
makeDragable,
|
||||
backgroundLayout,
|
||||
getIntersection,
|
||||
makeUnDragable,
|
||||
} from "../common";
|
||||
import { Game } from "./game";
|
||||
|
||||
class DropZone {
|
||||
constructor(sprite) {
|
||||
this.sprite = sprite;
|
||||
this.full = false;
|
||||
}
|
||||
|
||||
drop(bottle) {
|
||||
if (!this.full) {
|
||||
this.full = true;
|
||||
bottle.x = this.sprite.x;
|
||||
bottle.y = this.sprite.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class Fridge extends Game {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this._bottleCount = 6;
|
||||
this._bottlePlaced = 0;
|
||||
|
||||
const fridgeContainer = new Container();
|
||||
fridgeContainer.layout = { width: "50%" };
|
||||
const fridge = Sprite.from("frigo");
|
||||
|
|
@ -24,21 +48,82 @@ export class Fridge extends Game {
|
|||
this.gameContainer.addChild(fridgeContainer);
|
||||
this.gameContainer.addChild(bottleContainer);
|
||||
|
||||
const bottleLayout = {
|
||||
width: "12%",
|
||||
height: "16%",
|
||||
position: "absolute",
|
||||
};
|
||||
for (let i = 0; i < 12; i++) {
|
||||
const newBottle = Sprite.from("clubmate");
|
||||
newBottle.layout = bottleLayout;
|
||||
makeDragable(newBottle);
|
||||
this.gameContainer.addChild(newBottle);
|
||||
const bottles = [];
|
||||
this._dropZones = [];
|
||||
|
||||
newBottle.x = 0;
|
||||
const widthPercent = 0.12;
|
||||
this.gameContainer.on("layout", (event) => {
|
||||
const layoutBox = event.computedLayout;
|
||||
for (const bottle of bottles) {
|
||||
const width = layoutBox.width * widthPercent;
|
||||
bottle.width = width;
|
||||
bottle.height = width; // aspectRatio = 1
|
||||
if (bottle.x + bottle.width > layoutBox.width) {
|
||||
bottle.x = layoutBox.width - bottle.width;
|
||||
}
|
||||
if (bottle.y + bottle.height > layoutBox.height) {
|
||||
bottle.y = layoutBox.height - bottle.height;
|
||||
}
|
||||
}
|
||||
|
||||
let i = 0;
|
||||
for (const zone of this._dropZones) {
|
||||
const width = layoutBox.width * (widthPercent + 0.01);
|
||||
zone.sprite.width = width;
|
||||
zone.sprite.height = width; // aspectRatio = 1
|
||||
zone.sprite.x = i * width;
|
||||
zone.sprite.y = 0;
|
||||
i++;
|
||||
}
|
||||
});
|
||||
|
||||
for (let i = 0; i < this._bottleCount; i++) {
|
||||
const sprite = Sprite.from("clubmate_grey");
|
||||
this._dropZones.push(new DropZone(sprite));
|
||||
this.gameContainer.addChild(sprite);
|
||||
|
||||
sprite.x = 0;
|
||||
sprite.y = 0;
|
||||
}
|
||||
|
||||
for (let i = 0; i < this._bottleCount; i++) {
|
||||
const newBottle = Sprite.from("clubmate");
|
||||
makeDragable(newBottle, (node) => {
|
||||
this._onBottleDrop(node);
|
||||
if (this._bottlePlaced >= this._bottleCount) {
|
||||
console.log("fridge game won");
|
||||
}
|
||||
});
|
||||
this.gameContainer.addChild(newBottle);
|
||||
bottles.push(newBottle);
|
||||
|
||||
newBottle.x = 800;
|
||||
newBottle.y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
reset() {}
|
||||
|
||||
_onBottleDrop(bottle) {
|
||||
console.log("dropped at", bottle.position);
|
||||
|
||||
const intersection = new Rectangle();
|
||||
for (const dropZone of this._dropZones) {
|
||||
getIntersection(
|
||||
dropZone.sprite.getBounds(),
|
||||
bottle.getBounds(),
|
||||
intersection,
|
||||
);
|
||||
const intersectArea = intersection.width * intersection.height;
|
||||
const bottleArea = bottle.width * bottle.height;
|
||||
if (intersectArea > 0.5 * bottleArea) {
|
||||
if (!dropZone.full) {
|
||||
dropZone.drop(bottle);
|
||||
this._bottlePlaced++;
|
||||
makeUnDragable(bottle); // maybe not needed
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { Container } from "pixi.js";
|
|||
export class Game {
|
||||
constructor() {
|
||||
this._difficulty = 1;
|
||||
this.won = false;
|
||||
this.gameContainer = new Container(); // main container, to add the game to a node, add this container as a child
|
||||
this.gameContainer.layout = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ export class Opinator extends Game {
|
|||
this._pixelGoalScore = undefined;
|
||||
this._goalScore = 10 * this._difficulty; // goal to match, measured in play area, 10 = moving the mouse on the equivalent of 10 play areas
|
||||
this._lastMousePos = undefined; // use to compute the travelled distance
|
||||
this.won = false;
|
||||
|
||||
const backgroundSprite = Sprite.from("opinator");
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import "@pixi/layout";
|
||||
import { Application, Assets, Container, Sprite } from "pixi.js";
|
||||
|
||||
import { Fridge, Opinator } from "./games";
|
||||
import { backgroundLayout } from "./common";
|
||||
|
||||
|
|
@ -44,6 +43,10 @@ async function preload() {
|
|||
alias: "clubmate",
|
||||
src: "assets/img/clubmate.png",
|
||||
},
|
||||
{
|
||||
alias: "clubmate_grey",
|
||||
src: "assets/img/clubmate_grey.png",
|
||||
},
|
||||
{
|
||||
alias: "mate_caisse",
|
||||
src: "assets/img/caisse.jpg",
|
||||
|
|
|
|||
7
src/package-lock.json
generated
7
src/package-lock.json
generated
|
|
@ -9,6 +9,7 @@
|
|||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@pixi/layout": "^3.2.0",
|
||||
"@pixi/math": "^7.4.3",
|
||||
"pixi.js": "^8.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
@ -101,6 +102,12 @@
|
|||
"yoga-layout": "^3"
|
||||
}
|
||||
},
|
||||
"node_modules/@pixi/math": {
|
||||
"version": "7.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@pixi/math/-/math-7.4.3.tgz",
|
||||
"integrity": "sha512-/uJOVhR2DOZ+zgdI6Bs/CwcXT4bNRKsS+TqX3ekRIxPCwaLra+Qdm7aDxT5cTToDzdxbKL5+rwiLu3Y1egILDw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@pixi/react": {
|
||||
"version": "8.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@pixi/react/-/react-8.0.5.tgz",
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": true,
|
||||
"scripts": {
|
||||
"dev": "vite --host",
|
||||
"build": "vite build",
|
||||
|
|
|
|||
Loading…
Reference in a new issue