Hackster is hosting Hackster Holidays, Ep. 6: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Monday!Stream Hackster Holidays, Ep. 6 on Monday!
Published © CC BY-NC-SA

DARVA - The Event Assistant

DARVA is a cute animated robot that will assist us at events, by having a chat with people so we don’t have to repeat ourselves too much.

BeginnerFull instructions provided20 hours1,365
DARVA - The Event Assistant

Things used in this project

Hardware components

Raspberry Pi 4 Model B
Raspberry Pi 4 Model B
×1
Touchscreen
×1
Felt
×1

Software apps and online services

CreateJS

Hand tools and fabrication machines

Scissors, Free Fall
Scissors, Free Fall
Needle
Thread

Story

Read more

Code

JavaScript

JavaScript
Loading and animating the images.
// 8 Bits and a Byte - DARVA

// Global variables
var stage;

// // Load images as bitmaps
var bar;
var body;
var leftarm;
var leftleg;
var rightarm;
var rightleg;
var head;
var lefteye;
var righteye;
var leftpupil;
var rightpupil;
var chart;
var needle;
var blackled;
var orangeled;
var speechbubble;
var bodyHit;


// When the page is loaded
$(document).ready(function(){
  console.log("Document ready");
  loadImages();
  // Setup the HTML Canvas
  setupCanvas();

  showTexts();
  waveArm();
  moveNeedle();
  lookAround();

});

function loadImages() {
  console.log("Start loading images");
  // // Load images as bitmaps
  bar = new createjs.Bitmap('images/Bar.png');
  body = new createjs.Bitmap('images/Belly.png');
  leftarm = new createjs.Bitmap('images/LeftArm.png');
  leftleg = new createjs.Bitmap('images/LeftLeg.png');
  rightarm = new createjs.Bitmap('images/RightArm.png');
  rightleg = new createjs.Bitmap('images/RightLeg.png');
  head = new createjs.Bitmap('images/Head.png');
  lefteye = new createjs.Bitmap('images/LeftEye.png');
  righteye = new createjs.Bitmap('images/RightEye.png');
  leftpupil = new createjs.Bitmap('images/LeftPupil.png');
  rightpupil = new createjs.Bitmap('images/RightPupil.png');
  chart = new createjs.Bitmap('images/Chart.png');
  needle = new createjs.Bitmap('images/Needle.png');
  blackled = new createjs.Bitmap('images/BlackLight.png');
  orangeled = new createjs.Bitmap('images/OrangeLight.png');
  speechbubble = new createjs.Bitmap('images/SpeechBubble.png');
  console.log("End loading images");
}


// Setup the HTML Canvas
function setupCanvas(){
  console.log("Setting up canvas");
  // Create a new stage
  stage = new createjs.Stage("myCanvas");
  stage.enableMouseOver();


  // Set the scale, position and add to the stage
  // Of all the elements of DARVA

  // Left leg
  leftleg.regX = 257;
  leftleg.regY = 141;
  leftleg.scaleX = 0.4;
  leftleg.scaleY = 0.4;
  leftleg.x = 400;
  leftleg.y = 430;
  leftleg.rotation = 90;
  stage.addChild(leftleg);

  // Right leg
  rightleg.regX = 213;
  rightleg.regY = 150;
  rightleg.scaleX = 0.4;
  rightleg.scaleY = 0.4;
  rightleg.x = 400;
  rightleg.y = 650;
  rightleg.rotation = 90;
  stage.addChild(rightleg);




  // Body
  body.regX = 690;
  body.regY = 754;
  body.scaleX = 0.4;
  body.scaleY = 0.4;
  body.x = 780;
  body.y = 550;
  body.rotation = 90;


  bodyHit = new createjs.Shape();
  bodyHit.graphics.beginFill("#000").drawRect(550, 320, 450, 450);


  bodyHit.addEventListener("click", function(event) {
    console.log("You touched my body!");
    waveLeftArm();
    //
    createjs.Tween.get(body)
        .to({ rotation: 100}, 500)
        .to({ rotation: 90 }, 500)
        .to({ rotation: 80 }, 500)
        .to({ rotation: 90 }, 500);

  })

  stage.addChild(bodyHit);
  stage.addChild(body);

  // Chart
  chart.scaleX = 0.4;
  chart.scaleY = 0.4;
  chart.x = 825;
  chart.y = 350;
  chart.rotation = 90;
  stage.addChild(chart);

  // Bar
  bar.scaleX = 0.4;
  bar.scaleY = 0.4;
  bar.x = 1030;
  bar.y = 320;
  bar.rotation = 90;
  stage.addChild(bar);

  // Needle
  needle.regX = 43;
  needle.regY = 236;
  needle.scaleX = 0.4;
  needle.scaleY = 0.4;
  needle.x = 880;
  needle.y = 420;
  needle.rotation = 90;
  stage.addChild(needle);

  // Black Light
  blackled.scaleX = 0.4;
  blackled.scaleY = 0.4;
  blackled.x = 1030;
  blackled.y = 650;
  blackled.rotation = 90;
  stage.addChild(blackled);

  // Orange Light
  orangeled.scaleX = 0.4;
  orangeled.scaleY = 0.4;
  orangeled.x = 920;
  orangeled.y = 550;
  orangeled.rotation = 90;
  stage.addChild(orangeled);

  // Speech Bubble
  speechbubble.scaleX = 0.4;
  speechbubble.scaleY = 0.4;
  speechbubble.x = 1850;
  speechbubble.y = 150;
  speechbubble.rotation = 90;
  stage.addChild(speechbubble);

  // Head
  head.regX = 455;
  head.regY = 550;
  head.scaleX = 0.4;
  head.scaleY = 0.4;
  head.x = 1250;
  head.y = 520;
  head.rotation = 90;

  headHit = new createjs.Shape();
  headHit.graphics.beginFill("#000").drawRect(1120, 400, 250, 250);


  headHit.addEventListener("click", function(event) {
    console.log("You touched my head!");

    moveLegs();
    //
      createjs.Tween.get(head)
        .to({ rotation: 80}, 500)
        .to({ rotation: 90 }, 500)
        .to({ rotation: 100 }, 500)
        .to({ rotation: 90 }, 500);

  })



  stage.addChild(headHit);
  stage.addChild(head);


  // Left eye
  lefteye.scaleX = 0.4;
  lefteye.scaleY = 0.4;
  lefteye.x = 1180;
  lefteye.y = 390;
  stage.addChild(lefteye);

  // Left pupil
  leftpupil.scaleX = 0.4;
  leftpupil.scaleY = 0.4;
  leftpupil.x = 1190;
  leftpupil.y = 390;
  stage.addChild(leftpupil);

  // Right eye
  righteye.scaleX = 0.4;
  righteye.scaleY = 0.4;
  righteye.x = 1180;
  righteye.y = 530;
  stage.addChild(righteye);

  // Right pupil
  rightpupil.scaleX = 0.4;
  rightpupil.scaleY = 0.4;
  rightpupil.x = 1200;
  rightpupil.y = 550;
  stage.addChild(rightpupil);

  // Left arm
  leftarm.regX = 460;
  leftarm.regY = 111;
  leftarm.scaleX = 0.4;
  leftarm.scaleY = 0.4;
  leftarm.x = 900;
  leftarm.y = 230;
  leftarm.rotation = 90;
  stage.addChild(leftarm);


  // Right arm
  rightarm.regX = 130;
  rightarm.regY = 860;
  rightarm.scaleX = 0.4;
  rightarm.scaleY = 0.4;
  rightarm.x = 950;
  rightarm.y = 870;
  rightarm.rotation = 70;

  stage.addChild(rightarm);

 console.log("update stage");
 stage.update();

}

createjs.Ticker.addEventListener("tick", handleTick);
createjs.Ticker.timingMode = createjs.Ticker.RAF_SYNCHED;
createjs.Ticker.framerate = 60;

function handleTick(event) {
     stage.update();

 }

function showTexts() {
  var text1 = "Hi, my name is DARVA.";
  var text2 = "I'm a virtual robot assistant."
  var text3 = "I'm here to give you some more information about this booth.";
  var text4 = "We're 8 Bits and a Byte, a YouTube channel full of DIY tech projects.";
  var text5 = "This booth is all about sharing our love for tremendously terrible tech."
  var text6 = "You can find all project details on YouTube, Hackster and Instructables."
  var text7 = "If you have any questions, feel free to ask my humans.";
  var text8 = "Have fun at Eindhoven Maker Faire!";
  var text9 = "Fun fact: I'm an interactive robot, you can touch my head and belly!";


  var answer = new createjs.Text("Bliep Bloop!", "48px Bungee", "#000000");
  answer.x = 1750;
  answer.y = 200;
  answer.rotation = 90;
  answer.textBaseline = "alphabetic";
  answer.lineWidth = 690;
  stage.addChild(answer);

  createjs.Tween.get(answer, {loop: -1})
    .wait(5000)
    .to({text:text1}, 800)
    .wait(5000)
    .to({text:text2}, 800)
    .wait(5000)
    .to({text: text3}, 800)
    .wait(5000)
    .to({text: text4}, 800)
    .wait(5000)
    .to({text: text5}, 800)
    .wait(5000)
    .to({text: text6}, 800)
    .wait(5000)
    .to({text: text7}, 800)
    .wait(5000)
    .to({text: text8}, 800)
    .wait(5000)
    .to({text: text9}, 800)
    .wait(5000);






}

function waveArm(){

  var armWait = Math.floor(Math.random() * (+15000 - + 3000)) + +3000;
  var armRotation = Math.floor(Math.random() * (+60 - + 20)) + +20;


  createjs.Tween.get(rightarm)
    .to({ rotation: 60 + armRotation }, 500)
    .to({ rotation: 60 }, 500)
    .to({ rotation: 60 - armRotation }, 500)
    .to({ rotation: 60 }, 500)
    .wait(armWait)
    .call(waveArm);

}

function waveLeftArm(){

  var armRotation = Math.floor(Math.random() * (+60 - + 40)) + +40;

  createjs.Tween.get(leftarm)
    .to({ rotation: 90+armRotation}, 500)
    .to({ rotation: 90 }, 500)
    .to({ rotation: 90-armRotation }, 500)
    .to({ rotation: 90 }, 500);


}

// Move Right arm
function moveArm(times){
  createjs.Tween.get(rightarm, {loop: times})
    .to({ rotation: 40}, 500)
    .to({ rotation: 0 }, 500)
    .to({ rotation: -40 }, 500)
    .to({ rotation: -20 }, 500)
    .wait(3000);
}


function lookAround() {
  var lookWait =  Math.floor(Math.random() * (+25000 - + 5000)) + +5000;
  var checkWait = Math.floor(Math.random() * (+5000 - + 3000)) + +3000;

  if(lookWait % 2 == 0){
    // Look left
    createjs.Tween.get(leftpupil)
      .to({ y: 400}, 50)
      .wait(checkWait)
      .to({ y: 410 }, 50)
      .wait(lookWait);

    createjs.Tween.get(rightpupil)
        .to({ y: 540}, 50)
        .wait(checkWait)
        .to({ y: 550 }, 50)
        .wait(lookWait)
        .call(lookAround);
  }
  else {

    createjs.Tween.get(leftpupil)
      .to({ y: 420}, 50)
      .wait(checkWait)
      .to({ y: 410 }, 50)
      .wait(lookWait);

      createjs.Tween.get(rightpupil)
        .to({ y: 560}, 50)
        .wait(checkWait)
        .to({ y: 550 }, 50)
        .wait(lookWait)
        .call(lookAround);

  }


}

function moveNeedle(){
  var needleRotation = Math.floor(Math.random() * (+120 - + 60)) + +60;

  createjs.Tween.get(needle)
    .to({ rotation: needleRotation}, 500)
    .call(moveNeedle);

}

function moveLegs(times){
    var legRotation = Math.floor(Math.random() * (+50 - + 20)) + +20;

  createjs.Tween.get(leftleg)
    .to({ rotation: 90+legRotation}, 1000)
    .to({ rotation: 90 }, 1000)
    .to({ rotation: 90-legRotation }, 1000)
    .to({ rotation: 90 }, 1000);

    createjs.Tween.get(rightleg)
      .to({ rotation: 90-legRotation}, 1000)
      .to({ rotation: 90 }, 1000)
      .to({ rotation: 90+legRotation }, 1000)
      .to({ rotation: 90 }, 1000);

}

function moveLeftArm(times){
    var armRotation = Math.floor(Math.random() * (+90 - + 50)) + +50;

  createjs.Tween.get(leftarm)
    .to({ rotation: armRotation}, 1000)
    .to({ rotation: 0 }, 1000)
    .to({ rotation: -armRotation }, 1000)
    .to({ rotation: 0 }, 1000);

}

function dance() {

  moveNeedle(5);

  createjs.Tween.get(head, {loop: 5})
    .to({ rotation: -10}, 500)
    .to({ rotation: 0 }, 500)
    .to({ rotation: 10 }, 500)
    .to({ rotation: 0 }, 500);

  createjs.Tween.get(body, {loop: 5})
    .to({ rotation: 10}, 500)
    .to({ rotation: 0 }, 500)
    .to({ rotation: -10 }, 500)
    .to({ rotation: 0 }, 500);

  createjs.Tween.get(leftleg, {loop: 5})
    .to({ rotation: 60}, 500)
    .to({ rotation: 0 }, 500)
    .to({ rotation: -60 }, 500)
    .to({ rotation: 0 }, 500);

    createjs.Tween.get(rightleg, {loop: 5})
      .to({ rotation: -60}, 500)
      .to({ rotation: 0 }, 500)
      .to({ rotation: 60 }, 500)
      .to({ rotation: 0 }, 500);

    createjs.Tween.get(rightarm, {loop: 5})
        .to({ rotation: 60}, 500)
        .to({ rotation: 0 }, 500)
        .to({ rotation: -60 }, 500)
        .to({ rotation: -20 }, 500);

}

HTML

HTML
The HTML webpage
<!DOCTYPE html>
<!-- 8 Bits and a Byte - DARVA -->
<html lang="en">
	<head>
		<meta charset="utf-8">
		<title>DARVA</title>
		<script type="text/javascript" src="jquery-3.4.1.min.js"></script>
		<link rel="stylesheet" type="text/css" href="style.css" >
	</head>
	<body>
				<div>
					<canvas id="myCanvas" width="1920" height="1920" style="border:0px solid #000000;"></canvas>
				</div>
		<script type="text/javascript" src="createjs.js"></script>
		<script type="text/javascript" src="tweenjs.js"></script>
		<script type="text/javascript" src="darva.js"></script>
	  </body>
</html>

CSS

CSS
Styling
@font-face {
    font-family: Bungee;
    src: url('fonts/Bungee-Regular.ttf');
}


html, body {
  margin: 0;
  padding: 0;
  font-family: 'Bungee', sans-serif;
  background-image: url("images/BlueBackgroundCroppedTurned.png");
  background-repeat: no-repeat;
  background-size: cover;
  background-color: #cccccc;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

canvas {
    display:block;
    border: 0px none black;
    position: absolute;
}

Credits

Comments