Hello.

I am new to Java and I am creating a simple applet while I to learn.

My problem is that one of my methods doesn't seem to be working.

The applet is a simple moving sprite; use arrows to move, ect.

I am trying to create a missile using the spacebar, however, when I press it the missile is created, but not in the place I want it.

I want it to be created wherever my sprite is standing. I have created a method which finds out the sprite's position, yet this method doesn't work.

It creates the missile at the sprite's starting position, always, regardless if I move.
Here are some code snippets.

Sprite.java:

          // Gets x
         public int getX() {
         return x;
}

           // Gets y
         public int getY() {
         return y;
}
           // Sets x
         public void setX(int x) {
         this.x = x;
}

          // Sets y
        public void setY(int y) {
        this.y = y;
}

Missile.java:

       // paints image
      public void paint(Graphics g, Main main){
          if(visible){
          g.drawImage(shotimage, sprite.getX(), sprite.getY(), main);
          }

Can anyone help?
Thanks.

P.S Let me know if you need more code.

Edited 4 Years Ago by champmanking

My problem is that one of my methods doesn't seem to be working.

define: doesn't seem to be working. is it not doing what you want/expect? is there an error message?

I want it to be created wherever my sprite is standing. I have created a method which finds out the sprite's position, yet this method doesn't work.

and what method is that, and where/how do you call it?

Here are some code snippets.

They come in very handy. It would be easier, however, if you showed the code you're actually having trouble with.

Unless you'll be more specific, it'll be impossible for us to help you further, I'm afraid.

1) Not working = the missile image isn't created where the sprite is currently, it is created where the sprite starts

2) Method = getX() and getY() posted above

3) This is the code I'm having trouble with (2nd snippet)

getX() return x;

can you see why that doesn't tell us very much? I assume you're asking for the x co├Ârdinate, but are you sure you are setting the value right?

as you said: it is drawing it, just not where I want, that means the method is working, but there's something wrong in the logic you applied.

first: in your paint method, print the values of x and y, to check whether or not they contain the values you think they should have.
also, check whether or not your main variable is and does what you think.

In my sprite.java where the getX() method is, x = 300 and y = 200 (the starting co ords of the sprite).

x and y are then updated using x += velX; and y += velY; with velx and vely being 5, or -5(used to move sprite).

I'll try and print the values now.
Edit: It prints 300.

Seems like the movement of my sprite doesn't update the co ords and thus doesn't print where my sprite is. However, if i use the method in my sprite.java like I do to check if it goes off screen, it works.

Edited 4 Years Ago by champmanking

I think this is the problem. I set the x and y variables in the class like so:

     public class Sprite implements KeyListener{

        // sprite class variables
     private int x = 300;
     private int y = 200;

then in my update function i update their values to move my sprite like so:

     public void update(Main main){
        main.addKeyListener(this);    
        x += velX;
        y += velY;
}

but the method getX() only gets the first value if called in another class.

Edited 4 Years Ago by champmanking

How often do you call that update method, and from where (thread/loop/timer?)? Do you really keep adding key listeners every time you update the position?

       // Runs
    public void run(){

           // While app running
        while(true){

              // Update screen
            repaint();
            sprite.update(this);
            missile.update(this);

              // Refresh 
            try {
                 Thread.sleep(1000/30);
                } catch (InterruptedException e){
                   ; 
                                                 }
                   }

}

Thanks, I was checking for you blocking the Swing thread, but it's OK.
Next idea: maybe your other class is looking at a different non-executing instance of the first class? That would explain why it only ever sees the initial value. You could check carefully for how many "new" keywords there are in your total code!

I don't really understand what you said, but sprite does have two constructors maybe that's the issue.:

       //Picture loader constructor
     public Sprite(Main main){
     url = main.getDocumentBase();
     spriteimage = main.getImage(url, "sprite.jpg");
}

       public Sprite(Missile missile){}

I created the second so I could use the getX() and getY() methods from sprite class in missile class.

Sprite sprite = new Sprite(this);

Edited 4 Years Ago by champmanking

Perhaps this is what's going on:
Somewhere you call new Sprite(main) that creates a new Sprite that gets updated and displayed regularly
Somewhere else you call new Sprite(missile) and that creates a second Sprite instance that main doesn't know about so it never gets updated. If that's the one you query you only ever see the initial vlaues.

In my main.java I have this:

          Sprite sprite;
          Missile missile;
          Thread thread = new Thread(this);
          sprite = new Sprite(this);
          missile = new Missile(this);

In my missile.java I have this:

       Sprite sprite = new Sprite(this);

So, yeah, that's exactly what's going on. How can I solve this?

Edited 4 Years Ago by champmanking

Somewhere in your missile class you have something like sprite.getX() where/how is the variable sprite (or whatever you call it) initialised?

Like this:

//missile class
       public class Missile implements KeyListener{
       Sprite sprite = new Sprite(this);

Then I use sprite.getX() where I want to get the x co ord like so:

 // paints image
      public void paint(Graphics g, Main main){
          if(visible){
          g.drawImage(shotimage, sprite.getX(), sprite.getY(), main);

Edited 4 Years Ago by champmanking

Right. That's exactly what I was trying to explain. You have two sprites in your prohgram. You create a second Sprite right there. It's not the same as the Sprite you created in main. It has it's own data, and it's update never gets called because main doesn't know it exists. That's why it always gives you the initial values.
Is that clear yet? There's no point discussing solutions until you really understand the problem.

Yes, I understand. Shall I create two update methods in sprite.java then have main.java call the update for missile, too?

Edited 4 Years Ago by champmanking

Solutions:
1. If missile needs to call all kinds of sprite methods then you should add a Sprite to missile's constructor. Then main can pass the original sprite to Missile via Missile's constructor.
2. If this is the only reason why missile needs sprite then I would handle it via main - ie add a whereIsTheSprite? method to main that missile can call, because main knows about the original sprite and how to call its methods.

Solution 1:
missile.java

         // missile contrustor loads image
       public Missile(Main main, Sprite sprite){
         url = main.getDocumentBase();
         missileimage = main.getImage(url, "missile.png");


} 

in main.java:

new Missile(this, sprite);

?

Edited 4 Years Ago by champmanking

I knew you would ask that!
We have officially fallen into the "ask before thinking" mode.
You already know how to do that. Just think about it.
Once you've done that your original problem will be fixed, so I'm going offline now.
Good night, and good luck.
J

Thanks for helping, this far, JamesCherrill.

I made the changes (see previous post) and now just need some help with keeping a copy of the sprite's variable.

Edited 4 Years Ago by champmanking

No! Not the sprite's variable. I said the sprite variable.
There's no point passing a value into the constructor if you don't make a copy of it somewhere to use later.

// in the Missile class
Sprite sprite;  // for use in any Missile method

// missile contrustor loads image
public Missile(Main main, Sprite sprite){
   this.sprite = sprite;   // copy the parameter for use in other methods
   ...

Thanks. I done that, but now the missile image doesn't show when I press SPACE.

After I made these changes(see below), like JamesCherrill said to, the missile image doesn't print when I press space. Anyone know why? The image printed before I made the changes.

Missile.java

       Sprite sprite;

         // missile contrustor loads image
       public Missile(Main main, Sprite sprite){
         this.sprite = sprite;
         url = main.getDocumentBase();
         missileimage = main.getImage(url, "missile.png");

} 

Main.java

new Missile(this, sprite);

Edited 4 Years Ago by champmanking

This article has been dead for over six months. Start a new discussion instead.