We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › Drag and Drop for an array of images.
Page Index Toggle Pages: 1
Drag and Drop for an array of images. (Read 2267 times)
Drag and Drop for an array of images.
Oct 20th, 2009, 8:28am
 
Hi, I'm trying to create a code which will display several images and then allow the user to click on each particular iamge and then drag it across.

I have an array example for displaying several images.

Code:

Sprite[] sprites;        
void setup()
{
 size(800, 600);  // Set the size of the drawing window
 smooth();        // Which on smoothing (slower, but nicer graphics)
 sprites = new Sprite[5];
 for(int i = 0; i < sprites.length; i++)
   sprites[i] = new Sprite(loadImage(i + ".png"), (int)random(width), (int)random(height));
}
void draw()
{
 background(255, 255, 255);
 for(int i = 0; i < sprites.length; i++)
   image(sprites[i].img, sprites[i].x, sprites[i].y);
   
 if(mousePressed)
 {
   ellipse(mouseX, mouseY, 20, 20);
 }
}

void keyPressed()
{
 if(keyCode == UP)
 {
     sprites[0].y -= 5;
 }
 else if(keyCode == DOWN)
 {
     sprites[0].y += 5;
 }
 else if(keyCode == RIGHT)
 {
     sprites[0].x += 5;
 }
 else if(keyCode == LEFT)
 {
     sprites[0].x -= 5;
 }
 else
 {
   for(int i = 0; i < sprites.length; i++)
   {
     sprites[i].x = (int)random(width);
     sprites[i].y = (int)random(height);
   }
 }
}

class Sprite
{
 int x;
 int y;
 PImage img;
 Sprite(PImage img, int x, int y)
 {
   this.x = x;
   this.y = y;
   this.img = img;
 }
}



And another example for drag and droping images
Code:

float bx;
float by;
int bs = 40;
int bz = 30;
boolean bover = false;
boolean locked = false;
float bdifx = 0.0;
float bdify = 0.0;

PImage a;

void setup()
{
 size(600, 400);
 bx = width/2.0;
 by = height/2.0;
 rectMode(RADIUS);
 a = loadImage("Button.jpg");
}

void draw()
{
 background(0);
 // Test if the cursor is over the box
 if (mouseX > bx-bs && mouseX < bx+bs &&
     mouseY > by-bs && mouseY < by+bs)
 {
   bover = true;  
   if(!locked)
   {
     stroke(255);
     fill(153);
   }
 }
 else
 {
   stroke(153);
   fill(153);
   bover = false;
 }
 
 // Draw the box
 //rect(bx, by, bs, bs);
 image(a, bx, by, bs, bz);
}

void mousePressed() {
 if(bover) {
   locked = true;
   fill(255, 255, 255);
 } else {
   locked = false;
 }
 bdifx = mouseX-bx;
 bdify = mouseY-by;

}

void mouseDragged() {
 if(locked) {
   bx = mouseX-bdifx;
   by = mouseY-bdify;
 }
}

void mouseReleased() {
 locked = false;
}


How can I integrate these two files together, so that the user can click on one individual image and drag it around while the rest remain the same. Then click on another image and drag it around?

Thanks in advance.
Re: Drag and Drop for an array of images.
Reply #1 - Oct 20th, 2009, 8:55am
 
Hey, this may help:

http://processing.org/discourse/yabb2/num_1255222465_.html#1
Re: Drag and Drop for an array of images.
Reply #2 - Oct 21st, 2009, 8:22am
 
Thanks.

I tried using the 'break' method, but there was a error saying that it needs to be in for loop. How can I integrate that the orginal sprites code?
Re: Drag and Drop for an array of images.
Reply #3 - Oct 21st, 2009, 10:05am
 
No need to use break; at all if it's not in a loop -- all it does is say "stop checking the rest of these objects; a hit has been found."  That was so that if several areas overlapped, only the top one would be selected and dragged...('break' meaning: exit this loop)
Re: Drag and Drop for an array of images.
Reply #4 - Oct 24th, 2009, 9:40am
 
Sorry to bother again but I have rewritten the code.

Code:

Sprite[] sprites;

int bx=40;
int by=40;

int Imagex=40;
int Imagey=40;

int bs = 60;
int bz = 60;
boolean bover = false;
boolean locked = false;
int bdifx = 0;
int bdify = 0;


void setup()
{
size(800, 600); // Set the size of the drawing window
smooth(); // Which on smoothing (slower, but nicer graphics)
sprites = new Sprite[5];
for(int i = 0; i < sprites.length; i++)
{
bx=40;
by=80;
//Imagex+=40;
//Imagey+=80;
sprites[i] = new Sprite(loadImage(i + ".png"), (int)random(width), (int)random(height));
//sprites[i] = new Sprite(loadImage(i + ".png"),bx, by);
// sprites[i] = new Sprite(loadImage(i + ".png"),Imagex, Imagey);
}
}
void draw()
{
background(255, 255, 255);
// for(int i = 0; i < sprites.length; i++)
// image(sprites[i].img, sprites[i].x, sprites[i].y);

for(int p=0; p<sprites.length;p++)
image(sprites[p].img, bx, by);

if (mouseX > bx-bs && mouseX < bx+bs &&
mouseY > by-bs && mouseY < by+bs)
{

bover = true;
if(!locked)
{
}
}
else
{

bover = false;
}

}



void mousePressed()
{
//sprites[0].y-=mouseY-bx;
// sprites[0].x-=mouseX-by;
if(bover)
{

locked = true;
}
else
{
locked = false;
}

bdifx = mouseX-bx;
bdify = mouseY-by;
}

void mouseDragged()
{
for(int i = sprites.length-1; i>=0; i--)
if(locked)
{

bx = mouseX-bdifx;
by = mouseY-bdify;
}
}


class Sprite
{
int x;
int y;
PImage img;
Sprite(PImage img, int x, int y)
{
this.x = x;
this.y = y;
this.img = img;
}
}


So we have an array of images displayed in one section which is sandwiched together on top of one another.

How do I go about setting it identify when only one image is selected, rather than just dragging the whole images together on screen?
Re: Drag and Drop for an array of images.
Reply #5 - Oct 24th, 2009, 10:19am
 
You might be interested by the code  have in the Handles sketch.
The objects (sprites in your case) handle themselves their click detection, moving and dragged state.
The sketch also maintains a global state indicating if an object is currently dragged.
Re: Drag and Drop for an array of images.
Reply #6 - Oct 24th, 2009, 11:39am
 
Hi

Thanks again for the help. I just edited the code using Pilho's example.

Code:

Sprite[] sprites;      

int bx=40;
int by=40;

int s_size=10;
boolean spritesDragging;

void setup()
{
 size(800, 600);
 sprites = new Sprite[5];
 for(int i = 0; i < sprites.length; i++)
 {
   sprites[i] = new Sprite(loadImage(i + ".png"),s_size,(int)random(bx), (int)random(by));
 }
}


void draw()
{
 
   boolean bDragging = false;
   
   
   for (int i = 0; i < sprites.length; i++)
   {
// Check if the user tries to drag it
sprites[i].Update(spritesDragging);
// Ah, this one is indeed dragged!
if (sprites[i].IsDragged())
{
// We will remember a dragging is being done
bDragging = true;
// And move it to mouse position
sprites[i].Move();
}
// In all case, we redraw the handle
sprites[i].Draw();
}

}




class Sprite
{
 float x;
 float y;
 PImage img;
 float SpriteSize;
 int i;
 private boolean m_bIsHovered, m_bDragged;
 private float m_clickDX, m_clickDY;
 

 Sprite(PImage img, int SpriteSize,float x,float y)
 {
   this.x = x;
   this.y = y;
   this.img = img;
   
   this.SpriteSize=SpriteSize;
   
 }
 
 
 void Update(boolean bAlreadyDragging)
 {
     // Check if mouse is over the handle
m_bIsHovered = dist(mouseX, mouseY, x, y) <= SpriteSize ;

if (!bAlreadyDragging && mousePressed && mouseButton == LEFT && m_bIsHovered)
{
        // We record the state
m_bDragged = true;
       
m_clickDX = mouseX - x;
m_clickDY = mouseY - y;
}
     // If mouse isn't pressed
if (!mousePressed)
{
        // Any possible dragging is stopped
m_bDragged = false;
}
  }
 
 

boolean IsDragged()
{
return m_bDragged;
}


   void Move()
   {
if (m_bDragged)
{
x = mouseX - m_clickDX;
y = mouseY - m_clickDY;
}
   }
   
   void Draw()
   {
     image(sprites[i].img, x, y);
   }
   
 
 
}


But it's still only displaying one image and it's now creating a trail of images when the users tries to drag it across.
Re: Drag and Drop for an array of images.
Reply #7 - Oct 25th, 2009, 1:48am
 
The trail of image is because you accidentally removed the background() call in your reworking of the sketch.
The other problem of display is probably because the Draw() call is incorrect, each sprite should display itself (its 'img'), not sprites[i] (a class should, ideally, not rely on global variables, except constants and PApplet stuff).
Re: Drag and Drop for an array of images.
Reply #8 - Oct 25th, 2009, 11:59am
 
Hi

Thanks again, that did help a lot. Just another problem we're having now is that when the user clicks and drags a sprite across the screen, if they drag over another sprite then two are dragged along together and are sandwiched into the same position.

Code:

Sprite[] sprites;      

int bx=500;
int by=600;

int s_size=20;
boolean spritesDragging;

void setup()
{
 size(800, 600);
 sprites = new Sprite[5];
 for(int i = 0; i < sprites.length; i++)
 {
   sprites[i] = new Sprite(loadImage(i + ".png"),s_size,random(bx), random(by));
 }
}


void draw()
{
 
   background(#AADDFF);
   boolean bDragging = false;
   
   
   for (int i = 0; i < sprites.length; i++)
   {
// Check if the user tries to drag it
sprites[i].Update(spritesDragging);
// Ah, this one is indeed dragged!
if (sprites[i].IsDragged())
{
// We will remember a dragging is being done
bDragging = true;
// And move it to mouse position
sprites[i].Move();
}
// In all case, we redraw the handle
sprites[i].Draw();
}

}




class Sprite
{
 float x;
 float y;
 PImage img;
 float SpriteSize;
 int i;
 private boolean m_bIsHovered, m_bDragged;
 private float m_clickDX, m_clickDY;
 

 Sprite(PImage img, int SpriteSize,float x,float y)
 {
   this.x = x;
   this.y = y;
   this.img = img;
   
   this.SpriteSize=SpriteSize;
   
 }
 
 
 void Update(boolean bAlreadyDragging)
 {
     // Check if mouse is over the handle
m_bIsHovered = dist(mouseX, mouseY, x, y) <= SpriteSize ;

if (!bAlreadyDragging && mousePressed && mouseButton == LEFT && m_bIsHovered)
{
        // We record the state
m_bDragged = true;
       
m_clickDX = mouseX - x;
m_clickDY = mouseY - y;
}
     // If mouse isn't pressed
if (!mousePressed)
{
        // Any possible dragging is stopped
m_bDragged = false;
}
  }
 
 

boolean IsDragged()
{
return m_bDragged;
}


   void Move()
   {
if (m_bDragged)
{
x = mouseX - m_clickDX;
y = mouseY - m_clickDY;
}
   }
   
   void Draw()
   {
     image(img, x, y);
   }
   
 
 
}

Re: Drag and Drop for an array of images.
Reply #9 - Oct 25th, 2009, 11:12pm
 
If I recall correctly, that's the purpose of the global variable spritesDragging. It is tested: if true, it doesn't try to drag another sprite. But you never set it, so it is always false. You should set it as soon as user starts to drag one sprite (and reset it when it is released).
Re: Drag and Drop for an array of images.
Reply #10 - Oct 28th, 2009, 5:41am
 
Sorry for the late reply but my connection for done for a while, but that works perfectly thanks.
Re: Drag and Drop for an array of images.
Reply #11 - Oct 28th, 2009, 5:45am
 
Just one problem is that for using a sprite images, we can only click and drag the image by clicking on the top  left corner. How can we expand it so that we click on the whole image without dragging other images?

Code:

Sprite[] sprites;      

int bx=500;
int by=600;

int s_size=30;
boolean spritesDragging;

PImage b;

void setup()
{
 size(798, 760);
 sprites = new Sprite[7];
 for(int i = 0; i < sprites.length; i++)
 {
   sprites[i] = new Sprite(loadImage(i + ".png"),s_size,random(bx), random(by));
 }
}


void draw()
{
   
   b = loadImage("EiffelTower.jpg");
   background(b);
   boolean bDragging = false;
   
   
   for (int i = 0; i < sprites.length; i++)
   {
// Check if the user tries to drag it
sprites[i].Update(spritesDragging);
// Ah, this one is indeed dragged!
if (sprites[i].IsDragged())
{
// We will remember a dragging is being done
bDragging = true;
// And move it to mouse position
sprites[i].Move();
}
// In all case, we redraw the sprite
sprites[i].Draw();
               }
    spritesDragging = bDragging;
}




class Sprite
{
 float x;
 float y;
 PImage img;
 float SpriteSize;
 int i;
 private boolean m_bIsHovered, m_bDragged;
 private float m_clickDX, m_clickDY;
 

 Sprite(PImage img, int SpriteSize,float x,float y)
 {
   this.x = x;
   this.y = y;
   this.img = img;
   
   this.SpriteSize=SpriteSize;
   
 }
 
 
 void Update(boolean bAlreadyDragging)
 {
     // Check if mouse is over the handle
m_bIsHovered = dist(mouseX, mouseY, x, y) <= SpriteSize ;

if (!bAlreadyDragging && mousePressed && mouseButton == LEFT && m_bIsHovered)
{
        // We record the state
m_bDragged = true;
       
m_clickDX = mouseX - x;
m_clickDY = mouseY - y;
}
     // If mouse isn't pressed
if (!mousePressed)
{
        // Any possible dragging is stopped
m_bDragged = false;
}
  }
 
 

boolean IsDragged()
{
return m_bDragged;
}


   void Move()
   {
if (m_bDragged)
{
x = mouseX - m_clickDX;
y = mouseY - m_clickDY;
}
   }
   
   void Draw()
   {
     image(img, x, y);
   }
   
 
 
}


Thanks again in advance.
Re: Drag and Drop for an array of images.
Reply #12 - Oct 28th, 2009, 6:26am
 
You use
m_bIsHovered = dist(mouseX, mouseY, x, y) <= SpriteSize;
which works only for circles centered on x, y...

For rectangular shapes (or images) where x, y is the top-left corner, it should be something like:
m_bIsHovered = mouseX > x && mouseX < x + SpriteSize && mouseY > y && mouseY < y + SpriteSize;
Page Index Toggle Pages: 1