# Slick Forums

Discuss the Slick 2D Library
 It is currently Sat Feb 23, 2019 1:13 am

 All times are UTC

 Page 1 of 1 [ 9 posts ]
 Print view Previous topic | Next topic
Author Message
 Post subject: BUG: setRotation while scalingPosted: Sat Feb 18, 2012 11:03 pm

Joined: Thu Sep 01, 2011 10:15 pm
Posts: 31
Location: United States
http://www.youtube.com/watch?v=wLsuc5HsUyo for a video demonstrating the problem.

This code works
Code:

int x = (int) (location.x-cam.loc.x - radius);
int y = (int) (location.y-cam.loc.y - radius);

sprite.draw(x/cam.zoom + (gc.getWidth()/2) , y/cam.zoom + (gc.getHeight()/2),1/cam.zoom);
System.out.println("loc:" + location +"Dest" + destination + " x" + (x/cam.zoom + (gc.getWidth()/2)) + "y: " + (y/cam.zoom + (gc.getHeight()/2)));

but if i do this
Code:

sprite.setRotation((float) 90);

int x = (int) (location.x-cam.loc.x - radius);
int y = (int) (location.y-cam.loc.y - radius);

sprite.draw(x/cam.zoom + (gc.getWidth()/2) , y/cam.zoom + (gc.getHeight()/2),1/cam.zoom);
System.out.println("loc:" + location +"Dest" + destination + " x" + (x/cam.zoom + (gc.getWidth()/2)) + "y: " + (y/cam.zoom + (gc.getHeight()/2)));

It stops working and the image of the ship isn't where it supposed to be on the screen.

Note, I checked the actual x,y coordinates that it thinks it should be at and it is passing the correct location. It's just that it doesn't draw it at those locations (sometimes completely off the screen, even though 300x, 300y should still be visible on a 1000x900 window.

I would greatly appreciate any feedback on this problem. I looked at the slick code, and while I can tell where slick does the rotation math, I don't know gl to figure out what's going wrong.

Side note:
I did update the version of LWGL for the program to gain access to the 64bit binaries.

Top

 Post subject: Re: BUG: setRotation while scalingPosted: Sun Feb 19, 2012 2:01 am
 Slick Zombie

Joined: Sat Jan 27, 2007 7:10 pm
Posts: 1482
The problem has to do with Image's center of rotation not being scaled with the draw() method. Here's a test that demonstrates the issue and a couple of workarounds.

Use the arrow keys to move the camera, W/S to zoom the camera, and 1, 2 and 3 to change the way the sprite is drawn.

Code:
import org.newdawn.slick.Image;

import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;

/**
*
* @author davedes
*/
public class SlickTest extends BasicGame {

public SlickTest() {
super("");
}

public static void main(String[] args) throws SlickException {
new AppGameContainer(new SlickTest(), 800, 600, false).start();
}
private float locx, locy, camx, camy;
private float camzoom = 1f;
private Image sprite;

private int mode = 1;
private float rot = 0;

@Override
public void init(GameContainer gc) throws SlickException {
sprite = new Image("res/pic.jpg");

}

@Override
public void update(GameContainer gc, int delta) throws SlickException {
if (gc.getInput().isKeyDown(Input.KEY_LEFT)) {
camx -= 5;
}
else if (gc.getInput().isKeyDown(Input.KEY_RIGHT)) {
camx += 5;
}
else if (gc.getInput().isKeyDown(Input.KEY_UP)) {
camy -= 5;
}
else if (gc.getInput().isKeyDown(Input.KEY_DOWN)) {
camy += 5;
}
if (gc.getInput().isKeyDown(Input.KEY_W)) {
camzoom += 0.005f;
}
else if (gc.getInput().isKeyDown(Input.KEY_S)) {
camzoom -= 0.005f;
}
if (gc.getInput().isKeyPressed(Input.KEY_1)) {
mode = 1;
//reset to the default...
sprite.setCenterOfRotation(sprite.getWidth()/2f, sprite.getHeight()/2f);
} else if (gc.getInput().isKeyPressed(Input.KEY_2)) {
mode = 2;
} else if (gc.getInput().isKeyPressed(Input.KEY_3)) {
mode = 3;
//reset to the default...
sprite.setCenterOfRotation(sprite.getWidth()/2f, sprite.getHeight()/2f);
}

rot += delta * 0.03f;
}

@Override
public void render(GameContainer gc, Graphics g) throws SlickException {
int x = (int) (locx - camx - sprite.getWidth() / 2f);
int y = (int) (locy - camy - sprite.getHeight() / 2f);
float xpos = x/camzoom + (gc.getWidth()/2f);
float ypos = y/camzoom + (gc.getHeight()/2f);

if (mode==1) {
//what you are doing now...
sprite.setRotation(rot);
sprite.draw(xpos, ypos, 1 / camzoom);
} else if (mode==2) {
//until the bug is fixed you can resolve the issue like so:
float cx = sprite.getWidth() / camzoom / 2f;
float cy = sprite.getHeight() / camzoom / 2f;
sprite.setCenterOfRotation(cx, cy);

sprite.setRotation(rot);
sprite.draw(xpos, ypos, 1 / camzoom);
} else if (mode==3) {
//another way to do it would be to separate camera
//scaling/position and sprite scaling/position
g.translate(gc.getWidth()/2f - camx/camzoom, gc.getHeight()/2f - camy/camzoom);
g.scale(1/camzoom, 1/camzoom);

sprite.setRotation(rot);
sprite.draw(locx-sprite.getWidth()/2f, locy-sprite.getHeight()/2f);
g.resetTransform();
}

g.drawString("Cam zoom: "+camzoom, 10, 25);
g.drawString("Cam loc: "+camx+", "+camy, 10, 40);
g.drawString("Mode: "+mode, 10, 60);
}
}

Top

 Post subject: Re: BUG: setRotation while scalingPosted: Sun Feb 19, 2012 3:54 am

Joined: Thu Sep 01, 2011 10:15 pm
Posts: 31
Location: United States
Thanks for the workaround! I still hope that this will be fixed in the next version of slick though.

Top

 Post subject: Re: BUG: setRotation while scalingPosted: Sun Feb 19, 2012 10:24 am
 Game Developer

Joined: Thu Mar 03, 2011 6:22 pm
Posts: 534
To be honest I never used it this way. I always first rotate the context, then translating to the zoom position (center of image maybe) and draw it to the screen

I never used setRotation since there is no control over it, for rendering may images with the same rotation and so on :/

_________________
Current Projects:
Mr. Hat I
Vegan Vs. Zombies
Projects:
RadicalFish Engine - Build on top of Slick2D, Ideas, Bugs? Open an Issue ticket!

Top

 Post subject: Re: BUG: setRotation while scalingPosted: Sun Feb 19, 2012 3:59 pm

Joined: Thu Sep 01, 2011 10:15 pm
Posts: 31
Location: United States
Quote:
rotate the context

Which commands would let me do that?

Top

 Post subject: Re: BUG: setRotation while scalingPosted: Sun Feb 19, 2012 6:33 pm
 Slick Zombie

Joined: Sat Jan 27, 2007 7:10 pm
Posts: 1482
UAequals42 wrote:
Quote:
rotate the context

Which commands would let me do that?

Graphics.rotate
Graphics.translate
Graphics.scale

These are generally better than something like Image.setRotation. If you look in the setRotation code, you'll find that all it's doing is calling the above rotate/translate methods before drawing: (pseudo code)
Code:
public void draw(int x, int y) {
//apply transformations
g.translate(x, y);
if (getRotation() != 0) {
g.translate(getCenterOfRotationX(), getCenterOfRotationY());
g.rotate(0, 0, getRotation());
g.translate(-getCenterOfRotationX(), -getCenterOfRotationY());
}

// ... image is rendered here to OpenGL ... //

//reset transformations
if (getRotation() != 0) {
g.translate(getCenterOfRotationX(), getCenterOfRotationY());
g.rotate(0, 0, -getRotation());
g.translate(-getCenterOfRotationX(), -getCenterOfRotationY());
}
g.translate(-x, -y);
}

The less the OpenGL context needs to rotate/scale/transform/push/pop its transform matrices, the faster it will be able to render things.

Top

 Post subject: Re: BUG: setRotation while scalingPosted: Mon Feb 20, 2012 12:07 am

Joined: Thu Sep 01, 2011 10:15 pm
Posts: 31
Location: United States
Ah. Just a warning. I found out that the sprite.setCenterOfRotation workaround doesn't work very well. Objects are still off from where they should be.... just not grossly off. (Instead of being 700 pixels off, its at max 300 or less for my image) Probably some rounding errors or something creeping in. I'll try the other method of rotating in game latter.

EDIT
I was wrong.

Last edited by UAequals42 on Mon Feb 20, 2012 12:51 am, edited 1 time in total.

Top

 Post subject: Re: BUG: setRotation while scalingPosted: Mon Feb 20, 2012 12:14 am

Joined: Thu Sep 01, 2011 10:15 pm
Posts: 31
Location: United States
Found a workaround... don't know how much it will affect performance though....

Pre-scaling a copy of the image and rotating that fixes the issue.

Code:
Image sprite2 = sprite.getScaledCopy(1/cam.zoom);
sprite2.setRotation((float) Math.toDegrees(angle)+90);
int x = (int) (location.x-cam.loc.x - sprite.getWidth()/2);
int y = (int) (location.y-cam.loc.y - sprite.getHeight()/2);
sprite2.draw(x/cam.zoom + (gc.getWidth()/2) , y/cam.zoom + (gc.getHeight()/2));

Top

 Post subject: Re: BUG: setRotation while scalingPosted: Mon Feb 20, 2012 12:52 am

Joined: Thu Sep 01, 2011 10:15 pm
Posts: 31
Location: United States
Ok. I forgot a step when doing the setCenterofRotation workaround

Code:
sprite.setCenterOfRotation((sprite.getWidth()/2)/cam.zoom, (sprite.getHeight()/2)/cam.zoom);

I had forgotten to adjust the center based on the level of zoom.

Here's what my code now looks like. (and it works! Finally)
Code:
sprite.setCenterOfRotation((sprite.getWidth()/2)/cam.zoom, (sprite.getHeight()/2)/cam.zoom);
sprite.setRotation((float) Math.toDegrees(angle)+90);
int x = (int) (location.x-cam.loc.x - sprite.getWidth()/2);
int y = (int) (location.y-cam.loc.y - sprite.getHeight()/2);

sprite.draw(x/cam.zoom + (gc.getWidth()/2) , y/cam.zoom + (gc.getHeight()/2), 1/cam.zoom);

Top

 Display posts from previous: All posts1 day7 days2 weeks1 month3 months6 months1 year Sort by AuthorPost timeSubject AscendingDescending
 Page 1 of 1 [ 9 posts ]

 All times are UTC

#### Who is online

Users browsing this forum: Google [Bot] and 3 guests

 You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum

Search for:
 Jump to:  Select a forum ------------------ General    Games / Demos    Help / Discussion    Community Projects    Game Ideas/Design    Slick Competition 2011    Android Slick - LWJGL 2D Game Library    Announcements    Bug Reports / RFE    Extensions    Contribution depot Related Libraries and Tools    Phys2D    Tiled    TWL    Fizzy    Artemis Archive    Resolved Bugs/RFE    Useful Posts