Slick Forums

Discuss the Slick 2D Library
It is currently Wed Jul 17, 2019 1:15 pm

All times are UTC




Post new topic Reply to topic  [ 9 posts ] 
Author Message
PostPosted: Sat Feb 18, 2012 11:03 pm 
Offline

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
 Profile  
 
PostPosted: Sun Feb 19, 2012 2:01 am 
Offline
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
 Profile  
 
PostPosted: Sun Feb 19, 2012 3:54 am 
Offline

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


Top
 Profile  
 
PostPosted: Sun Feb 19, 2012 10:24 am 
Offline
Game Developer
User avatar

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 :o

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

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


Top
 Profile  
 
PostPosted: Sun Feb 19, 2012 3:59 pm 
Offline

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
 Profile  
 
PostPosted: Sun Feb 19, 2012 6:33 pm 
Offline
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
 Profile  
 
PostPosted: Mon Feb 20, 2012 12:07 am 
Offline

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
 Profile  
 
PostPosted: Mon Feb 20, 2012 12:14 am 
Offline

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
 Profile  
 
PostPosted: Mon Feb 20, 2012 12:52 am 
Offline

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
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 9 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


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

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group