Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use of Stage.js #44

Open
blizniak83 opened this issue Jan 19, 2018 · 17 comments
Open

Use of Stage.js #44

blizniak83 opened this issue Jan 19, 2018 · 17 comments

Comments

@blizniak83
Copy link

Hi,

I had a chance to play with Planck.js and Stage.js, but separately.
I'm not js guru. In the last few days I decided to use the library without the testbed.
My first choice was to replace it with Stage.js.

I follow box2d manual hello world example, nothing super ambitious.
I have a bouncing ball on a flat surface/edge. Now I want to use Stage.js to render that on the screen.

It seems like all examples are testbed examples. Even though it supposed to be only a case of calling the world.step(timestep) function, I'm still struggling as I assume there will be something similar needed on the Stage.js side.

Would it be possible to post an example that uses Stage.js? Something really simple.

Thank you.
Chris

@Cdvalencia
Copy link

Hi, the "testbet" have a basic example to create grapichs and can use Stage.js and Plank.js. i dont have a idea clear to create a firts prototype, but i know to be possible use the default render.

image
for example, i have inserted this graphics using the next function:

image
this lines are on the "planck-js/dist/planck-with-testbed.js", as i said, still i havn´t a clear idea, but planck and stage are joined on "planck-with-testbed.js"

@blizniak83
Copy link
Author

Hi Cristian,

Thanks for your suggestion. I'll definitely try that. It would be a lot better for me as I could use the debug/testbed functionality.

I came up with something different, but I don't know if it is correct and the most efficient way of achieving what I wanted. The example below is very primitive, is just a rolling ball down the sloped edge.

There are still few unknowns for me, like for example the step function - not sure what value should I use for that, I know 1/60 doesn't work well when you have a bouncing ball for example, as I had the impression that the ball never came to rest.

Finally, I've got a problem with scaling of my box2d/planck.js bodies vs graphics rendered by the stage.js, this is why I kind of like your approach as I still could have the debug/testbed functionality, currently I didn't manage to figure out how to enable debug/testbed in my simple stage.js example below.

Stage(function(stage) {

  // Set view box
  stage.viewbox(1000, 1000);
var Mouse = Stage.Mouse;
  // Create an image and append it to stage
  var ball = Stage.image('circle').appendTo(stage);

  var world;
  var ballBody;
  
  ball.pin('align', 0.5);
  		
  var pl = planck; Vec2 = pl.Vec2;

  world = this.world = new pl.World(Vec2(0, -10));

  var floorShape = pl.Edge(Vec2(-40.0, 10.0), Vec2(40.0, 0.0));
  var ballShape = pl.Circle(.5);
  
  var ballFix = {
	  density: 1.0,
	  friction: 0.5,
	  restitution: 1.0
  };
	  
  world.createBody().createFixture(floorShape);
  

  ballBody = world.createBody({
	  type: 'dynamic',
	  position: Vec2(-39.50, 10.0)
  });
  
  ballBody.createFixture(ballShape,ballFix);
  var outPos = ballBody.getPosition();

	ball.pin({
			handle: .5,
			offsetX: outPos.x *(25),
			offsetY: outPos.y *(-25)
  });	

	stage.tick(function()
	{
		world.step(1/60);
		outPos = ballBody.getPosition();
		
		ball.pin({
			handle: .5,
			rotation: -ballBody.getAngle(),
			offsetX: outPos.x *(25),
			offsetY: outPos.y *(-25)
			
		});
	});
});

Stage({
	image : { src : "./example.png", ratio : 2 },
	trim : 0.2,
	textures : {
		//box :      { x : 0,    y : 32, width : 16, height : 16, top : 4, bottom : 4, left : 4, right : 4},
		circle :   { x : 32,   y : 64, width : 32, height : 32}
	}
});

Thanks for your comment once again.

@shakiba
Copy link
Collaborator

shakiba commented Jan 26, 2018

Here is my recommended approach:

  • In each frame (tick/step) iterate over all bodies/fixtures and other elements which you like to render.
  • Translate each elements' position from physics engine to ui.
  • When creating physics elements attach associated rendering data (such as color or texture) to a specific field. Use this field along with elements' position to render them when iterating over them. Box2D has userData field dedicated to this, but in JS you can use another name as far as the name does not collide with existing fields. In planck's testbed it is render.

See renderWorld in tesbed.

@shakiba
Copy link
Collaborator

shakiba commented Jan 29, 2018

I added a stage.js example with planck.js physics. It does not support adding graphics yet, but I will add it soon.

@blizniak83
Copy link
Author

Thanks Ali,

For your both replies. Especially the first one. I indeed took a closer look at the testbed in planck.js, especially the viewer class and then started to look at the breakout code which uses stage-p2.js, where the viewer class is almost identical and that gave me some good idea how to move on.

Thanks for the new examples, I'm sure I'll make use of them.

Chris

@shakiba shakiba closed this as completed Jan 29, 2018
@shakiba shakiba reopened this Jan 29, 2018
@shakiba
Copy link
Collaborator

shakiba commented Jan 29, 2018

@blizniak83 Right, breakout/stage-p2.js is a good example.

@blizniak83
Copy link
Author

Is there any reason why the world in the asteroid example is upside down? I remember when initially using the viewer class from the testbed I had the same problem and I had to use the scale method on the stage object (scale(1,-1)) to get the right orientation. Is this caused because of the way you attache the viewer/Stage.planck? I noticed that after adding some bodies but also after setting the gravity to -10.

@shakiba
Copy link
Collaborator

shakiba commented Jan 30, 2018

The reason is that physics y-axis is upward, but rendering is downward. Physics engines orientation/scale is usually based on real world physics, but graphic libraries is based on the screen with top-left as the origin.

@blizniak83
Copy link
Author

undetstood but if I want to render the physics bodies like they behave in the physics world then I have to flip the stage upside down, correct? I think this is what was done in the breakout example. What would be the best method to achieve that in the asteroid example? I managed to achieve that by using world.scale(80, -80), but I know it isn't the best way as it is affecting stage.on() making it no longer responsive to the changes applied to the browser window size.

@blizniak83
Copy link
Author

I think I just solved my own problem, partially of course, I applied the scale to the stage, this time scale(1,-1), it renders what I want, when looking at the physics bodies, but of course the 'status' element etc. has to be rendered differently.

@shakiba
Copy link
Collaborator

shakiba commented Jan 31, 2018

Probably you could add the world element (with -y scale) to a new element, for example called gameView, and then add gameView to stage and scale it with window resize.

@blizniak83
Copy link
Author

Thank you for your suggestion. I tried few things and at one point I thought everything was working as expected but after adding the first texture I noticed that it was upside down. Of course I could use -y scale but there must be a better way.

Below is the code extracted from the asteroid example. I know I can flip everything just by -y scaling the stage node. How would you attach the world element to a new element? Do you mean to new node (node = Stage.create())? I'm sure I'm doing something wrong, I tried to -y scale the meta element just to see if this would turn the status text upside down but that didn't work.

Stage(function(stage) {
  var activeKeys = {};
  var KEY_NAMES = {
    32 : 'fire',
    37 : 'left',
    38 : 'up',
    39 : 'right',
    40 : 'down'
  };

  var physics = new Physics({
    updateStatus: updateStatus,
    activeKeys: activeKeys
  });

  var world, meta, status, box, gameView;

  stage.background('#222222');
  //stage.scale(1,-1); // this one is fine for turning the entire scene upside down
	stage.on('viewport', function(size) {
console.log("test");		
    meta.pin({
      scaleMode : 'in-pad',
      scaleWidth : size.width,
      scaleHeight : size.height,
    });
   world.pin({	  
      scaleMode : 'in-pad',
       scaleWidth : size.width,
       scaleHeight : size.height,	   
    });
   });
	
	world = new Stage
		.planck(physics.world, { ratio: 80 });
			
    world.pin({
      handle : -0.5,	  		
      width : physics.spaceWidth,
      height : physics.spaceHeight,	  
    });
    world.appendTo(stage);			

	stage.tick(physics.tick);
	
	meta = Stage
    .create()
    .pin({ width : 1000, height : 1000 })
	//.scale({x : 1, y: -1})    // doesn't work
    .appendTo(stage);
	
   	var ball = Stage.image('ball').appendTo(meta);
	
	ball.pin('align', 0.5);	
	
   status = Stage
   .string('text')
   .pin({ align : 0, offsetX: 0, offsetY : 10 })
   .appendTo(meta);

   function updateStatus() {
	status.value('TEXT: ' + 3 + ' TEXT: ' + 7);
   }

  document.onkeydown = function(evt) {
    activeKeys[KEY_NAMES[evt.keyCode]] = true;
  };

  document.onkeyup = function(evt) {
    activeKeys[KEY_NAMES[evt.keyCode]] = false;
  };

   physics.start();
});

@shakiba
Copy link
Collaborator

shakiba commented Feb 8, 2018

My last suggestion was not good, now I recall for P2.js viewer I actually multiplied all y values from physics simulation by -1, for example see here.

@shakiba
Copy link
Collaborator

shakiba commented Feb 8, 2018

I updated the viewer, please feel free to try it and let me know.

@shakiba
Copy link
Collaborator

shakiba commented Feb 8, 2018

Another solution is to just setup the game world with y pointing down.

@prolightHub
Copy link

If shakiba would just listen to what I have to say on my issue.

@lifeinchords
Copy link

@prolightHub what are your thoughts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants