Browse Source

海里套圈

master
jiannibang 6 years ago
parent
commit
e7de5a1922
  1. 6
      Game.vue
  2. 133
      games/fishMaster/assets.js
  3. BIN
      games/fishMaster/images/bg.png
  4. 59
      games/fishMaster/images/bottom.json
  5. BIN
      games/fishMaster/images/bottom.png
  6. BIN
      games/fishMaster/images/cannon1.png
  7. BIN
      games/fishMaster/images/cannon2.png
  8. BIN
      games/fishMaster/images/cannon3.png
  9. BIN
      games/fishMaster/images/cannon4.png
  10. BIN
      games/fishMaster/images/cannon5.png
  11. BIN
      games/fishMaster/images/cannon6.png
  12. BIN
      games/fishMaster/images/cannon7.png
  13. BIN
      games/fishMaster/images/fish1.png
  14. BIN
      games/fishMaster/images/fish10.png
  15. BIN
      games/fishMaster/images/fish2.png
  16. BIN
      games/fishMaster/images/fish3.png
  17. BIN
      games/fishMaster/images/fish4.png
  18. BIN
      games/fishMaster/images/fish5.png
  19. BIN
      games/fishMaster/images/fish6.png
  20. BIN
      games/fishMaster/images/fish7.png
  21. BIN
      games/fishMaster/images/fish8.png
  22. BIN
      games/fishMaster/images/fish9.png
  23. BIN
      games/fishMaster/images/shark1.png
  24. BIN
      games/fishMaster/images/shark2.png
  25. 35
      games/fishMaster/index.js
  26. 179
      games/fishMaster/scene.js
  27. 5
      h5/index.js
  28. 184
      h5/snake/css/snake.css
  29. BIN
      h5/water/area.png
  30. BIN
      h5/water/bg.jpg
  31. BIN
      h5/water/bubble.png
  32. 29954
      h5/water/createjs-2015.11.26.combined.js
  33. BIN
      h5/water/flash.png
  34. BIN
      h5/water/font.ttf
  35. 59
      h5/water/game.js
  36. BIN
      h5/water/green.png
  37. BIN
      h5/water/magnet.png
  38. BIN
      h5/water/needle.png
  39. BIN
      h5/water/red.png
  40. 183
      h5/water/ring.js
  41. 44
      h5/water/water.css
  42. 378
      h5/water/waterful.js
  43. BIN
      h5/water/yellow.png
  44. 2
      package.json
  45. 2
      phaser.js

6
Game.vue

@ -3,9 +3,9 @@
</template> </template>
<script> <script>
import phaserGames from "./phaser"; import phaserGames from "./phaser";
import flipper from "./h5/flipper/game";
import snake from "./h5/snake/snake";
const games = { ...phaserGames, flipper, snake };
import h5games from "./h5/index";
const games = { ...phaserGames, ...h5games };
const STATE_RUNNING = 0; const STATE_RUNNING = 0;
const STATE_LOSE = 1; const STATE_LOSE = 1;
const STATE_WON = 2; const STATE_WON = 2;

133
games/fishMaster/assets.js

@ -1,133 +0,0 @@
import fish1 from "./images/fish1.png";
import fish2 from "./images/fish2.png";
import fish3 from "./images/fish3.png";
import fish4 from "./images/fish4.png";
import fish5 from "./images/fish5.png";
import fish6 from "./images/fish6.png";
import fish7 from "./images/fish7.png";
import fish8 from "./images/fish8.png";
import fish9 from "./images/fish9.png";
import fish10 from "./images/fish10.png";
import shark1 from "./images/shark1.png";
import shark2 from "./images/shark2.png";
import cannon1 from "./images/cannon1.png";
export const fishFrames = {
fish1: {
url: fish1,
swim: { start: 0, end: 3 },
capture: { start: 4, end: 8 },
size: [54, 22],
offsets: [2, 2],
frameWidth: 55,
frameHeight: 37,
},
fish2: {
url: fish2,
swim: { start: 0, end: 3 },
capture: { start: 4, end: 8 },
size: [70, 35],
offsets: [10, 5],
frameWidth: 78,
frameHeight: 64,
},
fish3: {
url: fish3,
swim: { start: 0, end: 3 },
capture: { start: 4, end: 8 },
size: [65, 36],
offsets: [5, 0],
frameWidth: 72,
frameHeight: 56,
},
fish4: {
url: fish4,
swim: { start: 0, end: 3 },
capture: { start: 4, end: 8 },
size: [75, 36],
offsets: [3, -2],
frameWidth: 77,
frameHeight: 59,
},
fish5: {
url: fish5,
swim: { start: 0, end: 3 },
capture: { start: 4, end: 8 },
size: [85, 70],
offsets: [15, 18],
frameWidth: 107,
frameHeight: 122,
},
fish6: {
url: fish6,
swim: { start: 0, end: 8 },
capture: { start: 8, end: 12 },
size: [90, 60],
offsets: [15, 0],
frameWidth: 105,
frameHeight: 79,
},
fish7: {
url: fish7,
swim: { start: 0, end: 6 },
capture: { start: 6, end: 10 },
size: [70, 75],
offsets: [15, 2],
frameWidth: 92,
frameHeight: 151,
},
fish8: {
url: fish8,
swim: { start: 0, end: 7 },
capture: { start: 7, end: 12 },
size: [80, 85],
offsets: [40, 3],
frameWidth: 174,
frameHeight: 126,
},
fish9: {
url: fish9,
swim: { start: 0, end: 7 },
capture: { start: 7, end: 12 },
size: [100, 120],
offsets: [60, 15],
frameWidth: 166,
frameHeight: 183,
},
fish10: {
url: fish10,
swim: { start: 0, end: 5 },
capture: { start: 5, end: 10 },
size: [140, 100],
offsets: [20, 22],
frameWidth: 178,
frameHeight: 187,
},
shark1: {
url: shark1,
swim: { start: 0, end: 7 },
capture: { start: 7, end: 12 },
size: [450, 150],
offsets: [60, 50],
frameWidth: 509,
frameHeight: 270,
},
shark2: {
url: shark2,
swim: { start: 0, end: 7 },
capture: { start: 7, end: 12 },
size: [450, 150],
offsets: [60, 60],
frameWidth: 516,
frameHeight: 273,
},
};
export const cannonsFrames = {
cannon1: {
url: cannon1,
anims: { start: 0, end: 5 },
size: [37, 60],
offsets: [37 / 2, 0],
frameWidth: 74,
frameHeight: 74,
},
};

BIN
games/fishMaster/images/bg.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

59
games/fishMaster/images/bottom.json

@ -1,59 +0,0 @@
{"frames": {
"bottom-bar.png":
{
"frame": {"x":0,"y":0,"w":765,"h":72},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":765,"h":72},
"sourceSize": {"w":765,"h":72}
},
"cannon_minus.png":
{
"frame": {"x":132,"y":72,"w":44,"h":31},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":44,"h":31},
"sourceSize": {"w":44,"h":31}
},
"cannon_minus_down.png":
{
"frame": {"x":88,"y":72,"w":44,"h":31},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":44,"h":31},
"sourceSize": {"w":44,"h":31}
},
"cannon_plus.png":
{
"frame": {"x":44,"y":72,"w":44,"h":31},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":44,"h":31},
"sourceSize": {"w":44,"h":31}
},
"cannon_plus_down.png":
{
"frame": {"x":0,"y":72,"w":44,"h":31},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":44,"h":31},
"sourceSize": {"w":44,"h":31}
},
"energy-bar.png":
{
"frame": {"x":0,"y":103,"w":213,"h":19},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":213,"h":19},
"sourceSize": {"w":213,"h":19}
}
},
"meta": {
"app": "http://www.texturepacker.com",
"version": "1.0",
"image": "bottom.png",
"format": "RGBA8888",
"size": {"w":765,"h":122}
}
}

BIN
games/fishMaster/images/bottom.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

BIN
games/fishMaster/images/cannon1.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

BIN
games/fishMaster/images/cannon2.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

BIN
games/fishMaster/images/cannon3.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

BIN
games/fishMaster/images/cannon4.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

BIN
games/fishMaster/images/cannon5.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

BIN
games/fishMaster/images/cannon6.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

BIN
games/fishMaster/images/cannon7.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

BIN
games/fishMaster/images/fish1.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

BIN
games/fishMaster/images/fish10.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

BIN
games/fishMaster/images/fish2.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

BIN
games/fishMaster/images/fish3.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

BIN
games/fishMaster/images/fish4.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

BIN
games/fishMaster/images/fish5.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

BIN
games/fishMaster/images/fish6.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

BIN
games/fishMaster/images/fish7.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

BIN
games/fishMaster/images/fish8.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

BIN
games/fishMaster/images/fish9.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

BIN
games/fishMaster/images/shark1.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 287 KiB

BIN
games/fishMaster/images/shark2.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 382 KiB

35
games/fishMaster/index.js

@ -1,35 +0,0 @@
import Phaser from "phaser";
import Scene from "./scene";
const launch = ({ containerId, onLose }) => {
const container = document.getElementById(containerId);
const width = container.clientWidth;
const height = container.clientHeight;
const game = new Phaser.Game({
type: Phaser.CANVAS,
width,
height,
parent: containerId,
physics: {
default: "arcade",
arcade: {
debug: true,
},
},
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_BOTH,
parent: containerId,
width: 1080,
height: 1080,
},
scene: Scene,
});
Object.assign(game, {
onLose,
restart() {
this.scene.scenes[0].scene.start("scene");
},
});
return game;
};
export default launch;

179
games/fishMaster/scene.js

@ -1,179 +0,0 @@
import Phaser from "phaser";
import bg from "./images/bg.png";
import bottom from "./images/bottom.png";
import bottomMap from "./images/bottom.json";
import { fishFrames, cannonsFrames } from "./assets";
export default class Scene extends Phaser.Scene {
constructor() {
super({
key: "scene",
});
}
preload() {
this.load.image("bg", bg);
this.load.atlas("bottom", bottom, bottomMap);
Object.entries(fishFrames).forEach(
([k, { url, frameWidth, frameHeight }]) => {
this.load.spritesheet(k, url, { frameWidth, frameHeight });
}
);
Object.entries(cannonsFrames).forEach(
([k, { url, frameWidth, frameHeight }]) => {
this.load.spritesheet(k, url, { frameWidth, frameHeight });
}
);
}
get cannon() {
return this.cannons[this.cannonIndex];
}
create() {
this.layout();
this.addListeners();
this.animateFishes();
this.animateCannons();
this.addCannon();
this.addFish();
}
animateCannons() {
Object.entries(cannonsFrames).forEach(([k, { anims }]) => {
this.anims.create({
key: `${k}_fire`,
frames: this.anims.generateFrameNumbers(k, anims),
frameRate: 10,
repeat: 0,
});
});
}
animateFishes() {
Object.entries(fishFrames).forEach(([k, { swim, capture }]) => {
this.anims.create({
key: `${k}_swim`,
frames: this.anims.generateFrameNumbers(k, swim),
frameRate: 10,
repeat: -1,
});
this.anims.create({
key: `${k}_capture`,
frames: this.anims.generateFrameNumbers(k, capture),
frameRate: 10,
repeat: -1,
});
});
}
layout() {
this.addBg();
this.addBottomBar();
}
addListeners() {
this.input.on(
"gameobjectdown",
(_, obj) => {
switch (obj.name) {
case "minus":
obj.setFrame("cannon_minus_down.png");
break;
case "plus":
obj.setFrame("cannon_plus_down.png");
break;
default:
break;
}
},
this
);
this.input.on(
"gameobjectup",
(pointer, obj) => {
switch (obj.name) {
case "minus":
obj.setFrame("cannon_minus.png");
break;
case "plus":
obj.setFrame("cannon_plus.png");
break;
case "bg":
const theta = Math.atan2(
this.game.config.height - pointer.y,
this.game.config.width / 2 - pointer.x
);
this.cannon.setRotation(theta - Math.PI / 2);
this.cannon.anims.play(`${this.cannon.name}_fire`, true);
default:
break;
}
},
this
);
}
addBg() {
const bg = this.add.image(0, 0, "bg");
bg.name = "bg";
bg.setOrigin(0);
bg.displayWidth = this.game.config.width;
bg.displayHeight = this.game.config.height;
bg.setInteractive();
}
addBottomBar() {
const bottomBar = this.add.image(
this.game.config.width / 2,
this.game.config.height - 45,
"bottom",
"bottom-bar.png"
);
bottomBar.displayWidth = 958;
bottomBar.displayHeight = 90;
const minus = this.add.image(
this.game.config.width / 2 - 40,
this.game.config.height - 50,
"bottom",
"cannon_minus.png"
);
minus.name = "minus";
minus.setOrigin(0);
minus.displayWidth = 55;
minus.displayHeight = 38;
minus.setInteractive();
const plus = this.add.image(
this.game.config.width / 2 + 95,
this.game.config.height - 50,
"bottom",
"cannon_plus.png"
);
plus.name = "plus";
plus.setOrigin(0);
plus.displayWidth = 55;
plus.displayHeight = 38;
plus.setInteractive();
}
addFish() {
Object.entries(fishFrames).forEach(([k, { size, offsets }]) => {
const fish = this.physics.add.sprite(
(Math.random() * this.game.config.width) / 2 +
this.game.config.width / 4,
(Math.random() * this.game.config.width) / 2 +
this.game.config.width / 4,
"fish1"
);
fish.body.setSize(...size);
fish.body.setOffset(...offsets);
fish.anims.play(`${k}_swim`, true);
});
}
addCannon() {
this.cannonIndex = 0;
const [k, { size, offsets }] = Object.entries(cannonsFrames)[
this.cannonIndex
];
const cannon = this.physics.add.sprite(
this.game.config.width / 2 + 55,
this.game.config.height - 50,
k
);
cannon.body.setSize(...size);
cannon.body.setOffset(...offsets);
cannon.name = k;
this.cannon = cannon;
}
}

5
h5/index.js

@ -0,0 +1,5 @@
import flipper from "./flipper/game";
import snake from "./snake/snake";
import water from "./water/game";
let h5games = { flipper, snake, water };
export default h5games;

184
h5/snake/css/snake.css

@ -1,184 +0,0 @@
@charset "UTF-8";
html,body {
position: relative;
width: 100%;
max-width: 540px;
height: 100%;
margin: 0;
padding: 0;
background-color: #ece060;
margin: 0 auto;
}
.snake-game {
position: relative;
width: 100%;
height: auto;
}
.snake-game canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: auto;
}
.snake-controller {
position: absolute;
top: 60%;
left: 0;
width: 100%;
}
.snake-switch {
position: absolute;
width: 50px;
height: 53px;
background: url(../images/switch@2x.png) 0 0 no-repeat;
background-size: 100% 100%;
top: 160px;
right: 30px;
border: 0 none;
appearance: none;
-webkit-appearance: none;
outline: 0;
}
.snake-trigger {
position: absolute;
width: 50px;
height: 50px;
background: url(../images/pause@2x.png) 0 0 no-repeat;
background-size: 100% 100%;
top: 160px;
left: 30px;
border: 0 none;
appearance: none;
-webkit-appearance: none;
outline: 0;
}
.snake-trigger:checked {
background-image: url(../images/play@2x.png);
}
.snake-direction {
position: absolute;
left: 50%;
top: 0;
width: 160px;
height: 160px;
margin-left: -80px;
border: 2px solid #414042;
background-color: #414042;
border-radius: 100%;
overflow: hidden;
transform: rotateZ(45deg);
-webkit-transform: rotateZ(45deg);
}
.snake-up, .snake-right, .snake-down, .snake-left {
position: absolute;
width: 80px;
height: 80px;
background-color: #ddd;
}
.snake-up::after,
.snake-right::after,
.snake-down::after,
.snake-left::after {
content: '';
position: absolute;
left: 40px;
top: 40px;
width: 10px;
height: 10px;
border-width: 2px 0 0 2px;
border-color: #414042;
border-style: solid;
transform-origin: left top;
-webkit-transform-origin: left top;
}
.snake-up {
top: -1px;
left: -1px;
}
.snake-right {
top: -1px;
right: -1px;
}
.snake-right::after {
transform: rotate(90deg);
-webkit-transform: rotate(90deg);
}
.snake-down {
bottom: -1px;
right: -1px;
}
.snake-down::after {
transform: rotate(180deg);
-webkit-transform: rotate(180deg);
}
.snake-left {
bottom: -1px;
left: -1px;
}
.snake-left::after {
transform: rotate(270deg);
-webkit-transform: rotate(270deg);
}
.snake-direction.up .snake-up,
.snake-direction.right .snake-right,
.snake-direction.down .snake-down,
.snake-direction.left .snake-left
{
background-color: rgba(188, 188, 188, .7);
}
.snake-timer {
position: absolute;
top: 172px;
right: 0;
left: 0;
margin: 0 auto;
width: 200px;
text-align: center;
font-size: 16px;
font-weight: bold;
}
.snake-speed {
position: absolute;
top: 206px;
right: 0;
left: 0;
margin: 0 auto;
width: 120px;
height: 4px;
border-radius: 2px;
background-color: #ffeeee;
box-shadow: inset 1px 1px 3px -1px rgba(0, 0, 0, .3);
}
.snake-speed-thumb {
position: absolute;
top: -3px;
left: 50%;
width: 10px;
height: 10px;
border-radius: 100%;
box-shadow: 0 2px 4px rgba(0, 0, 0, .3);
background-color: #fff;
}

BIN
h5/water/area.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
h5/water/bg.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 997 KiB

BIN
h5/water/bubble.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

29954
h5/water/createjs-2015.11.26.combined.js

File diff suppressed because it is too large

BIN
h5/water/flash.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
h5/water/font.ttf

Binary file not shown.

59
h5/water/game.js

@ -0,0 +1,59 @@
import Waterful from "./waterful";
import "./water.css";
export default class Game {
constructor({ containerId, onWon, onLose }) {
const waterful = new Waterful();
const container = document.getElementById(containerId);
const containerWH = container.clientWidth;
const bg = document.createElement("div");
bg.style.transform = `scale(${containerWH / 2160})`;
bg.className = "bg";
["left", "right"].forEach((name) => {
const button = document.createElement("div");
button.className = "button " + name;
bg.appendChild(button);
});
container.appendChild(bg);
const meta = document.createElement("div");
meta.className = "meta";
bg.appendChild(meta);
this.loaded = false;
this.options = {
container: bg,
red: 6,
yellow: 6,
green: 6,
score: {
left: [],
right: [],
},
callbacks: {
score(score) {
console.log("score: ", score, score.total);
},
end(score) {
onWon(score.total);
},
step(step) {
if (step === 0) onLose();
meta.textContent = `剩余 ${step} 次机会`;
},
},
};
waterful.preload().then(() => {
this.loaded = true;
waterful.init(this.options);
});
this.waterful = waterful;
}
dispose() {}
restart() {
this.loaded && this.waterful.restart(this.options);
}
pause() {
this.loaded && this.waterful.pause();
}
resume() {
this.loaded && this.waterful.resume();
}
}

BIN
h5/water/green.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
h5/water/magnet.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
h5/water/needle.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

BIN
h5/water/red.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

183
h5/water/ring.js

@ -0,0 +1,183 @@
import createjs from "./createjs-2015.11.26.combined";
import Matter from "matter-js";
function rule(t, e) {
return !!(
[0, 1, 2, 3, 4, 5, 6].includes(t) &&
((e %= 180),
e < 0 && (e += 180),
(e >= 0 && e <= 65) || (e >= 115 && e <= 180))
);
}
function segmentsIntr(t, e, i, r) {
var n = (t.x - i.x) * (e.y - i.y) - (t.y - i.y) * (e.x - i.x),
s = (t.x - r.x) * (e.y - r.y) - (t.y - r.y) * (e.x - r.x);
if (n * s >= 0) return !1;
var a = (i.x - t.x) * (r.y - t.y) - (i.y - t.y) * (r.x - t.x),
o = a + n - s;
return !(a * o >= 0);
}
function stopUnusual(t, e, i, r) {
var n = 1e-4;
return Math.abs(t) <= n && Math.abs(e) <= n;
}
export default class Ring {
constructor(x, y, r, id, waterful) {
this.active = true;
this.color = id.replace("ring_", "");
this.r = r;
const sprite = new createjs.SpriteSheet({
images: [waterful._queue.getResult(id)],
frames: { width: 62, height: 62 },
animations: {
normal: {
frames: [
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
10,
9,
8,
7,
6,
5,
4,
3,
2,
1,
0,
],
speed: 0.3,
},
prepare: {
frames: [0, 1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1, 0],
speed: 0.1,
},
},
});
this.texture = new createjs.Sprite(sprite, "normal");
const bounds = this.texture.getBounds();
this.texture.regX = bounds.width / 2;
this.texture.regY = bounds.height / 2;
this.texture.stop();
this.texture.x = x;
this.texture.y = y;
this.texture.scaleX = (r * 2) / bounds.width;
this.texture.scaleY = (r * 2) / bounds.height;
this.texture.on("animationend", function (e) {
var target = e.currentTarget;
target.y < 528
? e.target.gotoAndPlay("prepare")
: e.target.gotoAndPlay("normal");
});
this.body = Matter.Bodies.circle(this.texture.x, this.texture.y, r, {
frictionAir: 0.02,
restitution: 0.15,
});
}
update(waterful) {
const { texture, body, r } = this;
const { x, y, rotation } = texture;
const { position, angle, velocity } = body;
const innerRadius = texture.scaleX * 16;
const startPoint = {
x: x - innerRadius * Math.cos(rotation * (Math.PI / 180)),
y: y - innerRadius * Math.sin(rotation * (Math.PI / 180)),
};
const endPoint = {
x: x + innerRadius * Math.cos(-rotation * (Math.PI / 180)),
y: y + innerRadius * Math.sin(rotation * (Math.PI / 180)),
};
const m = { x: 616, y: 264 };
const n = { x: 616, y: 700 };
const u = { x: 1196, y: 264 };
const v = { x: 1196, y: 700 };
if (
segmentsIntr(startPoint, endPoint, m, n) &&
this.afterCollision(waterful, "left")
)
return;
if (
segmentsIntr(startPoint, endPoint, u, v) &&
this.afterCollision(waterful, "right")
)
return;
const x1 = Math.round(x);
const x2 = Math.round(position.x);
const y1 = Math.round(y);
const y2 = Math.round(position.y);
if (x1 !== x2 || y1 !== y2) {
texture.paused && texture.play();
texture.rotation = (180 * angle) / Math.PI;
} else {
!texture.paused && texture.stop();
}
if (stopUnusual(velocity.x, velocity.y, x1, y1)) {
var factor = 1;
if (x1 < 206 || (x1 > 400 && x1 < 455)) {
factor = -1;
}
Matter.Body.applyForce(
body,
{ x: position.x, y: position.y },
{ x: 0.05 * factor, y: 0 }
);
}
texture.x = body.position.x;
texture.y = body.position.y;
}
afterCollision(waterful, dir) {
const { texture } = this;
const { currentFrame, rotation } = texture;
const followRule = rule(currentFrame, rotation);
if (
!followRule ||
waterful._score[dir].length > 8 ||
this.body.velocity.y <= 0
)
return false;
const scores = waterful._score[dir].length;
createjs.Tween.get(this.texture)
.to({ y: 666 - 30 * scores }, (666 - 30 * scores) / 0.21)
.call(function () {
waterful._staticRings.push(this);
});
Matter.World.remove(waterful._engine.world, this.body);
this.body = null;
this.active = false;
this.update = () => {
const { texture } = this;
const { currentFrame } = texture;
var t = this.texture,
e = t.currentFrame;
if (0 === currentFrame) texture.gotoAndStop(0);
else {
if (!this.frameCounter) this.frameCounter = 5;
texture.gotoAndStop(--texture.currentFrame);
this.frameCounter--;
if (texture.x < 582) ++texture.x;
if (texture.x > 660 && texture.x < 660 + 80) --texture.x;
if (texture.x > 1242) --texture.x;
if (texture.x > 1162 && texture.x < 1206) ++texture.x;
}
let angle = Math.round(texture.rotation) % 180;
angle < 0 && (angle += 180);
angle > 0 && angle <= 90
? (texture.rotation = angle - 1)
: angle > 90 && angle < 180
? (texture.rotation = angle + 1)
: 0 === currentFrame && (this.update = function () {});
};
waterful.score(dir, this.color);
return true;
}
}

44
h5/water/water.css

@ -0,0 +1,44 @@
.bg {
position: relative;
width: 2160px;
height: 2160px;
transform-origin: top left;
background-image: url(./bg.jpg);
background-size: cover;
}
@font-face {
font-family: "game";
src: url("./font.ttf") format("truetype");
}
.bg .watercanvas {
position: absolute;
left: 144px;
top: 383px;
width: 1868px;
height: 1075px;
}
.bg .button {
position: absolute;
bottom: 112px;
width: 540px;
height: 383px;
}
.bg .button.left {
left: 230px;
}
.bg .button.right {
right: 230px;
}
.bg .meta {
position: absolute;
text-align: center;
top: 1873px;
left: 837px;
right: 837px;
height: 117px;
line-height: 117px;
font-size: 52px;
color: #fff;
font-family: "game";
}

378
h5/water/waterful.js

@ -0,0 +1,378 @@
import createjs from "./createjs-2015.11.26.combined";
import red from "./red.png";
import yellow from "./yellow.png";
import green from "./green.png";
import bubble from "./bubble.png";
import flash from "./flash.png";
import magnet from "./magnet.png";
import needle from "./needle.png";
import Matter from "matter-js";
import Ring from "./ring";
import "./water.css";
const width = 1868;
const height = 1096;
const throttle = (t, e) => {
var i = null;
return function (r) {
var n = +new Date();
if (!(null != i && n - i <= e)) return (i = n), t.apply(this, [r]);
};
};
const loadImg = (src) =>
new Promise((resolve) => {
const img = new Image();
img.onload = () => resolve(img);
img.src = src;
});
class Queue {
constructor() {
this.map = {};
}
async loadManifest(manifest) {
const imgs = await Promise.all(manifest.map(({ src }) => loadImg(src)));
manifest.forEach((file, i) => {
this.map[file.id] = imgs[i];
});
}
getResult(id) {
return this.map[id];
}
}
export default class Waterful {
preload() {
const queue = new Queue();
this._queue = queue;
const manifest = [
{
id: "ring_red",
src: red,
},
{
id: "ring_yellow",
src: yellow,
},
{
id: "ring_green",
src: green,
},
{
id: "bubble",
src: bubble,
},
{
id: "flashAnim",
src: flash,
},
{
id: "magnetAnim",
src: magnet,
},
{
id: "needle",
src: needle,
},
];
return queue.loadManifest(manifest);
}
init(options) {
this.steps = 100;
this._options = options;
this._options.callbacks.step(this.steps);
this.enlarging = false;
this.magneting = false;
this.addForceLeft = false;
this.addForceRight = false;
this._score = {
left: options.score.left || [],
right: options.score.right || [],
};
Object.defineProperty(this._score, "total", {
get: function () {
return this.left.length + this.right.length;
},
});
this._idleBubbles = { left: [], right: [] };
this.totalRings =
this._score.total + options.red + options.yellow + options.green;
this.initStage(options.container);
this.initRings(options);
this.eventBinding(options.container);
this.getBubbleLeft = throttle(() => {
if (this._idleBubbles.left.length) return this._idleBubbles.left.shift();
const bubble = new createjs.Sprite(
new createjs.SpriteSheet({
images: [this._queue.getResult("bubble")],
frames: { width: 320, height: 480 },
animations: { run: [0, 14, null, 0.3] },
})
);
bubble.x = 0;
bubble.y = height / 2;
bubble.on(
"animationend",
function () {
this._stage.removeChild(bubble), this._idleBubbles.left.push(bubble);
}.bind(this)
);
return bubble;
}, 300);
this.getBubbleRight = throttle(() => {
if (this._idleBubbles.right.length)
return this._idleBubbles.right.shift();
var bubble = new createjs.Sprite(
new createjs.SpriteSheet({
images: [this._queue.getResult("bubble")],
frames: { width: 320, height: 480 },
animations: { run: [0, 14, null, 0.3] },
})
);
bubble.x = width;
bubble.y = height / 2;
bubble.scaleX = -1;
bubble.on(
"animationend",
function () {
this._stage.removeChild(bubble), this._idleBubbles.right.push(bubble);
}.bind(this)
);
return bubble;
}, 300);
}
initStage(container) {
const drawNeedle = (game, x) => {
const sheet = new createjs.SpriteSheet({
images: [game._queue.getResult("needle")],
frames: { width: 182, height: 659 },
});
const sprite = new createjs.Sprite(sheet);
sprite.x = x;
sprite.y = 334;
return sprite;
};
const drawFlash = (game, x) => {
const sheet = new createjs.SpriteSheet({
images: [game._queue.getResult("flashAnim")],
frames: { width: 332, height: 168 },
animations: { run: { frames: [0, 1, 2, 3, 4], speed: 0.2 } },
});
const sprite = new createjs.Sprite(sheet);
const bounds = sprite.getBounds();
sprite.regX = bounds.width / 2;
sprite.regY = bounds.height / 2;
sprite.x = x;
sprite.y = 334;
sprite.scaleX = 3;
sprite.scaleY = 3;
sprite.on("animationend", function () {
game._stage.removeChild(this);
});
return sprite;
};
const { Engine, World, Bodies, Events } = Matter;
const engine = (this._engine = Engine.create());
engine.world.gravity.y = 0.2;
World.add(engine.world, [
Bodies.rectangle(width / 2, 0, width, 1, { isStatic: true }),
Bodies.rectangle(width / 2, height, width, 1, { isStatic: true }),
Bodies.rectangle(0, height / 2, 1, height, { isStatic: true }),
Bodies.rectangle(width, height / 2, 1, height, { isStatic: true }),
Bodies.rectangle(602, 530, 1, 380, { isStatic: true }),
Bodies.rectangle(634, 530, 1, 380, { isStatic: true }),
Bodies.rectangle(1188, 530, 1, 380, { isStatic: true }),
Bodies.rectangle(1220, 530, 1, 380, { isStatic: true }),
Bodies.circle(616, 764, 90, { isStatic: true }),
Bodies.circle(1200, 764, 90, { isStatic: true }),
Bodies.rectangle(618, 906, 74, 100, { isStatic: true }),
Bodies.rectangle(1204, 906, 74, 100, { isStatic: true }),
Bodies.rectangle(618, 340, 32, 1, { isStatic: true, friction: 0 }),
Bodies.rectangle(1204, 340, 32, 1, { isStatic: true, friction: 0 }),
]),
Engine.run(engine),
Events.on(this._engine, "beforeUpdate", () => {
let force;
if (this.addForceLeft || this.addForceRight) {
if (this.addForceLeft) {
force = 1;
this.addForceLeft = false;
}
if (this.addForceRight) {
force = -1;
this.addForceRight = false;
}
this._rings.forEach((ring) => {
if (ring.active) {
const { x, y } = ring.body.position;
Matter.Body.applyForce(
ring.body,
{ x, y },
{ x: 0.3 * force, y: -0.4 }
);
Matter.Body.setAngularVelocity(ring.body, (force * Math.PI) / 24);
}
});
}
});
const canvas = document.createElement("canvas");
canvas.className = "watercanvas";
canvas.width = width;
canvas.height = height;
container.appendChild(canvas);
this._stage = new createjs.Stage(canvas);
this._needles = {};
const leftNeedle = (this._needles.left = drawNeedle(this, 524));
const rightNeedle = (this._needles.right = drawNeedle(this, 1106));
this._stage.addChild(leftNeedle, rightNeedle);
this._flashAnim = {
left: drawFlash(this, 616),
right: drawFlash(this, 1204),
};
}
initRings(options) {
this._rings = [];
this._staticRings = [];
this._score.left.forEach((ring, i) => {
this.addStaticRing(ring, i, "left");
});
this._score.right.forEach((ring, i) => {
this.addStaticRing(ring, i, "right");
});
this.addRing("ring_red", options.red);
this.addRing("ring_yellow", options.yellow);
this.addRing("ring_green", options.green);
if (options.priceRing && this._rings[0]) {
const ring = this._rings[0];
Matter.Body.setPosition(ring.body, { x: 206, y: 216 }),
(ring.active = true);
}
this._stage.update();
}
addStaticRing(t, e, i) {
var r = new createjs.SpriteSheet({
images: [waterful._queue.getResult("ring_" + t)],
frames: { width: 62, height: 62 },
}),
n = new createjs.Sprite(r),
s = n.getBounds();
(n.regX = s.width / 2),
(n.regY = s.height / 2),
(n.x = "left" === i ? 206 : 455),
(n.y = 380 - 14 * e),
n.gotoAndStop(0),
this._stage.addChild(n),
this._staticRings.push(n);
}
addRing(name, max) {
const getX = () => {
const x = 1670 * Math.random() + 90;
return (x > 523 && x < 705) || (x > 1106 && x < 1292) ? getX() : x;
};
let bodies = [];
for (let i = 0; i < max; i++) {
const x = getX();
const y = 1200 * Math.random() + 150;
const ring = new Ring(x, y, 80, name, this);
this._rings.push(ring);
this._stage.addChild(ring.texture);
bodies.push(ring.body);
}
Matter.World.add(this._engine.world, bodies);
}
eventBinding(container) {
container.querySelector(".button.left").addEventListener("click", (t) => {
if (this.steps) {
this.steps--;
this._options.callbacks.step(this.steps);
} else return;
t.preventDefault(), (this.addForceLeft = true);
var e = this.getBubbleLeft();
e && (this._stage.addChild(e), e.gotoAndPlay("run"));
});
container.querySelector(".button.right").addEventListener("click", (t) => {
if (this.steps) {
this.steps--;
this._options.callbacks.step(this.steps);
} else return;
t.preventDefault(), (this.addForceRight = true);
var e = this.getBubbleRight(this);
e && (e && this._stage.addChild(e), e.gotoAndPlay("run"));
});
createjs.Ticker.timingMode = createjs.Ticker.RAF;
createjs.Ticker.setFPS(60);
createjs.Ticker.addEventListener(
"tick",
function (t) {
if (!t.paused) {
for (var e = 0; e < this._rings.length; e++)
this._rings[e].update(this);
if (this.gamma)
for (var e = 0; e < this._staticRings.length; e++) {
if (this.gamma < 0) {
var i = this._staticRings[e].x - 0.1;
i < 200 && (i = 200), i > 400 && i < 448 && (i = 448);
} else if (this.gamma > 0) {
var i = this._staticRings[e].x + 0.1;
i > 213 && i < 300 && (i = 213), i > 462 && (i = 462);
}
this._staticRings[e].x = i;
}
this._stage.update(t);
}
}.bind(this)
);
}
score(t, e) {
"left" === t
? this._score.left.push(e)
: "right" === t && this._score.right.push(e),
this._stage.addChild(this._flashAnim[t]),
this._flashAnim[t].gotoAndPlay("run");
var i = this._options;
i.callbacks.score(this._score),
this._score.total === this.totalRings && i.callbacks.end(this._score);
}
restart(t) {
this.steps = 100;
this._options.callbacks.step(this.steps);
(this._score = { left: [], right: [] }),
(this.enlarging = false),
(this.magneting = false),
(this.addForceLeft = false),
(this.addForceRight = false),
this._rings.forEach(
function (t) {
this._stage.removeChild(t.texture),
t.body && Matter.World.remove(this._engine.world, t.body);
}.bind(this)
),
this._staticRings.forEach(
function (t) {
this._stage.removeChild(t);
}.bind(this)
),
this.initRings(t);
}
pause() {
createjs.Ticker.pause = true;
for (var t = 0; t < this._rings.length; t++) {
var e = this._rings[t].body;
e && Matter.Sleeping.set(e, true);
}
}
resume() {
createjs.Ticker.pause = false;
for (var t = 0; t < this._rings.length; t++) {
var e = this._rings[t].body;
e && Matter.Sleeping.set(e, false);
}
}
}

BIN
h5/water/yellow.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

2
package.json

@ -5,6 +5,8 @@
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@tweenjs/tween.js": "18", "@tweenjs/tween.js": "18",
"createjs": "^1.0.1",
"matter-js": "^0.14.2",
"phaser": "^3.24.1", "phaser": "^3.24.1",
"vue": "^2.6.12" "vue": "^2.6.12"
} }

2
phaser.js

@ -3,7 +3,6 @@ import flappyBird from "./games/game-flipbird/game";
import game2048 from "./games/game2048/game"; import game2048 from "./games/game2048/game";
import rect from "./games/game-rect/game"; import rect from "./games/game-rect/game";
import floodFill from "./games/game-flood-fill/game"; import floodFill from "./games/game-flood-fill/game";
import fishMaster from "./games/fishMaster/index";
import match3 from "./games/match3/game"; import match3 from "./games/match3/game";
const attachMethods = (fn) => (...p) => const attachMethods = (fn) => (...p) =>
Object.assign(fn(...p), { Object.assign(fn(...p), {
@ -33,7 +32,6 @@ const games = Object.entries({
game2048, game2048,
rect, rect,
floodFill, floodFill,
fishMaster,
match3, match3,
}) })
.map(([name, fn]) => ({ [name]: attachMethods(fn) })) .map(([name, fn]) => ({ [name]: attachMethods(fn) }))

Loading…
Cancel
Save