Slyth2727
|
 |
«
Posted
2013-01-25 15:50:29 » |
|
Right, so here is another post for my tower defense game  .. this time I would like to know how to rotate my cannon tower according to the position of the enemy it is locked on.. I know that there is a method in Graphics2D called rotate in which you specify the amount in radians, but every time I use this the screen flickers because I use Graphics to draw everything. So my main question is what is the best way to rotate the tower image, and what is a method/equation to get which way to rotate it? Thanks, cMp
|
|
|
|
StumpyStrust
|
 |
«
Reply #1 - Posted
2013-01-25 16:02:14 » |
|
It would be in your case I believe angle = atan2(y2 - y1, x2 - x1) * 180 / PI; where (x1,y1) is the location of tower and (x2,y2) is the location of bad guy. Then plug into rotate and bam. Good practice IMO for using graphics objects is this. 1 2 3 4 5 6
| public void render(Graphics g) { Graphics2D g2d = g.create(); g2d.dispose(); } |
that way you will not be reusing stuff from other rendering operations. You can also not do thing and return it to its original orientation after your done rendering but I never liked doing that.
|
|
|
|
Slyth2727
|
 |
«
Reply #2 - Posted
2013-01-25 16:41:11 » |
|
awesome thank you very much! Would you mind explaining what atan2 does? I am rather shady in that area.
|
|
|
|
Games published by our own members! Check 'em out!
|
|
RobinB
|
 |
«
Reply #3 - Posted
2013-01-25 16:53:51 » |
|
Thats just stuff whats easy googled. Its an mathematical function: 
|
|
|
|
Slyth2727
|
 |
«
Reply #4 - Posted
2013-01-25 17:54:51 » |
|
aahhh ok I see now, thanks
|
|
|
|
sproingie
|
 |
«
Reply #5 - Posted
2013-01-25 18:18:14 » |
|
The visual interpretation of atan2 is that it gives you the angle from the origin to the x,y point you give it. The x and y are reversed in atan2 -- you pass it as y,x -- because tan itself is described in those terms (sin/cos, i.e. y/x on the unit circle)
|
|
|
|
Slyth2727
|
 |
«
Reply #6 - Posted
2013-01-25 18:30:01 » |
|
alright, tried for quite a while but this is not working... Here is my code: 1 2 3 4 5 6
| Graphics2D g2d = (Graphics2D) g.create(); double angle = Math.atan2(targetY - pixY, targetX - pixX) * 180 / Math.PI; g2d.rotate(Math.toRadians(angle)); g2d.drawImage(Screen.tileset_air[id], pixX, pixY, Screen.room.blockSize, Screen.room.blockSize, null); g2d.dispose(); |
nothing happens when I use this code. If I dont use Math.toRadians(angle) the image just flies around the screen in a circle, but it is facing the mob... Any ways to fix this??
|
|
|
|
sproingie
|
 |
«
Reply #7 - Posted
2013-01-25 18:32:52 » |
|
You need to translate to where you're drawing, then rotate, then draw the image at 0,0. Also, rotate takes degrees already. Something like this: 1 2 3 4 5 6 7 8
| Graphics2D g2d = (Graphics2D) g.create(); double angle = Math.atan2(targetY - pixY, targetX - pixX) * 180 / Math.PI; - g2d.rotate(Math.toRadians(angle)); - g2d.drawImage(Screen.tileset_air[id], pixX, pixY, Screen.room.blockSize, Screen.room.blockSize, null); + g2d.translate(pixX, pixY); + g2d.rotate(angle); + g2d.drawImage(Screen.tileset_air[id], 0, 0, Screen.room.blockSize, Screen.room.blockSize, null); g2d.dispose(); |
|
|
|
|
ClickerMonkey
|
 |
«
Reply #8 - Posted
2013-01-25 18:38:47 » |
|
Thats just stuff whats easy googled. Its an mathematical function:  I can confirm this: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public static void main(String[] args) { for ( double x = -30; x <= 30; x++ ) { for ( double y = -30; y <= 30; y++ ) { double atan = 2 * Math.atan( ( Math.sqrt(x * x + y * y) - x ) / y ); double atan2 = Math.atan2( y, x ); if ( Math.abs( atan - atan2 ) > 0.000001 ) { System.out.println( atan + " isn't equal to " + atan2 ); } } } } |
(yes, when y is 0 there are problems, didn't feel like accounting for this)
|
|
|
|
Slyth2727
|
 |
«
Reply #9 - Posted
2013-01-25 18:45:14 » |
|
Alright, that makes sense, and it draws the image, but it still swings around and around the x and y.
|
|
|
|
Games published by our own members! Check 'em out!
|
|
sproingie
|
 |
«
Reply #10 - Posted
2013-01-25 18:51:28 » |
|
Hm, I'm not familiar enough with slick2d. Could you pastebin your current drawing code and maybe someone else more experienced with it could see what's wrong?
|
|
|
|
Slyth2727
|
 |
«
Reply #11 - Posted
2013-01-25 18:52:17 » |
|
No I am not using slick... just the build in java libraryu\
|
|
|
|
sproingie
|
 |
«
Reply #12 - Posted
2013-01-25 19:02:57 » |
|
Zounds, that would be why it says Graphics2D. I'm such a dummy.  (We need a :facepalm: emoticon). Well pastebin anyway, I know a little more about transforms in Java2D, but not enough.
|
|
|
|
|
ClickerMonkey
|
 |
«
Reply #14 - Posted
2013-01-25 19:16:55 » |
|
Change 1 2
| g2d.translate(pixX, pixY); g2d.rotate(angle); |
to 1 2
| g2d.rotate(angle); g2d.translate(pixX, pixY); |
let me know how that goes.
|
|
|
|
RobinB
|
 |
«
Reply #15 - Posted
2013-01-25 19:21:52 » |
|
Change 1 2
| g2d.translate(pixX, pixY); g2d.rotate(angle); |
to 1 2
| g2d.rotate(angle); g2d.translate(pixX, pixY); |
let me know how that goes. Almost 1 2 3 4 5 6 7 8
| Graphics2D g2d = (Graphics2D) g.create(); double angle = Math.atan2(targetY - pixY, targetX - pixX) * 180 / Math.PI; - g2d.rotate(Math.toRadians(angle)); - g2d.drawImage(Screen.tileset_air[id], pixX, pixY, Screen.room.blockSize, Screen.room.blockSize, null); + g2d.translate(pixX + Screen.room.blockSize/2, pixY + Screen.room.blockSize/2); + g2d.rotate(angle); + g2d.drawImage(Screen.tileset_air[id], -Screen.room.blockSize/2, -Screen.room.blockSize/2, Screen.room.blockSize, Screen.room.blockSize, null); g2d.dispose(); |
Im sure this can be optimized, but it will work.
|
|
|
|
Slyth2727
|
 |
«
Reply #16 - Posted
2013-01-25 19:32:57 » |
|
well the image is on the tile its supposed to be on! the only problem is that it just spins around instead of pointing at the mob..
|
|
|
|
|
Slyth2727
|
 |
«
Reply #18 - Posted
2013-01-25 19:46:17 » |
|
Hmmm. Well it is obviously rotating a lot slower now, its actually about 45 degrees off though haha I will try and fix this
|
|
|
|
Slyth2727
|
 |
«
Reply #19 - Posted
2013-01-25 19:52:43 » |
|
Ok, well if I use 1 2 3 4
| double angle = Math.atan2(targetY - pixY, targetX - pixX) * 270 / Math.PI; [\code]
instead, it locks on fine, buuut it doesnt stay right on target.. |
|
|
|
|
sproingie
|
 |
«
Reply #20 - Posted
2013-01-25 20:30:51 » |
|
If you want something drawn away from the origin (i.e. most things you draw), you need to translate then rotate. Otherwise you're rotating the axes you translate on, causing you to revolve instead of rotate.
And my bad, rotate takes radians in java2d. It's degrees in slick (because OpenGL takes degrees).
|
|
|
|
Slyth2727
|
 |
«
Reply #21 - Posted
2013-01-25 20:33:39 » |
|
Yes it is now rotating, buut not really correctly pointing at the target
|
|
|
|
RobinB
|
 |
«
Reply #22 - Posted
2013-01-25 20:39:09 » |
|
Hmmm. Well it is obviously rotating a lot slower now, its actually about 45 degrees off though haha I will try and fix this
Does this work? Otherwise try + 45 or any correction so it points at an mob. 1
| g2d.rotate(Math.toRadians(angle-45)); |
|
|
|
|
Slyth2727
|
 |
«
Reply #23 - Posted
2013-01-25 20:52:38 » |
|
I found the perfect number to be - 270  ! So the next thing: Getting the tower to rotate smoothly back to the next target?
|
|
|
|
ClickerMonkey
|
 |
«
Reply #24 - Posted
2013-01-25 21:09:48 » |
|
You had to adjust it to -270 because your coordinate system is flipped on the y-axis... if you do 1
| Math.atan2(pixY - targetY, targetX - pixX) |
instead of 1
| Math.atan2(targetY - pixY, targetX - pixX) |
you don't need to adjust. Also, you are needlessly converted to degrees, then back to radians.
|
|
|
|
Slyth2727
|
 |
«
Reply #25 - Posted
2013-01-25 21:20:55 » |
|
No, that doesnt work...
|
|
|
|
ClickerMonkey
|
 |
«
Reply #26 - Posted
2013-01-25 21:30:42 » |
|
Oh, well that typically works for me. We must have something else different!
|
|
|
|
Slyth2727
|
 |
«
Reply #27 - Posted
2013-01-25 21:31:57 » |
|
ay I suppose, but I gotta go somewhere, thanks for all of you guys' help!
|
|
|
|
ClickerMonkey
|
 |
«
Reply #28 - Posted
2013-01-30 12:22:21 » |
|
I think the source of why y is before x is in this alternative implementation of atan2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| if (fy == 0) { if (fx < 0) { return PI; } else { return 0; } } else if (fx == 0) { if (fy < 0) { return -ONE_HALF_PI; } else { return ONE_HALF_PI; } } else { float answer = atan(abs(fy/fx)); if (fy > 0 && fx < 0) { return PI - answer; } else if (fy < 0 && fx < 0) { return answer - PI; } else if (fy < 0 && fx > 0) { return -answer; } else { return answer; } } |
Note the atan(|y/x|)
|
|
|
|
Agro
|
 |
«
Reply #29 - Posted
2013-01-30 22:37:30 » |
|
I'm sure you guys are over complicating it with this long code. o.O Its not that hard to rotate a sprite. :/
|
|
|
|
|