Homework 3: Mr. Smiley's Strange Journey

Short Description:

Write a program that allows the user to move Mr. Smiley home.

This assignment is worth 30 points.

Goals

When you finish this homework, you should have written a program

Formal Description

Mr. Smiley lives in a strange two dimensional world. The world is filled with a number of randomly placed columns and a home location. This world is very well rounded as everything in the world, the columns, home and Mr. Smiley are all circles. Strangely enough, the world is a rectangle!

As pictured below, Mr Smiley is a circle yellow with two eyes, a smile and an outside border. You should feel free to implement your own version of Mr. Smiley, but please make sure the basic shape is a circle.

The columns in this world are also circles. They change color based on their distance from Mr. Smiley. If Mr. Smiley is next to a column it should be Red (#ff0000). A column the maximum distance from Mr. Smiley should be gray (#808080). Other pillars should be colored with a nice transition between the two based upon their distance from Mr. Smiley.

Columns have a random radius between MIN_RADIUS and MAX_RADIUS. You may define these two CONSTANTS but they should be enough different to be visually noticeable in your program. There are COLUMNS columns displayed. Again you may define COLUMNS but it must be at least 100.

Columns are randomly placed, but there must be a minimum of MIN_GAP between the outside edge of any two columns. Again, you may define MIN_GAP but it should be at least the diameter of Mr. Smiley. He needs to fit between the columns!

Each day, Mr. Smiley starts at a random location on the left hand side of his world. His home is also random, and appears somewhere on the right hand side of the world. His home is a dark blue (#0000ff) when Mr. Smiley is the maximum distance from it:

and a nice green (#33cc3d) when he arrives at home.

While Mr. Smiley may "walk onto" his home, he may not in any way shape or form walk over a column. Nor may he walk outside of his world. That would be bad, he would probably have a major change in his life if he were to do so.

Mr. Smiley should be "moved" by the hjkl keys. The key h moves Mr. Smiley to the left, j moves down, k moves up and l moves to the right. You may implement other movement keys if you wish, but you must do this set. When these keys are pressed, Mr. Smiley should move by one pixel at a time.

Discussion

Documentation

Please use relative references to your code in the html file. This will allow me to extract the file in my local environment.

Additional Requirements/Comments

Extras

I find that I want to continue to play with simulations/visualizations of this type. Please do so, but only if you have sufficient time, do not enhance this, or any other project at the expense of your other classes.

Submission

When you have finished your assignment, please submit a tar file containing all files needed for this project. Please do not post your project on line until after grades have been assigned.

If you have created any java script text files that are included in your program, please make sure that the file extension is not .js. Mail clients will reject tar files containing files with a .js extension. Please use the extension .prog.

Submit your tar file as an attachment to a message to dbennett@edinboro.edu. Please include your name.

To create a tar file

  1. Place all files to be submitted in a folder. HW3 for example.
  2. One level above HW3 type
This will produce a file called submission.tgz which you shoud submit to your instructor (dbennett@edinboro.edu).

The HTML file:

<html>
<html>
<head>
   <script src="https://cdn.rawgit.com/google/code-prettify/master/loader/
run_prettify.js"></script>
   <link rel="stylesheet" href="http://mirkwood.cs.edinboro.edu/~bennett/s
tyle/hw.css">
</head>

<center>
<h1> Homework 3: Mr. Smiley's Strange Journey</h1>
</center>
<h3>Short Description: </h3>
Write a program that allows the user to move Mr. Smiley home. 
<p>
This assignment is worth 30 points.  

</p><h3> Goals</h3>
When you finish this homework, you should have written a program
<ul>
    <li> where the user interacts with the scene via the keyboard.
    <li> that can detect collisions between circles.
    <li> that employs simple linear parametric equations.
    <li> that employs different color spaces.
    <li> that employs classes in java script.
</ul>

<h3> Formal Description</h3>

Mr. Smiley lives in a strange two dimensional world.  The world is filled with a number of randomly placed columns and a home location.  This world is very well rounded as everything in the world, the columns, home and Mr. Smiley are all circles.  Strangely enough, the world is a rectangle!
<p>
As pictured below, Mr Smiley is a circle yellow with two eyes, a smile and an outside border.    You should feel free to implement your own version of Mr. Smiley, but please make sure the basic shape is a circle.
<p>
<canvas id="smile" width=50 height=50 style="border:2px solid"></canvas>
<script type="text/javascript" src="smile.js"></script>


<p>

The columns in this world are also circles.  They change color based on their distance from Mr. Smiley.  If Mr. Smiley is next to a column it should be Red (#ff0000).  A column the maximum distance from Mr. Smiley should be gray (#808080).  Other pillars should be colored with a nice transition between the two based upon their distance from Mr. Smiley.  
<p>
Columns have a random radius between  MIN_RADIUS and MAX_RADIUS.  You may define these two <b>CONSTANTS</b> but they should be enough different to be visually noticeable in your program.  There are COLUMNS columns displayed.  Again you may define COLUMNS but it must be at least 100.  
<p>
Columns are randomly placed, but there must be a minimum of MIN_GAP between the outside edge of any two columns.  Again, you may define MIN_GAP but it should be at least the diameter of Mr. Smiley.  He needs to fit between the columns!
<p>

<canvas id="columns" width=350 height=50 style="border:2px solid"></canvas>
<script type="text/javascript" src="column.js"></script>

<p>
Each day, Mr. Smiley starts at a random location on the left hand side of his world. His home is also random, and appears somewhere on the right hand side of the world.  His home is a dark blue (#0000ff) when Mr. Smiley is the maximum distance from it:
<p>
<img src="ss1.png">
<p>
and a nice green (#33cc3d) when he arrives at home.   
<p>
<img src="ss2.png">
<p>
While Mr. Smiley may "walk onto" his home, he may not in any way shape or form walk over a column.  Nor may he walk outside of his world.  That would be bad, he would probably have a major change in his life if he were to do so.
<p>
Mr. Smiley should be "moved" by the hjkl keys.  The key <b>h</b> moves Mr. Smiley to the left, <b>j</b> moves down, <b>k</b> moves up and <b>l</b> moves to the right.  You may implement other movement keys if you wish, but you must do this set.  When these keys are pressed, Mr. Smiley should move by one pixel at a time.
<h3> Discussion</h3>
<ul>
    <li> All java script files must begin with <b>'use strict'</b>
    <li> Your program must run with no errors or warnings.
    <li> The majority of your java script code must be in .prog files.
    <li> For the most part, RGB is not your friend in this program.   Do not use an interpolation between RGB colors.  You will change a strange <em>hue</eM> of red when the <em>light</em> dawns on you that you <em>saturated</em> your debugging time with useless efforts working in RGB space.  
    <li> When Mr. Smiley arrives at home, he should "cover" or "walk over" the home circle.
    <li> You can assign constants such that the world is impossible to build.  I used the following (assuming a 500x500 canvas)
    <pre class="prettyprint">
const MIN_RADIUS =  2;
const MAX_RADIUS = 20;
const COLUMNS = 100;

const SMILE_WIDTH = 8;
const MIN_GAP = SMILE_WIDTH*2+1;
</pre>
    <li> You must create at least one class in javascript.  
    <li> I found <a href="https://www.w3schools.com/colors/colors_hsl.asp">this page</a> to be helpful.
</ul>
<h3> Documentation</h3>
Please use relative references to your code in the html file.  This will allow me to extract the file in my local environment.
<h3>Additional Requirements/Comments</h3>
<ul>
    <li> I expect you to build your code based on my examples.
</ul>
<h3>Extras</h3>
I find that I want to continue to play with simulations/visualizations of this type.  Please do so, but only if you have sufficient time, do not enhance this, or any other project at the expense of your other classes.  
<h3>Submission</h3>
When you have finished your assignment, please submit a tar file containing all files needed for this project.  Please do not post your project on line until after grades have been assigned.
<p>
If you have created any java script text files that are included in your program, please make sure that the file extension is not .js.  Mail clients will reject tar files containing files with a .js extension.  Please use the extension .prog.
<p>
Submit your tar file as an attachment to a message to dbennett@edinboro.edu.  Please include your name.
<p>
To create a tar file
<ol>
   <li> Place all files to be submitted in a folder.  <b>HW3</b> for example.
   <li> One level above HW3 type 
   <ul>
       <li> <tt>tar cvzf submission.tgz HW3</tt>
   </ul>
</ol>
This will produce a file called <b>submission.tgz</b> which you shoud submit to your instructor (dbennett@edinboro.edu).
</body></html>

column.js

'use strict'

function Column(ctx, cx, cy, radius,  color) {

    ctx.strokeStyle = 'black';
    ctx.fillStyle = color;
    ctx.beginPath();
    ctx.arc(cx, cy, radius, 0, 2*Math.PI);
    ctx.fill();
    ctx.stroke();
}

function DoColumns() {
    let columnCanvas = document.getElementById('columns');
    let ctx = columnCanvas.getContext('2d');

    let offset = Math.floor(columnCanvas.width/4);
    let cy = Math.floor(columnCanvas.height/2);
    let radius = Math.floor(0.9 * cy);

    Column(ctx, offset, cy, radius, "#ff0000");
    Column(ctx, offset*2, cy, radius, "#bf4040");
    Column(ctx, offset*3, cy, radius, "#808080");

    ctx.beginPath();
    ctx.moveTo(offset+radius, cy);
    ctx.lineTo(offset*2-radius, cy);

    let textMeasure = ctx.measureText("MIN_GAP");
    ctx.strokeText("MIN_GAP", offset + offset/2-textMeasure.width/2, cy-5);
    ctx.stroke();
}

DoColumns()

smile.js

'use strict'

function DoSmile() {
    var smileCanvas = document.getElementById('smile');
    var ctx = smileCanvas.getContext('2d');

    let cx = Math.floor(smileCanvas.width/2);
    let cy = Math.floor(smileCanvas.height/2);

    let radius = Math.floor(.9*Math.min(cx,cy));
    let smallR = Math.floor(.5*radius);
    let width = Math.max(Math.floor(.2*radius),1)

    ctx.strokeStyle = "black";
    ctx.fillStyle = "yellow";
    ctx.beginPath();
    ctx.arc(cx, cy, radius, 0, 2*Math.PI);
    ctx.fill();
    ctx.stroke();

    ctx.beginPath();
    ctx.arc(cx, cy, smallR, 0, Math.PI);
    ctx.stroke();
    ctx.fillStyle = "black";
    ctx.beginPath();
    ctx.arc(cx-smallR, cy-smallR, width,  0, 2*Math.PI);
    ctx.fill()
    ctx.beginPath();
    ctx.arc(cx+smallR, cy-smallR, width,  0, 2*Math.PI);
    ctx.fill()
}
DoSmile();