Code Couture Code Walkthrough
How I coded the Code Couture game!
<div class="nes-field is-inline">
<label for="error_field">Name</label>
<input type="text" id="error_field" class="nes-input is-error" id="nameInput" placeholder="What's Your Name ?">
</div>
<!--<a class="nes-btn is-error" href="{{ site.baseurl }}/story" id="myButton">PLAY NOW</a>-->
<button class="nes-btn is-error" onclick="saveName(); window.location.href='{{ site.baseurl }}/story'">PLAY NOW</button>
function saveName() {
var name = document.getElementById("nameInput").value;
localStorage.setItem("userName", name);
}
After clicking the continue button, a juicy text conversation plays out on the next page, directly involving the user, and prompts the user to respond. The user may enter whatever text they'd like, and it will be displayed in the chat, next to an icon labeled with their name.
<section class="message-list">
<!--Boyfriend-->
<section class="message -left">
<i class="nes-bcrikko"></i>
<!-- Balloon -->
<div class="nes-balloon from-left">
<p>Hey, I need to be honest with you. I cheated on you.</p>
</div>
</section>
<!--Boyfriend-->
<section class="message -left">
<i class="nes-bcrikko"></i>
<!-- Balloon -->
<div class="nes-balloon from-left">
<p>Honestly, they are better than you anyways.</p>
</div>
</section>
<section align="right" class="message -right">
<!-- Balloon -->
<div class="nes-balloon from-right">
<p id="contentDisplay"><span id="inputMessage"></span></p>
</div>
<i class="nes-bcrikko"></i>
<div align="right" id="nameDisplay"></div>
</section>
</section>
<div class="nes-field">
<label for="name_field"></label>
<input type="text" id="name_field" class="nes-input" id="textInput" onkeydown="keyEnter(event)" placeholder="Click ENTER key to send">
<!--<button type="button" class="nes-btn is-primary" onclick="printMessage()">send</button>-->
</div>
savedName() calls the stored name input from the last page, and displays it under the icon. keyEnter() senses when teh enter key is clicked, and when clicked, the content from the text input is displayed on the text bubble. It appears that the user is responding to the text messages from before. Now, the user clicks continue to go to the game.
var savedName = localStorage.getItem("userName");
if (savedName) {
document.getElementById("nameDisplay").textContent = savedName;
} else {
document.getElementById("nameDisplay").textContent = "User";
}
function keyEnter(event) {
if (event.keyCode === 13) {
displayContent();
}
}
function displayContent() {
var input = document.getElementById("textInput").value;
document.getElementById("contentDisplay").textContent = input;
document.getElementById("textInput").value = ""; // Reset input value
}
Multiple canvases positioned on the left side of the page hold the elements. On load, the blank base body is the only thing visible on the base canvas. Each type of clothing that the user can put on their doll has its own canvas in the same position as the base canvas, which is where the image will be displayed. The base body images and the clothing images will appear to be layered. There are three buttons under the canvas, each with different skin tones. The user can click the skin tone they want, and the base body will have that skin color.
<div id="display">
<div id="canvas">
<canvas id="base"></canvas>
<canvas id="shoes"></canvas>
<canvas id="dress"></canvas>
<canvas id="pants"></canvas>
<canvas id="shirtbase"></canvas>
<canvas id="shirt"></canvas>
<canvas id="eyes"></canvas>
<canvas id="hair"></canvas>
<canvas id="accessories"></canvas>
<canvas id="blank"></canvas>
<img id="results">
</div>
<audio id="music" src="audio/gametheme.mp3" autoplay loop></audio>
<div id="skin">
<button id="medskin" onclick="medskin()">
<span class="medskin-icon"></span>
</button>
<button id="lightskin" onclick="lightskin()">
<span class="lightskin-icon"></span>
</button>
<button id="darkskin" onclick="darkskin()">
<span class="darkskin-icon"></span>
</button>
</div>
</div>
When changing the skin color, a corresponding function is assigned to each color button. Each skin color is a new base body image. On click of the button, the function clears the canvas of the previous image, and displays the new one.
function medskin() {
context.clearRect(0, 0, canvas.width, canvas.height);
baseimg.src='https://raw.githubusercontent.com/codecouturebaddies/codec/gh-pages/images/base/base1.png';
baseimg.onload = function() {
context.drawImage(baseimg, 0, 0, canvas.width, canvas.height);
}
}
function lightskin() {
context.clearRect(0, 0, canvas.width, canvas.height);
baseimg.src='https://raw.githubusercontent.com/codecouturebaddies/codec/gh-pages/images/base/base2.png';
baseimg.onload = function() {
context.drawImage(baseimg, 0, 0, canvas.width, canvas.height);
}
}
function darkskin() {
context.clearRect(0, 0, canvas.width, canvas.height);
baseimg.src='https://raw.githubusercontent.com/codecouturebaddies/codec/gh-pages/images/base/base3.png';
baseimg.onload = function() {
context.drawImage(baseimg, 0, 0, canvas.width, canvas.height);
}
}
On the right of the screen, there is a menu holding all of the clothing options. The categories are displayed on the top of the menu, and the user can click between them. On each page, there are several images of clothing that they can click for it to appear on the canvas on the body.
<div class="content-item" id="dress-content">
<table>
<tr>
<td><button onclick="dressbtn(0)"><img src="images/dresses/dress1.png" alt="dress1"></button></td>
</tr>
<tr>
<td><button onclick="dressbtn(1)"><img src="images/dresses/dress2.png" alt="dress2"></button></td>
</tr>
</table>
</div>
<div class="content-item" id="shirt-content">
<table>
<tr>
<td><button onclick="shirtbtn(0)"><img src="images/zcropped/top1c.png" alt="shirt1"></button></td>
</tr>
<tr>
<td><button onclick="shirtbtn(1)"><img src="images/zcropped/top2c.png" alt="shirt2"></button></td>
</tr>
<tr>
<td><button onclick="shirtbtn(2)"><img src="images/zcropped/top3c.png" alt="shirt3"></button></td>
</tr>
<tr>
<td><button onclick="shirtbtn(3)"><img src="images/zcropped/top4c.png" alt="shirt4"></button></td>
</tr>
</table>
</div>
<div class="content-item" id="pants-content">
<table>
<tr>
<td><button onclick="pantsbtn(0)"><img src="images/zcropped/bottom1c.png" alt="pants1"></button></td>
</tr>
<tr>
<td><button onclick="pantsbtn(1)"><img src="images/zcropped/bottom2c.png" alt="pants2"></button></td>
</tr>
<tr>
<td><button onclick="pantsbtn(2)"><img src="images/zcropped/bottom3c.png" alt="pants3"></button></td>
</tr>
<tr>
<td><button onclick="pantsbtn(3)"><img src="images/zcropped/bottom4c.png" alt="pants4"></button></td>
</tr>
<tr>
<td><button onclick="pantsbtn(4)"><img src="images/zcropped/bottom5c.png" alt="pants5"></button></td>
</tr>
<tr>
<td><button onclick="pantsbtn(5)"><img src="images/zcropped/bottom6c.png" alt="pants6"></button></td>
</tr>
</table>
</div>
<div class="content-item" id="shoes-content">
<table>
<tr>
<td><button onclick="shoesbtn(0)"><img src="images/zcropped/shoe1c.png" alt="shoe1"></button></td>
</tr>
<tr>
<td><button onclick="shoesbtn(1)"><img src="images/zcropped/shoe2c.png" alt="shoe2"></button></td>
</tr>
<tr>
<td><button onclick="shoesbtn(2)"><img src="images/zcropped/shoe3c.png" alt="shoe3"></button></td>
</tr>
<tr>
<td><button onclick="shoesbtn(3)"><img src="images/zcropped/shoe4c.png" alt="shoe4"></button></td>
</tr>
<tr>
<td><button onclick="shoesbtn(4)"><img src="images/zcropped/shoe5c.png" alt="shoe5"></button></td>
</tr>
</table>
</div>
Upon click of the image/button, a function with an index is called. Each element, or piece of clothing, has a different assigned index. If the user selects the first shirt as the shirt they'd like to put on their doll:
var shirtcanvas = document.getElementById('shirt');
var shirtcontext = shirtcanvas.getContext('2d');
var shirtImages = [
'https://raw.githubusercontent.com/codecouturebaddies/codec/gh-pages/images/tops/top1.png',
'https://raw.githubusercontent.com/codecouturebaddies/codec/gh-pages/images/tops/top2.png',
'https://raw.githubusercontent.com/codecouturebaddies/codec/gh-pages/images/tops/top3.png',
"https://raw.githubusercontent.com/codecouturebaddies/codec/gh-pages/images/tops/top4.png",
];
var shirtImage = new Image();
var shirtIndex = -1; // Track the current shirt index
var shirtVisible = false; // Flag to track shirt visibility
function shirtbtn(index) {
if (index === shirtIndex) {
// Same button clicked again
if (shirtVisible) {
shirtcontext.clearRect(0, 0, shirtcanvas.width, shirtcanvas.height);
shirtVisible = false;
} else {
shirtcontext.drawImage(shirtImage, 0, 0, shirtcanvas.width, shirtcanvas.height);
shirtVisible = true;
}
} else {
// Different button clicked, update the current index and display the shirt
shirtIndex = index;
shirtImage.onload = function() {
shirtcontext.clearRect(0, 0, shirtcanvas.width, shirtcanvas.height);
shirtcontext.drawImage(shirtImage, 0, 0, shirtcanvas.width, shirtcanvas.height);
shirtVisible = true;
};
shirtImage.src = shirtImages[index];
}
}
The index of the first shirt is 0, so when the function shirtbtn() is called, 0 is the index used throughout the function. First, it checks whether 0 is already the index, aka if the shirt is already on the doll. If it is, which means the user has already clicked on the same shirt before, it will remove the shirt. It will do this by clearing the shirtcanvas. If the index was previously a different number, then 0 will be assigned to the index. The image comes from the shirtImages list, and the image at index 0 will be called. This is the first shirt in the list, and it will be drawn on the shirt canvas, appearing right on top of the base body.
The original index of shirtIndex is -1, to represent that no shirt is chosen.
If the canvas is cleared, shirtVisible is false.
The function is the approximately the same for the dresses, shirts, pants, and shoes. The hair is a little different:
<div id="hairbox">
<div class="body-arrow" id="L-arrow">
<i class="fa fa-solid fa-angle-left fa-3x" id="hairbtn-L" onclick="hairbtnL()"></i>
</div>
<canvas id="hairDcanvas"></canvas>
<div class="body-arrow" id="R-arrow">
<i class="fa fa-solid fa-angle-right fa-3x" id="hairbtn-R" onclick="hairbtnR()"></i>
</div>
</div>
<div id="hair-setting">
<div><button id="hairundo" onclick="hairundobtn()"> Remove </button></div>
</div>
The user is able to click arrows in order to select the hair that they want. The hair selected will be displayed on the menu as well as on the doll.
var haircanvas = document.getElementById('hair');
var haircontext = haircanvas.getContext('2d');
var hairDcanvas = document.getElementById('hairDcanvas');
var hairDcontext = hairDcanvas.getContext('2d');
var hairImages = [
'https://raw.githubusercontent.com/codecouturebaddies/codec/gh-pages/images/hair/hairL-Bla.png',
'https://raw.githubusercontent.com/codecouturebaddies/codec/gh-pages/images/hair/hairL-Blo.png',
'https://raw.githubusercontent.com/codecouturebaddies/codec/gh-pages/images/hair/hairL-Bro.png',
"https://raw.githubusercontent.com/codecouturebaddies/codec/gh-pages/images/hair/hairL-G.png",
"https://raw.githubusercontent.com/codecouturebaddies/codec/gh-pages/images/hair/hairS-Bla.png",
"https://raw.githubusercontent.com/codecouturebaddies/codec/gh-pages/images/hair/hairS-Blo.png",
"https://raw.githubusercontent.com/codecouturebaddies/codec/gh-pages/images/hair/hairS-Bro.png",
"https://raw.githubusercontent.com/codecouturebaddies/codec/gh-pages/images/hair/hairS-G.png",
];
var hairImage = new Image();
var hairIndex = -1; // Track the current hair index
var hairVisible = false; // Flag to track hair visibility
function hairbtnL() {
hairIndex--;
if (hairIndex < 0) {
hairIndex = hairImages.length - 1;
}
hairbtn(hairIndex);
}
function hairbtnR() {
hairIndex++;
if (hairIndex >= hairImages.length) {
hairIndex = 0;
}
hairbtn(hairIndex);
}
function hairbtn(index) {
if (hairundo === true) {
document.querySelector('#hairundo').innerHTML = 'REMOVE';
hairundo = false;
}
hairIndex = index;
hairImage.src = hairImages[index];
hairImage.onload = function() {
haircontext.clearRect(0, 0, haircanvas.width, haircanvas.height);
haircontext.drawImage(hairImage, 0, 0, haircanvas.width, haircanvas.height);
hairDcontext.clearRect(0, 0, hairDcanvas.width, hairDcanvas.height);
hairDcontext.drawImage(hairImage, 0, 0, hairDcanvas.width, 350);
};
}
var hairundo = false;
function hairundobtn() {
haircontext.clearRect(0, 0, canvas.width, canvas.height);
hairundo = true;
document.querySelector('#hairundo').innerHTML = 'remove';
}
haircanvas is the one on the doll, hairdcanvas is the one in the menu. The same image is displayed on both. When the user clicks the right arrow button, the hair index increases by one. If the index is more than how many hair items there are, 0 is assigned, which is the first one. When the user clicks left, hair index decreases. If the index becomes less than 0, the last in the list is assigned. Once the arrow is clicked, hairbtn() is called, with the index assigned after increasing or decreasing the previous value. From here, the function is very similar to the other clothing items, except, there is no visibility tracked, instead there is a remove button. The images are drawn on the canvas the same way. If the user clicks the REMOVE button, the canvas is cleared, leaving the doll bald. However, the previous hair will still be displayed on the menu, with the index saved, so if the user clicks the arrow again, the hair list will be at the same place.
That is the aspects of our simple Code Couture dress up game. Happy styling!