diff --git a/assets/js/platformer3x/BackgroundSnow.js b/assets/js/platformer3x/BackgroundSnow.js new file mode 100644 index 00000000..6a323e17 --- /dev/null +++ b/assets/js/platformer3x/BackgroundSnow.js @@ -0,0 +1,39 @@ +import Background from './Background.js'; + +export class BackgroundSnow extends Background { + constructor(canvas, image, data) { + super(canvas, image, data); + + this.parallaxSpeed = 0.3; // Speed for vertical parallax scrolling + } + + // Update method to handle vertical scrolling + update() { + this.y += this.parallaxSpeed; // Move vertically based on parallax speed + super.update(); + + // Reset the position once the entire image has scrolled through the canvas + if (this.y >= this.image.height) { + this.y -= this.image.height; // Reset to the top of the image + } + } + + // Draw method to render the background image vertically + draw() { + this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); + + // Calculate the vertical positions for drawing + const firstImageY = this.y % this.image.height; + const secondImageY = firstImageY - this.image.height; + + // Draw the first image + this.ctx.drawImage(this.image, 0, firstImageY, this.canvas.width, this.image.height); + + // Draw the second image above the first one for seamless scrolling + this.ctx.drawImage(this.image, 0, secondImageY, this.canvas.width, this.image.height); + + super.draw(); + } +} + +export default BackgroundSnow; \ No newline at end of file diff --git a/assets/js/platformer3x/BackgroundWinter.js b/assets/js/platformer3x/BackgroundWinter.js new file mode 100644 index 00000000..78face16 --- /dev/null +++ b/assets/js/platformer3x/BackgroundWinter.js @@ -0,0 +1,25 @@ +import GameEnv from './GameEnv.js'; +import Background from './Background.js'; + +export class BackgroundWinter extends Background { + constructor(canvas, image, data) { + super(canvas, image, data); + + this.parallaxSpeed = 0.4; + } + + // speed is used to background parallax behavior + update() { + this.speed = GameEnv.backgroundDirection * this.parallaxSpeed; + super.update(); + } + + //Cause of limited bg cutout, keeping just incase it causes issues later + draw() { + this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); + super.draw(); + } + +} + +export default BackgroundWinter; \ No newline at end of file diff --git a/assets/js/platformer3x/Cabin.js b/assets/js/platformer3x/Cabin.js new file mode 100644 index 00000000..1a2e0d10 --- /dev/null +++ b/assets/js/platformer3x/Cabin.js @@ -0,0 +1,35 @@ +import GameEnv from './GameEnv.js'; +import GameObject from './GameObject.js'; +export class Cabin extends GameObject { + constructor(canvas, image, data) { + super(canvas, image, data); + } + // Required, but no update action + update() { + } + // Draw position is always 0,0 + draw() { + this.ctx.drawImage(this.image, 0, 0, this.canvas.width, this.canvas.height); + } + // Set Cabin position + size() { + // Formula for Height should be on constant ratio, using a proportion of 832 + const scaledHeight = GameEnv.innerHeight * (600/832); + // Formula for Width is scaled: scaledWidth/scaledHeight == this.width/this.height + const scaledWidth = scaledHeight * this.aspect_ratio; + const cabinX = .80 * GameEnv.innerWidth; + const cabinY = (GameEnv.bottom - (.18 * scaledHeight)); + // set variables used in Display and Collision algorithms + this.bottom = cabinY; + this.collisionHeight = scaledHeight; + this.collisionWidth = scaledWidth; + //this.canvas.width = this.width; + //this.canvas.height = this.height; + this.canvas.style.Width = `${scaledWidth}px`; + this.canvas.style.Height = `${scaledHeight}px`; + this.canvas.style.position = 'absolute'; + this.canvas.style.left = `${cabinX}px`; + this.canvas.style.top = `${cabinY}px`; + } +} +export default Cabin; \ No newline at end of file diff --git a/assets/js/platformer3x/GameEnv.js b/assets/js/platformer3x/GameEnv.js index 1fa5a745..d31e2e7d 100644 --- a/assets/js/platformer3x/GameEnv.js +++ b/assets/js/platformer3x/GameEnv.js @@ -209,6 +209,21 @@ export class GameEnv { GameEnv.backgroundDirection = 1; } break; + case "s": + if (keys.includes("a") && keys.includes("s")) { + // If both "a" and "s" are clicked + if (GameEnv.player?.x > 2) { + GameEnv.backgroundDirection = -5; + } + } else if (keys.includes("d") && keys.includes("s")) { + // If both "d" and "s" are clicked + if (GameEnv.player?.x < (GameEnv.innerWidth - 2)) { + GameEnv.backgroundDirection = 5; + } + } else { + GameEnv.backgroundDirection = 0; + } + break; default: GameEnv.backgroundDirection = 0; break; diff --git a/assets/js/platformer3x/GameSetup.js b/assets/js/platformer3x/GameSetup.js index 4021885a..3759d909 100644 --- a/assets/js/platformer3x/GameSetup.js +++ b/assets/js/platformer3x/GameSetup.js @@ -7,24 +7,31 @@ import BackgroundHills from './BackgroundHills.js'; import BackgroundMountains from './BackgroundMountains.js'; import BackgroundTransitions from './BackgroundTransitions.js'; import BackgroundClouds from './BackgroundClouds.js'; +import BackgroundWinter from './BackgroundWinter.js'; +import BackgroundSnow from './BackgroundSnow.js'; import Platform from './Platform.js'; import JumpPlatform from './JumpPlatform.js'; import Player from './Player.js'; import PlayerHills from './PlayerHills.js'; +import PlayerWinter from './PlayerWinter.js'; import PlayerMini from './PlayerMini.js'; import PlayerBase from './PlayerBase.js'; import Tube from './Tube.js'; import Tube1 from './Tube1.js'; import Tree from './Tree.js'; +import Cabin from './Cabin.js'; import Goomba from './Goomba.js'; import FlyingGoomba from './FlyingGoomba.js'; import BlockPlatform from './BlockPlatform.js'; import Mushroom from './Mushroom.js'; import Coin from './Coin.js'; +import Snowflake from './Snowflake.js'; import FlyingUFO from './FlyingUFO.js'; import Alien from './Alien.js'; import GameControl from './GameControl.js'; import Enemy from './Enemy.js'; +import Owl from './Owl.js'; +import Snowman from './Snowman.js'; import Cerberus from './Cerberus.js'; import PlayerGreece from './PlayerGreece.js'; import Flag from './Flag.js'; @@ -207,12 +214,15 @@ const GameSetup = { tube: { src: "/images/platformer/obstacles/blue-tube-up.png", hitbox: { widthPercentage: 0.5, heightPercentage: 0.5} }, + cabin: { src: "/images/platformer/obstacles/cabin.png", + hitbox: { widthPercentage: 0.5, heightPercentage: 0.5} + }, + coin: { src: "/images/platformer/obstacles/coin.png"}, + snowflake: { src: "/images/platformer/obstacles/snowflake.png"}, tubeD: { src: "/images/platformer/obstacles/blue-tube.png", hitbox: { widthPercentage: 0.5, heightPercentage: 0.5} }, star: { src: "/images/platformer/obstacles/star.png"}, - coin: { src: "/images/platformer/obstacles/coin.png"}, - star: { src: "/images/platformer/obstacles/star.png"}, tree: { src: "/images/platformer/obstacles/tree.png", hitbox: { widthPercentage: 0.5, heightPercentage: 0.5} }, @@ -222,6 +232,8 @@ const GameSetup = { }, platforms: { grass: { src: "/images/platformer/platforms/grass.png" }, + snowyfloor: { src: "/images/platformer/platforms/snowyfloor.png" }, + snowywood: { src: "/images/platformer/platforms/snowywood.png" }, alien: { src: "/images/platformer/platforms/alien.png" }, bricks: { src: "/images/platformer/platforms/brick_wall.png" }, lava: { src: "/images/platformer/platforms/lava.jpg" }, @@ -250,8 +262,11 @@ const GameSetup = { loading: { src: "/images/platformer/backgrounds/greenscreen.png" }, complete: { src: "/images/platformer/backgrounds/OneStar.png" }, complete2: { src: "/images/platformer/backgrounds/TwoStar.png" }, + complete3: {src: "/images/platformer/backgrounds/ThreeStar.png" }, + end: { src: "/images/platformer/backgrounds/Congratulations!!!.png" }, + winter: {src: "/images/platformer/backgrounds/winter.png" }, + snow: {src: "/images/platformer/backgrounds/snowfall.png" }, mini: { src: "/images/platformer/backgrounds/mini.png" }, - end: { src: "/images/platformer/backgrounds/Congratulations!!!.png" } }, players: { mario: { @@ -277,6 +292,30 @@ const GameSetup = { right: { row: 10, frames: 15 }, }, hitbox: { widthPercentage: 0.3, heightPercentage: 0.8 } + }, + whitemario: { + src: "/images/platformer/sprites/white_mario.png", + width: 256, + height: 256, + scaleSize: 80, + speedRatio: 0.7, + idle: { + left: { row: 1, frames: 15 }, + right: { row: 0, frames: 15}, + }, + walk: { + left: { row: 3, frames: 7 }, + right: { row: 2, frames: 7 }, + }, + run: { + left: { row: 5, frames: 15 }, + right: { row: 4, frames: 15 }, + }, + jump: { + left: { row: 11, frames: 15 }, + right: { row: 10, frames: 15 }, + }, + hitbox: { widthPercentage: 0.3, heightPercentage: 0.8 } }, monkey: { src: "/images/platformer/sprites/monkey.png", @@ -340,6 +379,27 @@ const GameSetup = { xPercentage: 0.6, hitbox: { widthPercentage: 0.0, heightPercentage: 0.2} }, + Snowman: { + src: "/images/platformer/sprites/snowman.png", + width: 308, + height: 327, + scaleSize: 60, + speedRatio: 0.7, + xPercentage: 0.6, + hitbox: { widthPercentage: 0.0, heightPercentage: 0.2}, + wa: {row: 0, frames: 0}, // Up-Left Movement + wd: {row: 0, frames: 0}, // Up-Right Movement + a: { row: 0, frames: 0, idleFrame: { column: 0, frames: 0 } }, // Left Movement + s: {row: 0, frames: 0}, // Stop the movement + d: { row: 0, frames: 0, idleFrame: { column: 0, frames: 0 } }, // Right Movement + }, + Owl: { + src: "/images/platformer/sprites/owl.png", + width: 499, + height: 500, + scaleSize: 60, + speedRatio: 0.8, + }, flyingGoomba: { src: "/images/platformer/sprites/flying-goomba.png", width: 448, @@ -644,6 +704,43 @@ const GameSetup = { // Space Game Level added to the GameEnv ... new GameLevel( {tag: "mini", callback: this.playerOffScreenCallBack, objects: miniGameObjects} ); + const winterObjects = [ + // GameObject(s), the order is important to z-index... + { name: 'winter', id: 'background', class: BackgroundWinter, data: this.assets.backgrounds.winter }, + { name: 'snow', id: 'background', class: BackgroundSnow, data: this.assets.backgrounds.snow }, + { name: 'snowyfloor', id: 'platform', class: Platform, data: this.assets.platforms.snowyfloor }, + { name: 'blocks', id: 'jumpPlatform', class: BlockPlatform, data: this.assets.platforms.snowywood, xPercentage: 0.2, yPercentage: 0.82 }, + { name: 'blocks', id: 'jumpPlatform', class: BlockPlatform, data: this.assets.platforms.snowywood, xPercentage: 0.2368, yPercentage: 0.82 }, + { name: 'blocks', id: 'jumpPlatform', class: BlockPlatform, data: this.assets.platforms.snowywood, xPercentage: 0.2736 , yPercentage: 0.82 }, + { name: 'blocks', id: 'jumpPlatform', class: BlockPlatform, data: this.assets.platforms.snowywood, xPercentage: 0.3104, yPercentage: 0.82 }, + { name: 'blocks', id: 'jumpPlatform', class: BlockPlatform, data: this.assets.platforms.snowywood, xPercentage: 0.3472, yPercentage: 0.82 }, + { name: 'blocks', id: 'jumpPlatform', class: BlockPlatform, data: this.assets.platforms.snowywood, xPercentage: 0.384, yPercentage: 0.74 }, + { name: 'blocks', id: 'jumpPlatform', class: BlockPlatform, data: this.assets.platforms.snowywood, xPercentage: 0.4208, yPercentage: 0.66 }, + { name: 'blocks', id: 'jumpPlatform', class: BlockPlatform, data: this.assets.platforms.snowywood, xPercentage: 0.5090, yPercentage: 0.56 }, + { name: 'blocks', id: 'jumpPlatform', class: BlockPlatform, data: this.assets.platforms.snowywood, xPercentage: 0.5090, yPercentage: 0.48 }, + { name: 'blocks', id: 'jumpPlatform', class: BlockPlatform, data: this.assets.platforms.snowywood, xPercentage: 0.5090, yPercentage: 0.40 }, + { name: 'blocks', id: 'jumpPlatform', class: BlockPlatform, data: this.assets.platforms.snowywood, xPercentage: 0.5090, yPercentage: 0.32 }, + { name: 'blocks', id: 'jumpPlatform', class: BlockPlatform, data: this.assets.platforms.snowywood, xPercentage: 0.69, yPercentage: 0.76 }, + { name: 'blocks', id: 'jumpPlatform', class: BlockPlatform, data: this.assets.platforms.snowywood, xPercentage: 0.655, yPercentage: 0.68 }, + { name: 'blocks', id: 'jumpPlatform', class: BlockPlatform, data: this.assets.platforms.snowywood, xPercentage: 0.62, yPercentage: 0.68 }, + { name: 'blocks', id: 'jumpPlatform', class: BlockPlatform, data: this.assets.platforms.snowywood, xPercentage: 0.72, yPercentage: 0.76 }, + { name: 'blocks', id: 'jumpPlatform', class: BlockPlatform, data: this.assets.platforms.snowywood, xPercentage: 0.755, yPercentage: 1 }, + { name: 'blocks', id: 'jumpPlatform', class: BlockPlatform, data: this.assets.platforms.snowywood, xPercentage: 0.755, yPercentage: 0.92 }, + { name: 'blocks', id: 'jumpPlatform', class: BlockPlatform, data: this.assets.platforms.snowywood, xPercentage: 0.755, yPercentage: 0.84 }, + { name: 'snowflake', id: 'snowflake', class: Snowflake, data: this.assets.obstacles.snowflake, xPercentage: 0.2100, yPercentage: 0.75 }, + { name: 'snowflake', id: 'snowflake', class: Snowflake, data: this.assets.obstacles.snowflake, xPercentage: 0.2619, yPercentage: 0.75 }, + { name: 'snowflake', id: 'snowflake', class: Snowflake, data: this.assets.obstacles.snowflake, xPercentage: 0.3136, yPercentage: 0.75 }, + { name: 'owl', id: 'owl', class: Owl, data: this.assets.enemies.Owl, xPercentage: 0.3, minPosition: 0.05}, + { name: 'owl', id: 'owl', class: Owl, data: this.assets.enemies.Owl, xPercentage: 0.8, minPosition: 0.05}, + { name: 'snowman', id: 'snowman', class: Snowman, data: this.assets.enemies.Snowman, xPercentage: 0.2, minPosition: 0.1, difficulties: ["normal", "hard", "impossible"]}, + { name: 'snowman', id: 'snowman', class: Snowman, data: this.assets.enemies.Snowman, xPercentage: 0.35, minPosition: 0.1, difficulties: ["normal", "hard", "impossible"]}, + { name: 'snowman', id: 'snowman', class: Snowman, data: this.assets.enemies.Snowman, xPercentage: 0.5, minPosition: 0.1, difficulties: ["normal", "hard", "impossible"]}, + { name: 'mario', id: 'player', class: PlayerWinter, data: this.assets.players.whitemario }, + { name: 'cabin', id: 'cabin', class: Cabin, data: this.assets.obstacles.cabin }, + { name: 'complete', id: 'background', class: BackgroundTransitions, data: this.assets.backgrounds.complete }, + ]; + // Winter Game Level added to the GameEnv ... + new GameLevel( {tag: "winter", callback: this.playerOffScreenCallBack, objects: winterObjects} ); // Game Over Level definition... const endGameObjects = [ { name:'background', class: Background, id: 'background', data: this.assets.backgrounds.end} diff --git a/assets/js/platformer3x/Owl.js b/assets/js/platformer3x/Owl.js new file mode 100644 index 00000000..6e4e131b --- /dev/null +++ b/assets/js/platformer3x/Owl.js @@ -0,0 +1,84 @@ +import Character from './Character.js'; +import FlyingGoomba from './FlyingGoomba.js'; +import GameEnv from './GameEnv.js'; + +export class Snowman extends FlyingGoomba { + + // constructors sets up Character object + constructor(canvas, image, data, xPercentage, yPercentage, name, minPosition){ + super(canvas, image, data); + + //Unused but must be defined + this.name = name; + this.yPercentage = yPercentage; + + //Initial Position of Goomba + this.x = xPercentage * GameEnv.innerWidth; + this.y = 0.4 * GameEnv.innerHeight; + + //Access in which a Goomba can travel + this.minPosition = minPosition * GameEnv.innerWidth; + this.maxPosition = this.x + xPercentage * GameEnv.innerWidth; + + this.immune = 0; + + // Define Speed of Enemy + if (GameEnv.difficulty === "normal") { + this.speed = this.speed; + } else if (GameEnv.difficulty === "hard") { + this.speed = this.speed * 2; + } else if (GameEnv.difficulty === "easy") { + this.speed = this.speed * 1; + } else if (GameEnv.difficulty === "impossible") { + this.speed = this.speed * 3; + } +} + + update() { + super.update(); + + if (this.x <= this.minPosition || (this.x + this.canvasWidth >= this.maxPosition) || this.x > (GameEnv.innerWidth - 100) ) { + this.speed = -this.speed; + } + + if (this.speed < 0) { + this.canvas.style.transform = 'scaleX(1)'; + } else { + this.canvas.style.transform = 'scaleX(-1)'; + } + + this.dropGoomba(); + + // Every so often change direction + if (Math.random() < 0.005) { + this.speed = Math.random() < 0.5 ? -this.speed : this.speed; + } + + //Chance for Goomba to turn Gold + if (["normal","hard"].includes(GameEnv.difficulty)) { + if (Math.random() < 0.00001) { + this.canvas.style.filter = 'brightness(1000%)'; + this.immune = 1; + } + } + + //Immunize Goomba & Texture It + if (GameEnv.difficulty === "hard") { + this.canvas.style.filter = "invert(100%)"; + this.canvas.style.scale = 1.25; + this.immune = 1; + } else if (GameEnv.difficulty === "impossible") { + this.canvas.style.filter = 'brightness(1000%)'; + this.canvas.style.transform = "rotate(180deg)" + this.immune = 1; + } + + // Move the enemy + this.x -= this.speed; + } + + // Player action on collisions +} + + +export default Snowman; \ No newline at end of file diff --git a/assets/js/platformer3x/Player.js b/assets/js/platformer3x/Player.js index 4c2a99e1..11591a8c 100644 --- a/assets/js/platformer3x/Player.js +++ b/assets/js/platformer3x/Player.js @@ -233,7 +233,8 @@ export class Player extends Character { collisionAction() { // Tube collision check if (this.collisionData.touchPoints.other.id === "tube" - || this.collisionData.touchPoints.other.id === "tree") { + || this.collisionData.touchPoints.other.id === "tree" + || this.collisionData.touchPoints.other.id === "cabin") { // Collision with the left side of the Tube if (this.collisionData.touchPoints.other.left) { @@ -263,7 +264,7 @@ export class Player extends Character { // Goomba collision check // Checks if collision touchpoint id is either "goomba" or "flyingGoomba" - if (this.collisionData.touchPoints.other.id === "goomba" || this.collisionData.touchPoints.other.id === "flyingGoomba" || this.collisionData.touchPoints.other.id === "flyingUFO" || this.collisionData.touchPoints.other.id === "alien" ) { + if (this.collisionData.touchPoints.other.id === "goomba" || this.collisionData.touchPoints.other.id === "flyingGoomba" || this.collisionData.touchPoints.other.id === "Snowman" || this.collisionData.touchPoints.other.id === "Owl" || this.collisionData.touchPoints.other.id === "flyingUFO" || this.collisionData.touchPoints.other.id === "alien" ) { if (GameEnv.invincible === false) { GameEnv.goombaInvincible = true; // Collision with the left side of the Enemy diff --git a/assets/js/platformer3x/PlayerBase.js b/assets/js/platformer3x/PlayerBase.js index 4a34eddb..f92bb159 100644 --- a/assets/js/platformer3x/PlayerBase.js +++ b/assets/js/platformer3x/PlayerBase.js @@ -376,4 +376,4 @@ export class PlayerBase extends Character { } -export default PlayerBase; \ No newline at end of file +export default PlayerBase; diff --git a/assets/js/platformer3x/PlayerWinter.js b/assets/js/platformer3x/PlayerWinter.js new file mode 100644 index 00000000..2dd5e84e --- /dev/null +++ b/assets/js/platformer3x/PlayerWinter.js @@ -0,0 +1,124 @@ +import GameEnv from './GameEnv.js'; +import PlayerBase from './PlayerBase.js'; +import GameControl from './GameControl.js'; + +/** + * @class PlayerHills class + * @description PlayerHills.js key objective is to eent the user-controlled character in the game. + * + * The Player class extends the Character class, which in turn extends the GameObject class. + * Animations and events are activated by key presses, collisions, and gravity. + * WASD keys are used by user to control The Player object. + * + * @extends PlayerBase + */ +export class PlayerWinter extends PlayerBase { + + /** GameObject instantiation: constructor for PlayerHills object + * @extends Character + * @param {HTMLCanvasElement} canvas - The canvas element to draw the player on. + * @param {HTMLImageElement} image - The image to draw the player with. + * @param {Object} data - The data object containing the player's properties. + */ + constructor(canvas, image, data) { + super(canvas, image, data); + + // Goomba variables, deprecate? + this.timer = false; + GameEnv.invincible = false; // Player is not invincible + } + + /** + * @override + * gameLoop helper: Update Player jump height, replaces PlayerBase updateJump using settings from GameEnv + */ + updateJump() { + let jumpHeightFactor; + if (GameEnv.difficulty === "easy") { + jumpHeightFactor = 0.50; + } else if (GameEnv.difficulty === "normal") { + jumpHeightFactor = 0.40; + } else { + jumpHeightFactor = 0.30; + } + this.setY(this.y - (this.bottom * jumpHeightFactor)); + } + + /** + * @override + * gameLoop: Watch for Player collision events + */ + handleCollisionStart() { + super.handleCollisionStart(); // calls the super class method + // adds additional collision events + this.handleCollisionEvent("cabin"); + this.handleCollisionEvent("snowman"); + } + + /** + * @override + * gameloop: Handles additional Player reaction / state updates to the collision for game level + */ + handlePlayerReaction() { + super.handlePlayerReaction(); // calls the super class method + // handles additional player reactions + switch (this.state.collision) { + case "cabin": + // 1. Caught in tube + if (this.collisionData.touchPoints.this.top && this.collisionData.touchPoints.other.bottom) { + // Position player in the center of the tube + this.x = this.collisionData.newX; + // Using natural gravity wait for player to reach floor + if (Math.abs(this.y - this.bottom) <= GameEnv.gravity) { + // Force end of level condition + this.x = GameEnv.innerWidth + 1; + } + // 2. Collision between player right and tube + } else if (this.collisionData.touchPoints.this.right) { + this.state.movement.right = false; + this.state.movement.left = true; + // 3. Collision between player left and tube + } else if (this.collisionData.touchPoints.this.left) { + this.state.movement.left = false; + this.state.movement.right = true; + } + break; + case "snowman": // Note: Goomba.js and Player.js could be refactored + // 1. Player jumps on goomba, interaction with Goomba.js + if (this.collisionData.touchPoints.this.top && this.collisionData.touchPoints.other.bottom && this.state.isDying == false) { + // GoombaBounce deals with player.js and goomba.js + if (GameEnv.goombaBounce === true) { + GameEnv.goombaBounce = false; + this.y = this.y - 100; + } + if (GameEnv.goombaBounce1 === true) { + GameEnv.goombaBounce1 = false; + this.y = this.y - 250 + } + // 2. Player touches goomba sides of goomba + } else if (this.collisionData.touchPoints.this.right || this.collisionData.touchPoints.this.left) { + if (GameEnv.difficulty === "normal" || GameEnv.difficulty === "hard") { + if (this.state.isDying == false) { + this.state.isDying = true; + this.canvas.style.transition = "transform 0.5s"; + this.canvas.style.transform = "rotate(-90deg) translate(-26px, 0%)"; + GameEnv.playSound("PlayerDeath"); + setTimeout(async() => { + await GameControl.transitionToLevel(GameEnv.levels[GameEnv.levels.indexOf(GameEnv.currentLevel)]); + }, 900); + } + } else if (GameEnv.difficulty === "easy" && this.collisionData.touchPoints.this.right) { + this.x -= 10; + } else if (GameEnv.difficulty === "easy" && this.collisionData.touchPoints.this.left) { + this.x += 10; + } + + } + break; + } + + } + +} + +export default PlayerWinter; \ No newline at end of file diff --git a/assets/js/platformer3x/Snowflake.js b/assets/js/platformer3x/Snowflake.js new file mode 100644 index 00000000..6868588e --- /dev/null +++ b/assets/js/platformer3x/Snowflake.js @@ -0,0 +1,72 @@ +import GameControl from './GameControl.js'; +import GameEnv from './GameEnv.js'; +import GameObject from './GameObject.js'; + +export class Snowflake extends GameObject { + constructor(canvas, image, data, xPercentage, yPercentage) { + super(canvas, image, data, 0.5, 0.5); + this.snowflakeX = xPercentage * GameEnv.innerWidth; + this.snowflakeY = yPercentage; + this.size(); + } + + // Required, but no update action + update() { + this.collisionChecks() + } + + // Draw position is always 0,0 + draw() { + // Save the current transformation matrix + this.ctx.save(); + + // Rotate the canvas 90 degrees to the left + this.ctx.rotate(-Math.PI / 2); + + // Draw the image at the rotated position (swap x and y) + this.ctx.drawImage(this.image, -this.image.height, 0); + + // Restore the original transformation matrix + this.ctx.restore(); + } + + // Center and set Coin position with adjustable height and width + size() { + const scaledWidth = this.image.width*1.5; + const scaledHeight = this.image.height*0.75; + + const snowflakeX = this.snowflakeX; + const snowflakeY = (GameEnv.bottom - scaledHeight) * this.snowflakeY; + + // Set variables used in Display and Collision algorithms + this.bottom = snowflakeY; + this.collisionHeight = scaledHeight; + this.collisionWidth = scaledWidth; + + this.canvas.style.width = `${scaledWidth}px`; + this.canvas.style.height = `${scaledHeight}px`; + this.canvas.style.position = 'absolute'; + this.canvas.style.left = `${snowflakeX}px`; + this.canvas.style.top = `${snowflakeY}px`; + } + collisionAction() { + // check player collision + if (this.collisionData.touchPoints.other.id === "player") { + this.destroy(); + GameControl.gainCoin(5) + GameEnv.playSound("coin"); + } + } + + // Method to hide the coin + hide() { + this.canvas.style.display = 'none'; + } + + // Method to show the coin + show() { + this.canvas.style.display = 'block'; + } +} + +export default Snowflake; diff --git a/assets/js/platformer3x/Snowman.js b/assets/js/platformer3x/Snowman.js new file mode 100644 index 00000000..6c2a2ca2 --- /dev/null +++ b/assets/js/platformer3x/Snowman.js @@ -0,0 +1,69 @@ +import Character from './Character.js'; +import GameEnv from './GameEnv.js'; +import GameControl from './GameControl.js'; +import Enemy from './Enemy.js'; + +export class Snowman extends Enemy { + // constructors sets up Character object + constructor(canvas, image, data, xPercentage, yPercentage, name, minPosition){ + super(canvas, image, data); + + //Unused but must be Defined + this.name = name; + this.y = yPercentage; + + //Initial Position of Goomba + this.x = xPercentage * GameEnv.innerWidth; + + //Access in which a Goomba can travel + this.minPosition = minPosition * GameEnv.innerWidth; + this.maxPosition = this.x + xPercentage * GameEnv.innerWidth; + + this.immune = 0; + + //Define Speed of Enemy + if (["easy", "normal"].includes(GameEnv.difficulty)) { + this.speed = this.speed * Math.floor(Math.random() * 1.5 + 2); + } else if (GameEnv.difficulty === "hard", "impossible") { + this.speed = this.speed * Math.floor(Math.random() * 3 + 4); + } else { + this.speed = this.speed * 5 + } + } + + updateMovement(){ + if (this.direction === "d") { + this.speed = Math.abs(this.storeSpeed) + } + else if (this.direction === "a") { + this.speed = -Math.abs(this.storeSpeed); + } + else if (this.direction === "idle") { + this.speed = 0 + } + + //Immunize Goomba & Texture It + if (GameEnv.difficulty === "hard") { + this.canvas.style.filter = "invert(100%)"; + this.canvas.style.scale = 1.25; + this.immune = 1; + } else if (GameEnv.difficulty === "impossible") { + this.canvas.style.filter = 'brightness(1000%)'; + this.canvas.style.transform = "rotate(180deg)" + this.immune = 1; + } + + // Move the enemy\ + this.x += this.speed; + } + + update() { + super.update(); + super.checkBoundaries(); + this.updateMovement(); + } + + +} + +export default Snowman; \ No newline at end of file diff --git a/images/platformer/backgrounds/Congratulations!!!.png b/images/platformer/backgrounds/Congratulations!!!.png index 049a3c81..ee71eb73 100644 Binary files a/images/platformer/backgrounds/Congratulations!!!.png and b/images/platformer/backgrounds/Congratulations!!!.png differ diff --git a/images/platformer/backgrounds/ThreeStar.png b/images/platformer/backgrounds/ThreeStar.png new file mode 100644 index 00000000..049a3c81 Binary files /dev/null and b/images/platformer/backgrounds/ThreeStar.png differ diff --git a/images/platformer/backgrounds/snowfall.png b/images/platformer/backgrounds/snowfall.png new file mode 100644 index 00000000..7728fdad Binary files /dev/null and b/images/platformer/backgrounds/snowfall.png differ diff --git a/images/platformer/backgrounds/winter.png b/images/platformer/backgrounds/winter.png new file mode 100644 index 00000000..74ecfaaf Binary files /dev/null and b/images/platformer/backgrounds/winter.png differ diff --git a/images/platformer/obstacles/cabin.png b/images/platformer/obstacles/cabin.png new file mode 100644 index 00000000..c783121e Binary files /dev/null and b/images/platformer/obstacles/cabin.png differ diff --git a/images/platformer/obstacles/snowflake.png b/images/platformer/obstacles/snowflake.png new file mode 100644 index 00000000..e611ab17 Binary files /dev/null and b/images/platformer/obstacles/snowflake.png differ diff --git a/images/platformer/obstacles/snowflakewithoutbg.png b/images/platformer/obstacles/snowflakewithoutbg.png new file mode 100644 index 00000000..5222eca9 Binary files /dev/null and b/images/platformer/obstacles/snowflakewithoutbg.png differ diff --git a/images/platformer/platforms/snowyfloor.png b/images/platformer/platforms/snowyfloor.png new file mode 100644 index 00000000..4de62895 Binary files /dev/null and b/images/platformer/platforms/snowyfloor.png differ diff --git a/images/platformer/platforms/snowywood.png b/images/platformer/platforms/snowywood.png new file mode 100644 index 00000000..45ef6b6d Binary files /dev/null and b/images/platformer/platforms/snowywood.png differ diff --git a/images/platformer/sprites/owl.png b/images/platformer/sprites/owl.png new file mode 100644 index 00000000..264fcfca Binary files /dev/null and b/images/platformer/sprites/owl.png differ diff --git a/images/platformer/sprites/snowman.png b/images/platformer/sprites/snowman.png new file mode 100644 index 00000000..9ec4a447 Binary files /dev/null and b/images/platformer/sprites/snowman.png differ diff --git a/images/platformer/sprites/white_mario.png b/images/platformer/sprites/white_mario.png new file mode 100644 index 00000000..00336afa Binary files /dev/null and b/images/platformer/sprites/white_mario.png differ diff --git a/images/platformer/sprites/white_mario1.png b/images/platformer/sprites/white_mario1.png new file mode 100644 index 00000000..48466151 Binary files /dev/null and b/images/platformer/sprites/white_mario1.png differ