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

Conor Furlong | Complete #18

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
111 changes: 109 additions & 2 deletions css/style.css
Original file line number Diff line number Diff line change
@@ -1,11 +1,118 @@
/* global styles */

*{
box-sizing: border-box;
/* border: 1px solid red; */
}
/* element styles */

body{
/* fonts */
margin: 0;
min-height: 100vh;
background-color: #e6e6e6;
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
/* referene size for rem units (16px) */
}
h1{
font-size: 3.5rem;
/* margin: 0; */
}
/* layout */
.container{
/* border: 3px solid blue; */
width: 90vw;
margin: 0 auto;
/* auto calculates the remaining space avaiable (left over after calculating content size) */
}
.button-wrapper{
display: flex;
justify-content: space-around;
gap: 1rem;
}
.stats-wrapper{

}

.game-state-wrapper{
display: flex;
justify-content: center;
}
/* headings */
.game-title{
text-align: center;
}

/* buttons */
.button-wrapper button{
background-color: #0b99ff;
color: white;
padding: 1.3rem 1.6rem;
font-size: 1.8rem;
border: .2rem solid #134a71;
border-radius: .25rem;
}

.button-wrapper button:active{
background-color: #197bc2;
border: .2rem solid #0b3553;
}
/* 11, 153, 255 */
/* images */
.game-graphic{
max-height: 20vmin;
}

.game-graphic:hover{
/* source: https://www.w3schools.com/howto/howto_css_shake_image.asp */
/* Start the shake animation and make the animation last for 0.5 seconds */
animation: shake 0.5s;

/* When the animation is finished, start again */
animation-iteration-count: infinite;
}

@keyframes shake {
0% {
transform: translate(1px, 1px) rotate(0deg);
}
10% {
transform: translate(-1px, -2px) rotate(-1deg);
}
20% {
transform: translate(-3px, 0px) rotate(1deg);
}
30% {
transform: translate(3px, 2px) rotate(0deg);
}
40% {
transform: translate(1px, -1px) rotate(1deg);
}
50% {
transform: translate(-1px, 2px) rotate(-1deg);
}
60% {
transform: translate(-3px, 1px) rotate(0deg);
}
70% {
transform: translate(3px, 1px) rotate(-1deg);
}
80% {
transform: translate(-1px, -1px) rotate(1deg);
}
90% {
transform: translate(1px, 2px) rotate(0deg);
}
100% {
transform: translate(1px, -2px) rotate(-1deg);
}
}
40 changes: 29 additions & 11 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,16 +1,34 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/style.css" />
<script src="./js/main.js" defer></script>
</head>

<body>
<h1>Tamagotchi Code Along</h1>
</body>

</head>
<body>
<header>
<h1 class="game-title">Tamagotchi</h1>
</header>
<main class="container">
<section id="controller" class="button-wrapper">
<!-- button wrapper -->
<button>Feed</button>
<button>Play</button>
<button>Sleep</button>
</section>
<section id="stat-display" class="stats-wrapper">
<!-- stats display -->
<p>Happiness: <span id="boredom-stat">10</span></p>
<p>Hunger: <span id="hunger-stat">0</span></p>
<p>Tiredness: <span id="sleepiness-stat">5</span></p>
</section>
<section id="game-state" class="game-state-wrapper">
<!-- game state -> UI -> user interface for seeing changes to game -->
<img id="tama-graphic" src="./imgs/wolf-1.png" class="game-graphic">
</section>
</main>
</body>
</html>
155 changes: 153 additions & 2 deletions js/main.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,166 @@
console.log('js:loaded')
console.log("js:loaded");

/*----- constants -----*/
// initial data states
// animation names
// image assets paths

const INIT_STATE = {
boredom: 0,
hunger: 0,
sleepiness: 0,
};

/*----- state variables -----*/
// state is the data that will change while the game is running

// let boredom; // integer
// let hunger; // integer
// let sleepiness; // integer

let state; // object

// HFM later on - icebox features (age cycle for tama)
let age; // integer
let cycles; // integer

let timer; // setInterval id
let interval; // count of cycles

/*----- cached elements -----*/

const boredomStatEl = document.querySelector("#boredom-stat");
const hungerStatEl = document.querySelector("#hunger-stat");
const sleepyStatEl = document.querySelector("#sleepiness-stat");

// TODO: add cache for game message string once added to game

const gameBtnEls = document.querySelectorAll("#controller button");

// TODO: add cache for restart button after game over

/*----- event listeners -----*/
gameBtnEls.forEach(function (btn) {
btn.addEventListener("click", handleBtnClick);
});

// ICEBOX -> after a click remove the listener and then add it back 2 second later
// throttle the user and prevent spamming

function handleBtnClick(event) {
console.log(event.target.innerText);

const convertProp = {
feed: "hunger",
sleep: "sleepiness",
play: "boredom",
};

const key = convertProp[event.target.innerText];
console.log(key);

updateStat(key, -3);

render();
}
/*----- functions -----*/

init(); // starts game when js loads

function init() {
// init will start the game and load the initial values for our game state

state = { ...INIT_STATE };
// taking th init state object -> copy of its content and storing into a new object
// assigning the new object to the state variable

age = 0;
cycles = 0;

interval = 5000; // ms pass for each cycles
timer = setInterval(runGame, interval); // setInterval id

// TODO / ICEBOX - init() on load and after a reset (optional)
// it will also call render() -> dom updates (trigger all render helper function -> updating stats)
render();
}

function runGame() {
if (continueGame()) {
updateStats();
} else {
gameOver();
}
// game loop function all of the logic for the game will change state here -> func() -> state
render();
}

function render() {
// any features which might update the dom (the ui) -> will be called by render
renderStats();
}

function renderStats() {
boredomStatEl.textContent = state.boredom;
hungerStatEl.textContent = state.hunger;
sleepyStatEl.textContent = state.sleepiness;

// ICEBOX - consider iterator for dynamic render of content
}

function updateStats() {
// call iterator over state and for each state property update the corresponding key
// iterate over states {}
// capture random number
// capture property of state
// update current state for each key
for (let key in state) {
updateStat(key, Math.floor(Math.random() * 3));
}
}

function updateStat(stat, value) {
// error / user limit
// goal - prevent users from taking a stat below 0

if (state[stat] + value >= 0) {
state[stat] += value;
} else {
state[stat] = 0;
}
}

function continueGame() {
let keepRunning = true;
let currentStats = [];
// iterate through state object to check all values of state {}
for (let key in state) {
currentStats.push(state[key]);
}
// current state represented as an array
console.log(currentStats);

// check if any of the values are greater than 9
for (let stat of currentStats) {
if (stat >= 10) {
keepRunning = false;
}
}
return keepRunning; // returns either true or false
}

function gameOver() {
// testing with alert
clearInterval(timer);
console.log("Game Over")
// stop the interval calling runGame when gameOver is called ( the global timer variable stores an id associated with the interval)
}

/*----- functions -----*/
/**
* OLD CODE
* // let randomAmount = Math.floor(Math.random()*3) // engine for updating state
// let currentValue = state[key] // current state value
// state[key] = currentValue + randomAmount // updating state with new value
// console.log(key, state[key], randomAmount) // test
*
*/