Remove particle from box2d.world.getParticlePositionBuffer() - processing

How to remove a particle from box2d.world when it get out of screen?
Currently, I have this code from Nature of Code - LiquidFunTest example:
Vec2[] positionBuffer = box2d.world.getParticlePositionBuffer();
if (positionBuffer != null) {
for (int i = 0; i < positionBuffer.length; i++) {
Vec2 pos = box2d.coordWorldToPixels(positionBuffer[i]);
pg.stroke(255);
pg.strokeWeight(3);
pg.point(pos.x, pos.y);
}
}
I've changed the code to:
Vec2[] positionBuffer = box2d.world.getParticlePositionBuffer();
if (positionBuffer != null) {
for (int i = 0; i < positionBuffer.length; i++) {
Vec2 pos = box2d.coordWorldToPixels(positionBuffer[i]);
if(pos.y > height){
box2d.world.destroyParticle(i);
} else {
pg.stroke(255);
pg.strokeWeight(3);
pg.point(pos.x, pos.y);
}
}
}
But destroyParticle() method doesn't have the same index as getParticlePositionBuffer()

Related

Grouping points after cut plane three js with new library

Regarding the discussion in this link, where the object is a THREE.Geometry(), anyone has any idea to implement this code:
function getContours(points, contours, firstRun) {
//console.log("firstRun:", firstRun);
let contour = [];
// find first line for the contour
let firstPointIndex = 0;
let secondPointIndex = 0;
let firstPoint, secondPoint;
for (let i = 0; i < points.length; i++) {
if (points[i].checked == true) continue;
firstPointIndex = i;
firstPoint = points[firstPointIndex];
firstPoint.checked = true;
secondPointIndex = getPairIndex(firstPoint, firstPointIndex, points);
secondPoint = points[secondPointIndex];
secondPoint.checked = true;
contour.push(firstPoint.clone());
contour.push(secondPoint.clone());
break;
}
contour = getContour(secondPoint, points, contour);
contours.push(contour);
let allChecked = 0;
points.forEach(p => { allChecked += p.checked == true ? 1 : 0; });
console.log("allChecked: ", allChecked == points.length);
if (allChecked != points.length) { return getContours(points, contours, false); }
return contours;
}
function getContour(currentPoint, points, contour){
let p1Index = getNearestPointIndex(currentPoint, points);
let p1 = points[p1Index];
p1.checked = true;
let p2Index = getPairIndex(p1, p1Index, points);
let p2 = points[p2Index];
p2.checked = true;
let isClosed = p2.equals(contour[0], tolerance);
if (!isClosed) {
contour.push(p2.clone());
return getContour(p2, points, contour);
} else {
contour.push(contour[0].clone());
return contour;
}
}
function getNearestPointIndex(point, points){
let index = 0;
for (let i = 0; i < points.length; i++){
let p = points[i];
if (p.checked == false && p.equals(point, tolerance)){
index = i;
break;
}
}
return index;
}
function getPairIndex(point, pointIndex, points) {
let index = 0;
for (let i = 0; i < points.length; i++) {
let p = points[i];
if (i != pointIndex && p.checked == false && p.faceIndex == point.faceIndex) {
index = i;
break;
}
}
return index;
}
With new three library the object is a THREE.BufferGeometry() that has no face(s) and no checked.
I need to connect the points between themselves (separate arrays) where the plane passes.

Change variable in array coded with processing

Help!
I'm drawing a sketch with randomized letters that fill the screen. The code issue is with my
for (int i = 0; i < I1; i++) {
targets = tX + i * ts;
targets2 = tY;
} else {
runTowards = false;
for (int i = 0; i < I1; i++) {
targets = random(ts, width - ts);
targets2 = random(ts, height - ts);`
** I need to update i within the for loop to denote the array letters' locations. The error returns a type mismatch, "float" does not match with int[]
How do I update the i within the for loop?/ (the targets= and targets2=)
Here is the code**
String message = "a,b,c,d,e,f";
int []positions = new int [0];
int[]positions2= new int[1];
int []targets = new int [0] ;
int [] targets2= new int[1];
int I1= message.length();
boolean runTowards = true;
float runSpeed = 100;
float restSpeed = 1;
float currentSpeed = restSpeed;
float ts = 64;
boolean thisHasReached;
float bk;
float elapsedTime;
boolean allHaveReached;
float pauseTime = 1000;
float distX;
float distY;
float changeX;
float changeY;
float tX;
float tY;
float reachedTargetAt = 0;
boolean hasReachedTarget = true;
void setup() {
size (600,600);
background(255);
if ((I1 > targets.length) && (I1 > positions.length)){
pickNewTarget();
}
}
void draw() {
elapsedTime = millis() - reachedTargetAt;
if (elapsedTime > pauseTime) {
pickNewTarget();
}
drawChars();
updatePositions();
updateCurrentSpeed();
}
void drawChars() {
for (int i = 0; i < I1; i++) {
text(message.charAt(i),positions[i], positions[i]);
}
}
void updatePositions() {
allHaveReached = true;
thisHasReached = false;
for (int i = 0; i < I1; i++) {
distX = abs(positions[i] - targets[i]);
distY = abs(positions2[i] - targets2[i]);
changeX = random(currentSpeed);
changeY = random(currentSpeed);
thisHasReached = changeX > distX && changeY > distY;
if (positions[i] > targets[i]) {
changeX = -changeX;
}
if (positions2[i] > targets2[i]) {
changeY = -changeY;
}
positions[i] += changeX;
positions2[i] += changeY;
allHaveReached = allHaveReached && thisHasReached;
}
if ((!hasReachedTarget) && (allHaveReached)) {
hasReachedTarget = true;
reachedTargetAt = millis();
}
}
void updateCurrentSpeed() {
if (hasReachedTarget) {
if (currentSpeed >= restSpeed) {
currentSpeed -= (currentSpeed - restSpeed) * 9;
} else {
currentSpeed += 1;
}
} else {
if (currentSpeed <= runSpeed) {
currentSpeed += (runSpeed - currentSpeed) * 0.25;
} else {
currentSpeed -= 1;
}
}
}
void pickNewTarget() {
if (!runTowards && random(1) > 0.75) {
runTowards = true;
tX = random(ts, width - 3 * ts);
tY = random(ts, height - ts);
for (int i = 0; i < I1; i++) {
targets = tX + i * ts;
targets2 = tY;
}
} else {
runTowards = false;
for (int i = 0; i < I1; i++) {
targets = random(ts, width - ts);
targets2 = random(ts, height - ts);
}
}
hasReachedTarget = false;
}
Please look at this reference for random(): https://processing.org/reference/random_.html. Note that it states "If two parameters are specified, the function will return a float with a value between the two values." You got the error message because you tried to mix ints and floats. You can correct it by changing the array types from int to float, eg.
float[] targets = new float[80] ;
float[] targets2= new float[80];
You'll also need to make those arrays large enough to handle the size of your data or you'll wind up with another error that the array length has been overrun. Then change the loop to reflect that you are adding data to the arrays ([i]):
void pickNewTarget() {
if (!runTowards && random(1) > 0.75) {
runTowards = true;
tX = random(ts, width - 3 * ts);
tY = random(ts, height - ts);
for (int i = 0; i < I1; i++) {
targets[i] = tX + i * ts;
targets2[i] = tY;
}
} else {
runTowards = false;
for (int i = 0; i < I1; i++) {
targets[i] = random(ts, width - ts);
targets2[i] = random(ts, height - ts);
}
}
hasReachedTarget = false;
}
Also need to add a fill() for the text characters or you will see a blank screen.

Updating sand simulation in grid doesn't work

I want to make a falling sand simulation using cellular automata, but when I update it, nothing happens, and when I want to do a line of diffrent material using lineDrawing() this material appear in random cells. This is update code:
void update()
{
for (int i = verticalNumberOfCells - 1; i > 0; i--)
{
for (int j = 0; j < horizontalNumberOfCells; j++)
{
world[j][i].update(false);
}
}
for (int y = verticalNumberOfCells - 1; y > 0; y--)
{
for (int x = 0; x < horizontalNumberOfCells; x++)
{
if (world[x][y].hasMoved) continue;
if (world[x][y].state == 0 && world[x][y].state == 1) continue;
if (canMove(world[x][y].state, x, y + 1))
{
move(x, y, x, y + 1);
}
}
}
}
The auxiliary functions that I use to check if the contents of a cell can change and to change the contents of a cell look like this:
boolean canMove(int state, int positionX, int positionY)
{
if (positionX < 0 || positionX >= horizontalNumberOfCells || positionY < 0 || positionY >= verticalNumberOfCells) return false;
int otherSubstance = world[positionX][positionY].state;
if (state == 5) return (otherSubstance == 4);
if (otherSubstance == 0) return true;
if (state == 2 && otherSubstance == 3 && random(1f) < 0.5f) return true;
return false;
}
void move(int fromX, int fromY, int toX, int toY)
{
Cells otherSubstance = world[toX][toY];
world[toX][toY] = world[fromX][fromY];
world[fromX][fromY] = otherSubstance;
world[fromX][fromY].hasMoved = true;
world[toX][toY].hasMoved = true;
world[fromX][fromY].velocityX = 0;
world[fromX][fromY].velocityY = 0;
if (toX > fromX)
{
world[toX][toY].velocityX = 1;
} else if (toX < fromX)
{
world[toX][toY].velocityX = -1;
} else
{
world[toX][toY].velocityX = 0;
}
if (toY > fromY)
{
world[toX][toY].velocityY = 1;
} else if (toY < fromY)
{
world[toX][toY].velocityY = -1;
} else
{
world[toX][toY].velocityY = 0;
}
}
I was able to fix this problem. The thing was, copying a cell in the move function didn't work. Here is the wrong version of the code:
Cells otherSubstance = world[toX][toY];
world[toX][toY] = world[fromX][fromY];
world[fromX][fromY] = otherSubstance;
and here is right version of the code:
int oldState = world[toX][toY].state;
world[toX][toY].state = world[fromX][fromY].state;
world[fromX][fromY].state = oldState;

Array is only displaying 1 object instead of the full amount of variables

I'm new to coding (as I'm sure you might be able to tell). The program runs and generates 1 Tubble, but the additional objects don't show.
Here's my class:
class Tubble {
float x;
float y;
float diameter;
float yspeed;
float tempD = random(2,86);
Tubble() {
x = random(width);
y = height-60;
diameter = tempD;
yspeed = random(0.1, 3);
}
void ascend() {
y -= yspeed;
x = x + random(-2, 2);
}
void dis() {
stroke(0);
fill(127, 100);
ellipse(x, y, diameter, diameter);
}
void top() {
if (y < -diameter/2) {
y = height+diameter/2;
}
}
}
Class
class Particle {
float x, y;
float r;
float speed = 2.2;
int direction = 1;
PImage pbubbles;
Particle(float x_, float y_, float r_) {
x = x_;
y = y_;
r = r_;
}
void display() {
stroke(#F5D7D7);
strokeWeight(2.2);
noFill();
ellipse(x, y, r*2, r*2);
}
boolean overlaps(Particle other) {
float d = dist(x, y, other.x, other.y);
if (d < r + other.r) {
return true;
} else {
return false;
}
}
void move() { //testing
x += (speed * direction);
if ((x > (width - r)) || (x < r)) {
direction *= -1;
}
}
void updown() {
y += (speed * direction);
if ((y > (height - r)) || (y < r)) {
direction *= -1;
}
}
}
Main sketch:
Tubble[] tubbles = new Tubble [126];
PImage bubbles;
Particle p1;
Particle p2;
Particle p3;
Particle p4;
Particle p5;
float x,y;
float speed;
int total = 0;
int i;
//int direction = 1;
void setup() {
size(800, 925);
bubbles = loadImage("purple_bubbles.png");
p1 = new Particle (100, 100, 50);
p2 = new Particle (500, 200, 100);
p3 = new Particle (600, 600, 82);
p4 = new Particle (height/2, width/2, 200);
p5 = new Particle ((height/3), (width/3), 20);
for (int i = 0; i < tubbles.length; i++); {
tubbles[i] = new Tubble();
}
}
void mousePressed() {
total = total + 1;
}
void keyPressed() {
total = total - 1;
}
void draw() {
image(bubbles, 0, 0, 800, 925);
//background(0);
for (int i = 0; i < tubbles.length; i++); {
tubbles[i].ascend();
tubbles[i].dis();
tubbles[i].top();
}
if ((p2.overlaps(p1)) && (p2.overlaps(p4))) {
background(#BF55AB, 25);
}
if ((p3.overlaps(p2)) && (p3.overlaps(p4))) {
background(#506381, 80);
}
p2.x = mouseX;
p3.y = mouseY;
p1.display();
p2.display();
p3.display();
p4.display();
p5.display();
p4.move();
p5.updown();
// for (int i = 0; i < tubbles.length; i++); {
// tubbles[i].dis();
// tubbles[i].ascend();
// tubbles[i].top();
// }
}
There are extra semicolons in the lines
for (int i = 0; i < tubbles.length; i++); {
for (int i = 0; i < tubbles.length; i++); {
// for (int i = 0; i < tubbles.length; i++); {
It make the for loop do virtually nothing.
Then the block after the for loop will read the global variable i and do the action only once.
Remove the semicolons like this to put the block in the loop.
for (int i = 0; i < tubbles.length; i++) {
for (int i = 0; i < tubbles.length; i++) {
// for (int i = 0; i < tubbles.length; i++) {

Unable to run the program

I am making a game in Eclipse Mars using the Processing library. I had made the game elsewhere and it ran fine. There were no errors after I copied and pasted the files from my flash drive to the folder in Eclipse. When I tried to run it, it said "The selection cannot be launched, and there are no recent launches." There were no recent launches because I had just gotten Eclipse. My code is as follows:
Main Class:
//package dogeball;
import processing.core.PApplet;
import processing.core.PImage;
import java.awt.Color;
import processing.core.PFont;
public class Dogeball extends PApplet {
Ball ball;
Furniture butterChair;
Furniture[] bricks;
PFont dogefont;
float py;
float score;
boolean game;
int checker;
boolean mode;
PImage img = loadImage("doge.jpg");
PImage img2 = loadImage("doge2.png");
public void setup() {
checker = 0;
size(300,250);
game = false;
mode = true;
ball = new Ball(this, 100, 225, 0, 0, 10, Color.DARK_GRAY );
butterChair = new Furniture(this, 130, 238, 40, 10, Color.YELLOW);
py = butterChair.w /2;
bricks = new Furniture[56];
dogefont = loadFont("ComicSansMS-48.vlw");
for(int rowNum = 0; rowNum<8; rowNum+= 1) {
for(int colNum = 0; colNum<7; colNum += 1){
bricks[7*rowNum + colNum] = new Furniture(this, 10+40*colNum, 10+15*rowNum, 40, 15, Color.red);
score = 0;
}
}
}
public void draw() {
if(game == false) {
background(img);
fill(0,255,255);
textSize(30);
textFont(dogefont);
text("DogeBall",33, 170);
fill(255,255,0);
textSize(20);
text("Press Space", 120,190);
fill(255,0,0);
text("Such BrickBreaker", 20, 20);
fill(0,0,255);
text("Much Atari", 190, 80);
fill(0,255,0);
text("How Breakout", 150, 230);
}
if(keyPressed == true) {
if (key == ' ') {
game = true;
}
}
if(game == true) {
if(keyPressed == true) {
if (key == 'm') {
mode = !mode;
}
}
//checker = 0;
background(img);
ball.appear();
ball.hover();
butterChair.appear();
if(mode == true) {
butterChair.x = mouseX-butterChair.w/2;
}
if(mode == false) {
if(keyPressed == true) {
if (key == CODED) {
if (keyCode == LEFT){
butterChair.x -= 3;
}
}
}
if(keyPressed == true) {
if (key == CODED) {
if (keyCode == RIGHT){
butterChair.x += 3;
}
}
}
}
if(butterChair.x <= 0) {
butterChair.x = 0;
}
if(butterChair.x >= width - butterChair.w) {
butterChair.x = width - butterChair.w;
}
textFont(dogefont);
fill(255,0,255);
text("Much Doge", 12, 160);
fill(255,0,0);
textSize(20);
text("M to toggle mouse mode.", 20,200);
fill(0);
textSize(10);
text("You might have to press twice", 10,220);
fill(0,0,255);
textSize(20);
text("Press S to Start", 150, 230);
if (keyPressed == true) {
if (key == 's' || key == 'S'){
ball.vy = 2;
ball.vx = 1;
}
}
/*if(mousePressed == true) {
ball.vx = 0;
ball.vy = 0;
}*/
for(int i = 0; i<56; i+= 1) {
bricks[i].appear();
}
}
detectCollision();
if(ball.y >= height) {
checker = 0;
if(checker ==0){
background(img);
ball.vx = 0;
ball.vy = 0;
textSize(30);
fill(255,0,0);
game = false;
text("Such Sorry", 130, 160);
fill(0,255,255);
text("Much Game Over", 20, 215);
fill(255,255,0);
text("So Losing", 10, 30);
textSize(20);
text("Press P to Play Again", 20, 245);
}
if(keyPressed == true) {
if(key == 'p') {
game = true;
ball.x = 100;
ball.y = 225;
checker = 1;
for(int rowNum = 0; rowNum<8; rowNum+= 1) {
for(int colNum = 0; colNum<7; colNum += 1){
bricks[7*rowNum + colNum] = new Furniture(this, 10+40*colNum, 10+15*rowNum, 40, 15, Color.red);
score = 0;
}
}
}
}
}
}
void detectCollision() {
if(keyPressed == true) {
if(key == '-')
{
for(int cCode = 0; cCode < 56; cCode += 1) {
Furniture b = bricks[cCode];
b.x = width * 2;
b.y = height * 2;
score = 56;
}
}}
if(ball.x >= butterChair.x &&
ball.x <= butterChair.x + butterChair.w &&
ball.y + ball.s /2 > butterChair.y) {
ball.vy *= -1;
}
for(int i = 0; i<bricks.length; i+= 1) {
Furniture b = bricks[i];
if(ball.x >= b.x && ball.x <= b.x+b.w && ball.y-ball.s/2 <= b.y) {
b.y = height * 2;
b.x = width * 2;
ball.vy *= -1;
score += 1;
}
if(score == 56){
background(img);
ball.vx = 0;
ball.vy = 0;
fill(255,0,0);
textSize(20);
text("Such Winning!", 20, 20);
textSize(40);
fill(0,255,0);
text("Much Congrats!",12 ,160);
textSize(20);
fill(255,0,255);
text("Press P to Play Again", 20, 245);
if(keyPressed == true) {
if(key == 'p') {
game = true;
ball.x = 100;
ball.y = 225;
checker = 1;
for(int rowNum = 0; rowNum<8; rowNum+= 1) {
for(int colNum = 0; colNum<7; colNum += 1){
bricks[7*rowNum + colNum] = new Furniture(this, 10+40*colNum, 10+15*rowNum, 40, 15, Color.red);
score = 0;
}
}
}
}
}
}
}
static public void main(String args[]) {
PApplet.main("Dogeball");
}
}
Ball Class:
//package dogeball;
import java.awt.Color;
import processing.core.PApplet;
public class Ball extends PApplet {
float x;
float y;
float vx;
float vy;
float s;
Color c;
PApplet p;
Ball(PApplet pApp, float xLocation, float yLocation, float xSpeed, float ySpeed, float size, Color shade){
x = xLocation;
y = yLocation;
vx = xSpeed;
vy = ySpeed;
s = size;
c = shade;
p = pApp;
}
void hover() {
x += vx;
y += vy;
if(x< 0 || x> p.width) {
vx *= -1;
}
if(y< 0) {
vy *= -1;
}
}
void appear() {
p.fill(c.getRGB() );
p.ellipse(x,y,s,s);
}
}
Paddle Class:
//package dogeball;
import java.awt.Color;
import processing.core.PApplet;
public class Furniture extends PApplet {
float x;
float y;
float w;
float h;
Color c;
PApplet p;
Furniture(PApplet PApp, float locationX, float locationY, float fWidth, float fHeight, Color shade) {
x = locationX;
y = locationY;
w = fWidth;
h = fHeight;
c = shade;
p = PApp;
}
void appear() {
p.fill(c.getRGB());
p.rect(x,y,w,h);
}
}
You have probably the wrong project selected on the projects tree or the run configurations are set to another project, since you haven't run it yet.
Either way, you have to right click your projects folder on the projects tree, then find Run As > Java Applet.
Another way to do it would be adding a main function, as you already did, and run is as a Java Application. Instead of using the current main function, you can try to use the code below to see it in present mode and see if it works:
public static void main(String args[]) {
PApplet.main(new String[] { "--present", "Dogeball" });
}

Resources