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
Related
Letter O
Letter X
How to make a tic tac toe game using only context.save/context.restore, if statements, canvas, and animations? I'm also trying to make it so that if image X is displayed in box 1, image O can't be displayed in the same box so you can't cheat.
I do not know how to prevent someone to put image O on image X, vice versa. Please, someone, show me a way to prevent people to place an O on top of an X and vice versa.
This is what I have so far
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="U1TS.css">
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
<br>
<button onclick="Restart()">Restart</button>
<script type="text/javascript">
var canvas = document.getElementById("canvas");
var context = canvas.getContext('2d');
var c1 = 1
var c2 = 1
var c3 = 1
var c4 = 1
var c5 = 1
var c6 = 1
var c7 = 1
var c8 = 1
var c9 = 1
var cup1 = 2
var cup2 = 2
var cup3 = 2
var cup4 = 2
var cup5 = 2
var cup6 = 2
var cup7 = 2
var cup8 = 2
var cup9 = 2
//Line horizontale et verticale
context.beginPath();
context.moveTo(40,145);
context.lineTo(360,145);
context.lineWidth = 5
context.lineCap = 'round';
context.stroke();
context.beginPath();
context.moveTo(40,260);
context.lineTo(360,260);
context.lineCap = 'round';
context.stroke();
context.beginPath();
context.moveTo(260,40);
context.lineTo(260,360);
context.lineCap = 'round';
context.stroke();
context.beginPath();
context.moveTo(140,40);
context.lineTo(140,360);
context.lineCap = 'round';
context.stroke();
context.font = "italic bold 30pt Calibri"
context.fillText("1", 75, 325);
context.fillText("2", 190, 325);
context.fillText("3", 305, 325);
context.fillText("4", 75, 215);
context.fillText("5", 190, 215);
context.fillText("6", 305, 215);
context.fillText("7", 75, 105);
context.fillText("8", 190, 105);
context.fillText("9", 305, 105);
function Restart(){
document.location.reload(true);
}
document.onkeydown = Nombre;
Nombreup1 = 49; Nombreup2 = 50; Nombreup3 = 51;
Nombreup4 = 52; Nombreup5 = 53; Nombreup6 = 54;
Nombreup7 = 55; Nombreup8 = 56; Nombreup9 = 57;
Nombre7 = 103; Nombre8 = 104; Nombre9 = 105;
Nombre4 = 100; Nombre5 = 101; Nombre6 = 102;
Nombre3 = 99; Nombre2 = 98; Nombre1 = 97;
function Nombre(e){
toucheCourante = e.keyCode;
if (toucheCourante == Nombre7){
lettreO7();
} else if (toucheCourante == Nombre8){
lettreO8();
} else if (toucheCourante == Nombre9){
lettreO9();
} else if (toucheCourante == Nombre6){
lettreO6();
} else if (toucheCourante == Nombre5){
lettreO5();
} else if (toucheCourante == Nombre4){
lettreO4();
} else if (toucheCourante == Nombre3){
lettreO3();
} else if (toucheCourante == Nombre2){
lettreO2();
} else if (toucheCourante == Nombre1){
lettreO1();
}
/////////////////////////////////////////
if (toucheCourante == Nombreup7){
lettreX7();
} else if (toucheCourante == Nombreup8){
lettreX8();
} else if (toucheCourante == Nombreup9){
lettreX9();
} else if (toucheCourante == Nombreup6){
lettreX6();
} else if (toucheCourante == Nombreup5){
lettreX5();
} else if (toucheCourante == Nombreup4){
lettreX4();
} else if (toucheCourante == Nombreup3){
lettreX3();
} else if (toucheCourante == Nombreup2){
lettreX2();
} else if (toucheCourante == Nombreup1){
lettreX1();
}
}
function lettreO1()
{
lettreO = new Image();
lettreO.src = 'O.jpg';
lettreO.onload = function(){
context.drawImage(lettreO, 40, 265,95,93);
}
}
function lettreX1()
{
lettreX = new Image();
lettreX.src = 'X.PNG';
lettreX.onload = function(){
context.drawImage(lettreX, 40, 265,95,93);
}
}
function lettreO2()
{
lettreO = new Image();
lettreO.src = 'O.jpg';
lettreO.onload = function(){
context.drawImage(lettreO, 145, 265,110,93);
}
}
function lettreX2()
{
lettreX = new Image();
lettreX.src = 'X.PNG';
lettreX.onload = function(){
context.drawImage(lettreX, 145, 265,110,93);
}
}
function lettreO3()
{
lettreO = new Image();
lettreO.src = 'O.jpg';
lettreO.onload = function(){
context.drawImage(lettreO, 265, 265,95,93);
}
}
function lettreX3()
{
lettreX = new Image();
lettreX.src = 'X.PNG';
lettreX.onload = function(){
context.drawImage(lettreX, 265, 265,95,93);
}
}
function lettreO4()
{
lettreO = new Image();
lettreO.src = 'O.jpg';
lettreO.onload = function(){
context.drawImage(lettreO, 40,149,95,107);
}
}
function lettreX4()
{
lettreX = new Image();
lettreX.src = 'X.PNG';
lettreX.onload = function(){
context.drawImage(lettreX, 40,149,95,107);
}
}
function lettreO5()
{
lettreO = new Image();
lettreO.src = 'O.jpg';
lettreO.onload = function(){
context.drawImage(lettreO, 145,149,110,107);
}
}
function lettreX5()
{
lettreX = new Image();
lettreX.src = 'X.PNG';
lettreX.onload = function(){
context.drawImage(lettreX, 145,149,110,107);
}
}
function lettreO6()
{
lettreO = new Image();
lettreO.src = 'O.jpg';
lettreO.onload = function(){
context.drawImage(lettreO, 265,149,95,107);
}
}
function lettreX6()
{
lettreX = new Image();
lettreX.src = 'X.PNG';
lettreX.onload = function(){
context.drawImage(lettreX, 265,149,95,107);
}
}
function lettreO7()
{
lettreO = new Image();
lettreO.src = 'O.jpg';
lettreO.onload = function(){
context.drawImage(lettreO, 40,40,95,101);
}
}
function lettreX7()
{
lettreX = new Image();
lettreX.src = 'X.PNG';
lettreX.onload = function(){
context.drawImage(lettreX, 40,40,95,101);
}
}
function lettreO8()
{
lettreO = new Image();
lettreO.src = 'O.jpg';
lettreO.onload = function(){
context.drawImage(lettreO, 145,40,110,101);
}
}
function lettreX8()
{
lettreX = new Image();
lettreX.src = 'X.PNG';
lettreX.onload = function(){
context.drawImage(lettreX, 145,40,110,101);
}
}
function lettreO9()
{
lettreO = new Image();
lettreO.src = 'O.jpg';
lettreO.onload = function(){
context.drawImage(lettreO, 265,40,95,101);
}
}
function lettreX9()
{
lettreX = new Image();
lettreX.src = 'X.PNG';
lettreX.onload = function(){
context.drawImage(lettreX, 265,40,95,101);
}
}
</script>
</body>
</html>
We talked in the chat, but since I don't know when we will be on SO at the same time, I'm posting a solution. I still can help you step by step if you want to.
First, I cleaned and simplified some parts of your code to avoid to much work:
I put all the code designed to draw the grid in a drawGrid(context) function:
From:
// Line horizontale et verticale
To:
context.fillText("9", 305, 105);
Then, I rewrote the function Nombre(e) {...} function.
I used a keyboard map:
var KEYBOARD = {
NUMBER_UP_1: 49,
...
NUMBER_UP_9: 57,
NUMBER_1: 97,
...
NUMBER_9: 105,
};
I renamed the function function onKeyDown(e) {...}, because Nombre(e) isn't very explicit and may be confused with the Number(n) function.
I deduced the letter from the keyCode. It's an X if the keyCode is in [49, ..., 57], or an O if the keyCode is in [97, ..., 105].
Then, the calculation keyCode - {firstKeyCodeForCurrentLetter} - 1 gives you the number on the pressed key. For example, if you press 50, you have: 50 - 49 + 1 = 2, and according to the keyboard map, 50 is associated with the key UP_2.
Then, whenever a number key is pressed (except 0), I check if any player has already played here. I created a letterAt(memoryContext, position) function that returns true if a player has already played at the position, false otherwise. If the player hasn't, then I save the move with a memorizeMove(memoryContext, letter, position) that draws in the memoryCanvas, then I update the main canvas by draw either an X or a O on it.
Finally, I determine if there is a winner with a winOrLoss(memoryContext) function that returns either a letter: 'O' or 'X', or an empty string '' if there's no winner yet.
I didn't handle the draw nor the fact that each player must wait his turn to play. So a player can play twice in a row. But that's something you can fix. There isn't any proper game over either: if a player wins, there's an alert, that's all, the game can still continue after that.
But the restart() works: I initialized everything we needed in this function, so that every time it's called, it clears both canvases and initializes variables.
I also rewrote the lettreX1(), lettreO3() and so on, functions because: no need to load the same image each time you want to draw. Load once and use as many times as you want. Then, you just have to give the x,y position to a function to draw the image where you want, reducing your 18 functions to only one.
To save the game's state, you didn't want to use variables (like an array or a matrix to know which moves has already been played for instance), so we agreed to use a secondary canvas. This canvas is 3x3 in size. Each time a player plays, if the move is allowed, then we draw one pixel of this canvas, which indicates that the position isn't empty anymore. A player a color. I did this with the memorizeMove(memoryContext, letter, position) function:
function memorizeMove(memoryContext, letter, position) {
memoryContext.fillStyle = letter === `O` ? 'red' : 'blue';
var coords = getCoordinatesFromPosition(position);
memoryContext.fillRect(coords.x, coords.y, 1, 1);
}
It sets the color according to the player's letter (O -> red, X -> blue), gets the x,y coordinates from the position in the grid, then draws a pixel, that is to say a 1x1 rectangle, at this position with the set color.
To check if a move is allowed, I use the letterAt(memoryContext, position) function, which converts the pixel color (red, blue or blank) into a letter or an empty string. I could have just return true or false, but I needed the letters in the winOrLoss(memoryContext) function, and I thought that it may also be useful later to know which player has played here, if any.
function letterAt(memoryContext, position) {
var color = getPixelAt(memoryContext, position);
return color === 'red'
? 'O'
: color === 'blue'
? 'X'
: '';
}
It uses a getPixelAt(memoryContext, position) that returns the pixel's color on the memoryContext of the 2nd canvas at the specified position, as seen together. It converts the position into x,y coordinates, then gets the pixel at x,y, gets its RGBA colors and returns its color.
function getPixelAt(memoryContext, position) {
var coords = getCoordinatesFromPosition(position);
var pixel = memoryContext.getImageData(coords.x, coords.y, 1, 1);
var data = pixel.data;
var red = data[0];
var blue = data[2];
var color = '';
if (red === 255) {
color = 'red';
} else if (blue === 255) {
color = 'blue';
}
return color;
}
I was a bit lazy when I wrote the getCoordinatesFromPosition(position) function... In fact, you're supposed to use a combination of % and / but since your grid is inverted (top-left is a 7, not a 1), I thought that it might be trickier than expected, so I made something very simple instead, with ifs only.
function getCoordinatesFromPosition(position) {
var x = [1, 4, 7].includes(position)
? 0
: [2, 5, 8].includes(position)
? 1
: 2;
var y = position < 4
? 2
: position < 7
? 1
: 0;
return { x: x, y: y };
}
Lastly, for the winOrLoss(memoryContext) function, I read the canvas using the letterAt(memoryContext, i) function and store them in an array. Then I compared the letters between each others, horizontally, vertically and in diagonal, looking for 3 identical letters. It returns true if the condition is met, false otherwise.
function winOrLoss(memoryContext) {
var letters = [];
for (var i = 1; i <= 9; i++) {
letters.push(letterAt(memoryContext, i));
}
if (letters[0] === letters[1] && letters[1] === letters[2] && letters[0] !== ''
|| letters[3] === letters[4] && letters[4] === letters[5] && letters[3] !== ''
|| letters[6] === letters[7] && letters[7] === letters[8] && letters[6] !== ''
|| letters[0] === letters[3] && letters[3] === letters[6] && letters[0] !== ''
|| letters[1] === letters[4] && letters[4] === letters[7] && letters[1] !== ''
|| letters[2] === letters[5] && letters[4] === letters[8] && letters[2] !== ''
|| letters[0] === letters[4] && letters[4] === letters[8] && letters[0] !== ''
|| letters[2] === letters[4] && letters[4] === letters[7] && letters[2] !== ''
) {
return letters[0];
}
}
As usual, here's the fiddle: https://jsfiddle.net/nmerinian/2h87Ltr9/75/
I've been working on a simple matching puzzle game for a little while now. Currently I have been able to have a countdown time and the number of matching tiles displayed as a text and I'm trying to create one for the best time completed (basically how fast the person completed the puzzle). However whenever I try to create it the text never displays.I noticed while writing the code that if I where to place the variable "txt" followed by a "." the autocomplete box will appear with .text as an available option so I would get "txt.text". I do not however get that option when writing the bestTimeTxt variable which is what I am using to display the time. I'm not sure what I have done wrong, here is my code.
<!DOCTYPE html>
<html>
<head>
<title>Recipe: Drawing a square</title>
<script src="easel.js"></script>
<script type="text/javascript">
var canvas;
var stage;
var squareSide = 70;
var squareOutline = 5;
var max_rgb_color_value = 255;
var gray = Graphics.getRGB(20, 20, 20);
var placementArray = [];
var tileClicked;
var timeAllowable;
var totalMatchesPossible;
var matchesFound;
var txt;
var bestTime;
var bestTimeTxt;
var matchesFoundText;
var squares;
function init() {
var rows = 5;
var columns = 6;
var squarePadding = 10;
canvas = document.getElementById('myCanvas');
stage = new Stage(canvas);
var numberOfTiles = rows*columns;
matchesFound = 0;
timeAllowable = 5;
bestTime = 0
txt = new Text(timeAllowable, "30px Monospace", "#000");
txt.textBaseline = "top"; // draw text relative to the top of the em box.
txt.x = 500;
txt.y = 0;
bestTimeTxt = new Text(bestTime, "30px Monospace", "#000");
bestTimeTxt.textBaseLine = "top";
bestTimeTxt.x = 300;
bestTimeTxt.y = 0;
stage.addChild(txt);
stage.addChild(bestTimeTxt);
squares = [];
totalMatchesPossible = numberOfTiles/2;
Ticker.init();
Ticker.addListener(window);
Ticker.setPaused(false);
matchesFoundText = new Text("Pairs Found: "+matchesFound+"/"+totalMatchesPossible, "30px Monospace", "#000");
matchesFoundText.textBaseline = "top"; // draw text relative to the top of the em box.
matchesFoundText.x = 500;
matchesFoundText.y = 40;
stage.addChild(matchesFoundText);
setPlacementArray(numberOfTiles);
for(var i=0;i<numberOfTiles;i++){
var placement = getRandomPlacement(placementArray);
if (i % 2 === 0){
var color = randomColor();
}
var square = drawSquare(gray);
square.color = color;
square.x = (squareSide+squarePadding) * (placement % columns);
square.y = (squareSide+squarePadding) * Math.floor(placement / columns);
squares.push(square);
stage.addChild(square);
square.cache(0, 0, squareSide + squarePadding, squareSide + squarePadding);
square.onPress = handleOnPress;
stage.update();
};
}
function drawSquare(color) {
var shape = new Shape();
var graphics = shape.graphics;
graphics.setStrokeStyle(squareOutline);
graphics.beginStroke(gray);
graphics.beginFill(color);
graphics.rect(squareOutline, squareOutline, squareSide, squareSide);
return shape;
}
function randomColor(){
var color = Math.floor(Math.random()*255);
var color2 = Math.floor(Math.random()*255);
var color3 = Math.floor(Math.random()*255);
return Graphics.getRGB(color, color2, color3)
}
function setPlacementArray(numberOfTiles){
for(var i = 0;i< numberOfTiles;i++){
placementArray.push(i);
}
}
function getRandomPlacement(placementArray){
randomNumber = Math.floor(Math.random()*placementArray.length);
return placementArray.splice(randomNumber, 1)[0];
}
function handleOnPress(event){
var tile = event.target;
tile.graphics.beginFill(tile.color).rect(squareOutline, squareOutline, squareSide, squareSide);
if(!!tileClicked === false || tileClicked === tile){
tileClicked = tile;
tileClicked.updateCache("source-overlay");
}else{
if(tileClicked.color === tile.color && tileClicked !== tile){
tileClicked.visible = false;
tile.visible = false;
matchesFound++;
matchesFoundText.text = "Pairs Found: "+matchesFound+"/"+totalMatchesPossible;
if (matchesFound===totalMatchesPossible){
gameOver(true);
}
}else{
tileClicked.graphics.beginFill(gray).rect(squareOutline, squareOutline, squareSide, squareSide);
}
tileClicked.updateCache("source-overlay");
tile.updateCache("source-overlay");
tileClicked = tile;
}
stage.update();
}
function tick() {
secondsLeft = Math.floor((timeAllowable-Ticker.getTime()/1000));
txt.text = secondsLeft;
bestTimeTxt.text = "test";
if (secondsLeft <= 0){
gameOver(false);
}
stage.update();
}
function gameOver(win){
Ticker.setPaused(true);
for(var i=0;i<squares.length;i++){
squares[i].graphics.beginFill(squares[i].color).rect(5, 5, 70, 70);
squares[i].onPress = null;
if (win === false){
squares[i].uncache();
}
}
var replayParagraph = document.getElementById("replay");
replayParagraph.innerHTML = "<a href='#' onClick='history.go(0);'>Play Again?</a>";
if (win === true){
matchesFoundText.text = "You win!"
}else{
txt.text = secondsLeft + "... Game Over";
}
}
function replay(){
init();
}
</script>
</head>
<body onload="init()">
<header id="header">
<p id="replay"></p>
</header>
<canvas id="myCanvas" width="960" height="400"></canvas>
</body>
</html>
Apparently the issue I was having was that the x and y position of the text was causing it to appear behind everything else.
var leftf;
var rightf;
$(document).keyup(function() {
clearInterval(leftf);
clearInterval(rightf);
});
$(document).keydown(function (e) {
if (e.which == 37) {
// Left Arrow Pushed
leftf=setInterval(function(){
meshes[0].rotation.y=Math.PI/4;
if(meshes[0].position.x>-3.5)meshes[0].position.x-=0.1;
console.log(meshes[0].position.x);
},1000/engine.getFps());
} else if (e.which == 39) {
// Right Arrow Pushed
meshes[0].rotation.y=3*Math.PI/4;
//meshes[0].translate(BABYLON.Axis.X, Math.sin(v), BABYLON.Space.WORLD);
rightf=setInterval(function(){
meshes[0].position.x+=0.1;
},1000/engine.getFps());
}
});
Can you please tell me why this is not working in the browser although it is in my opinion the right way of moving the mesh on the screen without being torn (torn animation)?
It starts moving the mesh correctly but after a while the mesh is flying around without the logic. Is setting and clearing the Interval such a problem for the browsers?
Thank you.
Now it is running, perhaps I have a solution:
<!DOCTYPE html>
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Babylon.js sample code keyboard arrows</title>
<!-- Babylon.js -->
<script src="index_subory/hand.js"></script>
<script src="index_subory/cannon.js"></script>
<script src="index_subory/oimo.js"></script>
<script src="index_subory/babylon.2.0.debug.js"></script>
<script src="index_subory/jquery.min.js"></script>
<style>
html, body {
overflow: hidden;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#renderCanvas {
width: 100%;
height: 100%;
touch-action: none;
}
</style>
</head>
<body>
<div id="idecko" style="background-color:grey;color:white;font-weight:bold;margin-left:auto;margin-right:auto;text-align:center;">text </div>
<canvas height="782" width="1440" id="renderCanvas"></canvas>
<script>
var canvass = $('#renderCanvas');
// check to see if we can do webgl
// ALERT FOR JQUERY PEEPS: canvas is a jquery obj - access the dom obj at canvas[0]
var dcanvas = canvass[0];
expmt = false;
if ("WebGLRenderingContext" in window) {
//alert("browser at least knows what webgl is.");
}
// some browsers don't have a .getContext for canvas...
try {
gl = dcanvas.getContext("webgl");
}catch (x){
gl = null;
}
if (gl == null) {
try {
gl = dcanvas.getContext("experimental-webgl");
}catch (x){
gl = null;
}
if (gl == null) {
//console.log('but can\'t speak it');
}else {
expmt = true; //alert('webgl experimentally.');
}
} else {
//alert('webgl natively');
}
if (gl || expmt) {
//alert("loading webgl content.");
} else {
alert("CHYBA: Váš prehliadač nepodporuje WebGL, ľutujeme. (ERROR: Your browser does not support WebGL, sorry.)");
canvas.remove();
}
if (BABYLON.Engine.isSupported()) {
var canvas = document.getElementById("renderCanvas");
var engine = new BABYLON.Engine(canvas, true);
var scene = new BABYLON.Scene(engine);
// Skybox
var skybox = BABYLON.Mesh.CreateBox("skyBox", 800.0, scene);
var skyboxMaterial = new BABYLON.StandardMaterial("skyBox", scene);
skyboxMaterial.backFaceCulling = false;
skyboxMaterial.reflectionTexture = new BABYLON.CubeTexture("index_subory/skybox/cubemap", scene);
skyboxMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;
skyboxMaterial.diffuseColor = new BABYLON.Color3(0, 0, 0);
skyboxMaterial.specularColor = new BABYLON.Color3(0, 0, 0);
skybox.material = skyboxMaterial;
//var sphere = BABYLON.Mesh.CreateSphere("sphere", 1.0, 1.0, scene);
var createScene = function () {
// setup environment
var light0 = new BABYLON.PointLight("Omni", new BABYLON.Vector3(0, 10,80), scene);
var camera = new BABYLON.FreeCamera("FreeCamera", new BABYLON.Vector3(0, 0, -5), scene);
var light2 = new BABYLON.PointLight("Omni", new BABYLON.Vector3(10, 10, -80), scene);
var turnLeft = false; var turnRight = false;
var accelerate = false; var breaking = false;
BABYLON.SceneLoader.ImportMesh("Cube.001", "index_subory/", "jet2b.babylon", scene,function(meshes){
meshes[0].position.x = Math.round((Math.random() * 1) + 0);
meshes[0].position.y = Math.round((Math.random() * 1) + 0);
var speed = 0;
scene.registerBeforeRender(function() {
if (scene.isReady()) {
camera.target = sphere.position;
speed=0.02;
if (turnRight) {
meshes[0].rotation.y=3*Math.PI/4;
meshes[0].position.x += speed;
}
if (turnLeft) {
meshes[0].rotation.y=Math.PI/4;
meshes[0].position.x -= speed;
}
if (breaking) {
meshes[0].rotation.y=Math.PI/2;
meshes[0].position.y -= speed;
}
if (accelerate) {
meshes[0].rotation.y=Math.PI/2;
meshes[0].position.y += speed;
}
}
});
var sphere = BABYLON.Mesh.CreateSphere("sphere", 0.5, 0.5, scene);
var simpleMaterial = new BABYLON.StandardMaterial("texture2", scene);
simpleMaterial.diffuseColor = new BABYLON.Color3(0, 1, 0);//Green
sphere.material=simpleMaterial;
sphere.position.x = Math.floor((Math.random() * 2) );
sphere.position.y = Math.floor((Math.random() * 2) );
sphere.position.z=3;
var myVar2;
function myFunction2() {
myVar = setInterval(function(){
//sphere.translate(BABYLON.Axis.Z, -0.1, BABYLON.Space.WORLD);
sphere.position.z-=0.1;
var delta=0.2;
if(Math.abs(Math.round(meshes[0].position.x-sphere.position.x))<=delta&&Math.abs(Math.round(meshes[0].position.y-sphere.position.y))<=delta&&Math.abs(Math.round(meshes[0].position.z-sphere.position.z))<=delta){
$('#idecko').html('<span style=\'background-color:yellow;color:red;\'>BANG! Červeného trpaslíka trafila zelená planéta! (Red dwarf shot by green planet!)</span>');
//$('#idecko').append("<embed src='index_subory/explosion.mp3' hidden=true autostart=true loop=false>");
if(navigator.userAgent.indexOf("Trident")==-1)var audio = new Audio('index_subory/explosion.mp3');
if(navigator.userAgent.indexOf("Trident")!=-1)var audio = new Audio('index_subory/explosion.wav');
audio.loop = false;
audio.play();
simpleMaterial.diffuseColor = new BABYLON.Color3(0, 0, 1);//Green
sphere.material=simpleMaterial;
}else{
$('#idecko').html('<span style=\'background-color:grey;color:white;\'>Unikaj červený trpaslík (šípky na klávesnici)! (Run away red dwarf (keyboard arrows)!)</span>');
}
if(sphere.position.z<-5){
sphere.position.x = Math.floor((Math.random() * 2) );
sphere.position.y = Math.floor((Math.random() * 2) );
sphere.position.z=3;
simpleMaterial.diffuseColor = new BABYLON.Color3(0, 1, 0);//Green
sphere.material=simpleMaterial;
}
}, 50);
}
function myStopFunction2() {
clearTimeout(myVar2);
}
myFunction2();
$(document).keyup(function (evt) {
if (evt.keyCode == 37 || evt.keyCode == 39) {
turnLeft = false;
turnRight = false;
}
if (evt.keyCode == 38 || evt.keyCode == 40) {
accelerate = false;
breaking = false;
}
});
$(document).keydown(function (evt) {
if (!scene)
return;
//console.log(evt.keyCode);
if (evt.keyCode == 32) {
}
//Key LEFT
if (evt.keyCode == 37) {
turnLeft = true;
turnRight = false;
}
//Key RIGHT
if (evt.keyCode == 39) {
turnLeft = false;
turnRight = true;
}
//Key UP
if (evt.keyCode == 38) {
accelerate = true;
breaking = false;
}
//Key BACK
if (evt.keyCode == 40) {
breaking = true;
accelerate = false;
}
});
});
return scene;
}
var scene = createScene();
var assetsManager = new BABYLON.AssetsManager(scene);
//var meshTask = assetsManager.addMeshTask("jet2 task", "", "./index_subory/", "jet2.babylon");
var textTask0 = assetsManager.addTextFileTask("text task0", "./index_subory/jet2b.babylon");
var textTask1 = assetsManager.addTextFileTask("text task1", "./index_subory/hand.js");
var textTask2 = assetsManager.addTextFileTask("text task2", "./index_subory/cannon.js");
var textTask3 = assetsManager.addTextFileTask("text task3", "./index_subory/oimo.js");
var textTask4 = assetsManager.addTextFileTask("text task4", "./index_subory/babylon.2.0.debug.js");
var textTask5 = assetsManager.addTextFileTask("text task5", "./index_subory/jquery.min.js");
var binaryTask1 = assetsManager.addBinaryFileTask("binary task 1", "./index_subory/explosion.mp3");
var binaryTask2 = assetsManager.addBinaryFileTask("binary task 2", "./index_subory/explosion.wav");
var binaryTask3 = assetsManager.addBinaryFileTask("binary task 3", "./index_subory/skybox/cubemap_nx.jpg");
var binaryTask4 = assetsManager.addBinaryFileTask("binary task 4", "./index_subory/skybox/cubemap_ny.jpg");
var binaryTask5 = assetsManager.addBinaryFileTask("binary task 5", "./index_subory/skybox/cubemap_nz.jpg");
var binaryTask6 = assetsManager.addBinaryFileTask("binary task 6", "./index_subory/skybox/cubemap_px.jpg");
var binaryTask7 = assetsManager.addBinaryFileTask("binary task 7", "./index_subory/skybox/cubemap_py.jpg");
var binaryTask8 = assetsManager.addBinaryFileTask("binary task 8", "./index_subory/skybox/cubemap_pz.jpg");
//engine.displayLoadingUI();
engine.loadingUIText = "Loading... (Načítavanie...)";
assetsManager.onTaskSuccess = function (task) {
// Do something with task.data.
//engine.hideLoadingUI();
};
assetsManager.onTaskError = function (task) {
// Do something with task.data.
alert('Error with loading by assetsManager...');
};
assetsManager.onFinish = function (task) {
//engine.hideLoadingUI();
engine.setSize($(window).width(), $(window).height());
engine.runRenderLoop(function () {
scene.render();
});
};
assetsManager.load();
// Resize
window.addEventListener("resize", function () {
engine.resize();
});
}else{
alert("Chyba: Nemôžem spustiť WebGL. (Error: Can't run WebGL.)");
}
</script>
</body></html>
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 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);