@ -0,0 +1,133 @@ |
|||
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, |
|||
}, |
|||
}; |
|||
|
After Width: | Height: | Size: 1.1 MiB |
@ -0,0 +1,59 @@ |
|||
{"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} |
|||
} |
|||
} |
|||
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 121 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 80 KiB |
|
After Width: | Height: | Size: 101 KiB |
|
After Width: | Height: | Size: 105 KiB |
|
After Width: | Height: | Size: 287 KiB |
|
After Width: | Height: | Size: 382 KiB |
@ -0,0 +1,35 @@ |
|||
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; |
|||
@ -0,0 +1,179 @@ |
|||
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; |
|||
} |
|||
} |
|||