top of page
Search
cedarcantab

Verlet Physics+ Circle vs Circle Collision

Updated: Mar 26






class Dot extends Phaser.Geom.Point {

constructor(scene, x, y, r) {

super(x, y);

this.scene = scene;

// console.log("TIME=", Phaser.Time.Clock)

this.position = new Phaser.Math.Vector2(x, y);

this.oldPos = new Phaser.Math.Vector2(x,y); // velocity x, y

this.velocity = new Phaser.Math.Vector2();

this.acceleration = new Phaser.Math.Vector2();

this.radius = r;

this.color = Phaser.Display.Color.GetColor(255,0,0)

this.init=true;

this.olddt;

}

update(dt) {

this.velocity.set(this.position.x - this.oldPos.x, this.position.y - this.oldPos.y);

this.oldPos.copy(this.position);

this.position.add(this.velocity.clone().add(this.acceleration.clone().scale(dt * dt))); // update pos

}

render() {

this.graphics.fillStyle(this.color);

this.graphics.fillCircle(this.position.x, this.position.y, this.radius)

}

applyForce(force) {

this.acceleration.copy(force)

}

}



class Game extends Phaser.Scene {

constructor() {

super({key: "Game"});

this.dots = [];

this.sticks = [];

this.gravity = new Phaser.Math.Vector2(0,1000);

this.radius = 250;

this.position = new Phaser.Math.Vector2(300,300);

}

create() {

let timer = this.time.addEvent({

delay: 1000,

callback: this.spawn,

callbackScope: this,

repeat: 20

})

}

spawn() {

this.dots.push(new Dot(this, 200, 130, Phaser.Math.Between(10,30)));

}

update(t, dt) {

this.graphics.clear();

this.graphics.fillStyle('0x000000').fillCircle(this.position.x, this.position.y, this.radius);

this.dots.forEach(d=>this.applyGravity(d));

this.dots.forEach(d=>d.update(dt*0.001));

this.dots.forEach(d=> this.applyConstraint(d));

this.solveCollision();

this.dots.forEach(d=>d.render());

}

applyGravity(d) {

d.applyForce(this.gravity);

}

applyConstraint(d) {

const to_obj = new Phaser.Math.Vector2(d.position.x - this.position.x, d.position.y - this.position.y)

const dist = Phaser.Math.Distance.BetweenPoints(d.position, this.position);

if (dist > this.radius - d.radius) {

const n = to_obj.clone().scale(1/dist);

d.position.set(this.position.x+n.x*(this.radius-d.radius), this.position.y+n.y*(this.radius-d.radius));

}

}

solveCollision() {

for (let i = 0; i < this.dots.length; i++) {

const obj1 = this.dots[i];

for (let k = i + 1; k < this.dots.length; k++) {

const obj2 = this.dots[k]

const collision_axis = new Phaser.Math.Vector2(obj1.position.x - obj2.position.x, obj1.position.y - obj2.position.y);

const dist = collision_axis.length();

if (dist < obj1.radius + obj2.radius) {

const n = collision_axis.normalize();

const delta = (obj1.radius + obj2.radius) - dist;

obj1.position.add(n.clone().scale(delta*0.5));

obj2.position.subtract(n.clone().scale(delta*0.5));

}

}

}

}

}




CodePen




9 views0 comments

Recent Posts

See All

p2 naive broadphase

var Broadphase = require('../collision/Broadphase'); module.exports = NaiveBroadphase; /** * Naive broadphase implementation. Does N^2...

sopiro motor constranit

import { Matrix2, Vector2 } from "./math.js"; import { RigidBody } from "./rigidbody.js"; import { Settings } from "./settings.js";...

コメント


記事: Blog2_Post
bottom of page