Skip to content

Commit

Permalink
added a very basic crane game (#148)
Browse files Browse the repository at this point in the history
Part of #30
  • Loading branch information
r4pt0s authored Oct 14, 2024
2 parents cca8cdb + d19d49a commit 06ac8ce
Show file tree
Hide file tree
Showing 2 changed files with 264 additions and 0 deletions.
262 changes: 262 additions & 0 deletions src/interactions/map_arcade/game_machine_crawl.interaction.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
import { displayDialogue } from '../../utils';

export const interactionWithGameMachineCrawl = (player, k, map) => {
player.onCollide('game_machine_crawl', () => {
player.isInDialog = true;
// Trigger the custom prompt when the player collides with the game machine
showCustomPrompt(
'Do you want to play the Crawl Game?', // Updated Prompt message
['Yes', 'No'], // Options for the game prompt
(selectedOption) => {
// Logic based on the selected option
if (selectedOption === 'Yes') {
displayDialogue({
k,
player,
text: ['Starting the Crawl Game... Good luck!'],
onDisplayEnd: () => {
player.isInDialog = false;
startCrawlGame(k); // Pass k to the game start function
},
});
} else {
displayDialogue({
k,
player,
text: ['Maybe next time!'],
onDisplayEnd: () => {
player.isInDialog = false;
},
});
}
}
);
});
};

function showCustomPrompt(message, options, callback) {
// Set the prompt message
document.getElementById('prompt-message').textContent = message;

// Clear any existing options in the container
const optionsContainer = document.getElementById('options-container');
optionsContainer.innerHTML = '';

// Create buttons for each option
options.forEach((option) => {
const button = document.createElement('button');
button.textContent = option;
button.classList.add('option-btn');
button.setAttribute('tabindex', '0'); // Make the button focusable

// Add click event for mouse interactions
button.onclick = function () {
callback(option);
closeCustomPrompt();
};

// Add keyboard event listener for accessibility
button.addEventListener('keydown', function (e) {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault(); // Prevent the default behavior
callback(option);
closeCustomPrompt();
}
});

optionsContainer.appendChild(button);
});

// Display the custom prompt
document.getElementById('custom-prompt').style.display = 'flex';

// Set focus on the first button
if (optionsContainer.children.length > 0) {
optionsContainer.children[0].focus();
}
}

// Function to close the custom prompt
function closeCustomPrompt() {
// Hide the custom prompt
document.getElementById('custom-prompt').style.display = 'none';
}

// Function to start the Chrome Dino Game
function startCrawlGame(k) {
k.debug.log('Crawl game Started!');
k.go('startScreen', { title: 'Crawl Game', gameSceneName: 'crawlGame' });

k.scene("crawlGame", () => {
let width = k.width()
// Set the initial time remaining (e.g., 60 seconds or 1 minute)
let timeRemaining = 60 * 1000; // 60 seconds in milliseconds

// keep track of score
const timeLabel = k.add([k.text(timeRemaining), k.pos(68, 10)]);

// Pressing escape lets the player leave the game
k.onKeyPress('escape', () => {
k.go('lose', {
title: 'Crawl Game',
gameRestartSceneName: 'crawlGame',
gameExitSceneName: 'arcade',
score: timeLabel.text
});
});

// Create Crane
const crane = k.add([
k.rect(40, 20),
k.pos(50, 150),
k.area(),
k.body(),
{ isMovingDown: false, isMovingUp: false, isMovingHorizontal: false, speed: 300, startPos: k.vec2(50, 150), grabbedItem: null }
]);

// Number of items
const numItems = 1;

// Create items for the crane to pick up
for (let i = 0; i < numItems; i++) {
k.add([
k.rect(30, 30),
// Calculate the position of each item, spacing them evenly
k.pos(
(k.width() / (numItems + 1)) * (i + 1), // Spacing items evenly between width
k.height() - 200 // Y position (fixed 200 units from the bottom)
),
k.area(),
k.body({ isStatic: true }), // Ensure items don't move
"item",
]);
}

// Crane movement left
k.onButtonDown(["left"], () => {
if (!crane.isMovingDown && !crane.isMovingUp && !crane.isMovingHorizontal && crane.pos.x > 0) {
crane.move(-crane.speed, 0);
}
});

// Crane movement right
k.onButtonDown(["right"], () => {
if (!crane.isMovingDown && !crane.isMovingUp && !crane.isMovingHorizontal && crane.pos.x < width - 40) {
crane.move(crane.speed, 0);
}
});

// Drop the crane using the spacebar
k.onKeyPress(["space", "down"], () => {
if (!crane.isMovingDown && !crane.isMovingUp && !crane.isMovingHorizontal) {
crane.isMovingDown = true;
}
});

// Drop the crane using a mouse click
k.onClick(() => {
if (!crane.isMovingDown && !crane.isMovingUp && !crane.isMovingHorizontal) {
crane.isMovingDown = true;
}
});


// Add instructions with proper positioning
k.add([
k.text("Tap/Click/←→ or to move the crane left and right"),
k.pos(68, 40), // Position slightly below the score label
]);

k.add([
k.text("Tap/Click/↓ or space or mouse to move crane down"),
k.pos(68, 70), // Positioned below the first line of instructions
]);

// Update the crane position during each frame
k.onUpdate(() => {
width = k.width()

const deltaTime = k.dt() * 1000; // Get the time since last frame (in milliseconds)
timeRemaining -= deltaTime;

// Update the time label with the formatted remaining time
timeLabel.text = formatTime(timeRemaining);

const items = k.get("item")
if (items.length === 0) {
k.go('lose', {
title: 'Crawl game',
gameRestartSceneName: 'crawlGame',
gameExitSceneName: 'arcade',
score: timeLabel.text,
});
}
if (crane.isMovingDown) {
crane.move(0, crane.speed);
// Check for collision with any items
const item = k.get("item").find(item => crane.isColliding(item));
if (item && !crane.grabbedItem) {
crane.grabbedItem = item; // Attach the item to the crane
k.debug.log("Item grabbed!");
timeRemaining += 10000
// Reset crane position after reaching item
crane.isMovingDown = false; // Reset the flag so the crane can move again
crane.isMovingUp = true;
}
if (crane.pos.y > k.height()) {
// Reset crane position after reaching bottom
timeRemaining -= 5000
crane.isMovingDown = false; // Reset the flag so the crane can move again
crane.isMovingUp = true;
}
}
// Move crane back up to its starting position
if (crane.isMovingUp) {
crane.move(0, -crane.speed);
// Move the grabbed item with the crane
if (crane.grabbedItem) {
crane.grabbedItem.pos.x = crane.pos.x; // Align item's x position with the crane
crane.grabbedItem.pos.y = crane.pos.y + 20; // Adjust y position (offset for the crane's size)
}

// Check if crane has reached its starting position
if (crane.pos.y <= crane.startPos.y) {
crane.isMovingHorizontal = true
crane.isMovingUp = false; // Stop moving up
}
}
// Move crane horizontally back to the starting x position
if (crane.isMovingHorizontal) {
const moveDirection = crane.pos.x > crane.startPos.x ? -1 : 1; // Determine direction
crane.move(moveDirection * crane.speed, 0);

// Move the grabbed item with the crane horizontally
if (crane.grabbedItem) {
crane.grabbedItem.pos.x = crane.pos.x; // Align item's x position with the crane
}

// Check if crane has reached its starting x position
if (Math.abs(crane.pos.x - crane.startPos.x) <= 1) { // Small tolerance for precision
crane.pos.x = crane.startPos.x; // Ensure exact x positioning
crane.isMovingHorizontal = false; // Stop movement

// Drop the grabbed item after reaching the start position
if (crane.grabbedItem) {
crane.grabbedItem.destroy()
crane.grabbedItem = null; // Release the item
k.debug.log("Item released!");
}
}
}
});
});
}


// Helper function to format time as MM:SS
function formatTime(milliseconds) {
const totalSeconds = Math.floor(milliseconds / 1000);
const minutes = Math.floor(totalSeconds / 60);
const seconds = totalSeconds % 60;
return `${minutes}:${seconds.toString().padStart(2, '0')}`;
}
2 changes: 2 additions & 0 deletions src/interactions/map_arcade/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { interactionWithGameMachine10 } from './game_machine_10.interactions';
import { interactionWithGameMachine11 } from './game_machine_11.interaction';
import { interactionWithGameMachine12 } from './game_machine_12.interaction';
import { interactionWithGameMachine3 } from './game_machine_3.interactions';
import { interactionWithGameMachineCrawl } from './game_machine_crawl.interaction';

const interactions = [
enterMapCityInteraction,
Expand All @@ -30,6 +31,7 @@ const interactions = [
interactionWithGameMachine10,
interactionWithGameMachine11,
interactionWithGameMachine12,
interactionWithGameMachineCrawl
];

export default interactions;

0 comments on commit 06ac8ce

Please sign in to comment.