Skip to content

Instantly share code, notes, and snippets.

@JMStewart
Last active December 22, 2015 06:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JMStewart/6432668 to your computer and use it in GitHub Desktop.
Save JMStewart/6432668 to your computer and use it in GitHub Desktop.
LEAP: Target Shooter

A simple target shooter for the Leap Motion.

<!DOCTYPE html>
<html>
<head>
<script src="//js.leapmotion.com/0.2.0/leap.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<style>
body{
background-color: #e3e3e3;
}
</style>
</head>
<body>
<div id="canvas">
<svg height="100%" width="100%">
</svg>
</div>
<div id="data"></div>
</body>
<script>
var showCrosshair = true;
//D3 Stuff
var svg = d3.select("svg");
var height = svg.node().offsetHeight;
var width = svg.node().offsetWidth;
var circleGroup = svg.append("g")
.attr("id", "circleGroup");
var crosshair = svg.append("g");
crosshair.append("path")
.attr("d", "M-7,0h14M0,-7v14")
.style("stroke", "gray")
.attr("stroke-width", "3");
var circles = [];
function addCircle(circle){
var circleBox = circle.node().getBoundingClientRect();
circles.push({
x : +circleBox.left + circleBox.width/2,
y : +circleBox.top + circleBox.height/2,
r : +circleBox.width/2,
id : circle.attr("id")
});
}
var minX = -90;
var maxX = 90;
var minY = 230;
var maxY = 70;
var xScale = d3.scale.linear()
.domain([minX, maxX])
.range([0,width]);
var yScale = d3.scale.linear()
.domain([minY, maxY])
.range([0,height]);
var circleCount = 0
function loop() {
var rand = Math.round(Math.random() * (3000 - 500)) + 500;
setTimeout(function() {
createCircle();
loop();
}, rand);
};
loop();
var minR = 50;
var maxR = 150;
function createCircle(){
var newR = Math.random() * (maxR - minR) + minR;
var newX = Math.random() * (width - (2 * newR)) + newR;
var newY = Math.random() * (height - (2 * newR)) + newR;
var circle = circleGroup.append("g")
.attr("id", "circle" + circleCount)
circle.selectAll("circle")
.data([3,2,1])
.enter()
.append("circle")
.attr("cx", newX)
.attr("cy", newY)
.attr("r", "0")
.style("fill", function(d){return d%2 ? "red" : "white" ;});
var grow = circle.transition()
.duration(500)
.each("end", function(){addCircle(d3.select(this));});
grow.selectAll("circle")
.attr("r", function(d){ return d * newR / 3;})
.transition()
.delay(5000)
.duration(1000)
.attr("r", "0")
.remove();
circleCount++;
}
//End D3 stuff
var pausedFrame = null;
var latestFrame = null;
var oldFrame = null;
var firing = false;
window.onkeypress = function(e) {
if (e.charCode == 32) {
if (pausedFrame == null) {
pausedFrame = latestFrame;
} else {
pausedFrame = null;
}
}
};
var controller = new Leap.Controller({enableGestures: true});
controller.loop(function(frame) {
oldFrame = latestFrame;
latestFrame = frame;
var pointableCount = latestFrame.pointables.length;
var handCount = latestFrame.hands.length;
if(oldFrame && !pausedFrame && handCount == 1 && pointableCount == 2){
var position = latestFrame.pointables[0].stabilizedTipPosition;
var thumbDirection = latestFrame.pointables[1].direction
var x = xScale(position[0]);
var y = yScale(position[1]);
crosshair.attr("transform", "translate(" + x + "," + y + ")");
if(thumbDirection[2] < -0.8){
if(!firing){
firing = true;
fire(x,y);
}
}else{
firing = false;
}
}
});
function fire(x,y){
svg.append("circle")
.attr("cx", x)
.attr("cy", y)
.attr("r", 15)
.style("fill", "none")
.style("stroke", "black")
.transition()
.duration(500)
.attr("r", 0)
.remove();
for(var i=0;i<circles.length;i++){
var c = circles[i];
if(distance(x,y,c.x,c.y) < c.r){
console.log(distance(x,y,c.x,c.y));
svg.select("#"+c.id)
.selectAll("circle")
.style("fill", function(d){ return d%2 ? "green" : "white";})
.transition()
.duration(500)
.attr("r", 0)
.remove();
circles.splice(i,1);
}
}
}
function distance(x1,y1,x2,y2){
d = Math.sqrt(Math.pow(x1-x2,2) + Math.pow(y1-y2,2));
return d;
}
</script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment