diff --git a/assets/anais_talking.png b/assets/anais_talking.png new file mode 100644 index 0000000..6b5c67c Binary files /dev/null and b/assets/anais_talking.png differ diff --git a/assets/darwin_spritesheet.png b/assets/darwin_spritesheet.png index 00dcbc3..ddab284 100644 Binary files a/assets/darwin_spritesheet.png and b/assets/darwin_spritesheet.png differ diff --git a/assets/gumball_spritesheet.png b/assets/gumball_spritesheet.png index 59086a7..88149b6 100644 Binary files a/assets/gumball_spritesheet.png and b/assets/gumball_spritesheet.png differ diff --git a/assets/json/dialog.json b/assets/json/dialog.json index a7cccdf..e4a8086 100644 --- a/assets/json/dialog.json +++ b/assets/json/dialog.json @@ -28,7 +28,8 @@ }, { "speaker" : "anais", - "dialog" : "The fabric of the universe was ripped apart by Gumball." + "dialog" : "The fabric of the universe was ripped apart by Gumball.", + "newSpeaker": "true" } ], [ @@ -39,11 +40,11 @@ }, { "speaker" : "darwin", - "dialog" : "Looks like we will need to defeat the main boss to escape." + "dialog" : "Looks like we will need to beat the game to escape." }, { "speaker" : "anais", - "dialog" : "Look at your console and navigate through.", + "dialog" : "Sigh, can't be helped. Look at your console and navigate through.", "newSpeaker": "true" }, { @@ -52,11 +53,24 @@ }, { "speaker" : "anais", - "dialog" : "To attack go to the bottom of the menu and press attack." + "dialog" : "Try it, look at our names and scroll through with <- and ->." + }, + { + "speaker" : "anais", + "dialog" : "Remember each one of us has different attacks as well." }, { "speaker" : "anais", - "dialog" : "We will be obtaining items to use later on so keep an eye on that." + "dialog" : "To attack go to the bottom of the menu and press SPACE." + }, + { + "speaker" : "anais", + "dialog" : "To attack go to the bottom of the menu and press SPACE." + }, + { + "speaker" : "darwin", + "dialog" : "Oh yeah, by the way you can use the phone to summon friends in battle!!", + "newSpeaker": "true" } ] diff --git a/assets/livingroom.jpg b/assets/livingroom.jpg new file mode 100644 index 0000000..7c384f9 Binary files /dev/null and b/assets/livingroom.jpg differ diff --git a/assets/nicole_spritesheet.png b/assets/nicole_spritesheet.png index 97ca5a8..1cfcb49 100644 Binary files a/assets/nicole_spritesheet.png and b/assets/nicole_spritesheet.png differ diff --git a/src/prefabs/Character.js b/src/prefabs/Character.js index f65ea5c..52be358 100644 --- a/src/prefabs/Character.js +++ b/src/prefabs/Character.js @@ -123,6 +123,7 @@ class AttackState extends State { console.log(Object.entries(character.attackList)[character.selectedAttack][1][2] == 0) if (Object.entries(character.attackList)[character.selectedAttack][1][2] == 0) { character.body.setVelocityX(scene.enemy.x - character.x) + // character.body.setVelocityX(-1 * 350) this.collision = false; } else { @@ -144,25 +145,25 @@ class AttackState extends State { this.stateMachine.transition('idle') } + // console.log(character.willAttack + " " + character.hasAttacked) + scene.physics.add.collider(character, scene.enemy, () => { - // let collision = scene.enemy.projectile.handleCollision(character, scene.dmgToEnemy) - // if ( collision == true){ - // // reset that projectile once the collision is true - // console.log('collision was true') - // scene.enemy.projectile.resetProj(scene.enemy.projectile.startX, scene.enemy.projectile.startY) - // this.stateMachine.transition('hurt') - // // is entered - // } if (this.collision == false) { character.body.setVelocityX(0) - this.collision = true; + this.collision = true; + character.anims.play(`${character.name}_melee`, true) + // character.projectile.move(scene.enemy) + character.once('animationcomplete', () => { + // character.projectile.x = centerX + // character.projectile.y = centerY + // character.projectile.resetProj(character.projectile.startX, character.projectile.startY) + console.log("finished melee attack") + character.anims.play(`${character.name}_idle`) + character.willAttack = false + character.hasAttacked = true + character.setVelocityX(-1 * (scene.enemy.x - character.startX)) + }) } - character.anims.play(`${character.name}_melee`, true) - character.once('animationcomplete', () => { - character.willAttack = false - character.hasAttacked = true - character.setVelocityX(-1 * (scene.enemy.x - character.x)) - }) }, null, scene) } } diff --git a/src/prefabs/Enemy.js b/src/prefabs/Enemy.js index 7659324..e6432d5 100644 --- a/src/prefabs/Enemy.js +++ b/src/prefabs/Enemy.js @@ -68,12 +68,19 @@ class DefaultState extends State { // add a collider to collide with the incoming player projectile scene.physics.add.collider(scene.selectionMenu.attackingPlayer.projectile, enemy, () => { // create a collision to transition into damaged + console.log(scene.selectionMenu.attackingPlayer) let collision = scene.selectionMenu.attackingPlayer.projectile.handleCollision(enemy, scene.dmgToEnemy) if ( collision == true){ scene.selectionMenu.attackingPlayer.projectile.resetProj(scene.selectionMenu.attackingPlayer.projectile.startX, scene.selectionMenu.attackingPlayer.projectile.startY) this.stateMachine.transition('damaged') } }, null, scene) + + if (Object.entries(scene.selectionMenu.characters[scene.selectionMenu.availableChar[scene.selectionMenu.current_player]].attackList)[scene.selectionMenu.current_attack][1][2] == 0) { + if (scene.selectionMenu.characters[scene.selectionMenu.availableChar[scene.selectionMenu.current_player]].hasAttacked == true) { + this.stateMachine.transition('damaged') + } + } } // check if the summon was selected instead diff --git a/src/prefabs/Projectile.js b/src/prefabs/Projectile.js index cc4602a..c457fcb 100644 --- a/src/prefabs/Projectile.js +++ b/src/prefabs/Projectile.js @@ -28,7 +28,7 @@ class Projectile extends Phaser.Physics.Arcade.Sprite{ let direction if(this.x >= landX){ direction = 'left' - this.anims.play(`${this.character.name}_projectileAttack`) + // this.anims.play(`${this.character.name}_projectileAttack`) this.body.setVelocityX(-this.moveSpeed) } else if (landX >= this.x){ diff --git a/src/prefabs/Summon.js b/src/prefabs/Summon.js index 52bcfb7..bee4f72 100644 --- a/src/prefabs/Summon.js +++ b/src/prefabs/Summon.js @@ -1,27 +1,40 @@ class Summon extends Phaser.Physics.Arcade.Sprite { // upon selection the summon a summon should appear on screen and attack the enemy // the summon should then reset its location - constructor(scene, x, y , texture, damage) { + constructor(scene, x, y , texture, damage, name) { super(scene, x, y, texture) scene.add.existing(this) this.projectile = new Projectile(scene, this.x + this.width/2, this.y - this.height/2, `${this.name}_projectile`, this) - + this.name = name this.scene = scene this.hasAttacked = false this.summonUses = 2 this.damage = damage // damage to be added to enemy + + this.attackTimer = 200 } attack(){ // float up to a certain point and cast a projectile + this.setVisible(true) this.y = centerY this.projectile.y = this.y - this.height/2 this.summonUses -= 1 console.log("attack") // this.hasAttacked = true // for now remove - if (this.y == centerY){ + this.anims.play(`${this.name}_attack`) + this.once('animationcomplete', ()=> { this.projectile.move(this.scene.enemy) - } + this.scene.time.delayedCall(this.attackTimer, () => { + this.setVisible(false) + }) + }) + + + + // if (this.y == centerY){ + // this.projectile.move(this.scene.enemy) + // } // attacking position: rightPos - tileSize * 3, centerY // move summon towards the position diff --git a/src/scenes/Fighting.js b/src/scenes/Fighting.js index a1bb92e..0795241 100644 --- a/src/scenes/Fighting.js +++ b/src/scenes/Fighting.js @@ -72,7 +72,7 @@ class Fighting extends Phaser.Scene { this.enemy_hp = new HealthBar(this, centerX, tileSize / 4, this.enemy) // enemy does not need mana - this.summon = new Summon(this, rightPos - tileSize * 3, game.config.height + 100, 'nicole', 200).setOrigin(0,1) + this.summon = new Summon(this, rightPos - tileSize * 3, game.config.height + 100, 'nicole', 200, 'NICOLE').setOrigin(0,1) // setting up keyboard inputs @@ -92,7 +92,7 @@ class Fighting extends Phaser.Scene { if (this.active_players == 0 || this.active_enemies == 0){ this.gameOver = true } - // restart game if game over + // restart game if g ame over if (this.gameOver){ // check gameover condition if (this.active_enemies == 0){ diff --git a/src/scenes/Menu.js b/src/scenes/Menu.js index 66639dc..9a1dae7 100644 --- a/src/scenes/Menu.js +++ b/src/scenes/Menu.js @@ -9,6 +9,8 @@ class Menu extends Phaser.Scene{ this.load.path = './assets/' // setting up backgrounds this.load.image('background', 'gumball_side_walk_2.png') + this.load.image('livingroom', 'livingroom.jpg') + this.load.image('title_image', 'Title.png') this.load.image('container', 'container_1.png') this.load.image('cursor', 'cursor.png') @@ -43,8 +45,11 @@ class Menu extends Phaser.Scene{ frameWidth: 33, frameHeight: 34 }) + + this.load.image('anais_talk', 'anais_talking.png') + this.load.spritesheet('darwin', 'darwin_spritesheet.png', { - frameWidth: 46, + frameWidth: 42, frameHeight: 35 }) this.load.image('darwin_talk', 'darwin_talking.png') @@ -54,9 +59,10 @@ class Menu extends Phaser.Scene{ frameHeight: 60 }) this.load.spritesheet('nicole', 'nicole_spritesheet.png', { - frameWidth: 40, - frameHeight: 72 + frameWidth: 32, + frameHeight: 66 }) + this.load.spritesheet('ANAIS_projectile', 'sci_proj_spritesheet.png', { frameWidth: 16, @@ -100,7 +106,7 @@ class Menu extends Phaser.Scene{ this.anims.create({ key: 'GUMBALL_melee', frameRate: 8, - repeat: -1, + repeat: 0, frames: this.anims.generateFrameNumbers('gumball', { start: 8, end: 15}), }) this.anims.create({ @@ -109,12 +115,12 @@ class Menu extends Phaser.Scene{ repeat: -1, frames: this.anims.generateFrameNumbers('gumball', { start: 8, end: 8}), }) - this.anims.create({ - key: 'GUMBALL_projectileAttack', - frameRate: 8, - repeat: 0, - frames: this.anims.generateFrameNumbers('GUMBALL_projectile', { start: 0, end: 0}), - }) + // this.anims.create({ + // key: 'GUMBALL_projectileAttack', + // frameRate: 8, + // repeat: 0, + // frames: this.anims.generateFrameNumbers('GUMBALL_projectile', { start: 0, end: 0}), + // }) this.anims.create({ key: 'ANAIS_idle', @@ -128,12 +134,12 @@ class Menu extends Phaser.Scene{ repeat: -1, frames: this.anims.generateFrameNumbers('anais', { start: 8, end: 8}), }) - this.anims.create({ - key: 'ANAIS_projectileAttack', - frameRate: 8, - repeat: 0, - frames: this.anims.generateFrameNumbers('ANAIS_projectile', { start: 0, end: 7}), - }) + // this.anims.create({ + // key: 'ANAIS_projectileAttack', + // frameRate: 8, + // repeat: 0, + // frames: this.anims.generateFrameNumbers('ANAIS_projectile', { start: 0, end: 7}), + // }) this.anims.create({ key: 'DARWIN_idle', @@ -147,12 +153,12 @@ class Menu extends Phaser.Scene{ repeat: -1, frames: this.anims.generateFrameNumbers('darwin', { start: 8, end: 8}), }) - this.anims.create({ - key: 'DARWIN_projectileAttack', - frameRate: 8, - repeat: 0, - frames: this.anims.generateFrameNumbers('DARWIN_projectile', { start: 0, end: 0}), - }) + // this.anims.create({ + // key: 'DARWIN_projectileAttack', + // frameRate: 8, + // repeat: 0, + // frames: this.anims.generateFrameNumbers('DARWIN_projectile', { start: 0, end: 0}), + // }) this.anims.create({ key: 'PENNY_attack', @@ -186,6 +192,13 @@ class Menu extends Phaser.Scene{ frames: this.anims.generateFrameNumbers('penny', { start: 24, end: 24}), }) + this.anims.create({ + key: 'NICOLE_attack', + frameRate: 8, + repeat: 0, + frames: this.anims.generateFrameNumbers('nicole', { start: 0, end: 7}), + }) + } update() { diff --git a/src/scenes/Tutorial.js b/src/scenes/Tutorial.js index 10c92b1..65c52d5 100644 --- a/src/scenes/Tutorial.js +++ b/src/scenes/Tutorial.js @@ -35,12 +35,17 @@ class Tutorial extends Phaser.Scene { this.OFFSCREEN_X = -500 // x,y coordinates used to place characters offscreen this.OFFSCREEN_Y = 1000 - + this.hp = HP + this.mp = MP + this.placement = 2 this.FSM_holder = Array(3).fill(0) } create() { + this.background = this.add.image(this.scale.width / 1.5,this.scale.height / 2.5 , 'livingroom').setScale(0.4) + + // parse dialog from JSON file this.dialog = this.cache.json.get('dialog') //console.log(this.dialog) @@ -54,11 +59,43 @@ class Tutorial extends Phaser.Scene { // ready the character dialog images offscreen this.gumball = this.add.sprite(this.OFFSCREEN_X, this.DBOX_Y+8, 'gumball_talk').setOrigin(0, 1) - this.anais = this.add.sprite(this.OFFSCREEN_X, this.DBOX_Y+8, 'anais_talk').setOrigin(0, 1).setScale(0.20) + this.anais = this.add.sprite(this.OFFSCREEN_X, this.DBOX_Y+8, 'anais_talk').setOrigin(0, 1) this.darwin = this.add.sprite(this.OFFSCREEN_X, this.DBOX_Y+8, 'darwin_talk').setOrigin(0, 1) + + this.gumball_char = new Character(this, centerX + tileSize, floorY + tileSize /1.5, 'gumball', 0, this.hp, MP, 30, 'GUMBALL', 'MAGIC', 'physical', 0).setOrigin(0,1) + this.gumball_char.addAttack("SCRATCH", 120, 0); + this.gumball_char.addAttack("MAGIC", 50, 10, 1); + this.anais_char = new Character(this, leftPos +tileSize, floorY +tileSize / 1.5, 'anais', 0, this.hp, MP, 50, 'ANAIS', 'SCIENCE', 'mage', 1).setOrigin(0,1).setFlipX(true) + this.anais_char.addAttack("PUNCH", 25, 0); + this.anais_char.addAttack("SCIENCE", 200, 25, 1); + this.darwin_char = new Character(this, leftPos + tileSize * 2, floorY + tileSize / 1.5, 'darwin', 0, this.hp, MP, 10, 'DARWIN', 'SUPPORT', 'mage', 2).setOrigin(0,1).setFlipX(true) + this.darwin_char.addAttack("SLAP", 40, 0); + this.darwin_char.addAttack("SUPPORT", 40, 15, 1); + + this.gumball_hp = new HealthBar(this, centerX, tileSize - this.placement, this.gumball_char, 0) + this.gumball_mp = new ManaBar(this, centerX + tileSize * 3 + 12, tileSize - this.placement , this.gumball_char, 0) + + // this.anais_hp = new HealthBar(this, centerX, tileSize *1.5 -this.placement *1.5, this.anais_char, 0) + // this.anais_mp = new ManaBar(this, centerX + tileSize * 3 + 12, tileSize *1.5 - this.placement *1.5, this.anais_char, 1) + + // this.darwin_hp = new HealthBar(this, centerX, tileSize * 2 - this.placement *2, this.darwin_char, 2) + // this.darwin_mp = new ManaBar(this, centerX + tileSize * 3 + 12, tileSize * 2 - this.placement *2, this.darwin_char, 1) + this.characters = [ this.gumball_char, this.anais_char, this.darwin_char ] + // this.characters_hp = [ this.gumball_hp, this.anais_hp, this.darwin_hp ] + // this.characters_mp = [ this.gumball_mp, this.anais_mp, this.darwin_mp ] - // input - cursors = this.input.keyboard.createCursorKeys() + + + // place a hidden enemy + this.enemy = new Enemy(this, centerX, -1000, 'penny', 0, HP, MP, 152, 'PENNY').setOrigin(0,1).setFlipX(true) + + // setting up keyboard inputs + this.keys = this.input.keyboard.createCursorKeys() + this.selectionMenu = new SelectionMenu(this, centerX + tileSize * 2, floorY - tileSize * 2, this.characters) + this.selectionMenu.setVisibility(false) + this.selectionMenu.allowSelect = false + this.tutorial = this.add.bitmapText(centerX , 10 , 'font', "Note: Navigate with Arrow Keys", 8).setOrigin(0.5) + // start first dialog conversation this.typeText() @@ -67,13 +104,73 @@ class Tutorial extends Phaser.Scene { update() { // check for spacebar press - if(Phaser.Input.Keyboard.JustDown(cursors.space) && !this.dialogTyping) { - this.typeText() // trigger dialog + const { left, right, up, down, space, shift } = this.keys + this.FSM_holder[0].step() + this.FSM_holder[1].step() + this.FSM_holder[2].step() + if(!this.dialogTyping) { + if (this.dialogConvo == 1 && this.dialogLine == 3){ + // console.log('we are now discussing the tutorial') + this.selectionMenu.allowSelect = true + this.selectionMenu.setVisibility(true) + this.tutorial.setVisible(true) + // add pngs and gifs describing tutorial + } + if (this.dialogConvo == 1 && this.dialogLine == 5){ + // tutorial + if (this.selectionMenu.current_selection == 2){ + + if (Phaser.Input.Keyboard.JustDown(right)){ + this.selectionMenu.charChange(1) + this.typeText() + + } + if (Phaser.Input.Keyboard.JustDown(left)){ + this.selectionMenu.charChange(-1) + this.typeText() + } + + } + } + else if (Phaser.Input.Keyboard.JustDown(space)){ + this.typeText() // trigger dialog + } + + } - if (this.dialogConvo == 1 && this.dialogLine == 3){ - console.log('we are now discussing the tutorial') - // add pngs and gifs describing tutorial + + + + if (this.selectionMenu.allowSelect) { + if (Phaser.Input.Keyboard.JustDown(space)){ + this.selectionMenu.select() + } + if (this.selectionMenu.current_selection == 0){ + if (Phaser.Input.Keyboard.JustDown(right)){ + this.selectionMenu.attackChange(1) + } + if (Phaser.Input.Keyboard.JustDown(left)){ + this.selectionMenu.attackChange(-1) + } + } + + if (this.selectionMenu.current_selection == 2){ + if (Phaser.Input.Keyboard.JustDown(right)){ + this.selectionMenu.charChange(1) + } + if (Phaser.Input.Keyboard.JustDown(left)){ + this.selectionMenu.charChange(-1) + } + } + + if (Phaser.Input.Keyboard.JustDown(up)){ + this.selectionMenu.lookChoice(1) + } + if (Phaser.Input.Keyboard.JustDown(down)){ + this.selectionMenu.lookChoice(-1) + } } + } typeText() { @@ -179,4 +276,64 @@ class Tutorial extends Phaser.Scene { this.dialogLastSpeaker = this.dialogSpeaker // set past speaker } } + + checkActive(){ + let availableChar = Array(0); + for (let i = 0; i < this.characters.length; i++) { + if (!this.characters[i].hasAttacked && !this.characters[i].collapsed){ + // if character not collapsed nor attacked put into array + availableChar.push(this.characters[i].index) + } + } + // if availableChar's length == 0 then end turn + if (availableChar.length == 0){ + this.changeTurn() + // reset the move amount + availableChar = this.resetAttacks() + } + return availableChar + } + + resetAttacks() { + let availableCharacters = Array(0) + for (let i = 0; i < this.characters.length; i++) { + // if this character has not attacked + if (!this.characters[i].collapsed){ + this.characters[i].hasAttacked = false + availableCharacters.push(this.characters[i].index) + } + } + return availableCharacters + } + + changeTurn(){ + // when turn is changed reset the count of how many times character can be used + if (this.player_turn == false){ + this.selectionMenu.moves = 3 + + this.player_turn = true + this.selectionMenu.setVisibility(true) + // this.selectionMenu.allowSelect = true + } + else if (this.player_turn == true){ + this.player_turn = false + this.selectionMenu.setVisibility(false) + // this.selectionMenu.allowSelect = true + } + + } + + checkLiving(){ + // function to update living characters + let livingCharacters = Array(3).fill(-1); + + for (let i = 0; i < this.characters.length; i++) { + if (!this.characters[i].collapsed){ + // if character not collapsed put into array + livingCharacters[i] = this.characters[i].index + } + } + return livingCharacters + + } } \ No newline at end of file