@ -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; |
||||
|
} |
||||
|
} |
||||