Rotating an image - tower defense

Hi all, :slight_smile:

I’m new to java2d and so I decided to do a Tower Defense game.
So it’s very basic for now, in fact I show one tower and one ennemy, the first thing I wanted to get working is aiming the turret to the ennemy…
The problem is that the turret is spinning, instead of just smoothly following the ennemy.
Here’s my code, may look a bit weird since it’s bits of code from all over.
I guess the problem is coming from “gameRender()”.

Complete code:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class GamePanel extends JPanel implements Runnable
{
	private static int DEFAULT_FPS = 80;
	private static int period;
	
	private static final int PWIDTH = 500; // size of panel
	private static final int PHEIGHT = 400;
	private Thread animator; // for the animation
	private boolean running = false; // stops the animation

	private Graphics dbg;
	private Image dbImage = null;
	
	BufferedImage img = null;
	AffineTransform at = new AffineTransform();
	
	double x = 300;
	double y = 300;
	
	int x_turret = 250;
	int y_turret = 250;

	public GamePanel()
	{
		setBackground(Color.white); // white background
		setPreferredSize( new Dimension(PWIDTH, PHEIGHT));
		
		setFocusable(true);
		requestFocus();
		
		try { 
			img = ImageIO.read(new File("canon.png"));
		} catch (IOException e) {}
		
		/* Active rendering instead. */
		setDoubleBuffered(false);
	}

	public void addNotify()
	{
		super.addNotify(); 
		startGame();
	}
	private void startGame()
	{
		if (animator == null || !running) 
		{
			animator = new Thread(this);
			animator.start();
		}
	}
	
	public void stopGame()
	{ running = false; }

	public void run()
	{
		long beforeTime, timeDiff, sleepTime;
		
		beforeTime = System.currentTimeMillis();
		
		running = true;
		while(running) 
		{
			gameUpdate(); 
			gameRender(); 
			paintScreen();
			
			timeDiff = System.currentTimeMillis() - beforeTime;
			sleepTime = period - timeDiff; // time left in this loop
			
			if (sleepTime <= 0) // update/render took longer than period
				sleepTime = 5; // sleep a bit anyway

			try {
				Thread.sleep(sleepTime);
			}
			catch(InterruptedException ex){}
			
			beforeTime = System.currentTimeMillis();
		}
		System.exit(0); // so enclosing JFrame/JApplet exits
	}
	
	private void
	paintScreen
	()
	// actively render the buffer image to the screen
	{
		Graphics g;
		try {
			g = this.getGraphics(); // get the panel’s graphic context
			if ((g != null) && (dbImage != null))
				g.drawImage(dbImage, 0, 0, null);
			g.dispose();
		}
		catch (Exception e)
		{ System.out.println("Graphics context error: " + e); }
	}
	
	
	private void gameUpdate()
	{
		x += 0.1;
	}
	
	public void paintComponent(Graphics g)
	{
		super.paintComponent(g);
		if (dbImage != null)
			g.drawImage(dbImage, 0, 0, null);
	}
	
	private void gameRender()
	// draw the current frame to an image buffer
	{
		if (dbImage == null)
		{
			dbImage = createImage(PWIDTH, PHEIGHT);
			
			if (dbImage == null)
			{ 
				System.out.println("dbImage is null");
				return;
			}
			
			dbg = dbImage.getGraphics();
		}
		
		dbg.setColor(Color.gray);
		dbg.fillRect (0, 0, PWIDTH, PHEIGHT);
		
		dbg.setColor(Color.blue);
		dbg.fillRect((int)x, (int)y, 10, 10);

        AffineTransform at1 = new AffineTransform();
        
        double yourAngle = Math.atan2(y-(double)y_turret, x-(double)x_turret) * 180 / Math.PI;
        
        at1.translate(x_turret-img.getWidth(), y_turret-img.getHeight());
        at1.rotate(yourAngle, img.getWidth()/2, img.getHeight()/2);
        
        ((Graphics2D)dbg).drawImage(img, at1, null);

	}
	
	   public static void main(String args[])
	   {
	     period = (int) 1000.0/DEFAULT_FPS;

	     GamePanel gPanel = new GamePanel();

	     // create a JFrame to hold the timer test JPanel
	     JFrame app = new JFrame("Game Panel");
	     app.getContentPane().add(gPanel, BorderLayout.CENTER);
	     app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

	     app.pack();
	     app.setResizable(false);  
	     app.setVisible(true);
	  }
} 


I’m new to this forum, so tell me if I did something wrong :slight_smile:

Sam