Oracle Cards – Midterm Project Report
Oracle Cards is an interactive web-based application I developed, inspired by the mystical allure of tarot and oracle card readings. For this project, I utilized the p5.js library to create a visually engaging and user-friendly experience that allows users to select a category and receive either advice or a reflection question. My goal was to craft an accessible and contemplative digital experience, drawing from my interest in mindfulness and self-reflection. This project leverages p5.js for rendering graphics, handling user input, and incorporating audio to enhance immersion.
About
Gameplay Instructions:
To play Oracle Cards, click the game link above to open the application in a new window. Ensure your browser supports p5.js and that you have a stable internet connection for loading assets (images and audio). The game is controlled entirely via mouse clicks, making it intuitive and accessible. Upon loading, you’ll see a welcome screen with a background image and category buttons. Click a category to proceed, then choose between receiving advice or a reflection question. The result is displayed on a card, accompanied by ambient music you can control with on-screen buttons. All images (e.g., backgrounds, cards) were sourced from royalty-free libraries, and the music tracks are licensed for non-commercial use. I do not claim ownership of these assets but have customized their integration to suit the game’s aesthetic.
How the Game Works
Oracle Cards simulates a digital card-reading experience, drawing inspiration from oracle decks used for introspection and guidance. The game progresses through three states:
-
Start: Users select a category (“Yourself,” “Friends & Family,” or “Transcendence”).
-
Choose Type: Users pick between “Advice” or a “Reflection Question.”
-
Result: A randomly selected response is displayed on a card, based on the chosen category and type.
The game uses a desk-themed interface with a lady in the background (inspired by a fortune-teller aesthetic) to create an immersive atmosphere. Users can control background music via play/pause, next, and previous buttons, enhancing the reflective mood. The sequence of events is as follows:
-
The game loads with a welcome screen and category buttons.
-
Clicking a category transitions to the choice screen, displaying a card with two options.
-
Selecting a choice reveals the result on a card, with a prompt to restart by clicking anywhere.
The design emphasizes simplicity and emotional resonance, encouraging users to pause and reflect.
Game Controls
The controls are straightforward:
-
Mouse Click: Click on category buttons (e.g., “Yourself”) to select a category, choice buttons (e.g., “Advice”) to pick a type, or anywhere on the result screen to restart.
-
Music Controls: Click the previous, play/pause, or next buttons in the top-right corner to manage background music.
This minimal input method ensures accessibility for users of all skill levels.
Proud Moment
I’m particularly proud of implementing the state management system using p5.js, which seamlessly transitions between the start, chooseType, and result states without glitches. Debugging the button click detection was challenging, especially ensuring accurate hitboxes for the buttons, but I resolved this by carefully calculating their positions relative to the canvas. Additionally, integrating audio functionality with p5.js’s loadSound and managing playback states (play/pause, next/previous) was a significant achievement. The randomization of responses, tailored to each category and choice, adds replayability and depth, which I fine-tuned to ensure a balanced and meaningful user experience.
The Code
Reusability and p5.js
The code is designed with modularity in mind, separating concerns like state management, rendering, and user input. Key p5.js functions (preload, setup, draw) are organized to handle asset loading, canvas initialization, and continuous rendering efficiently. For example, the drawButtons function is reusable for rendering both category and choice buttons:
function drawButtons(options, yStart) { for (let i = 0; i < options.length; i++) { let x = width / 2; let y = yStart + i * 50; fill(200, 100, 100); // Button color (red) rect(x - 100, y - 20, 200, 40, 10); // Draw button with rounded corners fill(255); // White text textAlign(CENTER, CENTER); text(options[i], x, y); // Display button label } }
This function is called in both the start and chooseType states, reducing code duplication. The preload function ensures all images and sounds are loaded before rendering, with error handling via callbacks:
deskLadyImage = loadImage('assets/desk_lady.png', () => console.log("Desk lady image loaded successfully"), (err) => console.error("Failed to load desk lady image:", err) );
Object-Oriented Code
While the project primarily uses functional programming, the responses object is structured hierarchically to store advice and reflection questions for each category, enabling easy access and randomization:
let responses = { "Yourself": { "Advice": [ "Take a deep breath and trust yourself.", // ... other advice ], "Reflection Question": [ "What is one thing you truly love about yourself?", // ... other questions ] }, // ... other categories };
The mousePressed function handles state transitions and music controls, using conditional logic to detect clicks within button boundaries:
if (gameState === "start") { for (let i = 0; i < categories.length; i++) { if (mouseX > width / 2 - 100 && mouseX < width / 2 + 100 && mouseY > height / 2 + 150 + i * 50 - 20 && mouseY < height / 2 + 150 + i * 50 + 20) { selectedCategory = categories[i]; gameState = "chooseType"; } } }
This modular approach ensures the code is maintainable and extensible.
Training the Model
No machine learning models were used in this project, as the focus was on user interaction and randomization within p5.js. However, the randomization logic for responses mimics a lightweight decision model. I curated the responses object by researching mindfulness and self-help literature, ensuring each piece of advice or question is concise yet impactful. The random function in p5.js was used to select responses, tested extensively to confirm uniform distribution across options.
Areas of Improvement
I’m delighted with Oracle Cards as a reflective and engaging experience that aligns with my vision of digital mindfulness. However, there are opportunities for enhancement:
-
Additional Features: I’d like to add animations for card transitions and a settings menu to adjust music volume or toggle visuals (e.g., enabling/disabling the crystal ball image).
-
Visual Polish: Incorporating hover effects for buttons and more varied card designs could elevate the aesthetic.
-
Content Expansion: Adding more categories or allowing users to input custom questions would increase replayability.
-
Accessibility: Implementing keyboard controls alongside mouse clicks would make the game more inclusive.
As for the game logic, I plan to explore subtle physics-based animations (e.g., card flipping) using p5.js to enhance interactivity.
Conclusion
Overall, I’m proud of Oracle Cards and how it blends creativity, technical skill, and emotional resonance. It’s a meaningful step in my journey with interactive design, and I look forward to refining it further to share its calming experience with others.