This commit is contained in:
ethanf 2023-10-07 16:04:23 -05:00
commit cac5271a98
40 changed files with 10485 additions and 0 deletions

14
.babelrc Normal file
View File

@ -0,0 +1,14 @@
{
"presets": [
["@babel/env", {
"targets": {
"browsers": [
">0.25%",
"not ie 11",
"not op_mini all"
]
},
"modules": false
}]
],
}

36
.gitignore vendored Normal file
View File

@ -0,0 +1,36 @@
#MIT License
#Copyright (c) 2017 Richard Davey
#Permission is hereby granted, free of charge, to any person obtaining a copy
#of this software and associated documentation files (the "Software"), to deal
#in the Software without restriction, including without limitation the rights
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
#copies of the Software, and to permit persons to whom the Software is
#furnished to do so, subject to the following conditions:
#The above copyright notice and this permission notice shall be included in all
#copies or substantial portions of the Software.
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
#SOFTWARE.
# System and IDE files
Thumbs.db
.DS_Store
.idea
*.suo
*.sublime-project
*.sublime-workspace
# Vendors
node_modules/
# Build
dist/
/npm-debug.log

5
.prettierrc Normal file
View File

@ -0,0 +1,5 @@
{
"trailingComma": "none",
"tabWidth": 2,
"useTabs": false
}

71
README.md Normal file
View File

@ -0,0 +1,71 @@
/*MIT License
Copyright (c) 2017 Richard Davey
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.*/
# Phaser 3 Webpack Project Template
A Phaser 3 project template with ES6 support via [Babel 7](https://babeljs.io/) and [Webpack 4](https://webpack.js.org/) that includes hot-reloading for development and production-ready builds.
This has been updated for Phaser 3.50.0 version and above.
Loading images via JavaScript module `import` is also supported, although not recommended.
## Requirements
[Node.js](https://nodejs.org) is required to install dependencies and run scripts via `npm`.
## Available Commands
| Command | Description |
|---------|-------------|
| `npm install` | Install project dependencies |
| `npm start` | Build project and open web server running project |
| `npm run build` | Builds code bundle with production settings (minification, uglification, etc..) |
## Writing Code
After cloning the repo, run `npm install` from your project directory. Then, you can start the local development server by running `npm start`.
After starting the development server with `npm start`, you can edit any files in the `src` folder and webpack will automatically recompile and reload your server (available at `http://localhost:8080` by default).
## Customizing the Template
### Babel
You can write modern ES6+ JavaScript and Babel will transpile it to a version of JavaScript that you want your project to support. The targeted browsers are set in the `.babelrc` file and the default currently targets all browsers with total usage over "0.25%" but excludes IE11 and Opera Mini.
```
"browsers": [
">0.25%",
"not ie 11",
"not op_mini all"
]
```
### Webpack
If you want to customize your build, such as adding a new webpack loader or plugin (i.e. for loading CSS or fonts), you can modify the `webpack/base.js` file for cross-project changes, or you can modify and/or create new configuration files and target them in specific npm tasks inside of `package.json'.
## Deploying Code
After you run the `npm run build` command, your code will be built into a single bundle located at `dist/bundle.min.js` along with any other assets you project depended.
If you put the contents of the `dist` folder in a publicly-accessible location (say something like `http://mycoolserver.com`), you should be able to open `http://mycoolserver.com/index.html` and play your game.

17
index.html Normal file
View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<style>
body {
margin: 0;
height: 100%;
}
</style>
</head>
<body></body>
</html>

9357
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

39
package.json Normal file
View File

@ -0,0 +1,39 @@
{
"name": "phaser3-project-template",
"version": "1.1.2",
"description": "A Phaser 3 Project Template",
"main": "src/index.js",
"scripts": {
"build": "export NODE_OPTIONS=--openssl-legacy-provider && webpack --config webpack/prod.js ",
"dev-build": "export NODE_OPTIONS=--openssl-legacy-provider && webpack --config webpack/base.js ",
"start": "export NODE_OPTIONS=--openssl-legacy-provider && webpack-dev-server --config webpack/base.js --open"
},
"repository": {
"type": "git",
"url": "git+https://github.com/photonstorm/phaser3-project-template.git"
},
"author": "Richard Davey <rdavey@gmail.com> (http://www.photonstorm.com)",
"license": "MIT",
"licenseUrl": "http://www.opensource.org/licenses/mit-license.php",
"bugs": {
"url": "https://github.com/photonstorm/phaser3-project-template/issues"
},
"homepage": "https://github.com/photonstorm/phaser3-project-template#readme",
"devDependencies": {
"@babel/core": "^7.7.2",
"@babel/preset-env": "^7.7.1",
"babel-loader": "^8.0.6",
"clean-webpack-plugin": "^3.0.0",
"file-loader": "^4.2.0",
"html-webpack-plugin": "^3.2.0",
"raw-loader": "^3.1.0",
"terser-webpack-plugin": "^2.2.1",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.9.0",
"webpack-merge": "^4.2.2"
},
"dependencies": {
"phaser": "^3.50.0"
}
}

BIN
src/assets/chico-bald.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 KiB

BIN
src/assets/chico-carpet.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

BIN
src/assets/chico-corner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 KiB

BIN
src/assets/chico-couch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 KiB

BIN
src/assets/chico-ears.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 KiB

BIN
src/assets/chico-eating.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 KiB

BIN
src/assets/chico-house.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 KiB

BIN
src/assets/chico-loaf.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

BIN
src/assets/chico-nose.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 KiB

BIN
src/assets/chico-sleep.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 KiB

BIN
src/assets/chico-vent.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 KiB

BIN
src/assets/full-bald.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 KiB

BIN
src/assets/full-carpet.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 KiB

BIN
src/assets/full-corner.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 554 KiB

BIN
src/assets/full-couch.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 KiB

BIN
src/assets/full-ears.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

BIN
src/assets/full-eating.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 443 KiB

BIN
src/assets/full-house.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 KiB

BIN
src/assets/full-loaf.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

BIN
src/assets/full-nose.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 539 KiB

BIN
src/assets/full-sleep.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 451 KiB

BIN
src/assets/full-vent.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

BIN
src/assets/lapi.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

BIN
src/assets/question.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

74
src/components/Button.js Normal file
View File

@ -0,0 +1,74 @@
import Phaser from "phaser";
const WHITE = 0xffffff;
const OFFWHITE = 0xeeeeee;
export default class Button extends Phaser.GameObjects.Graphics {
constructor(
scene,
x,
y,
width,
height,
radius = 16,
label = "",
labelSize = 20,
color = OFFWHITE
) {
super(scene);
this.fillStyle(color);
this.fillRoundedRect(x, y, width, height, radius); // avoid redraw later
this.hitRect = scene.add.rectangle(x, y, width, height);
this.setInteractive(this.hitRect, Phaser.Geom.Rectangle.Contains)
.on("pointerup", this.handleUp, this)
.on("pointerout", this.handleOut, this)
.on("pointerdown", this.handleDown, this)
.on("pointerover", this.handleOver, this);
this.pressedRect = scene.add.rectangle(
x + width * (1 / 2),
y + height * (1 / 2),
width * (4 / 5),
height * (4 / 5),
0x000000,
1
); // add a rectangle to show when the button is pressed
this.pressedRect.setAlpha(0); // needed for it to show at all
this.pressedRect.setDepth(1); // bring to front
this.label = scene.add
.text(x, y, label, {
fontFamily: "sans-serif",
fontSize: labelSize,
color: "#000000",
align: "center",
wordWrap: { width: width + 4, useAdvancedWrap: true }
})
.setDepth(1);
this.setLabel(label);
}
handleUp(pointer) {
this.handleOut(pointer);
}
handleOut(pointer) {
this.pressedRect.setAlpha(0);
}
handleDown(pointer) {
this.pressedRect.setAlpha(0.25);
}
handleOver(pointer) {
if (pointer.wasTouch) this.pressedRect.setAlpha(0.25);
}
setLabel(label) {
this.label.setText(label);
this.label.setX(this.hitRect.x + (this.hitRect.width - this.label.width) / 2); // (bWidth - tWidth) / 2 = margin
this.label.setY(this.hitRect.y + (this.hitRect.height - this.label.height) / 2); // (bHeight - tHeight) / 2 = margin
}
}

241
src/components/ShopItem.js Normal file
View File

@ -0,0 +1,241 @@
import Phaser from "phaser";
import Button from "../components/Button";
export default class ShopItem extends Phaser.GameObjects.Container {
constructor(
scene,
x,
y,
width,
height = width,
children,
label = "Sample Chico",
imgKey = "",
startCost = 1,
production = 0,
description = "",
ears = false
) {
super(scene, x, y, children);
this.locked = true;
this.startCost = startCost;
this.imgKey = imgKey;
this.nextCost = startCost;
this.count = 0;
this.label = scene.add.text(0, 0, label, {
fontFamily: "sans-serif",
fontSize: 22,
color: "#000000",
})
this.label.visible = false;
this.img = scene.add
.image(0, this.label.height + 2, imgKey)
.setScale(0.25)
.setOrigin(0, 0);
this.lockedImg = scene.add
.image(0, this.label.height + 2, "locked")
.setScale(0.71)
.setOrigin(-0.05, 0.01);
this.description = scene.add
.text(width / 2, this.label.height + 8, description, {
fontFamily: "sans-serif",
fontSize: 17,
color: "#ffffff",
stroke: "#000000",
strokeThickness: 1,
align: "left",
fixedWidth: this.img.displayWidth,
wordWrap: { width: this.img.displayWidth, useAdvancedWrap: true }
})
.setOrigin(0.475, 0.1);
this.description.visible = false;
this.costLabel = scene.add
.text(
width / 2,
this.label.height + this.img.displayHeight - 20,
`Cost: ${this.nextCost}`,
{
fontFamily: "sans-serif",
fontSize: 18,
color: "#ffffff",
stroke: "#000000",
strokeThickness: 1,
align: "left",
fixedWidth: this.img.displayWidth,
wordWrap: { width: this.img.displayWidth, useAdvancedWrap: true }
}
)
.setOrigin(0.475, 0.1);
this.costLabel.visible = false;
this.countLabel = scene.add
.text(width / 2, this.costLabel.y - 18, `Count: ${this.count}`, {
fontFamily: "sans-serif",
fontSize: 18,
color: "#ffffff",
stroke: "#000000",
strokeThickness: 1,
align: "left",
fixedWidth: this.img.displayWidth,
wordWrap: { width: this.img.displayWidth, useAdvancedWrap: true }
})
.setOrigin(0.475, 0.1);
this.countLabel.visible = false;
this.label.setX(width / 2).setOrigin(0.5, 0);
this.img.setX((width - this.img.displayWidth) / 2);
const setStatsVisible = (visible) => {
this.description.visible = visible;
this.costLabel.visible = visible;
this.countLabel.visible = visible;
};
scene.input.on("pointerdown", (pointer) => {
if (pointer.wasTouch) {
setStatsVisible(false); // pointerout doesn't work on mobile
}
});
this.img.setInteractive();
this.img.on("pointerover", () => setStatsVisible(true));
this.img.on("pointerout", (pointer) => {
if (!pointer.wasTouch) {
setStatsVisible(false);
}
});
let items = [
this.label,
this.img,
this.description,
this.countLabel,
this.lockedImg,
this.costLabel,
];
if (ears) {
this.buyEars = new Button(
scene,
8,
height - 25,
width - 16,
24,
8,
"Buy Chico Ears",
16
);
this.buyEars.on("pointerup", () => {
if (this.nextCost <= scene.chicos) {
scene.chicos -= this.nextCost;
this.count++;
this.countLabel.setText(`Count: ${this.count}`);
} else {
this.buyEars.setLabel("No Chicos");
setTimeout(() => {
this.buyEars.setLabel("Buy Chico Ears");
}, 2000);
}
});
scene.add.existing(this.buyEars);
items = [
...items,
this.buyEars,
this.buyEars.pressedRect,
this.buyEars.label
];
} else {
this.buyOne = new Button(
scene,
4,
height - 24,
width / 2 - 8,
24,
8,
"Buy One",
14
);
scene.add.existing(this.buyOne);
this.buyOne.on("pointerup", () => {
if (this.nextCost <= scene.chicos) {
scene.chicos -= this.nextCost;
scene.perSecond += production;
this.count++;
this.countLabel.setText(`Count: ${this.count}`);
this.nextCost = Math.round(startCost * Math.pow(1.05, this.count + 1) + 1); this.costLabel.setText(`Cost: ${this.nextCost}`);
} else {
this.buyOne.setLabel("No Chicos");
setTimeout(() => {
this.buyOne.setLabel("Buy One");
}, 2000);
}
});
this.buyOne.on("pointerover", (pointer) => {
setStatsVisible(true);
});
this.buyOne.on("pointerout", (pointer) => {
if (!pointer.wasTouch) {
setStatsVisible(false);
}
});
this.buyMax = new Button(
scene,
width / 2 + 4,
height - 24,
width / 2 - 8,
24,
8,
"Buy Max",
14
);
scene.add.existing(this.buyMax);
this.buyMax.on("pointerup", () => {
let bought = 0;
while (this.nextCost <= scene.chicos) {
bought++;
scene.chicos -= this.nextCost;
scene.perSecond += production;
this.count++;
this.countLabel.setText(`Count: ${this.count}`);
this.nextCost = Math.round((this.nextCost + 1) * 1.4);
this.costLabel.setText(`Cost: ${this.nextCost}`);
}
this.buyMax.setLabel(`Bought ${bought}`);
setTimeout(() => {
this.buyMax.setLabel("Buy Max");
}, 2000);
});
this.buyMax.on("pointerover", () => {
setStatsVisible(true);
});
this.buyMax.on("pointerout", (pointer) => {
if (!pointer.wasTouch) {
setStatsVisible(false);
}
});
items = [
...items,
this.buyOne,
this.buyOne.pressedRect,
this.buyOne.label,
this.buyMax,
this.buyMax.pressedRect,
this.buyMax.label
];
}
this.add(items);
scene.add.existing(this);
}
}

47
src/index.js Normal file
View File

@ -0,0 +1,47 @@
import Phaser from "phaser";
import Handler from "./scenes/handler.js";
import Game from "./scenes/game.js";
// 9:16 portrait
const MAX_SIZE_WIDTH_SCREEN = 1920
const MAX_SIZE_HEIGHT_SCREEN = 1080
const MIN_SIZE_WIDTH_SCREEN = 150
const MIN_SIZE_HEIGHT_SCREEN = 270
const SIZE_WIDTH_SCREEN = 450
const SIZE_HEIGHT_SCREEN = 800
const config = {
type: Phaser.CANVAS,
parent: "phaser-example",
scale: {
mode: Phaser.Scale.RESIZE,
autoCenter: Phaser.Scale.CENTER_VERTICALLY,
width: SIZE_WIDTH_SCREEN,
height: SIZE_HEIGHT_SCREEN,
min: {
width: MIN_SIZE_WIDTH_SCREEN,
height: MIN_SIZE_HEIGHT_SCREEN
},
max: {
width: MAX_SIZE_WIDTH_SCREEN,
height: MAX_SIZE_HEIGHT_SCREEN
}
},
scene: [Handler, Game],
canvasStyle: "display: block;"
};
const game = new Phaser.Game(config);
game.screenBaseSize = {
maxWidth: MAX_SIZE_WIDTH_SCREEN,
maxHeight: MAX_SIZE_HEIGHT_SCREEN,
minWidth: MIN_SIZE_WIDTH_SCREEN,
minHeight: MIN_SIZE_HEIGHT_SCREEN,
width: SIZE_WIDTH_SCREEN,
height: SIZE_HEIGHT_SCREEN
};
/*game.scale.on('resize', (gameSize, baseSize, displaySize, previousWidth, previousHeight) => {
console.log("resize", gameSize, baseSize, displaySize, previousWidth, previousHeight);
});*/

401
src/scenes/game.js Normal file
View File

@ -0,0 +1,401 @@
import Phaser from "phaser";
import img from "../assets/lapi.png";
import Button from "../components/Button";
import ShopItem from "../components/ShopItem";
import CHICO_BALD from "../assets/chico-bald.png";
import CHICO_CARPET from "../assets/chico-carpet.png";
import CHICO_CORNER from "../assets/chico-corner.png";
import CHICO_EARS from "../assets/chico-ears.png";
import CHICO_EATING from "../assets/chico-eating.png";
import CHICO_HOUSE from "../assets/chico-house.png";
import CHICO_LOAF from "../assets/chico-loaf.png";
import CHICO_NOSE from "../assets/chico-nose.png";
import CHICO_SLEEP from "../assets/chico-sleep.png";
import CHICO_VENT from "../assets/chico-vent.png";
import CHICO_WITH_EARS from "../assets/chico-withears.png";
import LOCKED from "../assets/question.jpg";
export default class Game extends Phaser.Scene {
handlerScene = null;
sceneStopped = false;
chicos = 0;
perSecond = 0;
win = false;
spinRemaining = 360;
constructor() {
super({ key: "game" });
}
preload() {
this.load.image("img", img);
this.load.image("chico-bald", CHICO_BALD);
this.load.image("chico-carpet", CHICO_CARPET);
this.load.image("chico-corner", CHICO_CORNER);
this.load.image("chico-ears", CHICO_EARS);
this.load.image("chico-eating", CHICO_EATING);
this.load.image("chico-house", CHICO_HOUSE);
this.load.image("chico-loaf", CHICO_LOAF);
this.load.image("chico-nose", CHICO_NOSE);
this.load.image("chico-sleep", CHICO_SLEEP);
this.load.image("chico-vent", CHICO_VENT);
this.load.image("chico-with-ears", CHICO_WITH_EARS);
this.load.image("locked", LOCKED);
this.width = this.game.screenBaseSize.width;
this.height = this.game.screenBaseSize.height;
this.handlerScene = this.scene.get("handler");
this.handlerScene.sceneRunning = "game";
this.sceneStopped = false;
}
create() {
const { width, height } = this;
// scene config
this.handlerScene.updateResize(this);
const title = this.add
.text(width / 2, 0, "BALD CHICO TYCOON", {
fontFamily: "sans-serif",
fontSize: "32px",
fontStyle: "bold",
color: "#000000"
})
.setOrigin(0.5, 0);
// game objects
this.buttonContainer = this.add.container(0, 0);
this.chicoButton = this.add
.image(width / 4 + 8, title.height + height / 8, "chico-bald")
.setScale(0.4)
.setDepth(1);
console.log(title.height, height, height / 8);
this.chicoButton.firstClick = true;
this.chicoButton.setInteractive({ useHandCursor: true });
const infoButton = new Button(
this,
this.width - this.chicoButton.displayWidth - 8,
title.height,
this.chicoButton.displayWidth,
this.chicoButton.displayHeight,
16,
"I have lost my ears. Please help me buy new ears. I do not want to be bald anymore.",
19
);
this.add.existing(infoButton);
const startText = this.add.text(
this.width - this.chicoButton.displayWidth - 8,
title.height + this.chicoButton.displayHeight - 36,
"Press to start",
{
fontFamily: "sans-serif",
fontSize: 20,
fontStyle: "bold",
color: "#000000",
align: "center",
fixedWidth: this.chicoButton.displayWidth
}
);
this.numberWithCommas = (x) => {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
};
const handleChicoDown = () => {
this.chicoButton.setScale(0.375);
};
const handleChicoUp = () => {
this.chicos++;
if (this.chicoButton.firstClick) {
this.chicoButton.firstClick = false;
infoButton.label.destroy();
infoButton.destroy();
startText.destroy();
}
this.chicoButton.setScale(0.4);
};
this.chicoButton.on("pointerdown", handleChicoDown);
this.chicoButton.on("pointerup", handleChicoUp);
infoButton.on("pointerdown", handleChicoDown);
infoButton.on("pointerup", handleChicoUp);
this.chicoLabel = this.add
.text(width * (2 / 3), title.height + 36, "Chicos:", {
fontFamily: "sans-serif",
fontSize: 24,
color: "#000000"
})
.setDepth(-1);
this.chicoValue = this.add
.text(
width * (2 / 3) - this.chicoLabel.width * 1.5,
this.chicoLabel.y + 24,
this.chicos,
{
fontFamily: "sans-serif",
fontSize: 36,
color: "#000000",
align: "center",
fixedWidth: this.chicoLabel.width * 4,
wordWrap: { width: this.chicoLabel.width * 4, useAdvancedWrap: true }
}
)
.setDepth(-1);
this.productionLabel = this.add
.text(
width * (2 / 3) - this.chicoLabel.width * 0.5,
this.chicoValue.y + 40,
"Production:",
{
fontFamily: "sans-serif",
fontSize: 24,
color: "#000000",
align: "center",
fixedWidth: this.chicoLabel.width * 2
}
)
.setDepth(-1);
this.productionValue = this.add
.text(
width * (2 / 3) - this.chicoLabel.width * 0.5,
this.productionLabel.y + 24,
this.perSecond,
{
fontFamily: "sans-serif",
fontSize: 36,
color: "#000000",
align: "center",
fixedWidth: this.chicoLabel.width * 2,
wordWrap: { width: this.chicoLabel.width * 2, useAdvancedWrap: true }
}
)
.setDepth(-1);
this.thanksForEarsTop = this.add
.text(
width * (4 / 7),
title.height - 4,
"Thank you for buying\n me some new ears!",
{
fontFamily: "sans-serif",
fontSize: 18,
color: "#000000",
align: "center"
}
)
.setDepth(-1)
.setVisible(false);
this.thanksForEarsBottom = this.add
.text(
width * (3 / 5),
this.productionValue.y + 40,
"This is better than\n a bowlful of kale!",
{
fontFamily: "sans-serif",
fontSize: 18,
color: "#000000",
align: "center"
}
)
.setDepth(-1)
.setVisible(false);
const frameWidth = width;
const frameHeight = height - this.chicoButton.displayHeight;
const itemWidth = frameWidth / 3 - 8;
const itemHeight = frameHeight / 3 - 16;
const itemCarpet = new ShopItem(
this,
4,
0,
itemWidth,
itemHeight,
[],
"Carpet Chico",
"chico-carpet",
1,
0.2,
"I'm Chico"
);
const itemEating = new ShopItem(
this,
frameWidth / 3 + 4,
itemCarpet.y,
itemWidth,
itemHeight,
[],
"Eating Chico",
"chico-eating",
25,
0.6,
"Favorite time of the day"
);
const itemNose = new ShopItem(
this,
(frameWidth / 3) * 2 + 4,
itemCarpet.y,
itemWidth,
itemHeight,
[],
"Big Nose Chico",
"chico-nose",
100,
2,
"I can smell you from here"
);
const itemHouse = new ShopItem(
this,
itemCarpet.x,
itemHeight,
itemWidth,
itemHeight,
[],
"House Chico",
"chico-house",
200,
5.5,
"My lovely estate"
);
const itemLoaf = new ShopItem(
this,
itemEating.x,
itemHouse.y,
itemWidth,
itemHeight,
[],
"Loaf Chico",
"chico-loaf",
400,
12,
"I'm Chico"
);
const itemVent = new ShopItem(
this,
itemNose.x,
itemHouse.y,
itemWidth,
itemHeight,
[],
"Suspect Chico",
"chico-vent",
800,
28,
"Love good ventilation"
);
const itemCorner = new ShopItem(
this,
itemCarpet.x,
(itemHeight + 4) * 2,
itemWidth,
itemHeight,
[],
"Corner Chico",
"chico-corner",
1600,
64,
"Where have I found myself now?"
);
const itemSleep = new ShopItem(
this,
itemEating.x,
itemCorner.y,
itemWidth,
itemHeight,
[],
"Sleeping Chico",
"chico-sleep",
3200,
144,
"Long day of being a Chico"
);
const itemEars = new ShopItem(
this,
itemNose.x,
itemCorner.y,
itemWidth,
itemHeight,
[],
"Chico Ears",
"chico-ears",
100000,
0,
"",
true
);
this.shopItems = [
itemCarpet,
itemEating,
itemNose,
itemVent,
itemHouse,
itemLoaf,
itemCorner,
itemSleep,
itemEars
];
const shopFrame = new Phaser.GameObjects.Container(
this,
0,
this.chicoButton.displayHeight + 36,
this.shopItems
);
this.add.existing(shopFrame);
}
update(time, delta) {
this.chicos += this.perSecond * (delta / 1000);
this.chicoValue.setText(this.numberWithCommas(Math.floor(this.chicos)));
this.productionValue.setText(
this.numberWithCommas(Math.round(this.perSecond * 10) / 10) + "/s"
);
for (let i = 0; i < this.shopItems.length; i++) {
const item = this.shopItems[i];
if (item.locked && item.startCost <= this.chicos) {
item.locked = false;
item.lockedImg.destroy();
item.label.visible = true;
}
}
if (this.shopItems[this.shopItems.length - 1].count > 0 && !this.win) {
this.win = true;
this.chicoButton.setTexture("chico-with-ears");
this.thanksForEarsTop.setVisible(true);
this.thanksForEarsBottom.setVisible(true);
this.time.addEvent({
delay: 30000,
callback: () => {
this.thanksForEarsTop.setVisible(false);
this.thanksForEarsBottom.setVisible(false);
}
});
}
if (this.win && this.spinRemaining > 0) {
this.spinRemaining--;
this.chicoButton.angle += 2;
}
}
}

72
src/scenes/handler.js Normal file
View File

@ -0,0 +1,72 @@
import Phaser from "phaser";
export default class Handler extends Phaser.Scene {
sceneRunning = null;
constructor() {
super("handler");
}
create() {
this.cameras.main.setBackgroundColor("#D4D4D4");
this.launchScene("game");
}
launchScene(scene, data) {
this.scene.launch(scene, data);
this.gameScene = this.scene.get(scene);
}
updateResize(scene) {
scene.scale.on("resize", this.resize, scene);
const scaleWidth = scene.scale.gameSize.width;
const scaleHeight = scene.scale.gameSize.height;
scene.parent = new Phaser.Structs.Size(scaleWidth, scaleHeight);
scene.sizer = new Phaser.Structs.Size(
scene.width,
scene.height,
Phaser.Structs.Size.FIT,
scene.parent
);
scene.parent.setSize(scaleWidth, scaleHeight);
scene.sizer.setSize(scaleWidth, scaleHeight);
this.updateCamera(scene);
}
resize(gameSize) {
// 'this' means to the current scene that is running
if (!this.sceneStopped) {
const width = gameSize.width;
const height = gameSize.height;
this.parent.setSize(width, height);
this.sizer.setSize(width, height);
const camera = this.cameras.main;
const scaleX = this.sizer.width / this.game.screenBaseSize.width;
const scaleY = this.sizer.height / this.game.screenBaseSize.height;
camera.setZoom(Math.max(scaleX, scaleY));
camera.centerOn(
this.game.screenBaseSize.width / 2,
this.game.screenBaseSize.height / 2
);
}
}
updateCamera(scene) {
const camera = scene.cameras.main;
const scaleX = scene.sizer.width / this.game.screenBaseSize.width;
const scaleY = scene.sizer.height / this.game.screenBaseSize.height;
camera.setZoom(Math.max(scaleX, scaleY));
camera.centerOn(
this.game.screenBaseSize.width / 2,
this.game.screenBaseSize.height / 2
);
}
}

62
webpack/base.js Normal file
View File

@ -0,0 +1,62 @@
/*MIT License
Copyright (c) 2017 Richard Davey
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.*/
const webpack = require("webpack");
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
module.exports = {
mode: "development",
devtool: "eval-source-map",
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: [/\.vert$/, /\.frag$/],
use: "raw-loader"
},
{
test: /\.(gif|png|jpe?g|svg|xml)$/i,
use: "file-loader"
}
]
},
plugins: [
new CleanWebpackPlugin({
root: path.resolve(__dirname, "../")
}),
new webpack.DefinePlugin({
CANVAS_RENDERER: JSON.stringify(true),
WEBGL_RENDERER: JSON.stringify(true)
}),
new HtmlWebpackPlugin({
template: "./index.html"
})
]
};

49
webpack/prod.js Normal file
View File

@ -0,0 +1,49 @@
/*MIT License
Copyright (c) 2017 Richard Davey
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.*/
const merge = require("webpack-merge");
const path = require("path");
const base = require("./base");
const TerserPlugin = require("terser-webpack-plugin");
module.exports = merge(base, {
mode: "production",
output: {
filename: "bundle.min.js"
},
devtool: false,
performance: {
maxEntrypointSize: 900000,
maxAssetSize: 900000
},
optimization: {
minimizer: [
new TerserPlugin({
terserOptions: {
output: {
comments: false
}
}
})
]
}
});