Thread Help


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 6 of 6

Thread: Thread Help

  1. #1
    Join Date
    Sep 2004
    Posts
    223

    Thread Help

    Ok here is a pretty strait forward question asked in a complicated way, I have an application that will create a new thread every time the mouse is clicked, obviously the threads created need to act independantly of each other, but for some reason when you click more than once, the faster the threads go.

    The application i am making is just a simple little game, that is eventually going to be a scrolling shooter game, when the user clicks, a new object called laser is created, and then a thread for that laser is created which will move the laser up the screen by sleeping for 10milli seconds, then changing the y value of the laser, then calling repaint. When you click more than once, the lasers speed up and i think its because there are multiple threads with the same name and java is getting confused with the timings, here is the code for the main class in the game:

    Code:
    import java.util.*;
    import java.io.*;
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import sun.audio.*;
    
    
    
    public class MouseDisplay extends JPanel implements MouseListener, MouseMotionListener, Runnable{
    
    	private JPanel scorePanel = new JPanel();
        private Spaceship spaceship = new Spaceship(Toolkit.getDefaultToolkit().getImage("spaceship.JPG"), 0,0);
        private int x,y;
        private Laser laser;
        private Vector laserVector = new Vector();
        private Thread laserThread;
        
        
        /* Mouse listener methods  */
        
        public void mouseClicked(MouseEvent event) {}    
        public void mouseEntered(MouseEvent event) {}
        public void mouseExited(MouseEvent event) {}
        public void mouseReleased(MouseEvent event) {}    
        public void mousePressed(MouseEvent event) {
        	x = event.getX();
        	y = event.getY();
        	
        	Image laserImage = Toolkit.getDefaultToolkit().getImage("laser.JPG");
        	laser = new Laser(laserImage,x+12,y);
        	laserVector.add(laser);
        	createThread();
        	    	
        	
        }
        public void mouseMoved(MouseEvent event) {}
        public void mouseDragged(MouseEvent event) {}
        	
    	public MouseDisplay(){
    		setBackground(Color.white);	
    		addMouseListener(this);	
    		addMouseMotionListener(this);
    				
    		//set spaceship cursor
        	Image cursorImage = Toolkit.getDefaultToolkit().getImage("spaceship.JPG");
    		Cursor spaceshipCursor = Toolkit.getDefaultToolkit().createCustomCursor(cursorImage, new Point( 0, 0), "" );
    		setCursor( spaceshipCursor );
    		
    	}
    	
    	public void run(){
    		
    		while(true){
    		for(int c=0;c<laserVector.size();c++){
    			if(laserVector.elementAt(c) != null){
    				Laser tempYLaser = (Laser) laserVector.elementAt(c);
    				int tempy = tempYLaser.getY();
    				tempYLaser.setY(--tempy);
    			}
    		}
    		try {
    			laserThread.sleep(10);
    		} catch (InterruptedException e) {
    			System.out.println("Error running thread: " + e);
    		}
    		repaint();
    		}
    	}
    
    	public void paint(Graphics g){
        	super.paint(g);
        	for(int k=0;k<laserVector.size();k++){
        	//System.out.println(laserVector.size());
        		if(laserVector.elementAt(k) != null){
    	    		Laser tempLaser = (Laser) laserVector.elementAt(k);
    	    		Image tempImage = tempLaser.getImage();
    	    		if(tempImage != null){
    	    			g.drawImage(tempImage, tempLaser.getX(), tempLaser.getY(), this);
    	    		}else{
    	    			System.out.println("error drawing picture");
    	    		}
        		}
        	}
        }
        
    	public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) {
    		repaint();
    		return true;
    	}
    	public void createThread(){
                laserThread = new Thread(this);
                laserThread.start();
        }
    
    }
    A kram a day keeps the doctor......guessing

  2. #2
    Join Date
    Sep 2004
    Posts
    223
    ok, to extend on this further, i guess another question i could ask for more of an overview of this problem, would be. How can i make it so that each time the user clicks the mouse, a new thread with a different name is created?
    A kram a day keeps the doctor......guessing

  3. #3
    Join Date
    Feb 2004
    Posts
    541
    The naming of the variables have nothing to do with your problem. The names are just pointers, like a bit of string linked to the object. The problem is nothing to do with the names of the threads, but more to do with what you're putting in them.

    What you have is one uber object that is listening to all the mouse events, and also running all the laser threads. When the user presses a mouse button, this object creates a new laser object and stores it in a vector. Then a new thread is created, and this uber object is added to it. The run method runs, and ALL the laser objects in the vector are updated.

    The problem arrises when the mouse is clicked multiple times. The thread is created with the SAME uber object added to it. Imagine you have 10 threads created. They all have exactly the same uber object in it, which means each thread has access to exactly the same laser objects. There is no problem with the timing, each thread 'fires' every 10 milliseconds. But if you have 10 threads all updating the same lasers, every 10 milliseconds each laser is being updated 10 times!!! That is why they appear to have speeded up.

    Instead of adding the entire JPanel to a new thread, instead you should add each individual laser to a new thread and it should be updating itself every 10 seconds. The JPanel should just repaint itself ever XX seconds, and shouldn't be bothered about updating any lasers.

  4. #4
    Join Date
    Sep 2004
    Posts
    223
    Thanks matey!
    Me and my room mate last night were thinking it was something to do with the way i was starting the theads. If i read your post correctly, then the problem lies here:

    Code:
    public void createThread(){
                laserThread = new Thread(this);
                laserThread.start();
    }
    and the this is the main problem, the thing is you must pass a thread an object with implements runnable, and if i pass it a laser object then ill have to make the laser class implement the runnable interface.
    Im just a little confused as to what class should be doing the painting and what to do in the laser's run method etc...
    A kram a day keeps the doctor......guessing

  5. #5
    Join Date
    Feb 2004
    Posts
    541
    The reason the threads are a problem is because you pass the same object to it each time, which means there are multiples of all the laser objects. This means they get updated more than once (once by each thread), making them appear to go faster.

    You either need to make each laser a Runnable object and let them update themselves, or you need to have once thread that does all the updating. Either way, that would make sure that each laser only got updated once. Then you have the JPanel thread redraw itself once every x seconds, based on the positions of the lasers.

  6. #6
    Join Date
    Sep 2004
    Posts
    223
    oh yeah, derr...

    man thanks for the help, ill let you know how it goes tonight...
    A kram a day keeps the doctor......guessing

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center