import Phaser from 'phaser'
import FlappyState from "./FlappyState";
const States = {
IDLE: 0,
RUNNING: 1,
PAUSED: 2
}
/**
* @classdesc - This sets up, creates, and updates the environment for the game.
* This class is used to create, manage, and manipulate the environment for the game.
* @author Christian P. Auman
* @class
* @memberOf module:PlayScene
*/
class Backdrop extends FlappyState {
/**
* This will set up all the default values for the class variables
* @param scene - the current Scene game object
*/
constructor(scene) {
super(States.IDLE)
this.scene = scene
this.position = {
x: 0,
y: 0
}
this.frameWidth = 640
this.frameHeight = 252
this.treeFrameHeight = 88
this.buildingFrameHeight = 184
this.starCount = 30
this.buildings = null
this.trees = null
this.background = null
this.velocity = 200
this.height = null
this.startingY = 0
}
/**
* This function is called before anything is drawn on the canvas.
* This allows for asset preloading which prevents anything from drawing without
* it first loading the asset.
*/
preload() {
if (!this.height)
this.height = this.scene.game.canvas.height
// asset injection
this.scene.load.image('moon', '/assets/moon.png')
this.scene.load.image('star', '/assets/star.png')
this.scene.load.spritesheet('buildings', '/assets/cityscape-buildings.png', {
frameWidth: this.frameWidth,
frameHeight: this.buildingFrameHeight
})
this.scene.load.spritesheet('trees', '/assets/cityscape-trees.png', {
frameWidth: this.frameWidth,
frameHeight: this.treeFrameHeight
})
this.scene.load.spritesheet('background', '/assets/cityscape-background.png', {
frameWidth: this.frameWidth,
frameHeight: this.frameHeight
})
}
/**
* This will update every game object accordingly using the given class position variable
*/
updatePosition() {
this.buildings.x = this.position.x + this.scene.game.canvas.width / 2
this.buildings.y = this.position.y
this.trees.x = this.position.x + this.scene.game.canvas.width / 2
this.trees.y = this.position.y
this.background.x = this.position.x + this.scene.game.canvas.width / 2
this.background.y = this.position.y
}
/**
* this method will set the class position x and y values to the given x and y parameter values
* @param x - x pos
* @param y - y pos
*/
setPosition(x, y) {
this.position.x = x
this.position.y = y
this.updatePosition()
}
/**
* This is an algorithm that is based off of my cloud algorithm, and at the start of the game will
* create a new renderTexture and will draw stars based on a given grid parameter
*/
createStars() {
const horizontalSections = this.starCount / 2
const verticalSections = this.starCount / 2
const sceneDimensions = {
width: this.scene.game.canvas.width,
height: this.height - 200
}
const sectionWidth = sceneDimensions.width / horizontalSections
const sectionHeight = sceneDimensions.height / verticalSections
this.rt = this.scene.make.renderTexture(sceneDimensions)
this.rt.depth = -10001
this.rt.beginDraw()
for (let i = 0; i < verticalSections; i++) {
for (let j = 0; j < horizontalSections; j++) {
const x = Phaser.Math.RND.between(sectionWidth * j, sectionWidth * j + sectionWidth)
const y = Phaser.Math.RND.between(sectionHeight * i, sectionHeight * i + sectionHeight)
const star = this.scene.add.image(x, y, 'star')
star.alpha = Phaser.Math.RND.realInRange(0.1, 0.9)
star.scale = Phaser.Math.RND.realInRange(0.1, 0.5)
star.setAngle(Phaser.Math.RND.integerInRange(0, 360))
this.rt.draw(star)
star.visible = false
star.destroy()
}
}
this.rt.endDraw()
this.rt.saveTexture('stars')
}
/**
* This will create tileSprites for the buildings, the trees, and the background. Allows for repeating the image and
* the illusion of infinite images
*/
createCityscape() {
this.buildings = this.scene.add.tileSprite(0, 0, this.scene.game.canvas.width + 100, this.buildingFrameHeight, 'buildings')
.setOrigin(0.5, 1)
.setDepth(-101)
this.trees = this.scene.add.tileSprite(0, 0, this.scene.game.canvas.width + 100, this.treeFrameHeight, 'trees')
.setOrigin(0.5, 1)
.setDepth(-100)
this.background = this.scene.add.tileSprite(0, 0, this.scene.game.canvas.width + 100, this.frameHeight, 'background')
.setOrigin(0.5, 1)
.setDepth(-102)
}
/**
* This calls the needed create/setup methods and also creates a moon image and centers it accordingly
*/
create() {
this.createCityscape()
const canvas = this.scene.game.canvas
this.moon = this.scene.add.image(canvas.width / 2, canvas.height / 4, 'moon')
this.moon.depth = -10000
this.createStars()
this.rt.y = this.startingY
this.updatePosition()
}
/**
* This method will update the tile's x position for the trees, buildings, and background.
* Depending on how big the number added to the x value is, will determine how fast they move.
*/
updateTilePositions(delta) {
this.background.tilePositionX += this.velocity * 0.0001 * delta
this.buildings.tilePositionX += this.velocity * 0.0002 * delta
this.trees.tilePositionX += this.velocity * 0.00035 * delta
}
/**
* This will be updating the tile position for the cityscape if the state is not PAUSED
*/
update(time, delta) {
if (this.currentState === States.IDLE || this.currentState === States.RUNNING) {
this.updateTilePositions(delta)
} else if (this.currentState === States.PAUSED) {}
}
/**
* Called at the start of the game
*/
startG() {
super.start()
}
/**
* called at the end of the game
*/
stopG() {
super.stop()
}
/**
* called whenever the game needs to be reset
*/
resetG() {
super.reset()
this.buildings.tilePositionX = 0
}
}
export default Backdrop