Hi How do I make bullets to collide with the objects in Processing ?
Bullets are fired and being translated and rotated
but whenever i try to use function dist() it always gives me 0 as the position of the vector
How do i get the correct vector position if i want the bullet to collide with objects using distance and make the the other object disappear ?
Here's the code
void move(){
passed = passed + time;
if (passed > bulletLife) {
alive = false;
}
forward.x = sin(theta);
forward.y = -cos(theta);
float speed = 15.0f;
velocity = PVector.mult(forward, speed);
side.add(forward);
void display(){
pushMatrix();
translate(side.x, side.y);
rotate(theta);
stroke(255);
ellipse(side.x, side.y, 30, 30);
popMatrix();
Thanks
You're getting 0 from dist() because translate() moves the coordinate system! I think, more than your question, you need to reconsider your code overall. You translate to side.x, side.y (which will then be 0,0 until you call popMatrix()) but then you draw the ellipse at side.x, side.y which is offset from its actual position.
In other words: if the position is 100,200, you're actually drawing the object at 200,400!
If you skip the translate() part, you can use this to draw your object:
void display() {
stroke(255);
ellipse(side.x, side.y, 30,30);
}
And this to check collision:
if (dist(side.x, side.y, bullet.x, bullet.y) == 0) {
collision = true;
}
else {
collision = false;
}
You can also see my collision-detection functions for Processing, which have lots of examples that might help.
Related
I tried to make a jump look realistic, while I watched through the Videos:
The Natur of Code - The Coding Train
I got into PVectors. I strongly recomend watching him. But to get to my question, everything seems to work, exept that it draws the rectangle (my PVector) the way I want.
void keyPressed() {
if (keyCode == UP) {
for (int i = 0; i < 16; i++) {
location.sub(velocity);
velocity.sub(acceleration);
h.display();
background(0);
}
velocity.set(0, 15);
}
}
That's the Code, I expect it to "jump", but nothing realy happens. You can see that the rectangle get's drawn again (on the same spot), but there's no movement. It's definitly an issue with the drawing of the background or something, I don't know what exaclty though.
The nature of your question is unclear. You mentioned issues regarding the background interfering with your rectangle after the UP arrow key is pressed. This is likely because background(0) is called immediately after h.display(). I would remove background(0) from your loop if it's a display issue.
Other than that, there seem to be other issues with the loop itself. When the UP key is pressed, h is affected by acceleration only for 16 frames. To make your object more realistic, gravity (or whatever acceleration you choose) should constantly be acting upon the object.
With that in mind, here's a solution for you.
void keyPressed() {
if (keyCode == UP) {
// Make the character 'jump' upwards when the UP arrow is pressed.
// Setting the velocity should be the only thing happening when the key is pressed.
velocity.set(0, -2);
}
}
void draw() {
// Reset the background each frame so rectangles don't overlap.
background(255);
// Always draw the rectangle AFTER resetting the canvas.
h.display();
// Change the object's location by it's velocity.
location.add(velocity);
// And chance the object's velocity by it's acceleration.
// Since acceleration is the acting force of gravity in this situation, acceleration need not be changed.
velocity.add(acceleration);
// Prevent the rectangle from falling through the bottom of the canvas.
if(location.y > height - 5) location.y = height - 5;
}
// You negleteced to define your variables in your code snippet. Here they are.
PVector location = new PVector(0, 0);
PVector velocity = new PVector(0, 0);
PVector acceleration = new PVector(0, 0.1); // Notice that acceleration's y-value is 0.01. This is so you can see the effect of gravity.
// Define your rectangle object.
Object h = new Object();
class Object {
Object() {} // Constructor.
void display() {
// Draw the rectangle at the x- and y-positions of the location vector.
// The '+ width/2' places it at the center of the screen.
rectMode(CENTER);
rect(location.x + width/2, location.y, 10, 10);
}
}
Wondering if someone could help me, I am new to processing and programming in general.
I have created a random walker that walks a point around a 3D space. Please see code below.
Now I would like to be able to rotate the view of this walker as it is drawn, so I can view it from different angles. I have tried using PeasyCam to achieve this, but when I use the mouse to rotate the camera, it only affects the location of the new points, and not the previously plotted ones.
If anyone could let me know what I'm doing wrong that would be really helpful! Thanks, here is my code:
import peasy.*;
PeasyCam camera;
void setup() {
size(500,500,P3D);
background(0);
camera = new PeasyCam(this, 0, 0, 0, 50);
}
void draw() {
walker();
}
float x = 0;
float y = 0;
float z = 0;
void walker() {
pushMatrix();
stroke(255);
strokeWeight(5);
point(x,y,z);
x = x + random(-2.5,2.5);
y = y + random(-2.5,2.5);
z = z + random(-2.5,2.5);
popMatrix();
}
If you want your previous points to be affected by the rotation, then you need to redraw them.
You could do this by storing all of the points in a data structure like an array or ArrayList. Then you'd iterate over the points and redraw them every frame.
I am creating a model of a solar system in processing, and after removing the background I noticed the planets were leaving a trail of their image behind them. The program runs fine when the background is back in, but I want to add a lot more and I am sure this is inefficient and will bog things down.
I am very new to processing, and I am really not sure how to solve this. Maybe delete previous images after a delay to create a shortened trail?
These are just the parts I think are important cherry picked from the code, this is just the example of one planet. Sorry if the code is clunky, any suggestions are happily accepted.
Planet p1;
void setup() {
mercury = loadImage("mercury.png")
p1 = new Planet(40, random(TWO_PI), 0.05);
}
void draw() {
//background(0)
translate(width / 2, height / 2);
p1.display1();
p1.orbit();
}
class Planet {
float radius;
float angle;
float distance;
float orbitSpeed;
Planet(float r, float d, float o) {
radius = r;
distance = d;
orbitSpeed = o;
angle = random(TWO_PI);
}
void orbit() {
angle = angle + orbitSpeed;
}
void display1() {
pushMatrix();
rotate(angle);
translate(distance, 0);
imageMode(CENTER);
image(mercury, radius, radius, 10, 10);
popMatrix();
}
}
I realized that this would probably happen, and I am not sure how to stop it.
The behavior you describe is simply the nature of computer graphics; it's how games, operating systems, and hardware displays all work – they clear and redraw everything every frame.
In Processing, graphic objects that are pushed to a buffer remain there indefinitely until the buffer is cleared or something is pushed on top of them (this is why the planets are leaving a trail without calling background() – previous frames remain in the buffer).
You are worried about the background() being inefficient. Don't be, as it's one of the fastest operations (simply sets the value of each pixel, as given by the user).
Processing does provide a clear() function, but this is equivalent to background(0).
If you're are still concerned about efficiency and speed, one way to speed up Processing is to use the FX2D renderer rather than default AWT renderer. Another way is cache drawn objects into PGraphics objects to prevent successive rasterization (since your planets are image files and not drawn with processing, you needn't worry about this).
Your code is simple enough that it doesn't need optimisations at this stage.
As micycle mentions, you are are drawing an image at a translated position, pretty similar to blitting.
In terms of the trails, one common trick you could use is not clear the screen completely, but draw a transparent rectangle as the background. The more transparency, the longer the trails.
Here's a tweaked version of your code:
// planet object
Planet p1;
// planet texture
PImage mercury;
void setup() {
size(300, 300);
// draw image from center
imageMode(CENTER);
// clear to black one
background(0);
// remove strokes (we'll use rect() later)
noStroke();
// set the fill to black but with 9/255 transparency (~3.5% transparent)
fill(0,9);
// init texture
mercury = loadImage("mercury.png");
// init planet
p1 = new Planet(40, random(TWO_PI), 0.05);
}
void draw() {
// draw a transparent rectangle instead of completely clearing the screen
rect(0,0,width,height);
// render planet
translate(width / 2, height / 2);
p1.display1();
p1.orbit();
}
class Planet {
float radius;
float angle;
float distance;
float orbitSpeed;
Planet(float r, float d, float o) {
radius = r;
distance = d;
orbitSpeed = o;
angle = random(TWO_PI);
}
void orbit() {
angle = angle + orbitSpeed;
}
void display1() {
pushMatrix();
rotate(angle);
translate(distance, 0);
image(mercury, radius, radius, 10, 10);
popMatrix();
}
}
It's an efficient quick'n'dirty hack as you won't need to store previous position and redraw multiple times, however it has it limitations in terms of the flexibility of the trails. Hopefully tweaking the fill() alpha parameter will get you the desired effect.
Later on if you're drawing many many many planets it things start running slow have a peak at VisualVM. Profile the CPU and see the methods that take the longest to complete and focus on those. Don't need to optimise everything, just the slowest calls. Remember that Processing have multiple renderers: JAVA2D is the default one, but there's also FX2D and P2D/P3D and they will behave differently. I strongly recommend optimising at the last moment (otherwise code might be less flexible and readable and will slow down development/iteration).
//declaringglobalvaribales
float dia1=50;
//diameteroftheface
float x=400;
float y=400;
float speedX=4;
float speedY=0;
//setup
void setup() {
size(810, 810);
} //draw
void draw() {
background(225);
fill(225, 0, 0);
stroke(0);
ellipse(x, y, dia1, dia1);
fill(0, 225, 0);
//a nose
triangle(x, y, x+10, y+10, x-10, y+10);
//movingtheballXway
x=x+speedX;
//movingtheballYway
y=y+speedY;
//if it hits the left or right corners it will turn around
if (x>width-dia1/2 || x<2+dia1/2) {
speedX=speedX*-1;
}
// it its hits the top or bottom it will turn around
if (y>height-dia1/2 || y<2+dia1/2) {
speedY=speedY*-1;
}
// this code to move it according to the keys W S D A
void keyPressed() {
if (keyCode=='W') {
speedX=0;
speedY=-4;
}
if (keyCode=='S') {
speedX=0;
speedY=4;
}
if (keyCode=='A') {
speedX=-4;
speedY=0;
}
if (keyCode=='D') {
speedX=4;
speedY=0;
}
}
I made this ball with a nose, which moves around the screen with the keys W S D A. If it hits the edges it will bounce back.
I'm trying to change the direction the ball is facing to make it face the same way as it's moving. I wanted to use rotate for this, but once I use rotate it throws all the coordinates off. Rotating it back doesn't help either.
I have commented out the stuff I have tried to do. For example, I tried to translate it to 250,250 and then rotate it afterwards, but then the X and Y coordinates are switched. Also, the ball won't go all the way to the corners and it moves out (since it's translated down).
What kind of rotation/translation logic do I need to change?
It is likely that using the rotate function on your triangle is wreaking havoc as you are performing the rotate on several variables in your draw loop because you're not telling processing exactly which object you want to transform. One way to do this is to look up the pushMatrix and popMatrix functions (google "processing pushMatrix" to see helpful info for how to use the type and associated functions). It would be cumbersome to implement this into your code as the triangle is created in your draw loop every frame. An easy way to make transformations to a specific shape you have (in your instance, a triangle) is to store it as a PShape and then make transformations as you need to. Since PShape's can easily be transformed using PShape functions you don't need to worry about your transformations effecting other variables (so no need to use push/popmatrix. Here is a commented version of your code that implements your Triangle as a PShape.
//declaringglobalvaribales
float dia1=50;
//diameteroftheface
float x=400;
float y=400;
float speedX=4;
float speedY=0;
//Initialize PShape which we can later store a triangle in
PShape tri;
void setup() {
size(810, 810);
//Initialize triangle - this triangle faces right
tri = createShape(TRIANGLE, 0, 10, 0, -10, 10, 0);
}
void draw() {
background(225);
fill(225, 0, 0);
stroke(0);
ellipse(x, y, dia1, dia1);
fill(0, 225, 0);
//Draw the stored PShape at x and y coordinate
shape(tri,x,y);
//movingtheballXway
x=x+speedX;
//movingtheballYway
y=y+speedY;
//if it hits the left or right corners it will turn around
if (x>width-dia1/2 || x<2+dia1/2) {
speedX=speedX*-1;
//Flip PShape rotation
tri.rotate(PI);
} // it its hits the top or bottom it will turn around
if (y>height-dia1/2 || y<2+dia1/2) {
speedY=speedY*-1;
//Flip PShape rotation
tri.rotate(PI);
}
}
// this code to move it according to the keys W S D A
void keyPressed() {
if (keyCode=='W') {
speedX=0;
speedY=-4;
//reset triangle orientation (transformation matrix) to original then rotate to face UP
tri.resetMatrix();
tri.rotate(-PI/2);
}
if (keyCode=='S') {
//reset triangle orientation (transformation matrix) to original then rotate to face DOWN
speedX=0;
speedY=4;
tri.resetMatrix();
tri.rotate(PI/2);
}
if (keyCode=='A') {
//reset triangle orientation (transformation matrix) to original then rotate to face LEFT
tri.resetMatrix();
tri.rotate(PI);
speedX=-4;
speedY=0;
}
if (keyCode=='D') {
//reset triangle orientation (transformation matrix) to original - it is already pointing right
tri.resetMatrix();
speedX=4;
speedY=0;
}
}
I suspect your next step, or a more efficient way to write this piece of code might be to begin to implement PVectors (google processing PVectors to see helpful info for how to use the type and associated functions) for position and direction of your 'ball'. Here is some commented code that begins to show you how you might implement this in your current code. Although there are many improvements that can be made on this. For more information on how vectors work in processing follow this tutorial - http://natureofcode.com/book/chapter-1-vectors/
//declaringglobalvaribales
//diameteroftheface
float dia1=50;
//initialize position PVector and tell it where you want it to be - in this case 400,400
PVector position = new PVector(400, 400);
//how many steps you want your position to move per frame
float speed=4;
//initialize direction vector as 0,0 - the ellipse will not move until you give it a
//direction as it is initialized with no direction
PVector direction = new PVector(0, 0);
void setup() {
size(810, 810);
}
void draw() {
background(225);
fill(225, 0, 0);
stroke(0);
//draw ellipse at your position PVector using the PVectors x and y values
ellipse(position.x, position.y, dia1, dia1);
fill(0, 225, 0);
//drawing a line to indicate what direction the ellipse is heading in using the position coordinates and the position plus direction
line(position.x, position.y, position.x+direction.x*4, position.y+direction.y*4);
// add the direction to the position to make it move
position =position.add(direction);
//if the position PVector is close to sketch edges invert its direction by multiplying direction PVector by -1
if (position.x>width-dia1/2 || position.x<2+dia1/2) {
direction.mult(-1);
}
if (position.y>height-dia1/2 || position.y<2+dia1/2) {
direction.mult(-1);
}
}
// this code to move it according to the keys W S D A
void keyPressed() {
//set the direction coordinates based on keypresses
//also multiply the direction by speed variable so it moves at a speed set at top of script
if (keyCode=='W') {
direction.y = -1*speed;
direction.x = 0;
}
if (keyCode=='S') {
direction.y = 1*speed;
direction.x = 0;
}
if (keyCode=='A') {
direction.x = -1*speed;
direction.y = 0;
}
if (keyCode=='D') {
direction.x = 1*speed;
direction.y = 0;
}
}
If you have a center point, an angle you want to face, and a distance from that center, you can use cos() and sin() to calculate the end point. Here's a simple example:
float angle = 0;
float distance = 25;
void draw(){
angle += .01;
float startX = width/2;
float startY = height/2;
float endX = startX + cos(angle)*distance;
float endY = startY + sin(angle)*distance;
background(255);
line(startX, startY, endX, endY);
}
In the future, please try to narrow your question down to an MCVE like this before posting.
So I’m trying to give an obj some physics, and have work with the example of the bouncing ball that processing comes with, and I have make it instead of a ball to be a cylinder, but I can’t find the way to make the obj to have the physics.
I’m importing the obj with the library saito.objloader. I have this code, which is the invocation of the obj
import processing.opengl.*;
import saito.objloader.*;
OBJModel modelCan;
PVector location; // Location of shape
PVector velocity; // Velocity of shape
PVector gravity; // Gravity acts at the shape's acceleration
float rotX, rotY;
void setup() {
size(1028, 768, OPENGL);
frameRate(30);
modelCan = new OBJModel(this, "can.obj", "absolute", TRIANGLES);
modelCan.scale(50);
modelCan.translateToCenter();
modelCan.enableTexture();
location = new PVector(100,100,100);
velocity = new PVector(1.5,2.1,3);
gravity = new PVector(0,0.2,0);
}
void draw() {
background(129);
lights();
// Add velocity to the location.
location.add(velocity);
// Add gravity to velocity
velocity.add(gravity);
// Bounce off edges
if ((location.x > width) || (location.x < 0)) {
velocity.x = velocity.x * -1;
}
if (location.y > height) {
// We're reducing velocity ever so slightly
// when it hits the bottom of the window
velocity.y = velocity.y * -0.95;
location.y = height;
}
if (location.z < -height || location.z > 0) { //note that Zaxis goes 'into' the screen
velocity.z = velocity.z * -0.95;
//location.z = height;
}
println("location x: "+location.x);
println("location y: "+location.y);
println("location z: "+location.z);
println("velocidad x: "+velocity.x);
println("velocidad y: "+velocity.y);
println("velocidad z: "+velocity.z);
pushMatrix();
translate(width/2, height/2, 0);
modelCan.draw();
popMatrix();
}
I hope you guys can help me! Thanks!
The bouncing ball example is a very simple example, and I guess you can't apply it to a cylinder in an easy way.
You might want to have a look at these sites :
http://www.wildbunny.co.uk/blog/2011/04/20/collision-detection-for-dummies/
http://shiffman.net/ (his book is essential )
https://github.com/shiffman/Box2D-for-Processing (again : Daniel Shiffman)
Collision detection is made in computer time : it means that it's correlated with the frequency of your program execution. For instance, the velocity of an object can be so big that between two render cycles your first object is passing through your second object: collision detection won't happen. They didn't collide during the previous cycle, and don't collide during the current cycle.
That's why some physics "engine" like Box2D try to anticipate the collision, computing the bounding box of each object.
If you want to make accurate collision detection in 3D, you can look at the Bullet library, used in many games and movies : http://bulletphysics.org/wordpress/ but the learning curve might be large.
In your program, you can try to give a threshold to your collision detection (and add the dimensions of your object to its position, if you want the whole body to collide, not only its center !): if your object's position is between your limit and (your limit +/- a threshold) consider it's colliding, but you won't totally avoid tunnelling.