Cant get my balls to move - Page 2


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Page 2 of 3 FirstFirst 123 LastLast
Results 16 to 30 of 43

Thread: Cant get my balls to move

  1. #16
    Join Date
    Apr 2005
    Posts
    20
    I see what you mean makes more sense loading the image once than every time an instance of Frog is created. One thing still elludes me, If I am invoking the Frog class with these new arguments "Image FrogIm and theFrogsPlace" what values are being passed, If I remember correctly arguments do not need to have the same name when invoking other methods as long as they are of the same type, so that would suggest declaring "Image frogpic" then calling Frog like so but I tried it and it didn't like the fact that it was a non static variable being referenced from a static. and as for theFrogsPlace I am somewhat flumoxed by that one

    this is what i did to try and call Frog before realising i didn't quite know what to do about this panel thingy.

    Code:
    Image FrogIm;
    Panel frogsplace= ??;
     public  static Frog [] Frogs = {
          new Frog(15, 110, frogpic,  ??)
                                                ^ Presumably I would just put "frogsplace" in here
    Last edited by pwnedjoo; 04-19-2005 at 07:17 PM.

  2. #17
    Join Date
    Nov 2004
    Location
    Norway
    Posts
    1,560
    theFrogsPlace: this is the Panel/Applet that you use for drawing the frogs
    into. As for the static, you are right about that. If we were to declare a
    static Frog array like in the rollThemOut Applet, and the Frog constructor
    required a Panel as one of the parameters, then this would require that
    that Panel also had to be static (and declared prior to the Frog array).

    There is absolutely no connection between the names chosen for a
    method's parameters and the names used by the caller. I'll get a little
    technical here; When a method is called the caller pushes the parameters'
    pointers (or values if it is primitives) on to a 'calling stack'. This works the
    same way as a pile of plates in a restaurant's plate-storage box (...), -
    last in-first out. The invoked method then pops these values off
    the calling stack, one by one, and names them according to the sequence
    and names of its own parameter list.

    Anyway, lets get rid of that static mess and do it the dynamic way. To
    illustrate what I mean I am including a de-staticed (hehe) version of your rollerball game. It includes an additional image that is added to each ball.
    Check it out, the only thing that is static here is the set of parameters.

    (hope I haven't been too complicated here...)

    Code:
    import java.awt.event.*;
    import java.awt.*;
    import javax.swing.*;
    import java.util.*;
    
    /**
     * A ball w. a diameter, a color and a location
     */
    class Ball  {
      private Rectangle rect=null;
      private Color color=null;
      private Image picture=null;
      private Panel panel=null;
    
      public Ball (int x, int y, int diameter,
                   Color color, Image anImage,
                   Panel aPanel) {
    
        rect=new Rectangle(x,y,diameter, diameter);
        this.color=color;
        picture=anImage;
        panel=aPanel;
      }
      public void draw(Graphics g) {
          Color c = g.getColor();
          g.setColor(color);
          g.fillOval(rect.x, rect.y, rect.width, rect.height);
          g.drawImage(picture,rect.x+10, rect.y+10, panel);
          g.setColor(c);
      }
      public boolean isHit(Point p) {
        return rect.contains(p);
      }
      public Rectangle getRectangle() {
        return rect;
      }
      public void moveBall(Point p) {
    
          rect.x += p.x;
          /**
           * include next statement to allow vertical dragging, possibly
           * only allowed under the arc...some positional test perhaps ?
           */
          //rect.y += p.y;
      }
    }
    /**
     * Your applet as a panel
     */
    class RollThemOut extends Panel
        implements MouseListener, MouseMotionListener, Comparator {
    
      /**
       * I prefer uppercased names to have a clear visual difference
       * between static and dynamic variables.
       *
       * The first one here is a 2D array, the inner brackets delimits the
       * rows of this array.
       * BALL_PARAMS.length = number of rows (balls)
       * BALL_PARAMS[0].length = number of columns
       *
       * This setup requires that the number of rows in the 2D array equals
       * the number of rows in the color array....
       *
       */
      public  static int [][] BALL_PARAMS = { // numeric parameter array
          { 15, 110, 45  },
          { 60, 110, 45  },
          { 105, 110, 45 },
          { 150, 110, 45 },
          { 195, 106, 55 },
          { 250, 106, 55 },
          { 305, 106, 55 },
          { 360, 106, 55 }
      };
      public static Color [] BALL_COLORS = { // color parameter array
          Color.black,
          Color.black,
          Color.black,
          Color.black,
          Color.white,
          Color.white,
          Color.white,
          Color.white
      };
    
    
      public static ArrayList bList=new ArrayList();
      public Ball [] balls=null; // a non static array of balls
      public Image img=null; // a little image to add on to each ball
      private Point lastPos; // last dragging position
      private Point moveOffset=new Point(); // dragging distance
      private int selectedIndex=-1; // index of currently selected ball
    
      public void init() {
        img=getAnImage("c:\\tmp\\miniSjalle.jpg");
        balls=makeBalls(BALL_PARAMS, BALL_COLORS, img); // zap !
        this.addMouseMotionListener(this);
        this.addMouseListener(this);
        selectedIndex = -1;
    
      }
      /**
       * Get an image from file
       * @param filePath
       */
      private Image getAnImage(String filePath) {
        ImageIcon imgIcon=new ImageIcon(filePath);
        MediaTracker mt=new MediaTracker(this);
        mt.addImage(imgIcon.getImage(),0);
        try {
          mt.waitForAll();
        }
        catch (InterruptedException ex) {
          System.out.println("Image load failed");
          ex.printStackTrace();
          return null;
        }
        return imgIcon.getImage();
      }
      /**
       * Make a set of balls
       * Note: Im passing the Applets pointer to the Ball constructor.
       * This constructor requires a Panel as the last parameter, but
       * the Applet class is a descendant of the Panel class so
       * that works just fine.
       * @param ballParameters
       * @param ballColors
       */
      private Ball [] makeBalls(int [][] numericParameters,
                                Color [] ballColors,
                                Image bzz) {
    
        Ball [] newBalls=new Ball[numericParameters.length];
    
        for (int i=0; i<newBalls.length; i++) {
    
          newBalls[i]=new Ball(numericParameters[i][0],
                               numericParameters[i][1],
                               numericParameters[i][2],
                               ballColors[i],
                               bzz, this);
        }
        return newBalls;
      }
      public void paint(Graphics g) {
        update (g);
      }
      public void update(Graphics g) {
        Color c = g.getColor();
        g.setColor(Color.blue);
        g.fillRect(0, 0, this.getSize().width, this.getSize().height);
        drawBox(g);
        drawBalls(g);
        g.setColor(c);
      }
    
      private void drawBalls(Graphics g) {
        for (int i = 0; i < balls.length; i++) {
          balls[i].draw(g);
        }
      }
      public void drawBox(Graphics g) {
        g.setColor(Color.black);
        g.fillRect(10, 100, 685, 68);
        g.fillOval(410, 55, 65, 65);
        g.fillRect(410, 85, 65, 25);
        g.fillRect(690, 107, 20, 55);
    
        g.setColor(Color.darkGray);
        g.fillRect(15, 105, 675, 58);
        g.fillOval(415, 60, 55, 55);
        g.fillRect(415, 90, 55, 20);
        g.fillRect(690, 112, 30, 45);
      }
    
      public void mouseDragged(MouseEvent e) {
        if (selectedIndex == -1) {
          return;
        }
        moveOffset.x = e.getPoint().x - lastPos.x;
        moveOffset.y = e.getPoint().y - lastPos.y;
    
        balls[selectedIndex].moveBall(moveOffset);
        repaint();
    
        lastPos=e.getPoint();
      }
      /**
       * I dont know all the rules here but I've added a sort of the
       * balls array to simplify checking of move-space
       * @param e
       */
      public void mouseReleased(MouseEvent e) {
        if (selectedIndex >= 0) { // dragging may have occurred
          sortBalls();
        }
        selectedIndex = -1;
      }
      /**
       * Sort the ball array on x-position
       */
      private void sortBalls() {
        bList.clear();
        for (int i = 0; i < balls.length; i++) {
          bList.add(balls[i]);
        }
        Collections.sort(bList, this);
        for (int i = 0; i < bList.size(); i++) {
          balls[i] = (Ball) bList.get(i);
        }
      }
      public int compare(Object o1, Object o2) {
        Ball b1 = (Ball) o1;
        Ball b2 = (Ball) o2;
        return b1.getRectangle().x - b2.getRectangle().x;
      }
    
      public boolean equals(Object obj) {
        return false;
      }
    
      /**
       * Check for a hit
       * @param e
       */
      public void mousePressed(MouseEvent e) {
    
        lastPos = e.getPoint();
        selectedIndex = -1;
        for (int i=0; i<balls.length; i++) {
          if (balls[i].isHit(lastPos)) {
            selectedIndex = i;
            break;
          }
        }
        System.out.println("Select:"+selectedIndex+"\r\n");
      }
    
      public void mouseClicked(MouseEvent e) {}
      public void mouseMoved(MouseEvent e) {}
      public void mouseEntered(MouseEvent e) {}
      public void mouseExited(MouseEvent e) {}
    
    }
    public class RollDriver {
      /**
       * ************* MAIN ***************************
       * Sets up a jframe and a textarea for running the applet code
       * @param args
       */
      public static void main (String [] args) {
        Frame f=new Frame();
        f.setLayout(new GridLayout());
        RollThemOut p=new RollThemOut();
        p.init();
        f.add(p);
        f.setSize(780, 600);
        f.addWindowListener(new WindowAdapter() {
          public void windowClosing(WindowEvent e) {
            System.exit(0);
          }
        });
        f.validate();
        f.setVisible(true);
    
    
      }
    }

  3. #18
    Join Date
    Apr 2005
    Posts
    20
    okay I'm back on the balls puzzle, I have set about controlling movement within the chute and the arch by seting two new rects r1 and r2 which overlap like so:



    I have set theseup in init() and have also put the following code in alongside it
    Code:
    if (insideR1)
          {
    
    
               //not sure what goes in here	
    
          }
    
          if (insideR2)
          {
    	
             
             //not sure what goes in here
    
          }

    and then also included the method

    Code:
      public boolean mouseMove(Event e,int x,int y)
       {
          //submit the mouse coordinates to our instance variables
          this.x=x;
          this.y=y;
    
          //"inside" is a method of the Rectangle class
          if(r1.inside(x,y))
             insideR1=true;
          else
             insideR1=false;
    
          if(r2.inside(x,y))
             insideR2=true;
          else
             insideR2=false;
    
          repaint();
          return true;
       }
    I figure I can say something along the lines of

    if (inside r1)
    {
    rect.x += p.x;
    }
    else if (inside r2)
    {
    rect.y+= p.y;
    }

    The problem I have now is like i said above I'm not sure what to put in the if statement in init() to pass on to the class to control movement,
    ie the :

    Code:
    public void moveBall(Point p) {
    	
      		
       	rect.y += p.x;
      	rect.x += p.x;
    		
      }


    also I now get an error like this

    Note: RollThemOut.java uses or overrides a deprecated API.
    Note: Recompile with -deprecation for details.

    Now as you will have gathered, I am no expert but that seems a bit on the serious side even to me
    Last edited by pwnedjoo; 04-20-2005 at 05:43 PM.

  4. #19
    Join Date
    Nov 2004
    Location
    Norway
    Posts
    1,560

    Well, we will take it from the top

    In the code i posted I have commented away the logics for allowing the player
    to move the ball vertically.
    What you have to do is to check the current moving-ball's (rectangle's) position
    relative to your chute rectangle (inside chute?,at top of shute?) and adjust
    the moving-ball rectangle's coordinate manipulation accordingly.

    Your mouseMove method can never respond to a mouse move.

    What you need is to let theForgsPlace implement the MouseListener
    interface, i.e. implement a handfull of methods, but you only need to
    give one of them a code body:

    public void mouseReleased(MouseEvent e)]

    Read up un that, and I'll get back to you.
    Last edited by sjalle; 04-20-2005 at 08:25 PM.

  5. #20
    Join Date
    Apr 2005
    Posts
    20
    just one more quick question about one of the methods


    Code:
    public int compare(Object o1, Object o2) {
        Ball b1 = (Ball) o1;
        Ball b2 = (Ball) o2;
        return b1.getRectangle().x - b2.getRectangle().x;
      }

    have been right through code putting system.outs every where to see what each bit does and the only thing I cant figure out is what is this doing

  6. #21
    Join Date
    Nov 2004
    Location
    Norway
    Posts
    1,560
    That is one of the two methods that have to be implemented by a class that is
    going to be a Comparator. As you cas see I use the Collections' static
    method sort(List list, Comparator comparator) to sort the list. The comparator used
    as parameter is the applet (that implements Comparator). This means that the sort
    job done by Collections.sort uses the Comparator's implemetation of the compare method
    every time this sort algorithm is going to determine the sequence of two elements
    in the list. So, in other words; he two Objects passed to this method are two
    elements from the list. If the method returns zero they are equal, if it returns a positive
    number the first one has the highest rank, and vice versa. E.g using this means that
    you don't have to code the sort algorithm, you just have to code the method (rule)
    that determines what element of two elements in the sortlist comes first.

    In this case it is the x-position value of the balls.

  7. #22
    Join Date
    Apr 2005
    Posts
    20

    Woohoo! It works

    Finally completed my project, just want to say a big thanks to Sjalle for all his advise and help, I now have a fully functioning game and while it is completeley different to the one I started out on the methods I picked up here were invaluable to solving my problem, so thankyou.

    One thing still remains though......How do i get rid of the screen flicker when I move objects around, have tried a couple of techniques, none of which work, if anyone has any answers to this I would love to hear em as it would put the finishing touch to my game.

  8. #23
    Join Date
    Nov 2004
    Location
    Norway
    Posts
    1,560

    Heres is a basic setup for double buffering an image grid

    Its a piece of some other code I posted in this forum

    Code:
    import java.util.*;
    import java.awt.*;
    import java.applet.*;
    import java.awt.image.*;
    import java.awt.geom.*;
    import javax.swing.*;
    
    
    /****************************************************
     * Class for drawing a 2d array of images on
     * screen as a grid.
     * Atoformatting: Images a are not required to be of same size
     * @author sjalle
     * @version 0.9
     *
     */
    
    class ImageGridPanel
        extends JPanel {
      // grid h-v space
      public final static int VSPACE = 4;
      public final static int HSPACE = 4;
      public static Font imageGridFont = new Font("SansSerif", Font.BOLD, 12);
      private Graphics memG = null;
      private BufferedImage memImg = null;
      private ImageCell[][] imageGrid = null;
    
      /**
       * Constructors
       */
      public ImageGridPanel() {}
    
      public ImageGridPanel(ImageCell[][] imageGrid) {
        this.imageGrid = imageGrid;
      }
    
      /**
       * invoked on startup (and resize ?)
       */
      public void initializePanel() {
        Dimension dim = getSize();
        memImg = new BufferedImage(dim.width, dim.height,
                                   BufferedImage.TYPE_INT_RGB);
        MediaTracker mt = new MediaTracker(this);
        mt.addImage(memImg, 0);
        try {
          mt.waitForAll();
        }
        catch (InterruptedException ex) {
          ex.printStackTrace();
          return;
        }
    
        memG = memImg.getGraphics();
        memG.setFont(imageGridFont);
    
        repaint();
      }
    
      /**
       * Switches images
       * @param imageGrid
       */
      public void setImageGrid(ImageCell[][] imageGrid) {
        this.imageGrid = imageGrid;
        repaint();
      }
    
      /**
       * Paint the imageGrid
       * @param g
       */
      public void paint(Graphics g) {
        update(g);
      }
    
      public void update(Graphics g) {
        if (memG != null) {
          Color oldColor = g.getColor();
          paintImageGrid(memG);
          g.setColor(Color.black);
          g.drawImage(memImg, 0, 0, this.getWidth(), this.getHeight(), this);
          g.setColor(oldColor);
        }
        else {
          drawMessage(g, "Memory grapics not ready yet");
        }
    
      }
    
      /**
       * Message on screen
       * @param g
       * @param msg
       */
      private void drawMessage(Graphics g, String msg) {
        g.drawString(msg, 10, 20);
      }
    
      /**
       * Draw the image grid if available
       * @param g
       */
      private void paintImageGrid(Graphics g) {
    
        if (imageGrid == null) {
          drawMessage(g, "No ImageGrid to display");
          return;
        }
    
        Point p = new Point(0, 0);
        int maxHeight = 0;
        for (int row = 0; row < imageGrid.length; row++) {
    
          p.x = HSPACE;
          p.y += maxHeight + VSPACE;
    
          for (int col = 0; col < imageGrid[row].length; col++) {
    
            imageGrid[row][col].draw(g, p, this);
    
            maxHeight = (maxHeight > imageGrid[row][col].getSize().height) ?
                maxHeight :
                imageGrid[row][col].getSize().height;
    
            p.x += imageGrid[row][col].getSize().width + HSPACE;
          }
        }
      }
    }
    /**************************************************
     * A cell in an ImageGridPanel
     * @author sjalle
     * @version 0.9
     */
    class ImageCell {
      private Image img;
      private Dimension dim;
      /**
       * Forced size constructor
       * @param img
       * @param dim
       */
      public ImageCell(Image img, Dimension dim) {
        this.img = img;
        this.dim = dim;
      }
    
      /**
       * Actual size constructor
       * @param img
       */
      public ImageCell(Image img) {
        this.img = img;
      }
      /**
       * Will create the dim object if actual size constructor was used
       * @param g
       * @param p
       * @param pan
       */
      public void draw(Graphics g, Point p, ImageGridPanel pan) {
        if (dim == null) {
          dim = new Dimension(img.getWidth(pan), img.getHeight(pan));
        }
        g.drawImage(img, p.x, p.y, dim.width, dim.height, pan);
      }
      /**
       * Will return null if actual size constructor was used and
       * draw() has not yet been invoked. This is programmers error, no
       * exception handling here.
       * @return
       */
      public Dimension getSize() {
        return dim;
      }
    
      public Image getImage() {
        return img;
      }
    
      public void setImage(Image img) {
        this.img = img;
      }
    
      public void setSize(Dimension dim) {
        this.dim = dim;
      }
    
    }
    Last edited by sjalle; 04-28-2005 at 10:03 AM.

  9. #24
    Join Date
    Apr 2005
    Posts
    20
    I cant see anything,

  10. #25
    Join Date
    Nov 2004
    Location
    Norway
    Posts
    1,560
    now you can.. (need a cup of cofee...)

  11. #26
    Join Date
    Apr 2005
    Posts
    20
    aaah, now I see,

    cheers


  12. #27
    Join Date
    Apr 2005
    Posts
    20
    okay, I am going to shoot myself in the head, this is not going well at all,

    I am trying to convert my panel back to an applet and hav eit compiling nicely but when I open it in a browser it says

    Code:
    java.security.AccessControlException: access denied (java.io.FilePermission BlkFrog.gif read)
    	at java.security.AccessControlContext.checkPermission(Unknown Source)
    	at java.security.AccessController.checkPermission(Unknown Source)
    	at java.lang.SecurityManager.checkPermission(Unknown Source)
    	at java.lang.SecurityManager.checkRead(Unknown Source)
    	at sun.awt.SunToolkit.getImageFromHash(Unknown Source)
    	at sun.awt.SunToolkit.getImage(Unknown Source)
    	at javax.swing.ImageIcon.<init>(Unknown Source)
    	at javax.swing.ImageIcon.<init>(Unknown Source)
    	at Frogs.getAnImage(Frogs.java:93)
    	at Frogs.<init>(Frogs.java:11)
    	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    	at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    	at java.lang.reflect.Constructor.newInstance(Unknown Source)
    	at java.lang.Class.newInstance0(Unknown Source)
    	at java.lang.Class.newInstance(Unknown Source)
    	at sun.applet.AppletPanel.createApplet(Unknown Source)
    	at sun.plugin.AppletViewer.createApplet(Unknown Source)
    	at sun.applet.AppletPanel.runLoader(Unknown Source)
    	at sun.applet.AppletPanel.run(Unknown Source)
    	at java.lang.Thread.run(Unknown Source)
    I am asuming it doesn't like the getAnImage method but can't see why

  13. #28
    Join Date
    Apr 2005
    Posts
    20
    Wait a mo, I think I may have tracked down the problem, ImageIcon comes in the swing pakcage by the looks of it, now <clutching at straws here> would swing be picked up in a web browser/applet type situation or am I well off the mark...

    right have killed off swing, now using getImage(etc...), got rid of some of the errors, however these still remain


    Code:
    java.lang.NullPointerException
    	at java.applet.Applet.getCodeBase(Unknown Source)
    	at Frogs.<init>(Frogs.java:11)
    	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    	at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    	at java.lang.reflect.Constructor.newInstance(Unknown Source)
    	at java.lang.Class.newInstance0(Unknown Source)
    	at java.lang.Class.newInstance(Unknown Source)
    	at sun.applet.AppletPanel.createApplet(Unknown Source)
    	at sun.plugin.AppletViewer.createApplet(Unknown Source)
    	at sun.applet.AppletPanel.runLoader(Unknown Source)
    	at sun.applet.AppletPanel.run(Unknown Source)
    	at java.lang.Thread.run(Unknown Source)
    Last edited by pwnedjoo; 04-28-2005 at 02:58 PM.

  14. #29
    Join Date
    Nov 2004
    Location
    Norway
    Posts
    1,560
    Yes, off the mark by good measure

    You will have to do it the applet way, using Applet.getImage and MediaTracker. ..
    Ap applet cannot read files like an application, its not allowed, luckily.

  15. #30
    Join Date
    Apr 2005
    Posts
    20
    this leaves me with something of a problem to alleviate an error I was getting to do with illegal forward references I declared and loaded two images before the declaration of the array, and more importantly before init();

    I have commented out the 2 lines and left a simple declaration of two images with no path to load them, the applet now loads no problem but I cant see a way round this, If I then try to load the images withing init() nothing changes, i.e. I have the background for my image but no frogs.

    cant move the array into init(), - not going to like that at all as far as i can see

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