3

EDIT: OH!!!!! it works!!! It seems that at one point it was fixed However the wrong HTML file was opening up so the wrong code was running. I feel stupid, that should have been obvious.

But THANKYOU!!!

Its so awesome to actually get some help with this stuff. whenever i ask for some help anywhere else or even ask my teacher im usually ignored or get useless advice. (end of edit)

Im making a game for my final project in a java class. I just got mouse aiming to work using AffineTransform, however When ever the player object rotates to 90 degrees(or a multiple of it), it does this weird stutter thing. Heres the code im specifically concerned with.

    g2.drawImage(img, x_pos,y_pos,this);
    AffineTransform oldTransform = g2.getTransform();

g2.setTransform(AffineTransform.getRotateInstance(radAngle,x_pos +   (img.getWidth() / 2),y_pos+(img.getHeight() / 2)));

Could someone please help me figure out how to fix this? my project is due tomorrow so im slim on time. Here are the images i use

http://i56.tinypic.com/iolys3_th.png http://i53.tinypic.com/27hif_th.png http://i56.tinypic.com/21jayoh.jpg

Heres the code.

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.lang.Math.*;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import javax.imageio.ImageIO;
import java.io.*;
import java.net.URL;

public class Game extends Applet implements Runnable, KeyListener, MouseMotionListener
{

    int x_pos = 250;
    int y_pos = 250;
    float x_speed = 0;
    float y_speed = 0;
    int radius = 20;
    int appletsize_x = 800;
    int appletsize_y = 600;

    int x = 0;
    int y = 0;
    int up = 0;
    int down= 0;
    int left = 0;
    int right= 0;

    int mouse_x;
    int mouse_y;
    int tracking_angle;

    private BufferedImage dbImage;
    private Graphics dbg;
    private  Image curser;
    BufferedImage img = null;
    BufferedImage round = null;

    AffineTransform at = new AffineTransform();
    double radAngle;
    public void init()
    {
            try {
               URL url = new URL(getCodeBase(), "Player.png");
               img = ImageIO.read(url);
            } catch (IOException e) {System.out.println("Cant find player image");
        }
                        try {
                           URL url = new URL(getCodeBase(), "round.png");
                           round = ImageIO.read(url);}
             catch (IOException e) {}

        setBackground (Color.blue);
        setFocusable(true);
        addKeyListener( this );
        curser = getImage(getDocumentBase(), "mouse.png");
        addMouseMotionListener(this);
        try
                {
                    Toolkit tk = Toolkit.getDefaultToolkit();
                    Cursor c = tk.createCustomCursor( curser,new Point( 5, 5 ), "Inodrop" );
                    setCursor( c );
                }
                catch( IndexOutOfBoundsException x )
                {}
    }

    public class Shot {

        int x_loc = -50;
        int y_loc = -50;
        public Shot(){
            if(x_loc < 0){
                x_loc = x_pos;}
            if(y_loc < 0){
                y_loc = y_pos;}

                paint(dbg);}
        public void paint(Graphics g){
            System.out.println("hi");

             Graphics2D g2d = (Graphics2D)g;

            Graphics g2D = round.getGraphics();
            g2d.drawImage(round, x_loc,y_loc,null);}}

    public void start ()
    {

        Thread th = new Thread (this);

        th.start ();

    }

    public void stop()
    {

    }

    public void destroy()
    {

    }
    public void mouseMoved(MouseEvent e){
        //get position of mouse
        mouse_x = e.getX();
        mouse_y = e.getY();
        double x_dist = mouse_x - x_pos;
        double y_dist = mouse_y - y_pos;


        if (x_dist == 0) {
          radAngle = 90;
        } else if ((x_dist == 0) && (y_dist == 0)) {
          radAngle = 0;
        } else {
          radAngle = Math.atan(y_dist / x_dist);
        }


        tracking_angle = (int)(Math.sin(radAngle) * 100);
        //System.out.println(Math.toRadians(tracking_angle));
        }
    public void mouseDragged(MouseEvent e){}


    public void keyReleased(KeyEvent r)
    {
        //Left
        if (r.getKeyCode()  == 39 ){
            x = 0;
            left = 0;
            Shot shoot = new Shot();
            }
        //Right
        if (r.getKeyCode() == 37){
            x = 0;
            right = 0;
            }
        //Down
        if (r.getKeyCode() == 38 ) {
            //y_speed = 0;
            down = 0;}
        //Up
        if (r.getKeyCode() == 40 ) {
            //y_speed = 0;
            up = 0;}
            //move();
}
    public void keyTyped(KeyEvent t){}
    public void keyPressed(KeyEvent r){


        //Left
        if (r.getKeyCode()  == 39 ){
            left = 1;}
        //Right
        if (r.getKeyCode() == 37){
            right = 1;}
        //Down
        if (r.getKeyCode() == 38 ) {
            down = 1;}
        //Up
        if (r.getKeyCode() == 40 ) {
            up = 1;}
            //move();
}


    public void run ()
    {

        Thread.currentThread().setPriority(Thread.MIN_PRIORITY);


        while (true)
        {
            if (left  == 1 && x_speed < 11){
                x = 0;
                x_speed += 1;
                }
            //Right
            if (right == 1 && x_speed > -11){
                x = 0;
                 x_speed -= 1;
                }
            //Down
            if (down == 1  && y_speed > -11) {
                y_speed -= 1;}
            //Up
            if (up == 1  && y_speed < 11) {
            y_speed += 1;}
        if( x == 0 && x_speed > 0){
            x_speed -=.2;}
        if( x == 0 && x_speed < 0){
            x_speed +=.2;}
        if( y == 0 && y_speed > 0){
            y_speed -=.2;}
        if( y == 0 && y_speed < 0){
            y_speed +=.2;}



            if (x_pos > appletsize_x - radius && x_speed > 0)
            {

                x_pos = radius;
            }

            else if (x_pos < radius && x_speed < 0)
            {

                x_pos = appletsize_x + radius ;
            }
            //System.out.println(y_pos);
            if (y_pos > appletsize_y - radius && y_speed > 0){
                y_speed = 0;}
            else if ( y_pos < radius && y_speed < 0  ){
                    y_speed = 0;}

            x_pos += (int)x_speed;
            y_pos += (int)y_speed;



            repaint();

            try
            {


                Thread.sleep (15);


            }
            catch (InterruptedException ex)
            {

            }


            Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
        }
    }


    public void update (Graphics g)
    {

        if (dbImage == null)
        {
            dbImage = new BufferedImage(this.getSize().width, this.getSize().height, BufferedImage.TYPE_INT_RGB);
            dbg = dbImage.getGraphics ();
        }


        dbg.setColor (getBackground ());
        dbg.fillRect (0, 0, this.getSize().width, this.getSize().height);


        dbg.setColor (getForeground());
        paint (dbg);

        g.drawImage (dbImage, 0, 0, this);


    }

    public void paint (Graphics g)
    {
        //g = img.getGraphics();
        Graphics2D g2 = (Graphics2D)g;


        g2.drawImage(img, x_pos,y_pos,this);
        AffineTransform oldTransform = g2.getTransform();

        g2.setTransform(AffineTransform.getRotateInstance(radAngle,x_pos + (img.getWidth() / 2),y_pos+(img.getHeight() / 2)));



        System.out.println(img.getWidth());




    }
}
schnaader
  • 49,103
  • 10
  • 104
  • 136
Sean H
  • 33
  • 5
  • Can you post the tow images you use so i can try this outt o see whats wrong. – Shaunak May 05 '11 at 23:20
  • Please don't swallow exceptions. – trashgod May 05 '11 at 23:35
  • +0.95 for a nearly complete example. See [`RotatableImage`](http://stackoverflow.com/questions/3405799/how-to-rotate-an-image-gradually-in-swing/3420651#3420651) so people don't have to track down images and swallowed exceptions. :-) – trashgod May 06 '11 at 00:08
  • "my project is due tomorrow so im slim on time" We've all been there lol. – pbible Jun 02 '15 at 20:55

2 Answers2

3
    double x_dist = mouse_x - x_pos;
    double y_dist = mouse_y - y_pos;
    double radAngle = Math.atan(y_dist / x_dist);
    tracking_angle = (int) (Math.sin(radAngle) * 100);

I think the error is somewhere in this part. You're definitely dividing by 0 here if x_dist is 0. Better do something like this:

if (x_dist == 0) {
    radAngle = 90;
} else {
    radAngle = Math.atan(y_dist / x_dist);
}

EDIT: Additionally, I think you should throw away the tracking_angle line completely and just do this later:

g2.setTransform(AffineTransform.getRotateInstance(rad_angle,
  x_pos + (img.getWidth() / 2),y_pos+(img.getHeight() / 2)));

Also you should change that new code you posted in the comments:

double radAngle;
if (x_dist == 0) {
  radAngle = 90;
} else if (y_dist == 0) {
  radAngle = 90;
} else {
  radAngle = Math.atan(y_dist / x_dist);
}

You are solving this for x_dist == 0 or y_dist == 0 (which isn't an edge case), but not for the case that both are 0 where you simply can't compute an angle and I think you should go with 0. So use this instead:

double radAngle;
if (x_dist == 0) {
  radAngle = 90;
} else if ((x_dist == 0) && (y_dist == 0)) {
  radAngle = 0;
} else {
  radAngle = Math.atan(y_dist / x_dist);
}

Also, as trashgod pointed out, you're ignoring exceptions, for example:

    try {
        URL url = new URL(getCodeBase(), "Player.png");
        img = ImageIO.read(url);
    } catch (IOException e) {
    }

You should not just continue in such cases but f.e. display an useful error message and quit the program, in any case do something instead of just catching the exception and continue as if nothing happened.

schnaader
  • 49,103
  • 10
  • 104
  • 136
  • +1 for perseverance. I noticed the `tracking_angle` changing sign abruptly _near_ the problem angle, which makes me suspicious of `100`. – trashgod May 06 '11 at 00:01
  • It didnt work, i think it has something to do with this(which is from the java api) "Since 90 degrees is represented as PI/2 in radians, and since PI is a transcendental (and therefore irrational) number, it is not possible to exactly represent a multiple of 90 degrees as an exact double precision value measured in radians." heres the code i used, double radAngle; if (x_dist == 0) { radAngle = 90; }else if(y_dist == 0){ radAngle = 90;} else { radAngle = Math.atan(y_dist / x_dist); } that replaced the double radAngle = Math.atan(y_dist / x_dist); line. – Sean H May 06 '11 at 00:02
  • 1
    Please update your question with the new code; it's pretty hard to read in a comment. – trashgod May 06 '11 at 00:07
  • 1
    Well, the `tracking_angle = (int) (Math.sin(radAngle) * 100);` is strange, too. `radAngle` is in radians, so I think you should throw away `tracking_angle` and use `radAngle`directly instead of `Math.toRadians(tracking_angle)`. I'll do a edit with code to make it clearer. – schnaader May 06 '11 at 00:08
  • I actually thought of that after i tried the the thing recomended above and it didnt make a difference. Did the same stutter thing. it makes sense that i would have lost some precision when converting into degrees and than back to radians but apparently it doesnt make a difference. – Sean H May 06 '11 at 00:14
  • Well, in that case you should describe the "stutter thing" more precise. Also, debug the code, f.e. compare expected and actual values for specific `(x_dist,y_dist)` pairs. – schnaader May 06 '11 at 00:28
  • Forgive my noobishness,im not sure what exactly you mean; how would i do that? – Sean H May 06 '11 at 00:33
  • For example, instead of `x_dist = mouse_x - x_pos; y_dist = mouse_y - y_pos;`, use something like `x_dist = 0; y_dist = 123;` or `x_dist = 456; y_dist = 0;`, so some values for the cases that don't work and check if `radAngle` is what you expect it to be. – schnaader May 06 '11 at 00:39
  • Ive more or less done that already, before when i was trying to figure out how to get it to track the mouse i used the tracking_angle to see at what angle the mouse was to the object, and it looked fine to me. I didnt look at radAngle because frankly radians are weird, i didnt understand what they equated to at all. Ive never dealt with them before – Sean H May 06 '11 at 00:51
  • If you don't know enough about radians, have a look at http://en.wikipedia.org/wiki/Radian - it basically is just using another range, `0..2*PI` instead of `0..360` – schnaader May 06 '11 at 01:21
2

I haven't tested this, but try:

double radAngle = Math.atan2(y_dist, x_dist);
finnw
  • 47,861
  • 24
  • 143
  • 221
  • No change. Why cant java just rotate in degrees like...it should T_T – Sean H May 06 '11 at 00:19
  • +1, good catch, `atan2` should be exactly what we need here. http://en.wikipedia.org/wiki/Atan2#Definition gives a good explanation of `atan2`. There'll still be a check for (0,0) but the other cases where `atan(y/x)` fails are handled. – schnaader May 06 '11 at 00:19