Gift wrapping

It’s about time you wrap your presents if you haven’t done so already. Christmas is 3 days away! We’ll therefore be using 22 LEDs in a simple memory game related to gift wrapping.

gift_hero

You’ll need:

  • 5×4 5mm LEDs (yellow, red, white, blue, gree)
  • 2 10mm LEDs (red & green)
  • Makey Makey
  • Arduino UNO
  • Breadboard + wires + alligator clips
  • Conductive tape

1) The game logic
This game is pretty simple, it will display a gift, with a wrapper, a ribbon and a pattern that have different colours for a few seconds, and you’ll have to remember the colours to score points. Picking a colour will be done by tapping the area next to the LEDs with the associated colour. You will consecutively be picking the wrapper, the ribbon, and then the pattern.

a- HTML
Let’s start by drawing our gift on the screen, simply with divs

<body>
    <div class="score">0</div>

    <div class="ribbon-top"></div>
   <div class="gift">
        <div class="patterns">
            <div class="pattern"></div>
            <div class="pattern"></div>
            <div class="pattern"></div>
            <div class="pattern"></div>
            <div class="pattern"></div>
            <div class="pattern"></div>
            <div class="pattern"></div>
            <div class="pattern"></div>
            <div class="pattern"></div>
            <div class="pattern"></div>
            <div class="pattern"></div>
            <div class="pattern"></div>
            <div class="pattern"></div>
            <div class="pattern"></div>
            <div class="pattern"></div>
            <div class="pattern"></div>
            <div class="pattern"></div>
            <div class="pattern"></div>
            <div class="pattern"></div>
            <div class="pattern"></div>
        </div>
        <div class="ribbon vertical"></div>
        <div class="ribbon horizontal"></div>
    </div>
</body>

b- CSS
Now let’s style this to make it look more like a present with a bit of CSS.

body {
  width: 100%;
  height: auto;
  overflow: hidden;
}
.gift {
  position: relative;
  width: 400px;
  height: 500px;
  margin: 0 auto;
  border: 2px solid black;
  background-color: white;
}
.ribbon {
  position: absolute;
  width: 20px;
  height: 100%;
  border: 1px solid black;
  background-color: white;
}
.horizontal {
  height: 80%;
  left: 190px;
  top: 30px;
  -webkit-transform: rotate(90deg);
}
.vertical {
  top: 0;
  left: 190px;
}
.ribbon-top {
  width: 100px;
  height: 50px;
  border-radius: 50px;
  background-color: white;
  border: 1px solid black;
  margin: 100px auto 0 auto;
}
.patterns {
  position: absolute;
  width: 100%;
  height: 100%;
}
.pattern {
  border: 1px solid black;
  background-color: white;
  width: 50px;
  height: 50px;
  border-radius: 50px;
  float: left;
  margin: 25px 20px 20px 25px;
}

html_presents

c- JavaScript

var colours = ["yellow", "red", "blue", "green", "white"];
    var wrapProgressSelectors =[".gift", ".ribbon, .ribbon-top", ".pattern"];
    var selectedColours =[];
    var wrap_progress = 0;
    var score = 0;

    pickWrapping();

    function pickWrapping() {
        selectedColours =[];
        
        pickWrapperColour();
        pickRibbonColour();
        pickPatternColour();


        setTimeout(function(){
            resetWrapper();
        }, 1500);        
    }


    function pickWrapperColour() {
        var random = Math.floor(Math.random()*1000%colours.length);
        $(wrapProgressSelectors[0]).css({'background-color': colours[random]});

        selectedColours.push(colours[random]);
    }

    function pickRibbonColour() {
        var random = Math.floor(Math.random()*1000%colours.length);
        $(wrapProgressSelectors[1]).css('background-color', colours[random]);

        selectedColours.push(colours[random]);
    }

    function pickPatternColour() {
        var random = Math.floor(Math.random()*1000%colours.length);
        $(wrapProgressSelectors[2]).css('background-color', colours[random]);

        selectedColours.push(colours[random]);
    }

We set up the variables, and pick our first wrapper, display it for 1.5 seconds and hide it wit the resetWrapper() function:

    function resetWrapper() {
        $('.gift, .ribbon, .ribbon-top, .pattern').css({'background-color':'white'});
    }

Because the Makey Makey works with specific keyboard inputs, we assign those keys to a colour and update the display of the gift when a key is pressed:

$(document).keydown(detectKey);
 function detectKey(event){
        var unicode=event.keyCode? event.keyCode : event.charCode;

        switch(unicode)
        {
                 
            case 32: //Space
                updateGiftWrap(colours[0]);
                break;
                 
            case 38: //up
                updateGiftWrap(colours[1]);
                break;
                 
            case 40: //down
                updateGiftWrap(colours[2]);
                break;
                 
            case 39: //right
                updateGiftWrap(colours[3]);
                break;  
                 
            case 37: //left
                updateGiftWrap(colours[4]);
                break;      
        }
    }

function updateGiftWrap(colour) {
        $(wrapProgressSelectors[wrap_progress]).css({'background-color': colour});
        if(selectedColours[wrap_progress] == colour) {
            score += 10;
        }

        $('.score').text(''+score);
        
        updateWrappingStatus();
    }

Once we’ve compared which colours was picked for the wrapper, the ribbon and the pattern with the original present and updated the score accordingly, we pick a new design:

function updateWrappingStatus() {
        if(wrap_progress > 1) {
            wrap_progress = 0;
            resetWrapper();
            setTimeout(function(){
                pickWrapping();
            }, 1000);
        } else {
            wrap_progress++;
        }
    }

2) Adding the hardware
Now group the LEDs by colours, link each colour to 1 Arduino pin. If you’d like to know more about BreakoutJS, Arduino and Makey Makey, have a look at the Whack-A-Grinch project. We’re actually going to do something a bit simpler.
We’ll have the LEDs on all the time, but switched off on keyPress, to notice whether it’s been selected or not.
And we’ll use a green and a red LED to show if the present produced was the same as the one requested.

gifts_1

We need to declare the Arduino board and all the LED pins, then we light them on and finally switch them off on key press, before resetting them.

function init() {
        ledY = new LED(arduino, arduino.getDigitalPin(10));
        ledY.on();

        ledR = new LED(arduino, arduino.getDigitalPin(12));
        ledR.on();

        ledB = new LED(arduino, arduino.getDigitalPin(9));
        ledB.on();

        ledG = new LED(arduino, arduino.getDigitalPin(8));
        ledG.on();

        ledW = new LED(arduino, arduino.getDigitalPin(11));
        ledW.on();

        winLED = new LED(arduino, arduino.getDigitalPin(5));
        loseLED = new LED(arduino, arduino.getDigitalPin(6));

        ledColours.push(ledY, ledR, ledB, ledG, ledW);

        pickWrapping();


    }

function detectKey(event){
        var unicode=event.keyCode? event.keyCode : event.charCode;

        switch(unicode)
        {
                 
            case 32: //Space
                currentLED = ledColours[0];
                playerInput.push(colours[0]);
                updateGiftWrap(colours[0]);
                break;
                 
            case 38: //up
                currentLED = ledColours[1];
                playerInput.push(colours[1]);
                updateGiftWrap(colours[1]);
                break;
                 
            case 40: //down
                currentLED = ledColours[2];
                playerInput.push(colours[2]);
                updateGiftWrap(colours[2]);
                break;
                 
            case 39: //right
                currentLED = ledColours[3];
                playerInput.push(colours[3]);
                updateGiftWrap(colours[3]);
                break;  
                 
            case 37: //left
                currentLED = ledColours[4];
                playerInput.push(colours[4]);
                updateGiftWrap(colours[4]);
                break;      
        }
    }
function updateGiftWrap(colour) {
        currentLED.off();

        $(wrapProgressSelectors[wrap_progress]).css({'background-color': colour});

        $('.score').text(''+score);
        
        setTimeout(function(){
            currentLED.on();
            updateWrappingStatus();
            currentLED = "";

        }, 100);
    }

gifts_2

I am going to update the score to show only the number of gifts properly wrapped, instead of increasing it per correct colour.
That way, if the whole wrapping is correct, I can light up the green LED, and if not, the red one. I reset these when I pick a new wrapping instruction.


function updateScore (){
        var total = 0;
        for(var i = 0; i<selectedColours.length; i++){
            if(selectedColours[i] == playerInput[i]){
                total++;
            }
        }

        if(total == 3){
            winLED.blink(200,4);
        } else {
            loseLED.blink(300,4);
        }

        setTimeout(function(){
            resetWrapper();
            pickWrapping();
        }, 1000);
    }

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s