I need to move an image vertically by user input however, when I press the defined key nothing happens. I don't know if the command I am using to draw a new image going vertically is wrong or my function is?
Script.js
var map = document.getElementById("map");
var ctx = map.getContext("2d");
var baseImage = new Image();
baseImage.src = "assets/base.png";
baseImage.addEventListener("load", drawImage);
var speedyImage = new Image();
speedyImage.src = "assets/speedy.png";
speedyImage.addEventListener("load", drawImage);
var bubbleImage = new Image();
bubbleImage.src = "assets/bubble.png";
bubbleImage.addEventListener("load", drawImage);
document.addEventListener('keydown', function(event){ handleKeyPress(event);});
var dt = 1000/30.0;
function intersectRect(r1, r2) { // detects collision
return !(r2.left > r1.right ||
r2.right < r1.left ||
r2.top > r1.bottom ||
r2.bottom < r1.top);
}
function drawImage(){
setInterval(update, 1000/30.0);
}
var x = 0;
var y = 0;
var speed = 0.05;
var direction = 1;
document.getElementById("score").innerHTML = 0;
function update(){
ctx.clearRect(0, 0, map.width, map.height);
for(var i = 0; i < 1; i++){
ctx.drawImage(bubbleImage,x, map.height - baseImage.height - 50);
function handleKeyPress(event){
if(event.keyCode == 32){ // if space
// trouble here... would I just use the draw image function again?
}
}
}
for(var i = 0; i < 3; i++){
ctx.drawImage(speedyImage,x,0);
ctx.drawImage(speedyImage,x,70);
ctx.drawImage(speedyImage,x,150);
if(intersectRect(bubbleImage,speedyImage) == false)
score+= score+100;
}
ctx.drawImage(baseImage, x, map.height - baseImage.height );
y += speed*direction*dt;
x += speed * direction * dt;
if (x > map.width - baseImage.width || x < 0)
direction = -direction;
}
You have not declared handlekeyPress(event) function.
for(var i = 0; i < 1; i++){
ctx.drawImage(bubbleImage,x, map.height - baseImage.height - 50);
function handleKeyPress(event){
if(event.keyCode == 32){ // if space
// trouble here... would I just use the draw image function again?
}
}
}
As it is shown you are specifying function code inside another function .So this function cannot be called outside the function.
Related
This is my code and when run instead of a black box containing my game in the centre of the screen there is just a gap and no website can seem to tell me where I went wrong:
console.log("start")
//Global functions
var canvas = document.getElementById("canva");
var canvasCon;
var snakeX = 400;
var snakeY = 300;
var direction;
var snakeSpeed = 1;
var apple = false;
var appleX;
var appleY
var snakeSize = 30;
var scoreboard = document.getElementById("score");
var Score = 0;
var trailX = new Array();
var trailY = new Array();
console.log("set global variables!")
window.onload = function(){
console.log("ran on window load function")
canvasCon = canvas.getContext('2d');
//Calls "drawing" and "move" fps times per second
var fps = 30
setInterval(function(){
move()
drawing()
},1000/fps);
}
document.addEventListener('keydown', getKey);
function getKey(event){
//gets the keycode
direction = event.keyCode;
return direction;
}
//moves the objsects
function move(){
//creates a easier to read way to check the value of getKey
var left = 37;
var up = 38;
var right = 39;
var down = 40;
//changing the position of the snake
switch(direction){
case right:
snakeX = snakeX + snakeSpeed;
break;
case left:
snakeX = snakeX - snakeSpeed;
break;
case up:
snakeY = snakeY - snakeSpeed;
break;
case down:
snakeY = snakeY + snakeSpeed;
break;
}
trail()
//checks if snake has gone off the board and then moves the snake to the other end of the board if that returns True
if(snakeX > canvas.width){
snakeX = 0
}else if(snakeX < 0){
snakeX = canvas.width
}
if(snakeY > canvas.height){
snakeY = 0
}else if(snakeY < 0){
snakeY = canvas.height
}
}
//draws everything /w updated coordinates
function drawing(){
//Backround of the Game
canvasCon.fillStyle = 'black';
canvasCon.fillRect(0,0,canvas.width,canvas.height);
//The snake
canvasCon.fillStyle = 'green';
canvasCon.fillRect(snakeX,snakeY,snakeSize,snakeSize);
//apple creation
apples()
canvasCon.fillStyle = 'red';
canvasCon.fillRect(appleX,appleY,25,25);
}
//makes the apples work
function apples(){
if(collision()){
Score += 1
console.log(Score)
scoreboard.innerHTML = "<b>Score: "+Score+"<b>"
apple = false
}
if(apple == false){
apple = true
appleX = Math.floor(Math.random() * (canvas.width - 50));
appleY = Math.floor(Math.random() * (canvas.height - 50));
}
}
function collision(){
var distX = Math.abs(appleX - snakeX-snakeSize/2);
var distY = Math.abs(appleY - snakeY-snakeSize/2);
if (distX <= (snakeSize/2) && distY <= (snakeSize/2)) { return true; }
}
function trail(){
//adds X and Y coordinates to their respective lists
trailX.push(snakeX)
trailY.push(snakeY)
//makes sure the lists are the right length
while(trailX.length > Score){
var index = trailX.indexOf(0);
trailX.splice(index, 1);
}
while(trailY.length > Score){
var index = trailY.indexOf(0);
trailY.splice(index, 1);
}
if(trailY.length != trailX.length){
console.log("trailY != trailX")
}
for(i= trailX.length-1; i<=0; i--){
canvasCon.fillStyle = 'yellow';
canvasCon.fillRect(trailX[i],trailY[i],25,25);
}
}
<title>SNAKE!!</title>
<body>
<p style="text-align:center; text-color:red"><b>Hope you Enjoy Ma GREAT GAME!!</b></p>
<br/><br/><br/>
<div style="width:800px; margin:0 auto;">
<canvas id=canva width="800" height="600"></canvas>
<br/>
<p id="score">Score: </p>
</div>
</body>
whenever the page gets reloaded even on jsfiddle.net it crashes.
plz help I have no idea what i did wrong!
First rule of JS - if it is stuck, you probably have an endless loop.
And indeed You have an endless loop with your final for:
for(i= trailX.length-1; i<=0; i--){
canvasCon.fillStyle = 'yellow';
canvasCon.fillRect(trailX[i],trailY[i],25,25);
}
i<=0
If i start with 0 and goes down by 1 each iteration, it will always be less or equal to 0 so the end condition will never be met.
When I test or publish my project, which is a jigsaw puzzle from this tutorial: https://www.youtube.com/watch?v=uCQuUZs3UGE
Nothing gets drawn except the grey background. No puzzle pices nor any puzzle shape is drawn at all. I also get a warning:
WARNINGS:
Frame numbers in EaselJS start at 0 instead of 1. For example, this affects gotoAndStop and gotoAndPlay calls. (17)
But that should just be a warning, not an error. So might there be an error in my javascript code? This is the code, its fairly simple:
//************
// Initialize;
var numPieces = 16;
for (var i = 0; i = < numPieces; i++)
{
var pieceName = "p" + (i + 1);
var piece = this[pieceName];
if (piece)
{
piece.name = pieceName;
piece.on("mousedown", function(evt)
{
this.scaleX = 1;
this.scaleY = 1;
this.shadow = null;
this.parent.addChild(this);
this.offset = (x:this.x - evt.stageX, y:this.y - evt.stageY);
});
piece.on("pressmove", function (evt)
{
this.x = evt.stageX + this.offset.x;
this.y = evt.stageY + this.offset.y;
});
piece.on("pressup", function(evt)
{
var target = this.parent["t"+this.name.substr(1)];
if (target && hitTestInRange(target, 30) )
{
this.x = target.x;
this.y = target.y;
}
});
}
}
function hitTestInRange( target, range )
{
if (target.x > stage.mouseX - range &&
target.x < stage.mouseX + range &&
target.y > stage.mouseY - range &&
target.y < stage.mouseY + range)
{
return true;
}
return false;
}
I also included a screenshot of the project. screenshot
Thanks in advance
I have been making a game, my problem is when you click the space key it shoots 1 bullet, but when you do it again nothing happens. I have made it so the game starts with 30 bullets, and they are stored at the top left of screen out of view. When space is clicked they get fired from the tip of your ship using its X, Y values.
Click here to see what I mean:
http://www.taffatech.com/DarkOrbit.html
- as you can see only 1 fires, ever.
Here is the bullet object
function Bullet() //space weapon uses this
{
this.srcX = 0;
this.srcY = 1240;
this.drawX = -20;
this.drawY = 0;
this.width = 11;
this.height = 4;
this.bulletSpeed = 3;
this.bulletReset = -20;
}
Bullet.prototype.draw = function()
{
this.drawX += this.bulletSpeed;
ctxPlayer.drawImage(spriteImage,this.srcX,this.srcY,this.width,this.height,this.drawX,this.drawY,this.width,this.height);
if (this.drawX > canvasWidth)
{
this.drawX = this.bulletReset;
}
}
Bullet.prototype.fire = function(startX, startY)
{
this.drawX = startX;
this.drawY = startY;
}
This is the player Object: (the ship)
function Player() //Object
{
//////Your ships values
this.PlayerHullMax = 1000;
this.PlayerHull = 1000;
this.PlayerShieldMax = 1000;
this.PlayerShield = 347;
this.SpaceCrystal = 2684;
this.Speed = 5; //should be around 2 pixels every-time draw is called by interval, directly linked to the fps global variable
////////////
///////////flags
this.isUpKey = false;
this.isDownKey = false;
this.isLeftKey = false;
this.isRightKey = false;
////////space Weapon
this.noseX = this.drawX + 100;
this.noseY = this.drawY + 30;
this.isSpaceBar = false;
this.isShooting = false;
this.bullets = [];
this.currentBullet = 0;
this.bulletAmount = 30;
for(var i = 0; i < this.bulletAmount; i++) //
{
this.bullets[this.bullets.length] = new Bullet();
}
/////////////
////Pick Ship
this.type = "Cruiser";
this.srcX = PlayerSrcXPicker(this.type);
this.srcY = PlayerSrcYPicker(this.type);
this.drawX = PlayerdrawXPicker(this.type);
this.drawY = PlayerdrawYPicker(this.type);
this.playerWidth = PlayerWidthPicker(this.type);
this.playerHeight = PlayerHeightPicker(this.type);
////
}
Player.prototype.draw = function()
{
ClearPlayerCanvas();
ctxPlayer.globalAlpha=1;
this.checkDirection(); //must before draw pic to canvas because you have new coords now from the click
this.noseX = this.drawX + (this.playerWidth-10);
this.noseY = this.drawY + (this.playerHeight/2);
this.checkShooting();
this.drawAllBullets();
ctxPlayer.drawImage(spriteImage,this.srcX,this.srcY,this.playerWidth,this.playerHeight,this.drawX,this.drawY,this.playerWidth,this.playerHeight);
};
Player.prototype.drawAllBullets = function()
{
for(var i = 0; i < this.bullets.length; i++)
{
if(this.bullets[i].drawX >= 0)
{
this.bullets[i].draw();
}
}
}
Player.prototype.checkShooting = function()
{
if(this.isSpaceBar == true && this.isShooting == false)
{
this.isShooting = true;
this.bullets[this.currentBullet].fire(this.noseX, this.noseY);
this.currentBullet++;
if(this.currentBullet >= this.bullets.length)
{
this.currentBullet = 0;
}
else if(this.isSpaceBar == false)
{
this.isShooting = false;
}
}
}
This is in a method that checks what keys are down:
if (KeyID === 32 ) //spacebar
{
Player1.isSpaceBar = true;
e.preventDefault(); //webpage dont scroll when playing
}
This is in a method that checks what keys are up:
if (KeyID === 32 ) //left and a keyboard buttons
{
Player1.isSpaceBar = false;
e.preventDefault(); //webpage dont scroll when playing
}
Any other info you need just ask!
Okay, I think I figured it out
try adding isShooting false to the key up event
if (KeyID === 32 ) //left and a keyboard buttons
{
Player1.isSpaceBar = false;
Player1.isShooting = false;
e.preventDefault(); //webpage dont scroll when playing
}
I want to implement it using the konami code, which I've succesfully used on my site already. I just can't get it to work with skifree.
For quick reference, Here's the konami code:
var kkeys = [], konami = "38,38,40,40,37,39,37,39,66,65";
$(document).keydown(function(e) {
kkeys.push( e.keyCode );
if ( kkeys.toString().indexOf( konami ) >= 0 ){
$(document).unbind('keydown',arguments.callee);
// Launch easter egg here
}
});
Here's the code for skifree, as pulled from this site: http://timelessname.com/canvas/skifree/
var left;
var right;
var faster = false;
var step = 0;
var obst = new Array();
var locX = 430;
var locY = 100;
var running = true;
var guy = new Image();
var guyLeft = new Image();
var guyRight = new Image();
var crash = new Image();
var rock = new Image();
var tree = new Image();
var bush = new Image();
guy.src = "http://timelessname.com/canvas/skifree/guy_down.png";
guyLeft.src = "http://timelessname.com/canvas/skifree/guy_left.png";
guyRight.src = "http://timelessname.com/canvas/skifree/guy_right.png";
crash.src = "http://timelessname.com/canvas/skifree/crash.png";
rock.src = "http://timelessname.com/canvas/skifree/rock.png";
tree.src = "http://timelessname.com/canvas/skifree/tree.png";
$(window).keydown(function(e){
if(e.keyCode == 37){
left = true;
}
else if(e.keyCode == 39){
right = true;
}
else if(e.keyCode == 70){
faster = true;
}
});
$(window).keyup(function(e){
if(e.keyCode == 37){
left = false;
}
else if(e.keyCode == 39){
right = false;
}
else if(e.keyCode == 70){
faster = false;
}
else if(e.keyCode == 32){
if(!running){
step = 0;
obst = new Array();
locX = 430;
locY = 100;
running = true;
runSki();
}
}
});
//TODO: wrap edges (no wall)
function runSki(){
if(!running) return;
var canvas = document.getElementById("can");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "rgb(255,255,255)";
ctx.fillRect (0, 0, canvas.width, canvas.height);
if(left){
if(locX > -320){
locX--;
}
}
if(right){
if(locX < 640+320){
locX++;
}
}
ctx.fillStyle = "rgb(0,0,0)";
ctx.fillRect (-10-locX, 0, 10, canvas.height);
ctx.fillRect (640*2+20-locX, 0, 10, canvas.height);
for(var i = 0; i < obst.length;i++){
var o = obst[i];
o.y-=2.5;
if(faster){
o.y-=2.5;
}
ctx.drawImage(o.type,o.x-locX,o.y);
if(o.y < -30){
obst.splice(i,1);
i--;
}
var tX = o.x-locX+5;
var tY = o.y+5;
var d = Math.sqrt((tX-320+3)*(tX-320+3)+ (tY-100+5)*(tY-100+5));
if(d < 20){
ctx.drawImage(crash,320,locY);
running = false;
}
}
if(running){
if(left){
ctx.drawImage(guyLeft,320,locY);
}
else if(right){
ctx.drawImage(guyRight,320,locY);
}
else{
ctx.drawImage(guy,320,locY);
}
}
var randomnumber=Math.floor(Math.random()*641)
if(Math.floor(step*10)%10==0){
var type;
if(Math.floor(Math.random()*2) == 0){
type = rock;
}
else{
type = tree;
}
var obj = {x: Math.floor(Math.random()*641*2), y:480, type: type};
obst.push(obj);
}
step+= 0.1;
if(running){
setTimeout("runSki();",1);
}
}
setTimeout("runSki();",1000);
Not certain of this but your copied code looks wrong; see here:
if(left){
if(locX > -320){
locX--;
}
}
if(right){
if(locX < 640+320){
locX++;
}
}
Have you copied this from html? The > & < characters shouldn't be escaped :)
EDIT
Also remember to update your image paths :D
EDIT
I got this to work on this page. Just added the <canvas/> element, wrapped the ski javascript in a function called setupSki (which is called by the konami function) and replaced both instances of
setTimeout("runSki();"
with
setTimeout(runSki
I am trying to get the distance between my character and the ground, I have found something that looks like it should do what I want but it has been written for another version of box2d.
Original:
float targetHeight = 3;
float springConstant = 100;
//make the ray at least as long as the target distance
b2Vec2 startOfRay = m_hovercarBody->GetPosition();
b2Vec2 endOfRay = m_hovercarBody->GetWorldPoint( b2Vec2(0,-5) );
overcarRayCastClosestCallback callback;
m_world->RayCast(&callback, startOfRay, endOfRay);
if ( callback.m_hit ) {
float distanceAboveGround = (startOfRay - callback.m_point).Length();
//dont do anything if too far above ground
if ( distanceAboveGround < targetHeight ) {
float distanceAwayFromTargetHeight = targetHeight - distanceAboveGround;
m_hovercarBody->ApplyForce( b2Vec2(0,springConstant*distanceAwayFromTargetHeight),
m_hovercarBody->GetWorldCenter() );
}
}
I have tried to change it to what I think it should be but it doesn't even call the callback.
var targetHeight = 3;
var springConstant = 100;
//make the ray at least as long as the target distance
startOfRay = new b2Vec2(m_hovercarBody.GetPosition());
endOfRay = new b2Vec(m_hovercarBody.GetWorldPoint( b2Vec2(0,-5)));
function callback(raycast){
if ( raycast.m_hit ) {
var distanceAboveGround = (startOfRay - raycast.m_point).Length();
//dont do anything if too far above ground
if ( distanceAboveGround < targetHeight ) {
var distanceAwayFromTargetHeight = targetHeight - distanceAboveGround;
m_hovercarBody.ApplyForce( b2Vec2(0,springConstant*distanceAwayFromTargetHeight),
m_hovercarBody.GetWorldCenter() );
}
}
}
m_world.RayCast(callback, startOfRay, endOfRay);
Any idea how to convert it to work with box2dweb?
Thanks
It might be that the original bit of code was written for a platform where the coordinate system works differently.
In a Canvas element, the coordinate system starts from the top left corner, meaning that m_hovercarBody.GetWorldPoint( b2Vec2(0,-5)) is checking for a point above the character, rather than below.
I'm not sure about the rest of the code but try changing that to m_hovercarBody.GetWorldPoint( b2Vec2(0,5)) and see what happens.
EDIT:
I think actually the problem is with the way you've structured your callback. Looking up the reference for the Raycast function would reveal more.
(The Javascript version of Box2D you're using is an automatic port of the Actionscript one. Given the two have fairly similar syntax, you can use the reference for Flash.)
The original code you posted seems to be C++, but I don't know much about its syntax. It seems there's some sort of class that does the raycasting (overcarRayCastClosestCallback). You can either look for that, or try and build your own callback function according to the first link I posted. It would be something along the lines of:
function customRaycastCallback(fixture, normal, fraction) {
// you can, for instance, check if fixture belongs to the ground
// or something else, then handle things accordingly
if( /* fixture belongs to ground */ ) {
// you've got the fraction of the original length of the raycast!
// you can use this to determine the distance
// between the character and the ground
return fraction;
}
else {
// continue looking
return 1;
}
}
Try running this on your browser. I coded this when I was learning sensor and RAYCAST in Box2Dweb. Hope it helps.
<html>
<head>
<title>Box2dWeb Demo</title>
</head>
<body>
<canvas id="canvas" width="600" height="420" style="background-color:#333333;" ></canvas>
<div id="cc" style="position:absolute; right:0; top:100px; width:500px; height:50px; margin:0;"></div>
</body>
<script type="text/javascript" src="Box2dWeb-2.1.a.3.js"></script>
<script type="text/javascript" src="jquery-1.7.2.js"></script>
<script type="text/javascript">
var b2Vec2 = Box2D.Common.Math.b2Vec2
, b2BodyDef = Box2D.Dynamics.b2BodyDef
, b2Body = Box2D.Dynamics.b2Body
, b2FixtureDef = Box2D.Dynamics.b2FixtureDef
, b2World = Box2D.Dynamics.b2World
, b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape
, b2CircleShape = Box2D.Collision.Shapes.b2CircleShape
, b2ContactFilter = Box2D.Dynamics.b2ContactFilter
, b2MouseJointDef = Box2D.Dynamics.Joints.b2MouseJointDef
, b2DebugDraw = Box2D.Dynamics.b2DebugDraw
, b2Fixture = Box2D.Dynamics.b2Fixture
, b2AABB = Box2D.Collision.b2AABB
, b2WorldManifold = Box2D.Collision.b2WorldManifold
, b2ManifoldPoint = Box2D.Collision.b2ManifoldPoint
, b2RayCastInput = Box2D.Collision.b2RayCastInput
, b2RayCastOutput = Box2D.Collision.b2RayCastOutput
, b2Color = Box2D.Common.b2Color;
var world = new b2World(new b2Vec2(0,10), true);
var canvas = $('#canvas');
var context = canvas.get(0).getContext('2d');
//box
var bodyDef = new b2BodyDef;
bodyDef.type = b2Body.b2_dynamicBody;
bodyDef.position.Set(9,7);
bodyDef.userData = 'box';
var fixDef = new b2FixtureDef;
fixDef.filter.categoryBits = 1;
fixDef.density = 10.0;
fixDef.friction = 0.5;
fixDef.restitution = .5;
fixDef.shape = new b2PolygonShape;
fixDef.shape.SetAsBox(1,5);
var box1 = world.CreateBody(bodyDef);
box1.CreateFixture(fixDef);
//circle
var bodyDef2 = new b2BodyDef;
bodyDef2.type = b2Body.b2_dynamicBody;
bodyDef2.position.Set(4,8);
bodyDef2.userData = 'obj';
var fixDef2 = new b2FixtureDef;
fixDef2.filter.categoryBits = 2;
fixDef2.filter.maskBits = 13;
fixDef2.density = 10.0;
fixDef2.friction = 0.5;
fixDef2.restitution = .2;
fixDef2.shape = new b2CircleShape(1);
//circlesensor
var cc = new b2FixtureDef;
cc.shape = new b2CircleShape(2);
cc.shape.SetLocalPosition(new b2Vec2(0 ,0));
cc.density = 0;
cc.isSensor = true;
cc.filter.categoryBits = 8;
var wheel = world.CreateBody(bodyDef2);
wheel.CreateFixture(fixDef2);
wheel.CreateFixture(cc);
//create a ground
var holderDef = new b2BodyDef;
holderDef.type = b2Body.b2_staticBody;
holderDef.userData = "ground";
holderDef.position.Set(10, 14);
var fd = new b2FixtureDef;
fd.filter.categoryBits = 4;
fd.shape = new b2PolygonShape;
fd.shape.SetAsBox(10,1);
var ground = world.CreateBody(holderDef);
ground.CreateFixture(fd);
//create another static body
var holderDef = new b2BodyDef;
holderDef.type = b2Body.b2_staticBody;
holderDef.position.Set(10, 20);
var temp = world.CreateBody(holderDef);
temp.CreateFixture(fd);
var c=0;
$(window).keydown(function(e) {
$('#aa').html(++c);
code = e.keyCode;
if(c==1) {
if(code == 38 && onground)
wheel.SetLinearVelocity(new b2Vec2(0,-10));
if(code == 39)
wheel.ApplyForce(new b2Vec2(1000,0), box1.GetWorldPoint(new b2Vec2(0,0)));
if(code == 37)
wheel.ApplyForce(new b2Vec2(-1000,0), box1.GetWorldPoint(new b2Vec2(0,0)));
}
});
$(window).keyup(function(e) {
c=0;
});
var listener = new Box2D.Dynamics.b2ContactListener;
listener.BeginContact = function(contact) {
if(contact.GetFixtureA().GetBody().GetUserData()== 'obj' || contact.GetFixtureB().GetBody().GetUserData()== 'obj' ) // think about why we don't use fixture's userData directly.
onground = true;// don't put 'var' here!
fxA=contact.GetFixtureA();
fxB=contact.GetFixtureB();
sA=fxA.IsSensor();
sB=fxB.IsSensor();
if((sA && !sB) || (sB && !sA)) {
if(sA) {
$('#cc').prepend(contact.GetFixtureB().GetBody().GetUserData() + ' is in the viscinity of body '+contact.GetFixtureA().GetBody().GetUserData()+'<br>');
}
else {
$('#cc').prepend(contact.GetFixtureA().GetBody().GetUserData() + ' is in the viscinity of body '+contact.GetFixtureB().GetBody().GetUserData()+'<br>');
}
}
}
listener.EndContact = function(contact) {
if (contact.GetFixtureA().GetBody().GetUserData()== 'obj' || contact.GetFixtureB().GetBody().GetUserData()== 'obj' )
onground = false;
}
var debugDraw = new b2DebugDraw();
debugDraw.SetSprite ( document.getElementById ("canvas").getContext ("2d"));
debugDraw.SetDrawScale(30); //define scale
debugDraw.SetAlpha(1);
debugDraw.SetFillAlpha(.3); //define transparency
debugDraw.SetLineThickness(1.0);
debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
world.SetDebugDraw(debugDraw);
window.setInterval(update,1000/60);
//mouse
var mouseX, mouseY, mousePVec, isMouseDown, selectedBody, mouseJoint;
var canvasPosition = getElementPosition(document.getElementById("canvas"));
document.addEventListener("mousedown", function(e) {
isMouseDown = true;
handleMouseMove(e);
document.addEventListener("mousemove", handleMouseMove, true);
}, true);
document.addEventListener("mouseup", function() {
document.removeEventListener("mousemove", handleMouseMove, true);
isMouseDown = false;
mouseX = undefined;
mouseY = undefined;
}, true);
function handleMouseMove(e) {
mouseX = (e.clientX - canvasPosition.x) / 30;
mouseY = (e.clientY - canvasPosition.y) / 30;
};
function getBodyAtMouse() {
mousePVec = new b2Vec2(mouseX, mouseY);
var aabb = new b2AABB();
aabb.lowerBound.Set(mouseX - 0.001, mouseY - 0.001);
aabb.upperBound.Set(mouseX + 0.001, mouseY + 0.001);
// Query the world for overlapping shapes.
selectedBody = null;
world.QueryAABB(getBodyCB, aabb);
return selectedBody;
}
function getBodyCB(fixture) {
if(fixture.GetBody().GetType() != b2Body.b2_staticBody) {
if(fixture.GetShape().TestPoint(fixture.GetBody().GetTransform(), mousePVec)) {
selectedBody = fixture.GetBody();
return false;
}
}
return true;
}
//at global scope
var currentRayAngle = 0;
var input = new b2RayCastInput();
var output = new b2RayCastOutput();
var b = new b2BodyDef();
var f = new b2FixtureDef();
var closestFraction = 1;
var intersectionNormal = new b2Vec2(0,0);
var intersectionPoint = new b2Vec2();
rayLength = 25; //long enough to hit the walls
var p1 = new b2Vec2( 11, 7 ); //center of scene
var p2 = new b2Vec2();
var normalEnd = new b2Vec2();
function update() {
if(isMouseDown && (!mouseJoint)) {
var body = getBodyAtMouse();
if(body) {
var md = new b2MouseJointDef();
md.bodyA = world.GetGroundBody();
md.bodyB = body;
md.target.Set(mouseX, mouseY);
md.collideConnected = true;
md.maxForce = 300.0 * body.GetMass();
mouseJoint = world.CreateJoint(md);
body.SetAwake(true);
}
}
if(mouseJoint) {
if(isMouseDown) {
mouseJoint.SetTarget(new b2Vec2(mouseX, mouseY));
} else {
world.DestroyJoint(mouseJoint);
mouseJoint = null;
}
}
world.Step(1 / 60, 10, 10);
world.DrawDebugData();
world.ClearForces();
world.SetContactListener(listener);
ray();
};
function ray() {
//in Step() function
var k = 360/20;
var t = k/60;
var DEGTORAD = Math.PI/180;
currentRayAngle += t * DEGTORAD; //one revolution every 20 seconds
//console.log(currentRayAngle*(180/Math.PI));
//calculate points of ray
p2.x = p1.x + rayLength * Math.sin(currentRayAngle);
p2.y = p1.y + rayLength * Math.cos(currentRayAngle);
input.p1 = p1;
input.p2 = p2;
input.maxFraction = 1;
closestFraction = 1;
var b = new b2BodyDef();
var f = new b2FixtureDef();
for(b = world.GetBodyList(); b; b = b.GetNext()) {
for(f = b.GetFixtureList(); f; f = f.GetNext()) {
if(!f.RayCast(output, input))
continue;
else if(output.fraction < closestFraction) {
closestFraction = output.fraction;
intersectionNormal = output.normal;
}
}
}
intersectionPoint.x = p1.x + closestFraction * (p2.x - p1.x);
intersectionPoint.y = p1.y + closestFraction * (p2.y - p1.y);
normalEnd.x = intersectionPoint.x + intersectionNormal.x;
normalEnd.y = intersectionPoint.y + intersectionNormal.y;
context.strokeStyle = "rgb(255, 255, 255)";
context.beginPath(); // Start the path
context.moveTo(p1.x*30,p1.y*30); // Set the path origin
context.lineTo(intersectionPoint.x*30, intersectionPoint.y*30); // Set the path destination
context.closePath(); // Close the path
context.stroke();
context.beginPath(); // Start the path
context.moveTo(intersectionPoint.x*30, intersectionPoint.y*30); // Set the path origin
context.lineTo(normalEnd.x*30, normalEnd.y*30); // Set the path destination
context.closePath(); // Close the path
context.stroke(); // Outline the path
}
//helpers
//http://js-tut.aardon.de/js-tut/tutorial/position.html
function getElementPosition(element) {
var elem=element, tagname="", x=0, y=0;
while((typeof(elem) == "object") && (typeof(elem.tagName) != "undefined")) {
y += elem.offsetTop;
x += elem.offsetLeft;
tagname = elem.tagName.toUpperCase();
if(tagname == "BODY")
elem=0;
if(typeof(elem) == "object") {
if(typeof(elem.offsetParent) == "object")
elem = elem.offsetParent;
}
}
return {x: x, y: y};
}
</script>
</html>
Here's a Raycast in Box2dWeb that I got working:
var p1 = new b2Vec2(body.GetPosition().x, body.GetPosition().y); //center of scene
var p2 = new b2Vec2(body.GetPosition().x, body.GetPosition().y + 5); //center of scene
world.RayCast(function(x){
console.log("You've got something under you");
}, p1,p2);