Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Game Class - Reusable for Multiple Slides
- class Game {
- constructor(playerObjectId, enemy1ObjectId, enemy2ObjectId, overlayObjectId) {
- // Get object references
- this.question_Bot = object(playerObjectId);
- this.enemy_1 = object(enemy1ObjectId);
- this.enemy_2 = object(enemy2ObjectId);
- this.overlay = object(overlayObjectId); // Movement boundary overlay
- // Game settings
- this.MOVE_SPEED = 8; // pixels per frame
- this.COLLISION_THRESHOLD = 35; // collision detection distance (reduced for better precision)
- // Track key states (only left and right)
- this.keys = {
- left: false,
- right: false
- };
- // Track collision states to prevent multiple triggers
- this.collisionStates = {
- enemy_1: false,
- enemy_2: false
- };
- // Game state
- this.gameComplete = false;
- this.gameStarted = false;
- this.initializationComplete = false;
- // Store object IDs for variable names
- this.enemy1ObjectId = enemy1ObjectId;
- this.enemy2ObjectId = enemy2ObjectId;
- // Track initial positions to prevent startup collisions
- this.initialPositions = {
- player: null,
- enemy_1: null,
- enemy_2: null
- };
- }
- // Calculate distance between two objects (with fallback for dimensions)
- getDistance(obj1, obj2) {
- // Use fallback dimensions if width/height not available
- const obj1Width = obj1.width || 50;
- const obj1Height = obj1.height || 50;
- const obj2Width = obj2.width || 50;
- const obj2Height = obj2.height || 50;
- const dx = (obj1.x + obj1Width / 2) - (obj2.x + obj2Width / 2);
- const dy = (obj1.y + obj1Height / 2) - (obj2.y + obj2Height / 2);
- return Math.sqrt(dx * dx + dy * dy);
- }
- // More precise collision detection using smaller collision boxes
- checkBoundingBoxCollision(obj1, obj2) {
- const obj1Width = obj1.width || 50;
- const obj1Height = obj1.height || 50;
- const obj2Width = obj2.width || 50;
- const obj2Height = obj2.height || 50;
- // Use smaller collision boxes (80% of actual size) for more precise detection
- const collisionMargin = 0.2; // 20% margin
- const obj1CollisionWidth = obj1Width * (1 - collisionMargin);
- const obj1CollisionHeight = obj1Height * (1 - collisionMargin);
- const obj2CollisionWidth = obj2Width * (1 - collisionMargin);
- const obj2CollisionHeight = obj2Height * (1 - collisionMargin);
- // Center the collision boxes
- const obj1CollisionX = obj1.x + (obj1Width - obj1CollisionWidth) / 2;
- const obj1CollisionY = obj1.y + (obj1Height - obj1CollisionHeight) / 2;
- const obj2CollisionX = obj2.x + (obj2Width - obj2CollisionWidth) / 2;
- const obj2CollisionY = obj2.y + (obj2Height - obj2CollisionHeight) / 2;
- return obj1CollisionX < obj2CollisionX + obj2CollisionWidth &&
- obj1CollisionX + obj1CollisionWidth > obj2CollisionX &&
- obj1CollisionY < obj2CollisionY + obj2CollisionHeight &&
- obj1CollisionY + obj1CollisionHeight > obj2CollisionY;
- }
- // Animate and hide enemy when hit
- animateAndHideEnemy(enemy, enemyName, variableName) {
- // Add hit animation using Storyline's animate function
- /* addToTimeline(
- enemy.animate(
- [
- { transform: 'scale(1) rotate(0deg)', opacity: '1' },
- { transform: 'scale(1.5) rotate(180deg)', opacity: '0.5' },
- { transform: 'scale(0.1) rotate(360deg)', opacity: '0' }
- ],
- {
- duration: 800, // Animation duration in milliseconds
- easing: 'ease-in-out',
- fill: 'forwards' // Keep the final state after animation
- }
- )
- );*/
- // Set variable after animation completes
- setTimeout(() => {
- // Set the Storyline variable to true after animation
- setVar(variableName, true);
- }, 100);
- }
- // Hide all remaining enemies
- hideAllEnemies() {
- const enemies = [
- { obj: this.enemy_1, name: 'enemy_1' },
- { obj: this.enemy_2, name: 'enemy_2' }
- ];
- enemies.forEach(enemy => {
- // Add fade out animation for remaining enemies
- addToTimeline(
- enemy.obj.animate(
- [
- { opacity: '1' },
- { opacity: '0' }
- ],
- {
- duration: 10,
- easing: 'ease-out',
- fill: 'forwards'
- }
- )
- );
- // Animation complete - objects can be manually hidden via Storyline
- // No automatic hiding - let Storyline handle visibility
- });
- console.log("Game Complete! All enemies eliminated!");
- }
- // Store initial positions and check for overlaps
- storeInitialPositions() {
- this.initialPositions.player = { x: this.question_Bot.x, y: this.question_Bot.y };
- this.initialPositions.enemy_1 = { x: this.enemy_1.x, y: this.enemy_1.y };
- this.initialPositions.enemy_2 = { x: this.enemy_2.x, y: this.enemy_2.y };
- // Check if any objects are overlapping at start
- const startupCollision1 = this.getDistance(this.question_Bot, this.enemy_1) < this.COLLISION_THRESHOLD;
- const startupCollision2 = this.getDistance(this.question_Bot, this.enemy_2) < this.COLLISION_THRESHOLD;
- if (startupCollision1 || startupCollision2) {
- console.warn("Warning: Objects are overlapping at startup! Consider repositioning them.");
- console.log("Player position:", this.question_Bot.x, this.question_Bot.y);
- console.log("Enemy positions:",
- "E1:", this.enemy_1.x, this.enemy_1.y,
- "E2:", this.enemy_2.x, this.enemy_2.y);
- }
- }
- // Check if player has moved significantly from start position
- hasPlayerMoved() {
- if (!this.initialPositions.player) return false;
- const moveThreshold = 10; // pixels
- const dx = Math.abs(this.question_Bot.x - this.initialPositions.player.x);
- const dy = Math.abs(this.question_Bot.y - this.initialPositions.player.y);
- return (dx > moveThreshold || dy > moveThreshold);
- }
- // Check collision between question_Bot and enemies
- checkCollisions() {
- // Skip collision detection if game is complete or not started
- if (this.gameComplete || !this.gameStarted) return;
- // Only enable collision detection after player has moved or after a delay
- if (!this.initializationComplete && !this.hasPlayerMoved()) return;
- // Check collision with enemy_1 using both methods
- const distance1 = this.getDistance(this.question_Bot, this.enemy_1);
- const boxCollision1 = this.checkBoundingBoxCollision(this.question_Bot, this.enemy_1);
- if (distance1 < this.COLLISION_THRESHOLD || boxCollision1) {
- if (!this.collisionStates.enemy_1) {
- this.collisionStates.enemy_1 = true;
- console.log("Collision with enemy_1! Distance:", distance1, "Box collision:", boxCollision1);
- // Animate and hide the hit enemy, set variable after animation
- this.animateAndHideEnemy(this.enemy_1, "enemy_1", "enemy_1");
- // Set game complete - no automatic hiding of other enemies
- this.gameComplete = true;
- }
- } else {
- this.collisionStates.enemy_1 = false;
- }
- // Check collision with enemy_2 using both methods
- const distance2 = this.getDistance(this.question_Bot, this.enemy_2);
- const boxCollision2 = this.checkBoundingBoxCollision(this.question_Bot, this.enemy_2);
- if (distance2 < this.COLLISION_THRESHOLD || boxCollision2) {
- if (!this.collisionStates.enemy_2) {
- this.collisionStates.enemy_2 = true;
- console.log("Collision with enemy_2! Distance:", distance2, "Box collision:", boxCollision2);
- // Animate and hide the hit enemy, set variable after animation
- this.animateAndHideEnemy(this.enemy_2, "enemy_2", "enemy_2");
- // Set game complete - no automatic hiding of other enemies
- this.gameComplete = true;
- }
- } else {
- this.collisionStates.enemy_2 = false;
- }
- }
- // Update player position based on key states (only left and right movement)
- updatePlayerMovement() {
- // Stop movement if game is complete
- if (this.gameComplete) return;
- let newX = this.question_Bot.x;
- // Calculate new position based on key states (only horizontal movement)
- if (this.keys.left) {
- newX -= this.MOVE_SPEED;
- }
- if (this.keys.right) {
- newX += this.MOVE_SPEED;
- }
- // Constrain movement within overlay boundaries
- const antWidth = this.question_Bot.width || 50;
- const overlayLeft = this.overlay.x;
- const overlayRight = this.overlay.x + (this.overlay.width || 400);
- const minX = overlayLeft;
- const maxX = overlayRight - antWidth;
- // Apply constraints
- newX = Math.max(minX, Math.min(maxX, newX));
- // Update position (only X coordinate changes)
- this.question_Bot.x = newX;
- }
- // Keyboard event handlers (only left and right keys)
- handleKeyDown(event) {
- switch(event.code) {
- case 'ArrowLeft':
- this.keys.left = true;
- event.preventDefault();
- break;
- case 'ArrowRight':
- this.keys.right = true;
- event.preventDefault();
- break;
- }
- }
- handleKeyUp(event) {
- switch(event.code) {
- case 'ArrowLeft':
- this.keys.left = false;
- event.preventDefault();
- break;
- case 'ArrowRight':
- this.keys.right = false;
- event.preventDefault();
- break;
- }
- }
- // Touch Screen Button Functions (only left and right)
- keyLeftStart() {
- if (this.gameComplete) return;
- let newX = this.question_Bot.x - this.MOVE_SPEED;
- const antWidth = this.question_Bot.width || 50;
- const overlayLeft = this.overlay.x;
- const minX = overlayLeft;
- // Apply boundary constraint
- newX = Math.max(minX, newX);
- this.question_Bot.x = newX;
- console.log("Moved left a little");
- }
- keyRightStart() {
- if (this.gameComplete) return;
- let newX = this.question_Bot.x + this.MOVE_SPEED;
- const antWidth = this.question_Bot.width || 50;
- const overlayRight = this.overlay.x + (this.overlay.width || 400);
- const maxX = overlayRight - antWidth;
- // Apply boundary constraint
- newX = Math.min(maxX, newX);
- this.question_Bot.x = newX;
- console.log("Moved right a little");
- }
- // Initialize the game
- initializeGame() {
- // Initialize collision variables to false
- setVar("enemy_1", false);
- setVar("enemy_2", false);
- // Store initial positions and check for overlaps
- this.storeInitialPositions();
- // Add keyboard event listeners with bound context
- document.addEventListener('keydown', (event) => this.handleKeyDown(event));
- document.addEventListener('keyup', (event) => this.handleKeyUp(event));
- // Start the game with a small delay to ensure proper initialization
- setTimeout(() => {
- this.gameStarted = true;
- console.log("Game collision detection enabled!");
- }, 500); // Half second delay
- // Enable collision detection after 2 seconds regardless of movement
- setTimeout(() => {
- this.initializationComplete = true;
- console.log("Initialization period complete - full collision detection active!");
- }, 2000);
- // Start the game loop
- update(() => {
- this.updatePlayerMovement();
- this.checkCollisions();
- });
- console.log("Game initialized! Use left/right arrow keys to move the player within the overlay.");
- console.log("Collision detection will start after player moves or 2-second delay.");
- return this; // Return instance for method chaining
- }
- }
- // Global game instance reference
- let currentGame = null;
- // Global functions for touch buttons (call these from Storyline)
- // These work with the currently active game instance (only left and right)
- function keyLeftStart() {
- if (currentGame) {
- currentGame.keyLeftStart();
- } else {
- console.warn("No game instance active. Please initialize a game first.");
- }
- }
- function keyRightStart() {
- if (currentGame) {
- currentGame.keyRightStart();
- } else {
- console.warn("No game instance active. Please initialize a game first.");
- }
- }
- /* How to initialize Game in Storyline
- currentGame = new Game('playerObjectId', 'enemy1ObjectId', 'enemy2ObjectId', 'overlayObjectId')
- currentGame.initializeGame();
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement