Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
670 lines (568 sloc) 22.9 KB
<!doctype html>
<html>
<head>
<meta name="mobile-web-app-capable" content="yes">
<title>app</title>
<style type="text/css">
html, body, canvas {
height: 100%;
width: 100%;
margin: 0;
}
#viewport {
position: relative;
height: 100%;
background: #1d1f20;
}
</style>
<script src="/js/socket.io-1.2.0.js"></script>
<script src="/js/jquery-1.11.1.js"></script>
<script src="/js/paper-full.js"></script>
<script type="text/paperscript" canvas="myCanvas">
var socket = io();
var x = [];
var y = [];
// window
var width = view.bounds.width;
var height = view.bounds.height;
var size = 1;
var urchin_radius = 20;
// slingshot
var arm_size = 350;
var slingshot, firing_pad, arm_top, arm_bottom;
var ready;
var createCircle = function (x, y, r, color) {
return new Shape.Circle({
center: new Point(x,y),
radius: r,
strokeColor: color,
fillColor: color
});
};
var random = function (a, b) {
return a + (Math.random() * (b - a));
};
// Helper function to return min of two numbers
var min = function (a, b) {
if (a < b) return a;
else return b;
};
// Make eel glow red or green
var glow = function (eel, color) {
eel.body.strokeColor = color;
eel.tail.fillColor = color;
eel.head.fillColor = color;
};
function target_hit (urchin, target, width, arena) {
var bb_x = width - 50;
var urchin_x = urchin.group.position.x + arena.urchin_radius;
if (urchin_x >= bb_x) {
var urchin_y1 = urchin.group.position.y + arena.urchin_radius;
var urchin_y2 = urchin.group.position.y - arena.urchin_radius;
return (urchin_y2 >= target.top && urchin_y1 <= target.bottom);
}
return false;
}
function eel_hit (urchin, eel, arena) {
var bb_x = eel.group.position.x - 10;
var urchin_x = urchin.group.position.x + arena.urchin_radius;
if (urchin_x >= bb_x) {
var bb_y1 = eel.group.position.y + 100;
var bb_y2 = eel.group.position.y - 100;
var urchin_y1 = urchin.group.position.y + arena.urchin_radius;
var urchin_y2 = urchin.group.position.y - arena.urchin_radius;
return urchin_y1 <= bb_y1 && urchin_y2 >= bb_y2;
}
return false;
}
// Function to create a chest target
var chest = function (y1, y2, width) {
var box = new Rectangle({
topLeft: new Point(width + 60, y1),
topRight: new Point(width - 10, y1),
bottomLeft: new Point(width + 60, y2),
bottomRight: new Point(width - 10, y2)
});
var corner_size = new Size(10, 10);
var rounded_box = new Path.RoundRectangle(box, corner_size);
rounded_box.fillColor = 'brown';
rounded_box.strokeColor = 'yellow';
rounded_box.strokeWidth = 3;
var handle = new Path.Circle(new Point(width + 55, (y1 + y2) / 2), 15);
handle.fillColor = 'brown';
handle.strokeColor = 'yellow';
handle.strokeWidth = 3;
var group = new Group(handle, rounded_box);
var interval = (y2 - y1) / 8;
var line;
for (var i = 1; i < 8; i++) {
line = new Path(new Point(width + 60, y1 + (i * interval)), new Point(width, y1 + (i * interval)));
line.strokeColor = 'yellow';
line.strokeWidth = 3;
line.opacity = 0.7;
}
group.opacity = 0.7;
return group;
};
// Solve for y given circle radius and x
var circle_y = function (x, rad) {
return Math.sqrt(Math.pow(rad, 2) - Math.pow(x, 2));
};
// Function to create a slingshot line segment
var segment = function (x1, y1, x2, y2) {
var seg = new Path();
seg.strokeColor = 'coral';
seg.strokeWidth = 30;
seg.opacity = 0.8;
// Add the starting location
seg.add(new Point(x1, y1));
// Add segments between start and end
var unit = (x2 - x1) / 5.0;
for (var i = 1; i < 5; i++) {
// Make them deviate a little in the y direction
seg.add(new Point(x1 + i * unit, y1 + Math.random() * 20));
}
// Add the end location
seg.add(new Point(x2, y2));
seg.strokeCap = 'round';
seg.opacity = 0.5;
return seg;
};
var bubble_colors = ['#E2FFE6', '#DDFEFE', '#DEF6FD', '#FAECFF'];
// Function to create a bubble
var bubble = function (pos, size) {
var b = new Path.Circle(pos, size);
b.strokeColor = bubble_colors[Math.floor(Math.random() * bubble_colors.length)];
b.strokeWidth = Math.ceil(1 + Math.random() * 4);
b.opacity = 0.1 + Math.random();
return b;
};
// Function to create the resize buttons
var button = function (x, y, w, h) {
var rect = new Rectangle(new Point(x, y), new Size(w, h));
var cornerSize = new Size(10, 10);
var b = new Path.RoundRectangle(rect, cornerSize);
b.strokeColor = 'black';
b.strokeWidth = 3;
b.fillColor = 'white';
b.opacity = 0.4;
b.clicked = false;
return b;
};
// Have a different setup based on chosen slingshot arm separation size
var setup = function (size, width, height, radius, arm_size) {
var components = {};
// Where the spring/slingshot base starts off at
components.start = {};
// Used to position the arms
var mid = height / 2;
var a = mid + ((size / 2.0) * mid);
var b = mid - ((size / 2.0) * mid);
// Slingshot arms (made of coral)
components.armTop = {
x1: width, y1: a, x2: width - arm_size, y2: a,
create: function () { return segment(this.x1, this.y1, this.x2, this.y2); }
};
components.armBottom = {
x1: width, y1: b, x2: width - arm_size, y2: b,
create: function () { return segment(this.x1, this.y1, this.x2, this.y2); }
};
// Slingshot
components.slingshot = function () {
var slingshot = new Path();
// Add an extra 15 - this is half the size of the coral arm width
// allows seaweed to 'wrap around' arm
slingshot.add(new Point(width - arm_size, a + 15));
// Where the urchin will be nestled to start with
components.start.x = width - arm_size + 20;
components.start.y = a - ((a - b) / 2);
slingshot.apex = slingshot.add(new Point(components.start.x, components.start.y));
slingshot.add(new Point(width - arm_size, b - 15));
slingshot.strokeColor = 'green';
slingshot.strokeWidth = 10;
slingshot.smooth();
slingshot.strokeCap = 'butt';
return slingshot;
};
// Firing pad
components.pad = function () {
var p = new Path(new Point(1012, 0), new Point(1012, height));
p.strokeColor = 'red';
p.strokeWidth = 24;
p.opacity = 0.7;
return p;
};
// The urchin center is slightly offset from the center of the slingshot
components.urchin_radius = radius;
components.urchin_center = null;
components.urchin = function () {
components.urchin_center = center = {x: components.start.x + 20, y: components.start.y - 8};
// Add spikes to urchin
// var spikes = [];
// for (var i = 0; i < 200; i++) {
// var s = spike(center, components.urchin_radius);
// s.rotate(Math.random() * 500);
// spikes.push(s);
// }
// var body = new Group(spikes);
// body.fillColor = 'black';
// body.opacity = 0.6;
// body.position = center;
// // Add eyes to urchin
// var eye1 = new Path.Circle(new Point(center.x - 5, center.y), 8);
// var eye2 = new Path.Circle(new Point(center.x + 5, center.y), 8);
// var inner1 = new Path.Circle(new Point(center.x - 5, center.y), 2);
// var inner2 = new Path.Circle(new Point(center.x + 5, center.y), 2);
// var outers = new Group(eye1, eye2);
// var inners = new Group(inner1, inner2);
// outers.fillColor = 'black';
// inners.fillColor = 'white';
// var eyes = new Group(outers, inners);
// var group = new Group(body, eyes, inners);;
// var urchin = {body: body, eyes: eyes, inners: inners, group: group}
var ball = new Path.Circle(new Point(center.x - urchin_radius - 10, center.y), urchin_radius);
ball.fillColor = 'black';
ball.opacity = 0.7;
var urchin = {body: ball};
return urchin;
};
// Fish target
components.fish = function (size) {
var body = new Path();
// TODO
};
// Eel - direction is 1 or -1
components.eel = function (specs) {
var body = new Path(specs.p);
var back = new Path(specs.p);
// Add segments to the eel body, each of size 'size'
var point;
for (var i = 1; i < 4; i++) {
point = new Point(specs.p.x, specs.p.y + specs.dir * specs.size * i)
body.add(point);
back.add(point);
}
// Add the eyes
var lefteye = new Path.Circle(new Point(specs.p.x - 5, specs.p.y), 6);
var righteye = new Path.Circle(new Point(specs.p.x + 5, specs.p.y), 6);
var eyes = new Group(lefteye, righteye);
eyes.fillColor = 'black';
// Add the tip of the tail
var p = body.segments[3].point;
var end = new Point(p.x, p.y - (specs.size / 2));
var tail = new Path(new Point(p.x - 10, p.y), end, new Point(p.x + 10, p.y));
// Add a little head
p = body.segments[0].point;
var start = new Point(p.x, p.y + 10);
var head = new Path(new Point(p.x - 10, p.y), start, new Point(p.x + 10, p.y));
// Stylings
var group = new Group(body, back, eyes, tail);
body.smooth(); back.smooth(); tail.smooth(); head.smooth();
body.strokeColor = 'green'; tail.fillColor = 'green'; head.fillColor = 'green';
back.strokeColor = 'black';
body.strokeWidth = 20;
back.strokeWidth = 5;
body.opacity = 0.5; back.opacity = 0.5; tail.opacity = 0.5; eyes.opacity = 0.5; head.opacity = 0.5;
back.strokeCap = 'round';
this.body = body;
this.back = back;
this.eyes = eyes;
this.tail = tail;
this.head = head;
this.group = new Group(body, back, eyes, tail, head);
return this;
};
components.animate_eel = function (eel, time, step, start_x, width) {
// Start from top if we're at the bottom
if (eel.tail.position.y > 800) eel.group.position.y = -100;
var segment1, segment2, sinus, sway;
var top_pos, bottom_pos;
for (var i = 0; i < 4; i++) {
segment1 = eel.body.segments[i];
segment2 = eel.back.segments[i];
// Pick a cylic value between -1 and 1
sinus = Math.sin(time * 2 + i*1.3);
// Move the eel body segments side to side
sway = sinus * width + start_x;
segment1.point.x = sway;
segment2.point.x = sway;
if (i == 0) top_pos = segment1.point.x;
if (i == 3) bottom_pos = segment1.point.x;
}
// Advance the eel up and down
eel.group.position.y += step;
eel.eyes.position.x = top_pos;
eel.tail.position.x = bottom_pos;
eel.tail.segments[1].x = top_pos;
eel.head.position.x = top_pos;
};
components.init_bubbles = function (n, width, height) {
var bubbles = [];
var pos, rad, bub;
for (var i = 0; i < n; i++) {
pos = new Point(Math.random() * width, Math.random() * height);
rad = Math.random() * 10;
bub = bubble(pos, rad);
bubbles.push(bub);
}
return bubbles;
};
components.animate_bubbles = function (bubbles, step, width) {
for (var i = 0; i < bubbles.length; i++) {
// reset if needed
if (bubbles[i].position.x > width) bubbles[i].position.x = 0;
// otherwise move bubble
else bubbles[i].position.x += step;
}
};
// Chest targets
components.chest_top = function (y1, y2, width) {
this.top = y1;
this.bottom = y2;
this.chest = chest(y1, y2, width);
return this;
};
components.chest_bottom = function (y1, y2, width) {
this.top = y1;
this.bottom = y2;
this.chest = chest(y1, y2, width);
return this;
};
components.score_card = function (width, height) {
var mid = height / 2;
var card = new Rectangle({
topLeft: new Point(width + 60, mid - 25),
topRight: new Point(width - 10, mid - 25),
bottomLeft: new Point(width + 60, mid + 25),
bottomRight: new Point(width - 10, mid + 25)
});
var round_card = new Path.RoundRectangle(card, new Size(5, 5));
round_card.fillColor = 'red';
round_card.opacity = 0.6;
var score = new PointText(new Point(width + 28, mid + 9));
score.justification = 'center';
score.fillColor = 'black';
score.content = '2';
score.fontSize = 25;
score.fontWeight = 200;
score.rotate(-90);
this.card = card;
this.score = score;
return this;
};
return components;
};
// Colors and gradient width percentages for the sea gradient
var sea_colors = ["#9ED1B7", "#78A890", "#09738A", "#092B5A"];
// Make the background a nice gradient of blue/green
var background = new Path.Rectangle({
topLeft: new Point(0, 0),
topRight: new Point(width, 0),
bottomLeft: new Point(0, height),
bottomRight: new Point(width, height),
fillColor: {
gradient: {stops: sea_colors},
origin: new Point(0, height / 2),
destination: new Point(width, height / 2)
}
});
var topLeft = createCircle(view.center.x, 0, 60, 'red');
var topRight = createCircle(view.bounds.width, 0, 60, 'red');
var bottomLeft = createCircle(view.center.x, view.bounds.height, 60, 'red');
var bottomRight = createCircle(view.bounds.width, view.bounds.height, 60, 'red');
var center = createCircle(view.center.x, view.center.y, 60, 'red');
var ball = createCircle(-100, -100, 40, 'OrangeRed');
var initCircles = [topLeft, bottomLeft, bottomRight, topRight];
var user = new Shape.Circle({
center: view.center,
radius: 60,
strokeColor: 'DarkGoldenRod',
strokeWidth: 20
});
var arena, urchin, eel;
var countClicks = 0;
var buttons = {};
function onMouseDown(event) {
if (countClicks < 6) {
switch (countClicks) {
case 0:
center.fillColor = 'green';
center.strokeColor = 'green';
view.draw();
socket.emit('map', countClicks);
countClicks++;
break;
case 1:
bottomLeft.fillColor = 'green';
bottomLeft.strokeColor = 'green';
view.draw();
socket.emit('map', countClicks);
countClicks++;
break;
case 2:
bottomRight.fillColor = 'green';
bottomRight.strokeColor = 'green';
view.draw();
socket.emit('map', countClicks);
countClicks++;
break;
case 3:
topRight.fillColor = 'green';
topRight.strokeColor = 'green';
view.draw();
socket.emit('map', countClicks);
countClicks++;
break;
case 4:
topLeft.fillColor = 'green';
topLeft.strokeColor = 'green';
view.draw();
socket.emit('map', countClicks);
countClicks++;
break;
case 5:
center.remove();
topLeft.remove();
topRight.remove();
bottomLeft.remove();
bottomRight.remove();
ball.position = new Point(500, 100);
// Set up the slingshot arena
arena = setup(size, width, height, urchin_radius, arm_size);
arm_top = arena.armTop.create();
arm_bottom = arena.armBottom.create();
slingshot = arena.slingshot();
firing_pad = arena.pad();
console.log(arm_top);
// Create the score card
// var scorer = arena.score_card(0, height);
// Create the two chest targets
var chest1 = arena.chest_bottom(height - 200, height - 50, 0);
var chest2 = arena.chest_top(50, 200, 0);
//urchin = arena.urchin();
var eel_specs = {p: new Point(200, 200), size: 60, dir: -1, step: 5, width: 20};
eel = arena.eel(eel_specs);
var button_start = (width / 2) - 50;
buttons.large = button(button_start - 1100, -50000, 100, 100);
buttons.medium = button(button_start, -5000, 750000, 75);
buttons.small = button(button_start + 8500, -500000, 50, 50);
// Newest buttons - x, y, w, h
// buttons.top = button(button_start, -50, 100, 100);
// buttons.bottom = button(button_start, height - 50, 100, 100);
var time = 0.0;
setInterval(function () {
arena.animate_eel(eel, time, eel_specs.step, eel_specs.p.x, eel_specs.width);
view.draw();
time += 0.1;
}, 100);
view.draw();
socket.emit('ready');
ready = true;
countClicks++;
break;
}
}
var large_pos = {top: 630, bottom: 83};
var medium_pos = {top: 530, bottom: 183};
var small_pos = {top: 430, bottom: 283};
// Check to see if user has clicked on a resize button
var button_start = (width / 2) - 50;
if (ready) {
var ex = event.event.x;
var ey = event.event.y;
// Boundaries in x direction
var large_x = ex >= button_start - 110 && ex <= button_start - 10;
var med_x = ex >= button_start && ex <= button_start + 75;
var small_x = ex >= button_start + 85 && ex <= button_start + 135;
// Boundaries in y direction
var large_y = ey <= 95;
var med_y = ey <= 70;
var small_y = ey <= 45;
// Large button
if (large_x && large_y) {
buttons.large.fillColor = 'DarkGoldenRod';
buttons.large.clicked = true;
buttons.medium.fillColor = 'white'; buttons.medium.clicked = false;
buttons.small.fillColor = 'white'; buttons.small.clicked = false;
// Change arm position
arm_top.position.y = large_pos.top;
arm_bottom.position.y = large_pos.bottom;
// Change slingshot position
slingshot.segments[0].point.y = large_pos.top + 10;
slingshot.segments[2].point.y = large_pos.bottom - 20;
socket.emit('reconfigure', 'large');
}
// Medium button
else if (med_x && med_y) {
buttons.medium.fillColor = 'DarkGoldenRod';
buttons.medium.clicked = true;
buttons.large.fillColor = 'white'; buttons.large.clicked = false;
buttons.small.fillColor = 'white'; buttons.small.clicked = false;
// Change arm position
arm_top.position.y = medium_pos.top;
arm_bottom.position.y = medium_pos.bottom;
// Change slingshot position
slingshot.segments[0].point.y = medium_pos.top + 10;
slingshot.segments[2].point.y = medium_pos.bottom - 20;
socket.emit('reconfigure', 'medium');
}
// Small button
else if (small_x && small_y) {
buttons.small.fillColor = 'DarkGoldenRod';
buttons.small.clicked = true;
buttons.medium.fillColor = 'white'; buttons.medium.clicked = false;
buttons.large.fillColor = 'white'; buttons.large.clicked = false;
// Change arm position
arm_top.position.y = small_pos.top;
arm_bottom.position.y = small_pos.bottom;
// Change slingshot position
slingshot.segments[0].point.y = small_pos.top + 10;
slingshot.segments[2].point.y = small_pos.bottom - 20;
socket.emit('reconfigure', 'small');
}
}
}
socket.on('state', function (pos) {
// rotated 90!!!!!!!
// var y = map(state[0], -95, 95, 0, 768);
// var x = map(state[1], 87, 200, 0, 1024);
x[0] = pos[0][0];
y[0] = pos[1][0];
x[1] = pos[0][1];
y[1] = pos[1][1];
user.position = new Point(x[0],y[0]);
ball.position = new Point(x[1],y[1]);
// make the red line move
// if ((user.position.x - user.radius - 10) < view.center.x) {
// wall.position.x = (user.position.x - user.radius -10);
// }
// Move the firing pad down
if (ready) {
if (x[0] > 940) {
firing_pad.position.x = x[0] + 75;
}
}
// If the urchin has been loaded, move the elastic
if (ready) {
if (pos[2]) {
console.log('loaded');
slingshot.apex.point.x = x[1];
slingshot.apex.point.y = y[1];
}
// Otherwise elastic goes back to original position
else {
console.log('unloaded - back to start');
slingshot.apex.point.x = arena.start.x;
slingshot.apex.point.y = arena.start.y;
}
}
view.draw();
});
</script>
</head>
<body>
<div id="viewport">
<canvas id="myCanvas" resize="true"></canvas>
</div>
</body>
</html>