Hi I have a web programming class, and I am having difficulty with writting the
ID: 3571535 • Letter: H
Question
Hi I have a web programming class, and I am having difficulty with writting the javascript code. For this assignment we have to use the JQuery and Raphael libraries.
For this project we have to create a game area using Raphael. When the user selects the difficulty and type of shape, they shapes should appear and the user has to click the shapes before they dissapear. Here is a link to the video which shows the behaviour the webpage should have: https://www.youtube.com/watch?v=fiWhAHx2TW8
Requirements for the game:
1) A choice of “difficulty” as a text input. Higher numbers are harder. The way the game becomes “difficult” is up to you, but some options: more shapes; smaller shapes; faster shapes; less time to zap them.
2) A selector where the player can choose the shape they want added to the game, with at least three options.
3) At least one of the shapes must be drawn with as a .path (not one of the built-in shapes Raphaël will draw for you). (I want to use a triangle)
4) The shapes appear at random locations and move in random directions (i.e. towards a random point).
5) Count the score: the number of shapes “zapped” to make them disappear, and the number that “escape”.
Here is my HTML and CSS:
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script src="http://cmpt165.csil.sfu.ca/js/jquery-3.1.0.js"></script>
<script src="http://cmpt165.csil.sfu.ca/js/raphael-2.1.4.js"></script>
<script src="game.js"></script>
<link rel="stylesheet" href="game.css" />
<title>Assignment 4 Zap'em</title>
</head>
<body>
<h1>Assignment 4 Zap'em</h1>
<div class="form">Difficulty:
<input type="text" id="level" />
Shape: <select id="selectshape">
<option value="a">Circle</option>
<option value="b">Square</option>
<option value="c">Triangle</option>
</select> <br>
<button id="start">Start</button>
</div>
<div id="svg"></div>
<div>Zapped:<span id='zap' value='0'>0</span></div>
<div>Escaped:0</div>
</body>
</html>
CSS:
div#svg {
border: thin #888 solid;
height: 400px;
width: 400px;
margin: 1.5em 0em;
}
body {
margin-left: 1.5em;
}
input#level {
max-width: 35px;
}
Here is what I have so far for the Javascript: (It doesn't work at all, and i am probably missing a ton of code)
var paper;
zap = function() {
this.remove();
}
gamestart = function() {
shapeNum = $('#level').val();
shapetype = $('#selectshape').val();
for (step = 0; step < shapeNum; step += 1) {
if ( shapetype = a) {
shape = paper.circle(x,y,10); /* draw shape 1 near (0,0) */
}
if ( shapetype = b ) {
shape = paper.rect(x,y,10,10); /* draw shape 2 near (0,0) */
}
if (shapetype = c) {
shape = paper.path('M0,0 L20,30 L20,60 Z'); /* draw shape 3 near (0,0) */
}
}
x = Math.random() * 400;
y = Math.random() * 400;
shape_attr = {
'transform': 't' + x + ',' + y,
'fill': '#ddf'
}
shape.attr(shape_attr);
shape.click(zap);
}
}
setup = function() {
paper = Raphael('svg', 400, 400);
$('#start').click(gamestart);
}
$(document).ready(setup)
Here is the hints the prof gave:
Drawing
You will need a for to draw several shapes, and an if (inside the for) to draw the shape the user requested.
It may be easier to draw all of your shapes in the same place and then translate them to a random location. I drew all of mine around 0,0, generated random x and y values, and applied a transform to get it there:
if ( ??? ) {
shape = ??? /* draw shape 1 near (0,0) */
}
if ( ??? ) {
shape = ??? /* draw shape 2 near (0,0) */
}
if ( ??? ) {
shape = ??? /* draw shape 3 near (0,0) */
}
x = ???
y = ???
shape_attr = {
'transform': 't' + x + ',' + y,
'fill': ...
...
}
shape.attr(shape_attr)
Make sure you give the shapes a 'fill' so the player can click the middle, not just the outlines.
The .path() shape needs to be closed so it will look nice filled: end your path string with Z.
Keeping Score
Keeping the number zapped and missed is a little tricky. The strategy needs to be:
When the shape is created, give it a .click() handler so we can zap it when the user clicks.
When it's created, start an animation that determines the time during which it can be clicked: at the end of the animation, we'll declare it missed.
In the shape's click handler, remove it from the SVG and count it as zapped.
When the animation is over, remove the shape from the SVG and count it as missed.
To do this, we need to use more arguments on .animate():
shape.animate(attributes, time, 'linear', callback)
We have see the first two arguments: new attributes, and how long the animation should take. We'll ignore the third argument and leave it as 'linear' (the default).
When the animation is over, Raphaël will run the function callback(). The callback argument gives us a way to run some logic at the end of the animation. For us, that's when the user has “missed”.
The initial setup for each shape will be:
shape.click(zap)
shape.animate(..., ..., 'linear', miss)
Then in each of the miss and zap functions:
Remove the shape from the image.
Add one to a variable keeping track of the total zaps/misses.
Update the display of zaps and misses in the HTML.
if ( ??? ) {
shape = ??? /* draw shape 1 near (0,0) */
}
if ( ??? ) {
shape = ??? /* draw shape 2 near (0,0) */
}
if ( ??? ) {
shape = ??? /* draw shape 3 near (0,0) */
}
x = ???
y = ???
shape_attr = {
'transform': 't' + x + ',' + y,
'fill': ...
...
}
shape.attr(shape_attr)
Explanation / Answer
Ok, So you have outlined the basic Code of JavaScript. You just need little bit of guidance.
There were some syntax errors and assignment statements in if,else instead of comparison statements. So let me first paste the correct version of your code.
var paper;
var zap = function() {
this.remove();
};
var gamestart = function() {
var shapeNum = $('#level').val();
var shapetype = $('#selectshape').val();
var shape;
for (var step = 0; step < shapeNum; step += 1) {
if ( shapetype == "a") {
shape = paper.circle(x,y,10); /* draw shape 1 near (0,0) */
}
if ( shapetype == "b" ) {
shape = paper.rect(x,y,10,10); /* draw shape 2 near (0,0) */
}
if (shapetype == "c") {
shape = paper.path('M0,0 L20,30 L20,60 Z'); /* draw shape 3 near (0,0) */
}
}
var x = Math.random() * 400;
var y = Math.random() * 400;
var shape_attr = {
'transform': 't' + x + ',' + y,
'fill': '#ddf'
};
shape.attr(shape_attr);
shape.click(zap);
};
var setup = function() {
paper = Raphael('svg', 400, 400);
$('#start').click(gamestart);
};
$(document).ready(setup)
Now, there are some more variables and functions which you need to define. Like one for total number of zaps, or missed. Then, the .animate with .click. .animate() will take a callback function and time while you want that animation/image/shape to last. Last but not the least the value of zaps, and misses should be handled in miss function (callback for animate) and zap function. So the code should look like :
var paper;
var totalZaps=0, totalMisses =0;
var zap = function() {
totalZaps++;
this.remove();
};
var miss = function() {
this.remove();
totalMisses++;
};
var gamestart = function() {
var shapeNum = $('#level').val();
var shapetype = $('#selectshape').val();
var shape;
var x = 0, y = 0;
for (var step = 0; step < shapeNum; step += 1) {
if ( shapetype == "a") {
shape = paper.circle(0,0,10); /* draw shape 1 near (0,0) */
shape.animate({cy:Math.random() * 400,cx:Math.random() * 400}, 5000, 'linear', miss);
}
if ( shapetype == "b" ) {
shape = paper.rect(0,0,10,10); /* draw shape 2 near (0,0) */
shape.animate({y:Math.random() * 400,x:Math.random() * 400}, 5000, 'linear', miss);
}
if (shapetype == "c") {
var _transformedPath = Raphael.transformPath('M100 100L190 190', 'T400,0');
shape = paper.path('M0,0 L20,30 L20,60 Z');/* draw shape 3 near (0,0) */
shape.animate({path:_transformedPath}, 5000, 'linear', miss);
}
x = Math.random() * 400;
y = Math.random() * 400;
var shape_attr = {
'transform': 'T'+x+','+y,
'fill': '#ddf'
};
shape.attr(shape_attr);
shape.click(zap);
}
};
var setup = function() {
paper = Raphael('svg', 400, 400);
$('#start').click(gamestart);
};
$(document).ready(setup);
You can use the time section as per difficulty in your html and attributes section in animate to add more attributes. and show totalZaps and totaMisses on HTML page.