been a lurker for a while, first time posting :)
I'm currently working on a little game for uni. I have the the majority of it done, but the "problem" that I'm running into is getting lost to tunnel vision. I was hoping someone would be able to point me in the right direction.
I have a program (code below) that prints an image of a fly to the canvas. A fly swatter follows the mouse and, when a fly is within range of the swatter and the mouse is pressed, the fly gets rekt.
The issue that I'm encountering is that the program is still recognising dead flies as having collision detection, and so whether I click on a dead fly of a live fly, the collision is still detected and a new fly is spawned.
Any help would be appreciated :) Thanks!
PImage fly, flybye, swatter, swatted;
float[] fX, fY; // fly locations array
float[] swat; // fly swatted binary boolean array, 1 = swatted, 0 = not swatted
int score = 0; // increments when swatted.
void setup(){
size(800,400);
fX = new float[0];
fY = new float[0];
swat = new float[0];
fly = loadImage("fly.png");
flybye = loadImage("flybye.png");
swatter = loadImage("swatter.png");
swatted = loadImage("swatted.png");
fX = append(fX, random(1, 800)); //first fly - random location
fY = append(fY, random(1, 400));
swat = append(swat, 0); // used as a boolean and matches to each individual fly, 0 = fly not
swatted, 1 = swatted.
}
void populate(){ // draw the flies in memory to the screen.
for(int i = 0; i < fX.length; i++){
if(swat[i] == 1){ // if swatted
flybye.resize(30, 30);// resize the fly image and place based on fx/fy array values
image(flybye, fX[i], fY[i]);
} else { // not swatted
fly.resize(30, 30);
image(fly, fX[i], fY[i]);
}
}
}
void collisionDetect(){ //collision detection - detect collision between swatter and fly
for(int i = 0; i < swat.length; i++){ // bounding box detection
if(dist(fX[i], fY[i], mouseX, mouseY) < 50){ // condition should look at location of mouse
and individual coordinates in fX and fY
swat[i] = 1; // swatted
fX = append(fX, random(1, 800)); //new fly placed in random location when old fly dies.
fY = append(fY, random(1, 400));
swat =append(swat, 0); // new fly not swatted
score++; //increment score
}
}
}
void draw(){
background(255);
populate(); // draw flys to screen.
fill(0);
textSize(20);
text(score, 5, 20);// set a text size and location for the score.
if(mousePressed) { // image swap
collisionDetect();
image(swatted, mouseX - 30, mouseY - 30); //draw swatter image to around mouse locaiton - might want to play with this to get it to look right.
}else{
image(swatter, mouseX - 30, mouseY - 30); // if not pressed then alternative image.
}
}
Shouldn't you test if the fly is swatted in your collision detection:
if(swat[i] == 0 && dist(fX[i], fY[i], mouseX, mouseY) < 50){
Related
How do you get a certain object to hit another object?
I am making a game where trash is falling from the sky, you are meant to drag and drop the trash into the correct bins. How do I make it so when you drag it into the regional area of the bin is, it gives you a score and resets again. I have made the score & lives function but how do you get it to hit the bin and give you a score?
Here's the progress I have made so far:
PImage scene, can, brownB, blueB, greenB;
int can_x = -100; //CAN IS HIDDEN FOR NOW
int can_y = 500;
int canX = 100;
int canY = 50;
int canwidth = width/2;
int canheight = height/2;
int score = 0;
int lives = 3;
int can_count = 0;
int quit = 0;
boolean mouseInCan = false;
void setup() // Entry point (start of program), runs once
{
size(800,600,P2D); // Create a Window, must be same size as scene
scene = loadImage("backround.png"); // load image and data into scene data structure
can = loadImage("can.png"); // load image of can into the GPU
greenB = loadImage("green_bin.png");
textureMode(NORMAL); // Scale texture Top right (0,0) to (1,1)
blendMode(BLEND); // States how to mix a new image with the one behind it
noStroke(); // Do not draw a line around objects
canX = 0 + (int)random(800); // Choose drop starting position
canY = 0;
}
//check if the mouse is in the can
void mousePressed() {
if (mouseX > canX && mouseX < canX + canwidth && mouseY > canY && mouseY < canY + canheight) {
mouseInCan = true;
}
}
//if the mouse is in the can, then move it when the mouse is dragged
void mouseDragged() {
if (mouseInCan) {
float deltaX = mouseX - pmouseX;
float deltaY = mouseY - pmouseY;
canX += deltaX;
canY += deltaY;
}
}
//when we let go of the mouse, stop dragging the can
void mouseReleased() {
mouseInCan = false;
}
void draw()
{
background(scene); // Display background image referenced by scene
image(can, canX, canY, canwidth, canheight); //Can is drawn at position
image(greenB, 100, 450, width/8, height/4);
pushMatrix(); // Store current location of origin (0,0)
translate(can_x,can_y); // Change origin (0,0) for drawing to (drop_x,drop_y)
beginShape(); // Open graphics pipeline
texture(can); // Tell GPU to use drop to texture the polygon
vertex( -20, -20, 0, 0); // Load vertex data (x,y) and (U,V) texture data into GPU
vertex(20, -20, 1, 0); // Square centred on (0,0) of width 40 and height 40
vertex(20, 20, 1, 1); // Textured with an image of a drop
vertex( -20, 20, 0, 1);
endShape(CLOSE); // Tell GPU you have loaded shape into memory.
popMatrix();
canY += 1.5; // Make "drop" move down the screen (two pixels at a time)
if (canY>600) // If y value is entering the bottom of screen
{
canX = 0+(int)random(800); // Restart the drop again in the cloud.
canY = 0;
lives--;
}
if ((canY>100)&&(canY<450)) // If drop is on same level as player
{
if(abs((canX+100)-(canX+450))<25) // And drop is near player
{
score++; // Increase drop count by one (caught)
canX=0+(int)random(800); // Restart a new drop in the cloud
canY=0;
}
}
textSize(18); // Display score information on the screen
fill(0,0,0);
text("Lives: "+lives, 540, 20);
textSize(18);
fill(0,0,0);
text("Score: "+score, 640, 20);
if(quit==1) // Wait five seconds before exiting
{
delay(5000);
exit();
}
if (lives<1) // All lives lost so game over but
{ // return to draw one more time to
quit = 1; // allow "Game Over to be displayed.
}
}
I have tried doing it where the comment with 'If drop is on same level as player' but no luck, The code is a mess right now but I will clean it up, still new to processing.
What you are looking for is some kind of collision detection. There are very complex algorithms out there that can do an accurate detection with complex shapes, at the cost of CPU time, but in your case, just checking the intersection of two rectangles will probably be enough, at least for a start.
First you need to have your bin and can's positions and dimensions stored somewhere. We'll use the enclosing rectangle of each as a collision box.
PImage scene, can, brownB, blueB, greenB;
int canX = 100, canY = 50, canwidth = 80, canheight = 80;
int binX = 100, binY = 450, binW = 100, binH = 150;
You can then adjust the dimensions according to your screen size, but it has to be done after you have initialized it in setup:
void setup() // Entry point (start of program), runs once
{
size(800, 600, P2D); // Create a Window, must be same size as scene
scene = loadImage("backround.png"); // load image and data into scene data structure
can = loadImage("can.png"); // load image of can into the GPU
greenB = loadImage("green_bin.png");
//...
canwidth = width / 10;
canheight = width / 10;
binW = width / 8;
binH = height / 4;
binY = height - binH; //Set the bin at the bottom of the screen
}
Now your elements can be drawn according to the stored values, how and where you intend them, and you can do your collision detection inside your draw loop:
void draw()
{
background(scene); // Display background image referenced by scene
image(can, canX, canY, canwidth, canheight); //Can is drawn at position
image(greenB, binX, binY, binW, binH);
//...
/* If the top of the can is below the top of the bin and the can is
* horizontally within the bin, then we count score
*/
if (canY > binY && canX > binX && canX + canwidth < binX + binW) {
score++; // Increase drop count by one (caught)
canX=0+(int)random(800); // Restart a new drop in the cloud
canY=0;
}
//...
}
I've neglected the check for bottom coordinates of the can relative to the bin, as the bin is at the very bottom, and hitting the bottom kills you.
As was said already, you need some kind of collision detection. I would abstain though from trying to implement any algorithms myself and would instead use a professional library for that like:
https://github.com/locationtech/jts
That way you can also test against the real geometry and the overhead is minimal because these tests are first run againt the bounding boxes and only when that is positive they are refined to the real geometry. In addition you could also use a spatial index to speed up the search.
I have the following code (in Processing Software) which I want to stop the particles before they leave the screen…
So I dont know how to stop them near the edges of the screen…
Please advice…
Thanks
Particle [] pickles = new Particle [100];
void setup () {
size (500, 500);
smooth ();
for (int i=0; i<pickles.length; i++) {
pickles [i] = new Particle ();
}
}
void draw () {
background (0); //clear the background
for (int i=0; i<pickles.length; i++) {
pickles[i].update();
}
}
class Particle {
float x;
float y;
float velX ; // speed or velocity
float velY;
Particle () {
//x and y position to be in middle of screen
x = width/2;
y = height/2;
velX = random (-10, 10);
velY = random (-10, 10);
}
void update () {
x+=velX;
y+=velY;
fill (255);
ellipse (x, y, 10, 10);
}
}
You can check whether a particle is going outside the bounds of the screen by comparing its x and y values to the screen dimensions. For example:
if(x < 0){
// particle is off left edge of screen
}
else if(x > width){
// particle is off right edge of screen
}
When you detect one of these conditions, you can do a number of things:
Remove the particle from the array so it stops using system resources after it leaves the screen
Wrap the value around to the other side of the screen
Have it bounce off the edge by reversing its velocity
Which approach you take depends on exactly what you want to happen.
Shameless self-promotion: here is a tutorial on collision detection in Processing, which includes the above approaches.
I have been doing a small little project using Processing, and the effect I wanted to achieve was a kind of "mountains" forming and moving, using Perlin Noise with the noise() function, with 2 parameters.
I was originally using a image for the background, but for illustrational purposes, I made the background black, and it's basically the same effect.
My issue is that I want to have a "history" of the mountains because they should fade away after some time, and so I made a history of PShapes, and draw the history and update it each frame.
Updating it is no issue, but drawing the PShapes seems to take a lot of time, reducing the frame rate from 60 to 10 when the length of the history is 100 elements.
Below is the code I used :
float noise_y = 0;
float noise_increment = 0.01;
// increment x in the loop by this amount instead of 1
// makes the drawing faster, since the PShapes have less vertices
// however, mountains look sharper, not as smooth
// bigger inc = better fps
final int xInc = 1;
// maximum length of the array
// bigger = less frames :(
final int arrLen = 100;
int lastIndex = 0;
PShape[] history = new PShape[arrLen];
boolean full = false;
// use this to add shapes in the history
PShape aux;
void setup() {
size(1280, 720);
}
void draw() {
background(0);
// create PShape object
aux = createShape();
aux.beginShape();
aux.noFill();
aux.stroke(255);
aux.strokeWeight(0.5);
for (float x = 0; x < width + xInc; x = x + xInc) {
float noise = noise(x / 150, noise_y) ;
// get the actual y coordinate
float y = map(noise, 0, 1, height / 2, 0);
// create vertex of shape at x, y
aux.vertex(x, y);
}
aux.endShape();
// push the current one in the history
history[lastIndex++] = aux;
// if it reached the maximum length, start it over ( kinda works like a queue )
if (lastIndex == arrLen) {
lastIndex = 0;
full = true;
}
// draw the history
// this part takes the MOST TIME to draw, need to fix it.
// without it is running at 60 FPS, with it goes as low as 10 FPS
if (full) {
for (int i = 0; i < arrLen; i++) {
shape(history[i]);
}
} else {
for (int i = 0; i < lastIndex; i++) {
shape(history[i]);
}
}
noise_y = noise_y - noise_increment;
println(frameRate);
}
I have tried to use different ways of rendering the "mountains" : I tried writing my own class of a curve and draw lines that link the points, but I get the same performance. I tried grouping the PShapes into a PShape group object like
PShape p = new PShape(GROUP);
p.addChild(someShape);
and I got the same performance.
I was thinking of using multiple threads to render each shape individually, but after doing some research, there's only one thread that is responsible with rendering - the Animation Thread, so that won't do me any good, either.
I really want to finish this, it seems really simple but I can't figure it out.
One possible solution would be, not to draw all the generated shapes, but to draw only the new shape.
To "see" the shapes of the previous frames, the scene can't be cleared at the begin of the frame, of course.
Since the scene is never cleared, this would cause, that the entire view is covered, by shapes over time. But if the scene would be slightly faded out at the begin of a new frame, instead of clearing it, then the "older" shapes would get darker and darker by time. This gives a feeling as the "older" frames would drift away into the depth by time.
Clear the background at the initlization:
void setup() {
size(1280, 720);
background(0);
}
Create the scene with the fade effect:
void draw() {
// "fade" the entire view
blendMode(DIFFERENCE);
fill(1, 1, 1, 255);
rect(0, 0, width, height);
blendMode(ADD);
// create PShape object
aux = createShape();
aux.beginShape();
aux.stroke(255);
aux.strokeWeight(0.5);
aux.noFill();
for (float x = 0; x < width + xInc; x = x + xInc) {
float noise = noise(x / 150, noise_y) ;
// get the actual y coordinate
float y = map(noise, 0, 1, height / 2, 0);
// create vertex of shape at x, y
aux.vertex(x, y);
}
aux.endShape();
// push the current one in the history
int currentIndex = lastIndex;
history[lastIndex++] = aux;
if (lastIndex == arrLen)
lastIndex = 0;
// draw the newes shape
shape(history[currentIndex]);
noise_y = noise_y - noise_increment;
println(frameRate, full ? arrLen : lastIndex);
}
See the preview:
I have written a program in which a UFO (in essence, a gray ellipse) appears from the center of the screen and flies to the edge. There is a laser that appears when the mouse is pressed, and disappears when the mouse is released. I want to make it so that the UFO disappears when the mouse clicks on it/the laser touches it.
I've made it as far as to make the UFO class and create variables that determine its movements and speed, and I was able to get the laser to appear directly on the cursor. I thought of making an 'if' statement to check if the cursor is within the radius (or diameter) of the UFO, and placing it inside of the for loop I created for the UFOs. However, I am not sure how to achieve the proper syntax to make it happen.
Note: You may need to wait a few seconds for the first circle to appear after you play the sketch.
UFO[] ufos = new UFO[3];
void setup() {
size(700, 700);
for (int j = 0; j < ufos.length; j++) {
ufos[j] = new UFO();
}
}
//UFO class
//Class setup ends on line 61
class UFO {
float a;
float b;
float c;
float sa;
float sb;
float d;
UFO() {
//declare float a/b/c value
a = random(-width/2, width/2);
b = random(-height/2, width/2);
c = random(width);
}
//UFO movement
void update() {
//float c will serve as a speed determinant of UFOs
c = c - 1;
if (c < 5) {
c = width;
}
}
//UFO setup
void show() {
//moving x/y coordinates of UFO
float sa = map(a / c, 0, 1, 0, width);
float sb = map(b / c, 0, 1, 0, height);
float d = map(c, 0, width, 50, 0);
//UFO drawing shapes
//ellipse is always sa (or sb) / c to allow UFO to appear
//as if it is moving through space
fill(200);
ellipse((sa / c), (sb / c), d + 5, d+5);
//Hides UFO way off the screen
//and replaces it with a black-filled ellipse until
//it forms into a full circle
//When radius d becomes 50, the UFO flies from the
//center of the screen to off of the screen
if (d < 50) {
fill(0);
ellipse(-5, -10, 90, 90);
sa = 10000;
sb = 10000;
}
}
}
void draw() {
//Background
background(0);
//Translated the screen so that the UFOs appear to fly from
//the center of the screen
translate(width/2, height/2);
//UFO draw loop, make UFO visible on screen
for (int j = 0; j < ufos.length; j++) {
ufos[j].update();
ufos[j].show();
//mouse-click laser
if (mousePressed == true) {
fill(200,0,0);
ellipse(mouseX - 352,mouseY - 347,50,50);
}
}
}
Like I said on the Happy Coding forum:
Basically, if your UFO is a series of circles, then you just need to use the dist() function to check whether the distance from the mouse to the center of the circle is less than the radius of the circle. If it is, then the mouse is inside the circle. Here's a small example:
float circleX = 50;
float circleY = 50;
float circleDiameter = 20;
boolean showCircle = true;
void draw(){
background(0);
if(showCircle){
ellipse(circleX, circleY, circleDiameter, circleDiameter);
}
}
void mousePressed(){
if(dist(mouseX, mouseY, circleX, circleY) < circleDiameter/2){
showCircle = false;
}
}
If your UFO is multiple circles, then you need to apply this logic to each circle. Please try something and post a small example like this one (not your whole sketch) if you get stuck. Good luck.
I will keep this short, I am making a Tower Defence game as a mini project while I have some spare time and I am trying to figure out how I can implement the towers to be able to shoot the enimies when they come into range using dist but I just don't know how to implement a method that uses the enimies position and the towers position. I have an ArrayList of CreepSprites and Towers
CreepSprite[] CreepSprites;
ArrayList<Tower> AllTowers = new ArrayList<Tower>();
ArrayList<Creep> AllCreeps = new ArrayList<Creep>();
If someone could give me some guidence as to how I would go about making the towers able to shoot the Creeps that would be great, even if it doesn't get rid of them, just able to shoot at them would be great.
Cheers
#GoneUp's answer is in the right direction. In Processing you have a class called PVector which provides a distance method as well: dist()
PVector towerPos = new PVector(100, 100);
PVector enemyPos = new PVector(300, 300);
float towerAttackRadius = 200;
void setup() {
size(400, 400);
rectMode(CENTER);
strokeWeight(3);
}
void draw() {
background(255);
//draw tower
noFill();
//check range
if(towerPos.dist(enemyPos) < towerAttackRadius){
//tower engaged, draw in green
stroke(0,192,0);
}else{
//tower in idle mode, draw in blue
stroke(0, 0, 192);
}
//visualise tower attack radius
//(towerAttackRadius * 2 -> radius * 2 = diameter (width/height))
ellipse(towerPos.x, towerPos.y, towerAttackRadius * 2, towerAttackRadius * 2);
//visualise tower
rect(towerPos.x, towerPos.y, 30, 30);
//draw enemy
stroke(192, 0, 0);
rect(enemyPos.x, enemyPos.y, 10, 10);
//instructions
fill(0);
text("click and drag to move enemy",10,15);
}
void mouseDragged() {
enemyPos.set(mouseX, mouseY);
}
I warmly recommend Daniel Shiffman's Nature of Code chapter on Vectors.
It's a little bit of linear algebra, but it's super useful, especially for games so worth getting the hang of it early.
For example, to shoot a bullet, you will need to workout the direction towards.
You can do that by using vector subtraction.
Additionally, you probably want to control how fast the bullet moves on screen towards that direction. That can also be done by normalising the vector: keeping it's direction, but reducing it's size to 1.0:
After that point it's easy to scale (multiply) the vector to any size you want.
If you know the tower's position, you simply need to add this scaled velocity to compute where the bullet should be drawn each frame.
PVector already has a function that does both: setMag().
(set mag is short for set magnitude (or vector length))
It also provides a heading() function which is handy to workout the angle.
Here's a basic proof of concept:
PVector towerPos = new PVector(100, 100);
PVector enemyPos = new PVector(300, 300);
float towerAttackRadius = 300;
ArrayList<Bullet> bullets = new ArrayList<Bullet>();
void setup() {
size(400, 400);
rectMode(CENTER);
strokeWeight(3);
}
void draw() {
background(255);
//check if an enemy is within range using dist()
//if the distance is smaller than the radius, attack!
if(towerPos.dist(enemyPos) < towerAttackRadius){
//hacky frame based counter: please use a millis() based timer instead
//shoot every 30 frames
if(frameCount % 30 == 0){
shoot();
}
}
//update bullets
for(Bullet b : bullets) {
b.update();
}
//draw tower
noFill();
stroke(0, 0, 192);
//visualise tower attack radius
//(towerAttackRadius * 2 -> radius * 2 = diameter (width/height))
ellipse(towerPos.x, towerPos.y, towerAttackRadius * 2, towerAttackRadius * 2);
//visualise tower
rect(towerPos.x, towerPos.y, 30, 30);
//draw enemy
stroke(192, 0, 0);
rect(enemyPos.x, enemyPos.y, 10, 10);
//instructions
fill(0);
text("click and drag to move enemy",10,15);
}
void mouseDragged() {
enemyPos.set(mouseX, mouseY);
}
void shoot(){
//make a new Bullet pointing from the tower to the enemy
Bullet b = new Bullet(towerPos.x,towerPos.y,enemyPos.x,enemyPos.y);
//add it to the list of bullets (for updates)
bullets.add(b);
println(b);
}
class Bullet {
//where does the bullet shoot from (and it's current position)
PVector position = new PVector();
//where does the bullet shooting towards
PVector target = new PVector();
//how fast does the bullet move on screen
float speed = 1.2;
//how large goes the bullet appear on screen
float size = 10;
//bullet velocity
PVector velocity;
Bullet(float startX,float startY, float endX, float endY) {
position.set(startX,startY);
target.set(endX,endY);
//compute the difference vector (start to end) = direction
velocity = PVector.sub(target,position);
//normalize the vector = same direction but magnitude of 1 -> makes it easy to scale
//velocity.normalize();
//scale by the speed to move on screen)
//normalize + multiple = resize the vector -> same direction, different length
//velocity.mult(speed);
//or do both normalize and multiple using setMag()
velocity.setMag(speed);
}
void update() {
//update position based on velocity (simply add velocity to current position)
position.add(velocity);
//render
//compute rotation angle from velocity (implementation is 2D only btw)
float angle = velocity.heading();
pushMatrix();
translate(position.x,position.y);
rotate(angle);
stroke(0);
line(0,0,size,0);
popMatrix();
}
String toString(){
return position+"->"+target;
}
}
You can actually play with a preview bellow:
var towerPos,enemyPos;
var towerAttackRadius = 300;
var bullets = [];
function setup() {
createCanvas(400, 400);
rectMode(CENTER);
strokeWeight(3);
towerPos = createVector(100, 100);
enemyPos = createVector(300, 300);
}
function draw() {
background(255);
//check if an enemy is within range using dist()
//if the distance is smaller than the radius, attack!
if(towerPos.dist(enemyPos) < towerAttackRadius){
//hacky frame based counter: please use a millis() based timer instead
//shoot every 30 frames
if(frameCount % 30 === 0){
shoot();
}
}
//update bullets
for(var i = 0; i < bullets.length; i++) {
bullets[i].update();
}
//draw tower
noFill();
stroke(0, 0, 192);
//visualise tower attack radius
//(towerAttackRadius * 2 -> radius * 2 = diameter (width/height))
ellipse(towerPos.x, towerPos.y, towerAttackRadius * 2, towerAttackRadius * 2);
//visualise tower
rect(towerPos.x, towerPos.y, 30, 30);
//draw enemy
stroke(192, 0, 0);
rect(enemyPos.x, enemyPos.y, 10, 10);
//instructions
noStroke();
fill(0);
text("click and drag to move enemy",10,15);
}
function mouseDragged() {
enemyPos.set(mouseX, mouseY);
}
function shoot(){
//make a new Bullet pointing from the tower to the enemy
var b = new Bullet(towerPos.x,towerPos.y,enemyPos.x,enemyPos.y);
//add it to the list of bullets (for updates)
bullets.push(b);
}
function Bullet(startX,startY,endX,endY) {
//where does the bullet shoot from (and it's current position)
this.position = createVector(startX,startY);
//where does the bullet shooting towards
this.target = createVector(endX,endY);
//how fast does the bullet move on screen
this.speed = 1.2;
//how large goes the bullet appear on screen
this.size = 10;
//compute the difference vector (start to end) = direction
this.velocity = p5.Vector.sub(this.target,this.position);
//normalize the vector = same direction but magnitude of 1 -> makes it easy to scale
this.velocity.normalize();
//scale by the speed to move on screen)
//normalize + multiple = resize the vector -> same direction, different length
this.velocity.mult(this.speed);
this.update = function() {
//update position based on velocity (simply add velocity to current position)
this.position.add(this.velocity);
//render
//compute rotation angle from velocity (implementation is 2D only btw)
var angle = this.velocity.heading();
push();
translate(this.position.x,this.position.y);
rotate(angle);
stroke(0);
line(0,0,this.size,0);
pop();
}
}
//http://stackoverflow.com/questions/39698472/processing-tower-defence-game-towers-attacking-enemies
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.3/p5.min.js"></script>
Have fun with PVectors ! :)
One important note:
the above code is a proof of concept and not optimized.
On the long run with a lot of towers and enemies it will slow down.
Once you get the math/code right, you can start doing a few improvements:
manage bullets/instances (e.g. re-use bullets that are off screen
rather than creating new instances all the time)
use the squared distance via magSq() instead and the squared radius to speed up calculations
You could use the Point2D class to represent the x,y coordinates of your figures. The class got a pre-implemented distance method wich can be checked against a radius.