Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added a very basic crane game #148

Merged
merged 3 commits into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;