Sign in to follow this  

Recommended Posts

Right, I'm new. Hello!  

This might help someone.

It's an example of drag and drop, collision detection and physics (a drag puzzle game).
I sketched it pretty quickly, and I'm  sorry it's not commented.
Bit messy but you should be able to grab the helpful bits.
I had a nightmare putting this together to be honest, but on the 5th evening this is the result, so I'm pleased.

I'll update it soon to make things clearer.

SHARE YOURS!



<html xmlns="http://www.w3.org/1999/xhtml"><head>
<script src="hand.js"></script>
<script type="text/javascript" src="cannon.js"></script>
<script src="babylon.js"></script>
<script src="jquery.min.js"></script>
<script type="text/javascript" src="oimo.js"></script>
<style>
html, body {
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
}    
#renderCanvas {
    width: 100%;
    height: 100%;
    touch-action: none;
}
.debugDiv{
    display:nones;
}
</style>
</head>
<body>
<div class="debugDiv"></div>
<canvas id="renderCanvas"></canvas>

<script>
var boxes = new Array();
var materials = new Array();
var box1, box2, blueBox, camera, scene, ground;
var canvas = document.querySelector("#renderCanvas");
var engine = new BABYLON.Engine(canvas, true);
var mazeSize = 3;

var createScene = function(){
    scene = new BABYLON.Scene(engine);
    var canvas = engine.getRenderingCanvas(); var startingPoint;    var currentMesh;
    var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0, 0, new BABYLON.Vector3(0, 5, 0), scene);
    camera.setPosition(new BABYLON.Vector3(200,150, 10)); scene.clearColor = new BABYLON.Color3(0, 0, 0);
    camera.attachControl(canvas, true);
    
    scene.enablePhysics(new BABYLON.Vector3(0, -500, 0), new BABYLON.OimoJSPlugin());
        
    ground = BABYLON.Mesh.CreateGround("ground", 1000, 1000, 1, scene, false);
    ground.setPhysicsState(BABYLON.PhysicsEngine.BoxImpostor, {mass:0, friction:0.5, restitution: 1});
    ground.visibility = 0;

    createWalls();
    createBoxes();
    
    var getGroundPosition = function(){
        var pickinfo = scene.pick(scene.pointerX, scene.pointerY, function (mesh){return mesh == ground;});
        if(pickinfo.hit){return pickinfo.pickedPoint;}
        return null;
    }
    
    var onPointerDown = function (evt) {
        if (evt.button !== 0){return;}
        var pickInfo = scene.pick(scene.pointerX, scene.pointerY, function(mesh){ return mesh !== ground;});
        if(pickInfo.hit){
            currentMesh = pickInfo.pickedMesh; startingPoint = getGroundPosition(evt);
            if(startingPoint){setTimeout(function(){camera.detachControl(canvas);}, 0);}
        }
    }
    
    var onPointerUp = function(){if(startingPoint){camera.attachControl(canvas, true); startingPoint = null; return;}}
    
    var onPointerMove = function(evt){
        if(!startingPoint){return;}
        var current = getGroundPosition(evt); if(!current){return;}
        var diff = current.subtract(startingPoint);
        if(currentMesh.draggable){return;}
        currentMesh.moveWithCollisions(diff); startingPoint = current;
        currentMesh.updatePhysicsBodyPosition();
    }

    $(canvas).bind("pointerdown", onPointerDown).bind("pointerup", onPointerUp).bind("pointermove", onPointerMove);
    scene.onDispose = function(){$(canvas).unbind("pointerdown", onPointerDown).bind("pointerup", onPointerUp).bind("pointermove", onPointerMove);}
    return scene;
};

function createBoxes(){
    matUnit = (1/mazeSize);
    blocks = new Array();
    for(x=0;x<mazeSize;x++){
        for(y=0;y<3;y++){
            //materials
            materialsIndex = materials.length;
            materials[materialsIndex] = new BABYLON.StandardMaterial("texture1", scene);
            var m = materials[materialsIndex]; m.id = materialsIndex; m.diffuseTexture = new BABYLON.Texture("profilePic.jpg", scene);
            m.diffuseTexture.uScale = 1/mazeSize; m.diffuseTexture.vScale = 1/mazeSize;
            m.diffuseTexture.uOffset = matUnit*(-(x+1)); m.diffuseTexture.vOffset = matUnit*(0+y);
            boxIndex = boxes.length;
            boxes.push(BABYLON.Mesh.CreateBox("red", 49.9, scene));
            var b = boxes[boxIndex]; b.id = materialsIndex; b.position.y = 25.1; b.position.x = 50-(50*y); b.position.z = 50-(50*x);
            b.setPhysicsState(BABYLON.PhysicsEngine.BoxImpostor, {mass:0.1, friction:0.1, restitution:0.1});
            b.checkCollisions = true; b.ellipsoid = new BABYLON.Vector3(24, 24, 24);
            
            coords = [Math.round(b.position.x),Math.round(b.position.z)];
            m.coords = coords; b.coords = coords;
            
            if(x == mazeSize-1 && y == mazeSize-2){
                coords = [Math.round(b.position.x),Math.round(b.position.z)];
                m.coords = coords; b.coords = coords;
                break;
            }
        }
    }
    swapArrayElements(boxes, 5, 7);
    swapArrayElements(boxes, 4, 7);
    //swapArrayElements(boxes, 3, 7);
    //shuffle(boxes);
    for(x=0;x<materials.length;x++){boxes[x].material = materials[x];}
}

function createWalls(){
    wallScaleAxis = new Array("x","z","x","z");
    wallDimsArr = new Array([25*mazeSize, 25, 0],[0,25,25*mazeSize],[0-(25*mazeSize),25,0],[0,25,0-(25*mazeSize)]);
    wallsArr = new Array();
    lightsArr = new Array();
    for(x=0;x<4;x++){
        lightsArr[x] = new BABYLON.PointLight("omni", new BABYLON.Vector3(wallDimsArr[x][0]*2, 150, wallDimsArr[x][2]*2), scene);
        lightsArr[x].intensity = 0.3; wallsArr[x] = BABYLON.Mesh.CreateBox("ground", 50*mazeSize, scene); var w = wallsArr[x];
        w.scaling[wallScaleAxis[x]] = 0.001; w.scaling.y = 0.5;
        w.position = new BABYLON.Vector3(wallDimsArr[x][0], wallDimsArr[x][1], wallDimsArr[x][2]);
        w.setPhysicsState(BABYLON.PhysicsEngine.BoxImpostor, {mass:0});
        w.checkCollisions = true; w.draggable = true;
        w.ellipsoid = new BABYLON.Vector3(25*mazeSize, 25, 0.01); 
        w.showBoundingBox = false; w.visibility = 0;
    }
}

var scene = createScene();
engine.runRenderLoop(function(){scene.render();});
$(window).bind("resize", function(){engine.resize();});

function swapArrayElements(arr, indexA, indexB){
  var temp = arr[indexA];
  arr[indexA] = arr[indexB];
  arr[indexB] = temp;
  return arr;
};

function shuffle(array) {
  var currentIndex = array.length, temporaryValue, randomIndex;

  // While there remain elements to shuffle...
  while (0 !== currentIndex) {

    // Pick a remaining element...
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex -= 1;

    // And swap it with the current element.
    temporaryValue = array[currentIndex];
    array[currentIndex] = array[randomIndex];
    array[randomIndex] = temporaryValue;
  }

  return array;
}

doer = 0;
function showBoxPos(){
    doer++;
    $(".debugDiv").html(doer)
    correct = 1;
    for(x=0;x<boxes.length;x++){
        boxes[x].coords = [Math.round(boxes[x].position.x),Math.round(boxes[x].position.z)];
        if(!(boxes[x].coords.toString()  == materials[x].coords.toString())){correct++; break;};
    }
    for(x=0;x<4;x++){
        if(correct <= 1){
            for(y=0;y<boxes.length;y++){
                boxes[y].setPhysicsState(BABYLON.PhysicsEngine.BoxImpostor, {mass:-10});
                boxes[y].updatePhysicsBodyPosition();
                boxes[y].draggable = true;
            }
            clearTimeout(boxTimer);
            ground.setPhysicsState(BABYLON.PhysicsEngine.BoxImpostor, {mass:1, friction:0.5, restitution: 1});
            break;
        }
    }
}

var boxTimer = setInterval(showBoxPos, 1)
</script>
</body>
</html>

Share this post


Link to post
Share on other sites

Well that was painful.

Spent an hour trying to get it working in the playground, but it just wont work.

I'm not impressed. Console reported errors with a toString function, and continued to produce the error when that line was commented out.

Adding textures to the playground is also a pain. And plugins like oimo? God knows.

Not good

 

 

Share this post


Link to post
Share on other sites

Nice one, but it's not quite there. If you look at the version on my site the puzzle drops away, and the blocks spin when the puzzle is completed.
You only have to move the top left 3 cubes to complete the puzzle.

I'm getting into BabylonJS. Just need to push through the initial pain, then I'll be producing some cool stuff.

Share this post


Link to post
Share on other sites

So are you two both Babylon support?

RE "the physics engine controlling them" - can animations be applied using the physics engine?

I suppose the whole point of the physics engine is that objects behave according to the gravity settings you apply, but I wondered if for example you could have a bird flapping its wings whilst having physics applied to it? I guess that has to be done using animation without physics?

I'm really impressed - it's very easy to pickup the basics from the examples in the playground.
It's harder to progress from there tho. Googling my queries either gives me basic answers, or really advanced stuff that's hard to pick apart.

Cheers

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.