From 438240741eb5c9b1eed14b4696052c0a1b6c911a Mon Sep 17 00:00:00 2001 From: kdrzazga Date: Thu, 5 Dec 2024 19:27:57 +0100 Subject: [PATCH] Electrician 1 (#79) --- index.html | 2 +- other/electrician/files/classdef.js | 53 +++++++++ other/electrician/files/electrician.js | 117 ++++++++++++++++++++ other/electrician/files/electrician.png | Bin 0 -> 5631 bytes other/electrician/files/electrician.test.js | 73 ++++++++++++ other/electrician/index.html | 13 +++ other/electrician/package-lock.json | 29 +++++ other/electrician/package.json | 15 +++ 8 files changed, 301 insertions(+), 1 deletion(-) create mode 100644 other/electrician/files/classdef.js create mode 100644 other/electrician/files/electrician.js create mode 100644 other/electrician/files/electrician.png create mode 100644 other/electrician/files/electrician.test.js create mode 100644 other/electrician/index.html create mode 100644 other/electrician/package-lock.json create mode 100644 other/electrician/package.json diff --git a/index.html b/index.html index 0dd1087..08b84f1 100644 --- a/index.html +++ b/index.html @@ -25,7 +25,7 @@ K&A+ | Cube | Brainfuck
- Arkanoid | + Electrician | X-Mas |
diff --git a/other/electrician/files/classdef.js b/other/electrician/files/classdef.js new file mode 100644 index 0000000..cc5ac84 --- /dev/null +++ b/other/electrician/files/classdef.js @@ -0,0 +1,53 @@ +class Floor { + static COUNT = 0; + static BUILDING_HEIGHT = 500; + + constructor() { + this.id = Floor.COUNT; + Floor.COUNT++; + this.floorLevel = 0; + } + + calculateFloorLevel(){ + //should be called only after all floors are created + this.floorLevel = Math.ceil((this.id + 1) * Floor.BUILDING_HEIGHT / (Floor.COUNT + 1)); + console.log(`Floor ${this.id} is on level = ${this.floorLevel}`); + } + + onFloor(y) { + const tolerance = this.floorLevel * 0.10; + const lowerBound = this.floorLevel; + const upperBound = this.floorLevel + tolerance; + return y >= lowerBound && y <= upperBound; + } + +} + +class Ladder { + static WIDTH = 60; + + constructor() { + this.x = 30; + } + + onLadder(x1){ + const edge1 = this.x - Ladder.WIDTH /2; + const edge2 = this.x + Ladder.WIDTH /2; + return x1 > edge1 && x1 < edge2; + } +} + +class Building { + constructor(floorCount){ + this.ladder = new Ladder(); + + this.floors = []; + for (let i = 0; i < floorCount; i++) { + const floor = new Floor(); + this.floors.push(floor); + } + this.floors.forEach(f => f.calculateFloorLevel()); + } +} + +module.exports = { Floor, Ladder, Building}; diff --git a/other/electrician/files/electrician.js b/other/electrician/files/electrician.js new file mode 100644 index 0000000..aed06ce --- /dev/null +++ b/other/electrician/files/electrician.js @@ -0,0 +1,117 @@ +class MainScene extends Phaser.Scene { + constructor() { + super({ key: 'MainScene' }); + this.floors = []; + this.ladder = new Ladder(); + this.spriteCanJump = true; + } + + preload() { + this.load.image('sprite', 'files/electrician.png'); + } + + create() { + this.physics.world.setBounds(0, 0, 800, 600); + + this.building = new Building(3); + + this.sprite = this.physics.add.sprite(100, 400, 'sprite'); + this.sprite.setCollideWorldBounds(true); + + this.cursors = this.input.keyboard.createCursorKeys(); + } + + update() { + this.handleMovement(); + this.conditionalFallDown(); + } + + jump(direction) { + if (!this.spriteCanJump) return; + + this.spriteCanJump = false; + const jumpHeight = 45; + const duration = 750; + + const jumpTween = { + targets: this.sprite, + y: this.sprite.y - jumpHeight, // Move up + duration: duration / 2, // Up for half the duration + ease: 'Linear', + onComplete: () => { + + const comeDownTween = { + targets: this.sprite, + y: this.sprite.y + jumpHeight, // Move down + duration: duration / 2, + ease: 'Linear', + onComplete: () => { + // Re-enable jumping after 1 second + this.spriteCanJump = true; + } + }; + this.tweens.add(comeDownTween); + } + } + + this.tweens.add(jumpTween); + + if (direction === 'left') { + this.sprite.setVelocityX(-160); + } else if (direction === 'right') { + this.sprite.setVelocityX(160); + } else { + this.sprite.setVelocityX(0); // No horizontal movement if just jumping + } + } + + conditionalFallDown(){ + if (this.ladder.onLadder(this.sprite.x)) + return; //Ladder prevents from falling; + else this.sprite.setVelocityY(160); + } + + handleMovement() { + let velocityX = 0; + let velocityY = 0; + + if (this.cursors.left.isDown) { + velocityX = -160; + if (this.cursors.up.isDown) { + this.jump('left'); + } + } else if (this.cursors.right.isDown) { + velocityX = 160; + if (this.cursors.up.isDown) { + this.jump('right'); + } + } + + if (velocityX === 0 && this.ladder.onLadder(this.sprite.x)) { + if (this.cursors.up.isDown) { + velocityY = -160; + } else if (this.cursors.down.isDown) { + velocityY = 160; + } + } + + this.sprite.setVelocityX(velocityX); + this.sprite.setVelocityY(velocityY); + } +} + +const config = { + type: Phaser.AUTO, + width: 800, + height: 600, + physics: { + default: 'arcade', + arcade: { + gravity: { y: 0 }, + debug: false + } + }, + scene: MainScene +}; + +const game = new Phaser.Game(config); diff --git a/other/electrician/files/electrician.png b/other/electrician/files/electrician.png new file mode 100644 index 0000000000000000000000000000000000000000..1710604aa3e76cb216750e482f3dd76280e8fdfc GIT binary patch literal 5631 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 literal 0 HcmV?d00001 diff --git a/other/electrician/files/electrician.test.js b/other/electrician/files/electrician.test.js new file mode 100644 index 0000000..fd78bfd --- /dev/null +++ b/other/electrician/files/electrician.test.js @@ -0,0 +1,73 @@ +const { Floor, Ladder, Building } = require('./classdef'); + +describe('Floor Class', () => { + beforeEach(() => { + Floor.COUNT = 0; // Reset the static COUNT before each test + }); + + test('should create a Floor instance with a unique id', () => { + const floor1 = new Floor(); + const floor2 = new Floor(); + + expect(floor1.id).toBe(0); + expect(floor2.id).toBe(1); + }); + + test('should increment the static COUNT correctly', () => { + const floor1 = new Floor(); + const floor2 = new Floor(); + const floor3 = new Floor(); + + expect(Floor.COUNT).toBe(3); + }); +}); + +describe('Ladder Class', () => { + let ladder; + + beforeEach(() => { + ladder = new Ladder(); + }); + + test('should be initialized with correct x position', () => { + expect(ladder.x).toBe(30); + }); + + test('should report if a given x position is on the ladder', () => { + expect(ladder.onLadder(0)).toBe(false); // Outside WIDTH (30 - 60) + expect(ladder.onLadder(100)).toBe(false); // Outside WIDTH (30 + 60) + expect(ladder.onLadder(30)).toBe(true); // Exact position + expect(ladder.onLadder(45)).toBe(true); // Within WIDTH (30 + 30) + }); + + test('should correctly handle different x positions for being on the ladder', () => { + expect(ladder.onLadder(90)).toBe(false); // Way outside + expect(ladder.onLadder(29)).toBe(true); // Just inside + expect(ladder.onLadder(31)).toBe(true); // Just inside + }); +}); + +describe('Building', () => { + let building; + + beforeEach(() => { + Floor.COUNT = 0; + building = new Building(5); + }); + + test('should create the correct number of floors', () => { + expect(building.floors.length).toBe(5); + }); + + test('should correctly calculate floor levels', () => { + const expectedLevels = [84, 167, 250, 334, 417]; + building.floors.forEach((floor, index) => { + expect(floor.floorLevel).toBe(expectedLevels[index]); + }); + }); + + test('should create a ladder with correct position', () => { + expect(building.ladder.x).toBe(30); + }); + +}); diff --git a/other/electrician/index.html b/other/electrician/index.html new file mode 100644 index 0000000..46d2a83 --- /dev/null +++ b/other/electrician/index.html @@ -0,0 +1,13 @@ + + + + + +
+ +
+ + + + + diff --git a/other/electrician/package-lock.json b/other/electrician/package-lock.json new file mode 100644 index 0000000..6b1c62a --- /dev/null +++ b/other/electrician/package-lock.json @@ -0,0 +1,29 @@ +{ + "name": "electrician", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "electrician", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "phaser": "^3.87.0" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + }, + "node_modules/phaser": { + "version": "3.87.0", + "resolved": "https://registry.npmjs.org/phaser/-/phaser-3.87.0.tgz", + "integrity": "sha512-AyI1b3T5fp05gzf6WUmu2FNqaZL+Y7w88yBRLf7YZXF9bncUSHpnDrupnTGoPqy/RKHRLBcay7zWeqQ2wiMWcw==", + "dependencies": { + "eventemitter3": "^5.0.1" + } + } + } +} diff --git a/other/electrician/package.json b/other/electrician/package.json new file mode 100644 index 0000000..903b38a --- /dev/null +++ b/other/electrician/package.json @@ -0,0 +1,15 @@ +{ + "name": "electrician", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "jest" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "phaser": "^3.87.0" + } +}