I am trying to make a image that was loaded into processing be able to move along with the click of the mouse, and dropped when the mouse is let go.
I am new to Processing and am learning everything I can off the Internet. I am trying to make a image, that was loaded into Processing, be able to move along with the click of the mouse and dropped when the mouse is let go.
I have done this with a shape, but I don't know the how to do it with images. I am completely new to java Processing so I don't really know what I am doing so if you go through each step individually please.
Here is the code. It is a mess:
PImage scene, can;
int can_x, can_y, can_count;
float squareX = 200;
float squareY = 200;
float squareWidth = 50;
float squareHeight = 50;
//keep track of when the mouse is inside the square
boolean mouseInSquare = false;
boolean mouseInCan = false;
void setup() {
size(800,600,P2D);
scene = loadImage("backround.png"); // load image and data into scene data structure
can = loadImage("can.png"); // load image of rain drop into the GPU
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
can_x=0+(int)random(800); // Choose drop starting position
can_y=0;
}
//check if the mouse is in the square
void mousePressed() {
if (mouseX > squareX && mouseX < squareX + squareWidth && mouseY > squareY && mouseY < squareY + squareHeight) {
mouseInSquare = true;
}
}
//void mousePressed() {
//if (mouseX > can_x && mouseX < can_x + mouseY > can_y && mouseY < can_y) {
// mouseInCan = true;
//}
//}
//if the mouse is in the square, then move it when the mouse is dragged
void mouseDragged() {
if (mouseInSquare) {
float deltaX = mouseX - pmouseX;
float deltaY = mouseY - pmouseY;
squareX += deltaX;
squareY += deltaY;
}
}
//when we let go of the mouse, stop dragging the square
void mouseReleased() {
mouseInSquare = false;
}
//draw the square
void draw() {
background(scene);
image(can, 0, 0);
rect(squareX, squareY, squareWidth, squareHeight);
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();
can_y+=1.5; // Make "drop" move down the screen (two pixels at a time)
if(can_y>600) // If y value is entering the bottom of screen
{
can_x=0+(int)random(800); // Restart the drop again in the cloud.
can_y=0;
}
}
I know it's not organized as I was just trying different ways of trying to get it to work.
Related
I have been coding a significantly simple game for my academic work in which the PNG bee sprite is meant to run away from the orange ball. If the bee collides with the orange ball, she dies. Apart from this, I intend to include a timer that keeps going onwards as the bee succeeds in running away from the ball. The ball moves automatically throughout the screen, whereas the bee bounces throughout the screen with the arrow keys and gravity.
I have come across some explanations towards collision detection upon the Processing forum, however I still don't understand how this event can occur in the cases of circles x circles collisions, rectangles x circles collisions, etc.
Please, excuse my messy code. Also, excuse my poor description of what I want to know.
This is what I see on the screen:
My code:
//background
PImage background;
// keys | keyboard
boolean upPressed = false;
boolean downPressed = false;
boolean leftPressed = false;
boolean rightPressed = false;
// bee player character
PImage charImage;
float charSpeed = 5.5;
float charX = 0;
float charY = 450;
float gravity = 1.5;
float vy = 0;
float bounce = -0.8;
// platforms
PImage bee;// bee
float beeX = 300;
float beeY = 490;
PImage hi; // hi
float hiX = 400;
float hiY = 300;
PImage ve; // ve
float veX = 420;
float veY = 440;
// more beehives
PImage beehive4;// beehive4
float bee4X = 120;
float bee4Y = 90;
PImage beehive5; // beehive5
float bee5X = 200;
float bee5Y = 300;
PImage beehive6; // beehive6
float bee6X = 30;
float bee6Y = 400;
PImage beehive7; // beehive7
float bee7X = 496;
float bee7Y = 90;
// enemy ball
float ballX = 100;
float ballY = 100;
float xspeed = 100;
float yspeed = 100;
//////
public void setup() {
size(600, 800);
noStroke();
smooth();
noFill(); // to adjust the image in the screen properly in fullscreen
//load beehives
bee = loadImage("beehive 1.png");
bee.resize(100, 100);
hi = loadImage("beehive 2.png");
hi.resize(100,100);
ve = loadImage("beehive 3.png");
ve.resize(100, 100);
// load more beehives
beehive4 = loadImage("beehive 4.png");
beehive4.resize(100, 100);
beehive5 = loadImage("beehive 5.png");
beehive5.resize(100, 100);
beehive6 = loadImage("beehive 6.png");
beehive6.resize(100, 100);
beehive7 = loadImage("beehive 7.png");
beehive7.resize(100, 100);
}
/*********** drawing section !***********/
public void draw() {
background(244, 240, 219);
noStroke();
// render beehives
image(bee, beeX, beeY);
image(hi, hiX, hiY);
image(ve, veX, veY);
// render more beehives
image(beehive4, bee4X, bee4Y);
image(beehive5, bee5X, bee5Y);
image(beehive6, bee6X, bee6Y);
image(beehive7, bee7X, bee7Y);
// render bee
charImage = loadImage("bee walk 3.png");
charImage.resize(200, 200);
vy += gravity; // it applies gravity to the bee sprite
charY += vy;
if(charY > height - 150 )
vy *= bounce; // bouncing bee
// Add the current speed to the location.
ballX = ballX + xspeed;
ballY = ballY + yspeed;
// Check for bouncing
if ((ballX > width) || (ballX < 0)) {
xspeed = xspeed * -1;
}
if ((ballY > height) || (ballY < 0)) {
yspeed = yspeed * -1;
}
// Display at x,y location
stroke(0);
fill(179, 98, 0);
ellipse(ballX, ballY,80,80);
// update keys
if (upPressed) {
charY--;
}
if (downPressed) {
charY++;
}
if (leftPressed) {
charX--;
}
if (rightPressed) {
charX++;
}
if(keyPressed){
if(keyCode == UP && charY > 0){
charY -= 30;
}
if(keyCode == DOWN && charY < height){
charY += 10;
}
if(keyCode == LEFT && charX > 0){
charX -= 30;
}
if(keyCode == RIGHT && charX < width){
charX += 10;
}
}
// render beecharacter on screen
image(charImage, charX, charY);
}
There mulitple ways to tackle the problem.
Collision detection can be coarse: less accurate but faster (and simpler) or detailed (e.g. pixel level precision) but slower (and more complex).
In terms of simple collision detection two options could rectangle or circle intersections.
Rectangle intersection can be implemented manually or using Rectangle's intersects() method.
Circle intersection is trivial: if the distance(dist()) between the 1st circle's center and 2nd circle's center is smaller than the two radii then they must intersect.
here's a basic example illustrating circle intersection:
// check collision: circle
if (dist(ballX, ballY, charX, charY) < charImage.width) {
// tint red to display collision: placeholder for subtracting bee health
tint(192, 0, 0);
}else{
noTint();
}
this condition can be added before this section in draw():
// render beecharacter on screen
image(charImage, charX, charY);
The collision detection is quite rough: not pixel perfect, but hopefully a good starting point. It should tint everything red if there's a collision.
I have two other small suggestions:
reducing xspeed, yspeed to 10 or smaller values will make the game more playable. 100px/frame is too fast for people and the bee will likely collide instantly before the users even has a chance to react.
intead of a boolean beeIsAlive sort of variable that immediately, with one ball hit switches to true also might be too harsh as a game rule. Consider something like int beeHealth = 100; and gradually reducing the health with each collision will make the game more playable.
im trying to make the bouncing ball bounce on the arrays of rectangles. I've looked at various other codes but cant seem to find a solution. Would appreciate any help!!!
Basically, i want the bouncing ball to recognise that theres the rectangles there and for it to be able to jump onto the rectangles.
PVector location; // Location of shape
PVector velocity; // Velocity of shape
PVector gravity; // Gravity acts at the shape's acceleration
PVector upwardForce;
PImage bg;
int radius = 10, directionX = 1, directionY = 0;
float x=20, y=20, speed=0.5;
int xarray[] = new int[20];
int yarray[] = new int[20];
// =========================================================
void setup() {
size(380,750);
location = new PVector(100,50);
velocity = new PVector(0.0,2.1);
upwardForce = new PVector(0.0,-10.0);
gravity = new PVector(0,0.4);
bg = loadImage("bg.png");
bg.resize(1600,1600);
background(0);
for(int i =0; i< 20;i++){
xarray[i]= i*100;
yarray[i] = 750-int(random(10))*50;
}
}
int xd =0, yd=0;
void draw() {
background(0);
noStroke();
xd--;
yd++;
// display image twice:
image(bg, y, 0);
image(bg, y+bg.height, 0);
// pos
y--;
if (y<-bg.height)
y=0;
for (int i = 0;i< 20;i++){
if (xarray[i] <100 && xarray[i]+100 >100){
fill(255,0,0);
}
else {
fill(255);
}
rect(xarray[i],yarray[i],100,1200);
fill(255);
xarray[i]=xarray[i]-4;
//yarray[i]=yarray[i]+1;
if (xarray[i] + 100 < 0){
xarray[i]+=2000;
// yarray[i]-=850;
}
}
// changing Position
x=x+speed*directionX;
y=y+speed*directionY;
// check boundaries
if ((x>width-radius) || (x<radius))
{
directionX=-directionX;
}
if ((y>height-radius) || (y<radius))
{
directionY=-directionY;
}
// draw
// if(direction==1)
// 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) || (location.y < 0)){
// We're reducing velocity ever so slightly
// when it hits the bottom of the window
velocity.y = velocity.y * -0.95;
location.y = height;
}
// Display circle at location vector
stroke(255);
strokeWeight(0);
fill(255);
ellipse(location.x,location.y,30,30);
}
void keyPressed()
{
velocity.add(upwardForce);
}
The best advice we can give you is to break your problem down into smaller steps and to take those steps on one at a time.
For example, can you create a simple sketch that just shows a single hard-coded circle and a single hard-coded rectangle? Now add some code that prints a message to the console if they're colliding. You're going to have to do some research into collision detection, but here's a hint: a common technique is to treat the ball as a rectangle, so you can do rectangle-rectangle collision detection.
Get that working perfectly by itself, and then work your way forward in small steps. Can you add a second rectangle to your sketch? How about a third?
Then if you get stuck, you can post a MCVE (not your whole project, just a small example) along with a more specific question. Good luck.
Here's a few suggestions:
You're best off using a Rectangle class. That way, you don't have to store the locations in an array, and the collide function can be a method of the class. It's easier to just call the positions of the rectangles "x" and "y", but this would obviously conflict with the x and y global variables which you declared at the top of the code. Assuming that you would want to make the ball bounce if it collided, you would need to have a "ballLastx" and a "ballLasty" in order to keep track of which direction the ball came from. You would also need to store the Rectangles in an array or arrayList. It would be something like this:
PVector lastLocation;
Rectangle[] rects;
As for the rectangle class, here's how it would probably look like this:
class Rectangle {
float x, y;
Rectangle(float x_, float y_) {
x = x_;
y = y_;
}
void show() {
//Displays rectangle
if (x < 100 && x+100 > 100) fill(255,0,0);
else fill(255);
rect(x,y,100,1200);
fill(255);
x=x-4;
if (x + 100 < 0) x+=2000;
}
private boolean insideX(PVector pos) {
return (pos.x + 15 >= x && pos.x - 15 <= x+100);
}
private boolean insideY(PVector pos) {
return (pos.y + 15 >= y && pos.y - 15 <= x + 1200);
}
boolean collidedX() {
//Detects if the ball has collided along the x-axis
return ((insideX(location) && !insideX(lastLocation)) && insideY(location))
}
boolean collidedY() {
//Detects if the ball has collided along the y-axis
return ((insideY(location) && !insideY(lastLocation)) && insideX(location))
}
}
And then, in your setup function, you could declare the Rectangle classes in a for-loop:
//declare the rects array
rects = new Rectangle[20];
//declare each item of the rects array to be a Rectangle
for(int i = 0; i < rects.length; i++) {
rects[i] = new Rectangle(i*100, 750-int(random(0,10))*50;
}
In order to detect the collision and to bounce the ball, you would need to loop through all of the Rectangles and see if the ball should bounce off any of them:
boolean bouncex = false;
boolean bouncey = false;
//see if any of the rects are colliding with the ball
for(Rectangle r : rects) {
if(r.collidedX()) bouncex = true;
if(r.collidedY()) bouncey = true;
}
//if any are colliding, bounce the ball
if(bouncex) velocity.x = -velocity.x;
if(bouncey) velocity.y = -velocity.y;
Finally, don't forget to set the lastLocation PVector to the current location, just before moving the current location:
lastLocation = location.copy();
//move the ball...
Hope this was helpful!
I am trying to calculate the accumulating area for every creation of a rectangle.
I am aware of how to calculate the area for every time I create a rectangle, but I was hoping to get a running total.
Thanks!
float[] p1x = new float[0]; // hold the mouse pressed marks
float[] p1y = new float[0];
float[] p1z = new float[0];
float[] p2x = new float[0]; // hold the mouse pressed marks
float[] p2y = new float[0];
float[] p2z = new float[0];
int count = 0;
int rect_x1; // catch the start dragging point x
int rect_y1; // catch the start dragging point y
int rect_x2; // record moving mouseX
int rect_y2; // record moving mouseY
int rect_z1; // record mouseX releasing point
int rect_z2; // record mouseY releasing point.
boolean press, release, drag, drawRect;
void setup() {
smooth();
size(600, 400);
stroke(255);
fill(255, 255, 255, 10);
}
void draw() {
background(50);
Rect();
}
void Rect() {
float sizex = rect_x2 - rect_x1;
float sizey = rect_y2 - rect_y1;
for (int i = 0; i < count; i++) {
beginShape();
vertex(p1x[i], p1y[i]);
vertex(p2x[i], p1y[i]);
vertex(p2x[i], p2y[i]);
vertex(p1x[i], p2y[i]);
endShape(CLOSE);
}
if (mousePressed && mouseButton == LEFT) {
rect(rect_x1, rect_y1, sizex, sizey);
}
}
void mousePressed() {
p1x = append(p1x, mouseX);
p1y = append(p1y, mouseY);
rect_x1 = mouseX;
rect_y1 = mouseY;
mouseDragged(); // Reset vars
}
void mouseReleased() {
p2x = append(p2x, mouseX);
p2y = append(p2y, mouseY);
rect_x2 = mouseX;
rect_y2 = mouseY;
count++;
}
void mouseDragged() {
rect_x2 = mouseX;
rect_y2 = mouseY;
}
Well, you've got a couple options.
Option 1: Calculate the total every time you draw the rectangles. You've got a for loop in your Rect() function that loops through and draws them. You can just calculate the total area then.
Option 2: Keep a running total, and increment that every time you add a rectangle. You can do this in your mouseReleased() function.
I'm not sure exactly what you mean when you say you want one single accumulated number. You either have to total them up whenever you want the total, or you need to keep a running total and add to it whenever you add a new rectangle.
I need to draw a line in JPanel with mouse, clicking two points in panel. First click would be the start of the line, and second click would be the end of the line.
This is my programm
I have something like this:
private void jPanel1MouseClicked(java.awt.event.MouseEvent evt) {
// TODO add your handling code here:
Graphics g = this.jPanel1.getGraphics();
int x = evt.getX();
int y = evt.getY();
g.drawLine(x, y, x, y);
}
But it only draws pixel.
Line with coordinates
I need something like this, but just drawing it with mouse clicking.
You're drawing a line from (x, y) to (x, y) which is why you're getting just a single pixel. You need to capture the co-ordinates of the first click, and then draw the line on the second click.
private int startX = -1;
private int startY = -1;
private void jPanel1MouseClicked(java.awt.event.MouseEvent evt) {
if (startX == -1 && startY == -1) {
startX = evt.getX();
startY = evt.getY();
} else {
Graphics g = this.jPanel1.getGraphics();
g.drawLine(startX, startY,
evt.getX(), evt.getY());
// reset the start point
startX = -1;
startY = -1;
}
}
From the doc
Draws a line, using the current color, between the points (x1, y1) and (x2, y2) in this graphics context's coordinate system.
In your case x1=x2 and y1=y2, that's why your line is 1 pixel long. After each click you must record the coordinates of your click so that you can use them as the origin of the line for the next click.
In order to build a tic-tac-toe game for testing, I have following routine. But problem is that I am getting too many events for just one touch. I suspect isTouched() returns all of down, up, and move. Is there any way to just get up event?
UPDATE: Resolved the issue by employing justTouched() instead.
#Override
public void render() {
// we update the game state so things move.
updateGame();
// First we clear the screen
GL10 gl = Gdx.graphics.getGL10();
gl.glViewport(0, 0, width, height);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
// Next we update the camera and set the camera matrix
camera.update();
camera.apply(Gdx.gl10);
...
}
private void updateGame() {
// the delta time so we can do frame independant time based movement
float deltaTime = Gdx.graphics.getDeltaTime();
// Has the user touched the screen? then position the paddle
if (Gdx.input.isTouched() && !isProcess) {
// get the touch coordinates and translate them
// to the game coordinate system.
isProcess=true;
int width = Gdx.graphics.getWidth();
int height = Gdx.graphics.getHeight();
int offx=-width/2;
int offy=-height/2;
float x = Gdx.input.getX();
float y = Gdx.input.getY();
float touchX = 480 * (x
/ (float) width - 0.5f);
float touchY = 320 * (0.5f - y
/ (float) height);
for(int i=0;i<3;i++) {
for(int j=0;j<3;j++)
{
if(touchX >= offx+i*width/3 && touchX < offx+(i+1)*width/3 &&
touchY >= offy+j*height/3 && touchY < offy+(j+1)*height/3)
{
if(isCurrentO)
data[i][j]=CellStatus.O;
else
data[i][j]=CellStatus.X;
isCurrentO=!isCurrentO;
break;
}
}
}
isProcess=false;
}
}
An alternative to using justTouched is to implement the InputProcessor interface, as it has a touchUp(x,y,pointer,button) which gives you greater control over the input. There are several classes that implement this or you can have your class implement it.
You can create a board for example (with hash map) and each object in your game wants to be clickable add itself to that board if an object was touched and was in board it will catch the event. If not it will not catch the event. So easy! :)