CyberLord09 / CSSE1_Final

MIT License
0 stars 0 forks source link

HP Bar and Player change(parallel players) #8

Open TianbinLiu opened 1 month ago

TianbinLiu commented 1 month ago

Player change

Image Image

As you see, the player will change to a zombie when it hits the item block.

At first, we try to achieve that by removing the original player(Mario) and replacing it with our zombie player during the gameplay. We tried, and we failed. Because of the time limit, we don't want to spend more time on this hard way. So according to Mr.M's advice, we plan to make the "parallel players".

Parallel players

Image Instead of replacing the player, we plan to add two players to our level and make one, the zombie player, invisible in the beginning.

  1. We create PlayerZombie.js for our zombie player and PlayerBoss.js for the Mario player(therefore we don't need to change the PlayerHills.js)

  2. And because our zombie sprite sheet has only one direction, so we added a new Base Player file, PlayerBaseOneD.js, for sprites that only have one direction.

The only difference between PlayerBaseOneD.js and PlayerBase.js is we added a if-statement to the updateAnimation() function.

    if(this.state.direction == "left"){
          this.canvas.style.transform = 'scaleX(-1)';
    }
    else{
          this.canvas.style.transform = 'scaleX(1)';
    }
    updateAnimation() {
        switch (this.state.animation) {
            case 'idle':
                if(this.state.direction == "left"){
                    this.canvas.style.transform = 'scaleX(-1)';
                }
                else{
                    this.canvas.style.transform = 'scaleX(1)';
                }
                this.setSpriteAnimation(this.playerData.idle);
                break;
//...code hidden
        }
    }

The PlayerZombie.js extends the new base file PlayerBaseOneD.js we created instead of extending the old PlayerBase.js.

  1. To make the player invisible, we create a new property to the constructor called "this.invisible" for both player files and we set it equal to true.

    constructor(canvas, image, data) {
        super(canvas, image, data);
    
        this.invisible = true;
    
        // Goomba variables, deprecate?
        this.timer = false;
        GameEnv.invincible = false; // Player is not invincible 
    }

And then we overwrite the function draw() and add an if-statement to it so that when "this.invisible"=true, the player image won't draw/won't appear and therefore the player is invisible.

        if (!this.invisible) {
            this.ctx.fillText(this.name, 0, this.canvas.height / 4);
            this.ctx.drawImage(
                this.image,
                this.frameX * this.spriteWidth,
                this.frameY * this.spriteHeight,
                this.spriteWidth,
                this.spriteHeight,
                0,
                0,
                this.canvas.width,
                this.canvas.height
            );
        }
  1. Last, we create a new file "BossItem.js" for our itemBlock. Everything is the same except we change "GameControl.startRandomEvent("game");" to "GameControl.startRandomEvent("zombie");"

startRandomEvent("game") is the global event includes time stop, background change, and randomly kill a Goomba in the Hill level.

startRandomEvent("zombie"); is the new event we create to change the "this.invisible"

So that when Mario player hits our itemBlock, it will run the function startRandomEvent("zombie"); and change "this.invisible" to false and let the zombie player appear and the Mario player disappear/invisible.

Hypernova101 commented 1 month ago

2 Week Sprint 2

We made two changes to our Boss Level in this 2 week sprint. This issue will focus on creating the HP Bar and adding it to to the Boss, and as a bonus, helping our teammates add it to the player in the Ancient Greece Level.

Step 1: Creating the Canvas for the HP Bar

In Boss.js

this.maxHp = 100; // Maximum health points
this.currentHp = 100; // Current health points
this.hpBar = document.createElement("canvas");
this.hpBar.width = 100; 
this.hpBar.height = 15;
document.querySelector("#canvasContainer").appendChild(this.hpBar);

Originally, the canvas was somehow set to be 800 x 300, and when we drew it, (we'll get to that later), it looked like this.

Image

We noticed this when we tried to add a border radius, because it only applied to the top left corner. So, we had to add the .width and .height to fit the canvas so that we could actually style it and make it look nice.

Step 2: Drawing the HP Bar

We created a function called drawHPBox which gets called repeatedly to draw the HPBox on the screen.

In Boss.js

drawHpBox() { //Hp box

    // Position and size of the health bar
    const hpBarWidth  =  this.hpBar.width; // The width of the health bar matches the boss's width
    const hpBarHeight  =  this.hpBar.height; // A fixed height for the health bar
    const hpBarX  = (this.x  +  this.canvasWidth/2  -  this.hpBar.width/2); // Position above the boss
    const hpBarY  =  this.y  -  this.canvasHeight/40; // 20 pixels above the boss
    this.hpBar.id  =  "hpBar"; // Calculate health percentage
    const hpPercentage  =  this.currentHp  /  this.maxHp;

    this.hpBar.getContext('2d').fillStyle  =  'gray'; // Draw the background (gray)
    this.hpBar.getContext('2d').fillRect(0, 0, hpBarWidth, hpBarHeight); // Draw the health bar (green, based on current health)
    this.hpBar.getContext('2d').fillStyle  =  'green';
    this.hpBar.getContext('2d').fillRect(0, 0, hpBarWidth  *  hpPercentage, hpBarHeight);

    this.hpBar.style.position  =  'absolute'; //code from Flag.js, define the style of the Hp Bar
    this.hpBar.style.left  =  `${hpBarX}px`;
    this.hpBar.style.top  =  `${hpBarY}px`;
    this.hpBar.style.borderRadius  =  '5px';
    this.hpBar.style.width  =  `${hpBarWidth}px`;
    this.hpBar.style.height  =  `${hpBarHeight}px`;
    this.hpBar.style.border  =  '2px solid black';
}

HPBarHeight and HPBarWidth determine the actual dimensions of the bar, while HPBarX and HPBarY change based on the position of the boss, so that the HPBar follows the boss around. Finally, the HP Percentage is a ratio of the current hp and the max hp (100), which determines how the health is shown on the bar.

We used the fill style and fill rect built in functions to draw the HP Bar into the Canvas. We set a background color of gray, and an overlap color with a higher z index of green. The idea is that as the boss loses health, the percentage of green in the bar slowly reduces and the gray shows up, which indicates that the boss has lost HP.

Step 3: Reducing the HP

Finally, we had to reduce the HP whenever a collision occurs with the player and the boss. Naturally, this code will exist in the collision action section.

else if(this.collisionData.touchPoints.other.bottom  &&  this.immune  ==  0){
    if(this.currentHp  ==  0){
        this.state.animation  =  "death";
        if(!this.state.isDying  &&  this.state.animation  ==  "death"){
            this.frameX  =  0;
        }
        this.state.isDying  =  true;
        GameEnv.invincible  =  true;
        GameEnv.goombaBounce  =  true;
        GameEnv.playSound("goombaDeath");
    }
else{
    this.currentHp  -=  20;
    GameEnv.goombaBounce  =  true;
    }
}

Here, we check for collisions with the player. First, we check if the currentHp is 0 (which means that the boss has been hit 5 times). If the currentHP is 0, we set the current animation state to be death. We then set the isDying state, invincible, goombaBounce to be true. Then, we play the GoombaDeath sound as the boss dies.

Else, we reduce the currentHP by 20, and in the loop, the drawHPBox function gets called again, so the amount of Green in the Bar gets reduced and the Gray shows.

Step 4: Destroying the HP Bar

This part is rather simple.

When we remove the Boss, we remove the HPBar along with it.

this.destroy();
this.hpBar.remove();

With these changes, we now have a working HP Bar.

Image

Hypernova101 commented 1 month ago

Parallax Changes

This was one of the challenges given to us by another team. We decided to make the background a parallax and add a icon at the top to resemble the narwal in thr winter level.

Step 1: Add Parallax to the Background

With the new and updated Parallax version that Mr. Mortensen made, integration of Parallax becomes easier.

We edited everything in GameSetup.js to add parallax features.

First, we added parallax features to the source in GameSetup.js

boss: { src: "/images/platformer/backgrounds/BossBackground.png", parallaxSpeed: 0.4, moveOnKeyAction: true

And, we changed the class from Background to be BackgroundParallax in the bossgameobjects array.

{ name: 'bossbackground', id: 'background', class: BackgroundParallax, data: this.assets.backgrounds.boss },

Now, the background moves with the player.

Step 2: Add a moving icon at the top

Like the background, we added a parallax feature in the source to the devil image.

devil: {src: "/images/platformer/backgrounds/devil.png", parallaxSpeed: 2 },

Then, we edited the bossgameobjects array by changing th class to BackgroundParallax as well.

{ name: 'devil', id: 'devil', class:BackgroundParallax, data: this.assets.backgrounds.devil},

Now, we have a moving background and moving icon on the boss level.