I'm trying out matter.js on p5.js.
I'm trying to make a simple Top Down simulation where bodies collide with each other when trying to move.
Here's my code:
let engine,world;
function setup() {
createCanvas(400, 400);
engine = Matter.Engine.create();
world = engine.world;
m1 = Matter.Bodies.rectangle(50,50,50,50);
m2 = Matter.Bodies.rectangle(100,50,50,50);
Matter.World.add(world,m1);
Matter.World.add(world,m2);
}
function draw() {
background(220);
Matter.Body.translate(m1,{x: 1,y: 0});
pos1 = m1.position;
pos2 = m2.position;
rectMode(CENTER);
rect(pos1.x,pos1.y,50,50);
rect(pos2.x,pos2.y,50,50);
}
My intention was to make body m1 push body m2 when trying to move in his direction. Unfortunately m1 is just going through m2. How do I make them collide?
I've seen that I can add stiffness to the body's options but I don't think that will help me if they are not colliding in the first place.
I just found the problem: the translate function won't ever check collisions. Instead I used the setVelocity function and updated the engine every frame.
Matter.Engine.update(engine);
Matter.Body.setVelocity(m1,v1);
I also had to turn off the gravity in the setup.
engine.world.gravity.y = 0;
Related
I am just starting trying to make some animation using HTML5 and JavaScript.
Currently I have created a JavaScript class for the ball. It has an update function which should update the position of the ball and a draw function which should draw it:
/*global Vector*/
var Ball = (function () {
function Ball(pPostion) {
this.setPosition(pPostion);
}
Ball.prototype.getPosition = function () {
return this.mPosition;
};
Ball.prototype.setPosition = function (pPosition) {
this.mPosition = pPosition;
};
Ball.prototype.draw = function (pContext) {
pContext.save();
pContext.beginPath();
pContext.arc(100, 100, 20, 0, Math.PI * 2, true);
pContext.closePath();
pContext.fillStyle = '#ff0000';
pContext.stroke();
pContext.restore();
};
Ball.prototype.update = function () {
this.getPosition().add(new Vector(10, 0));
};
return Ball;
}());
In the my main section I have created the following method:
function ballGameLoop() {
ball.draw(mainContext);
ball.update();
requestAnimationFrame(ballGameLoop);
}
And when called, it does draw the ball but it doesn't seem to move at all. I don't have a specific type of way I want the ball to be animated, just any kind of movement would be good. Can anyone give any advice on where I may be going wrong?
From the looks of it, it seems you are just drawing an arc at the same coordinates over and over again (center at (100,100)).
Incorporating your Ball's position into this would be the way to make the render location dependent on the object's position. From what it seems, something along the lines of the following would give movement:
Ball.prototype.draw = function (pContext) {
var coordinates = this.getPosition();
pContext.save();
pContext.beginPath();
pContext.arc(coordinates.X, coordinates.Y, 20, 0, Math.PI * 2, true);
pContext.closePath();
pContext.fillStyle = '#ff0000';
pContext.stroke();
pContext.restore();
};
I'm of course assuming on how you setup the Vector object, so I'm guessing x and y can be accessed by (Vector).X and (Vector).Y respectively.
anyway just my approach at it.
So i'm trying to rewrite some of main proccessing sketches to p5.js, but (there is always a but..) i have a problem with creating Vecotrs. I think i'm lacking some simple java script uderstanding here.
So i use the example provided with p5.js, and my code looks like that:
var location ;
function setup() {
createCanvas(1000, 1000);
background(0);
location = new Vector(0, 0);
//location = createVector(0, 0);
//location = new p5.Vector(0, 0);
}
function draw() {
ellipse(location.x, location.y, 80, 80);
}
function Vector (x,y) {
this.x = x;
this.y = x;
}
I tryied 3 ways of creating vectors, the one right now, with creating custom "class" Vector, and those 2 commented out. And if i try it out, i have page not found and address bar is changed to "address to my index.html/p5.Vector%20Object%20:%20[0,%200,%200]".
I really have now idea what is wrong.
The variable name was the culprit. I was actualy accessing window.location . Simple name change did the trick.
I'm reading through an article about continuously drawing frames of an HTML5 video player on canvas. I heard about JS iterators a while back and I think there's supposedly a performance advantage, so I'd like to know how to write this set of canvas painting functions into an Iterator:
function canvasVideo(){
//DECLARE VARIABLES
var $videoPlayer = $('#Video-Player');
var $canvasPlayer = $('#Canvas-Player');
var videoPlayer = $videoPlayer[0];
var canvasPlayer = $canvasPlayer[0];
var context = canvasPlayer.getContext("2d");
//DEFINE FUNCTIONS
//draw the video
function draw() {
//Background
context.fillStyle = '#ffffaa';
context.fillRect(0, 0, canvasPlayer.width, canvasPlayer.height);
//video
context.drawImage(videoPlayer , 0, 0);
}
//update canvas at set interval with video frames
function canvasRun(int){
//set timer with interval
var canvasTimer = setTimeout(canvasRun, int);
//draw the video frame
draw();
}
function videoLoaded(event){
canvasRun(20);
}
//HANDLE EVENTS
$videoPlayer.on("canplaythrough", function (){
videoLoaded();
});
}
How can this be done with JS Iterators?
I've tried using tutorials to learn iterators, but the generic examples have confused me, and think seeing it done with an example like this would help me learn.
I've recently started working on a side project, and experimenting with the canvas as I go. So let me explain what I want to happen:
In my JS, the main() function is set to an interval. During main() the drawStep() function is called. This does several things, or it should.
Sorry for the long explanation.
Clear the canvas, so that what is drawn doesn't stick.
Using a for loop, iterate through the array containing things that need to be drawn. currently only menu objects.
checking if the variable debug is true, if so, draw the mouse coordinates as two red lines.
However, when step 1 is done, drawing the menu objects fails, it flickers and the canvas clears to whatever color step 1 set the canvas to. When the debug var is set to true (through the console) Drawing the debug lines functions fine.
Here is the code blocks that matter.
Variables defined in an init() function, including the cookie cutter function for defining menu objects:
canvas = document.getElemntByID("canvas");
room = canvas.getContext("2d");
gameMode = 1; // telling the code that it is in the main menu
debug = false; //not drawing the cursor coordinates
menObj = new Array(); //an array of menu objects
mouse_x = 0; //variable set through onMouseMove event in the canvas
mouse_y = 0; //variable set through onMouseMove event in the canvas
drawList = {}; //array of menu object draw() functions, and any other item that
needs to be drawn during the main loop
function menu(mxpos,mypos,mwid,mhid,name, funct,drawing){
this.x = mxpos;
this.y = mypos;
this.width = mwid;
this.height = mhid;
this.value = name;
this.doing = funct;
this.canDraw = drawing; //the code relies on a gameMode variable, only drawing what is allowed to when the game mode is set correctly.
this.expand = 0; //not important, but was going to make buttons expand on mouse over
this.maxExpand = 10; // same as above
//The draw function passed on to the drawList array:
this.draw = function(){
if (this.canDraw == gameMode){
room.fillStyle = "rgba(150,150,150,1)";
room.strokeStyle = "rgba(200,200,200,1)"
room.fillRect(this.x-this.width/2,this.y-this.height/2,this.width,this.height);
room.strokeRect(this.x-this.width/2,this.y-this.height/2,this.width,this.height);
room.strokeStyle = "rgb(30,150,90)";
var xoff = room.measureText(this.value).width;
var yoff = room.measureText(this.value).height;
room.strokeText(this.value,this.x-xoff/2,this.y-yoff/2);
}
}
}
Sample menu object creation and the for loop that adds that objects draw event to the drawList array:
var temMenVal = new menu(width/2,height/5,96,32,"Start",function(){gamemode = 1},0)
menObj.push(temMenVal);
for(var mobj in menObj){
if (!menObj.hasOwnProperty(mobj)) continue;
drawList[mobj]=menObj[mobj].draw(); //push wasn't working, so I improvised.
}
Main function, called from an interval timer.
function main(){
drawStep();
}
This is the draw function, where my issue is:
function drawStep(){
//the latest attempt at a fix, instead of using a clearRect(), which failed.
//I tried this
room.save()
room.fillStyle="black";
room.fillRect(0,0,width,height);
room.restore();
for (var n in drawList){
room.save();
if (!drawList.hasOwnProperty(n)) continue;
if (n<drawList.length){
drawList[n](); //calling the draw() from the nested menu object, it DOES work, when the above clear to black is NOT called
}
room.restore();
}
if (debug == true){
room.beginPath();
room.strokeStyle="rgb(255,0,0)";
room.moveTo(mouse_x,0); //variable set through onmousemove event in the canvas
room.lineTo(mouse_x,height);
room.moveTo(0,mouse_y); //variable set through onmousemove event in the canvas
room.lineTo(width,mouse_y);
room.stroke();
room.closePath();
}
}
I can't figure out why it keeps clearing to black, when the menu objects SHOULD be drawn after the clear. Like I said way up there, setting debug to true DOES draw the cursor coordinates correctly.
When you set up your draw list, try removing the two parens in menObj[mobj].draw()
What it seems like is that you are actually calling the method instead of passing it as a variable.
Try init menu with drawing = 1 and edit code as Hylianpuffball point out. I think this.canDraw == gameMode is always false.
I am creating a simple drawing app using the HTML5 canvas element. The program logic works fine, and everything runs great, except for one thing.
When I draw the first line, the mouse coordinates and the line match perfectly. However, after each subsequent line, the coordinates of the line being drawn are about 0.5~1px off. These discrepancies accumulate, and the effect is readily visible after drawing about ten separate lines. This occurs in all browsers.
For a live example, check this fiddle. I have stripped down everything as much as I could. Obviously the real app is a lot more complex, but even in this simplified version the problem persists, which leads me to think I'm missing something incredibly obvious.
It occurred to me that I might be somehow rounding up the coordinates, which is about the only thing I can think of that could account for such a gradual drift. I was using a proprietary function for getting the offset values, so I tried using jQuery (since that has never given me problems in the past) but nothing changed.
Please help me figure out why this is happening!
Apparently I need to post code now in order to link to jsfiddle. I have no idea which part of the code might be wrong, so I apologise in advance for posting everything and creating a wall of text.
var offsetX = 0, offsetY = 0;
var currentMouseCoords = {
x : 0,
y : 0
};
var drawPing = null;
var ctx = null;
$('#cover').mousedown(function (event) {
event.preventDefault();
var f = $(this).offset();
offsetX = f.left;
offsetY = f.top;
currentMouseCoords.x = event.pageX - offsetX;
currentMouseCoords.y = event.pageY - offsetY;
drawStart();
if (!drawPing) {
drawPing = setInterval(draw, 10);
}
})
.mousemove(function (event) {
currentMouseCoords.x = event.pageX - offsetX;
currentMouseCoords.y = event.pageY - offsetY;
})
.mouseout(function (event) {
//When mouse leaves canvas, quit drawing
drawEnd();
})
.mouseup(function (event) {
//When mouse leaves canvas, quit drawing
drawEnd();
})
/* Functions that perform the actual drawing */
function drawStart () {
//Get canvas context
ctx = document.getElementById('canvas').getContext("2d");
ctx.translate(0.5,0.5);
//Set styles
ctx.strokeStyle = '#333333';
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
ctx.lineWidth = 1;
//Begin path
ctx.beginPath();
ctx.moveTo(
currentMouseCoords.x,
currentMouseCoords.y
);
}
function draw () {
ctx.lineTo(
currentMouseCoords.x,
currentMouseCoords.y
);
ctx.stroke();
}
function drawEnd () {
clearInterval(drawPing);
drawPing = null;
if (ctx) {
ctx.closePath();
ctx = null;
}
}
I imagine it'll make a lot more sense if you just look at the actual fiddle....
For the record, I googled for quite a while to see if anyone else had this issue, but either it's not that common or I can't find the right combination of words. There are myriad problems with mouse coordinates but none of them seem to be the same as the one I am experiencing.
You are repeatedly translating in your drawStart function and those translations are accumulating:
ctx.translate(0.5,0.5)
You can reverse the translate with translate(-.5,-.5) or wrap your drawing code in ctx.save()/ctx.restore().
You might also want to move your ctx=document... outside the drawStart "loop" for better performance.
//Get canvas context outside drawStart
ctx = document.getElementById('canvas').getContext("2d");