Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (499)
Games in Android Showcase (118)
games submitted by our members
Games in WIP (567)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Tile an image across a given x,y,height,width - slick2d  (Read 3212 times)
0 Members and 1 Guest are viewing this topic.
Offline agm_ultimatex

Senior Newbie





« Posted 2010-06-09 02:23:11 »

Been trying to figure this out. I have an ArrayList of my own Sprite class. The sprite class simply contains x, y, width, height, and a type Image from Slick. In my gameplaystate, I loop through the arraylist that contains all the ground sprites. I just have one in there for now. To pull in my ground image, i have it in the same .png as my player sprite. I just use the getSubImage() method to separate it. The problem is, when im using GL11 code to tile out the image, it has both the ground and character images in the tile, even though im referring to the subbed image. I might just be using it wrong, or perhaps there's a better way with slick methods to accomplish this. Here's my loop to draw out the ground objects:

Quote
public void drawSurfaces() {
      for(int i = 0; i < levels.size(); i++) {
         ArrayList<Sprite> tempGrounds = levels.get(i).getGrounds();
         for(int g = 0; g < tempGrounds.size(); g++) {
            Sprite ground = tempGrounds.get(g);
            ground.getGraphic().bind();
            // ground.getGraphic().draw(ground.getX(), ground.getY(), ground.getSizeX(), ground.getSizeY());
            float x = ground.getX();
            float y = ground.getY();
            float rightX = ground.getRightX();
            float bottomY = ground.getBottomY();
            // draw the pattern
            GL11.glBegin(GL11.GL_QUADS);
            GL11.glTexCoord2f(0, 0);
            GL11.glVertex2f(x, y);
            GL11.glTexCoord2f(3, 0);
            GL11.glVertex2f(rightX, y);
            GL11.glTexCoord2f(3, 3);
            GL11.glVertex2f(rightX, bottomY);
            GL11.glTexCoord2f(0, 3);
            GL11.glVertex2f(x, bottomY);
            GL11.glEnd();
         }
      }
   }

ground.getGraphic().draw(ground.getX(), ground.getY(), ground.getSizeX(), ground.getSizeY()); will draw out the correct image, but it stretches it. While my current ground image is just a single colour, learning to tile now will be better. Plus the stretched image doesn't look as good.
Offline Eli Delventhal

JGO Kernel


Medals: 42
Projects: 11
Exp: 10 years


Game Engineer


« Reply #1 - Posted 2010-06-09 03:15:57 »

Seems to me like you've got change the texcoord values. I don't really know Slick but it sounds like you've got an atlas and getSubImage() does some kind of magic to change the texture coordinates for the next draw call.

As such, reduce the texcoord values. I don't know what scale you've got there, but usually I use values between 0 and 1, so that 0.5 represents halfway, 0.75 is 3/4, etc. Looks like maybe you're doing it per sprite, so you would put 2 instead of 3.

See my work:
OTC Software
Offline agm_ultimatex

Senior Newbie





« Reply #2 - Posted 2010-06-09 22:29:21 »

Hmm, think i might crack open my book on opengl and read a bit about texture mapping, as this is starting to go over my head. I have tried messing around with the values. With 0,3 i see the image tiled 3 times across the rectangular area. Switching it to 0, 1 has it once. Now if i switch it to 0.5f, 1, I just see the character image once, not the one for my ground at all. This image just has a stickman, and then to the right of it, the ground.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Eli Delventhal

JGO Kernel


Medals: 42
Projects: 11
Exp: 10 years


Game Engineer


« Reply #3 - Posted 2010-06-09 23:51:03 »

Hmm, think i might crack open my book on opengl and read a bit about texture mapping, as this is starting to go over my head. I have tried messing around with the values. With 0,3 i see the image tiled 3 times across the rectangular area. Switching it to 0, 1 has it once. Now if i switch it to 0.5f, 1, I just see the character image once, not the one for my ground at all. This image just has a stickman, and then to the right of it, the ground.
Looks like you've got the values I would expect.

Say your atlas looks like this:
1  
2  
3  
4  
5  
__________
| 1    2 |
|        |
| 3    4 |
|________|

Let's add some lines in (purely imaginary, not part of the image data) to make it easier to visualize.
1  
2  
3  
4  
5  
__________
| 1 || 2 |
|___||___|
| 3 || 4 |
|___||___|

So our different sprites are the 1, the 2, the 3, and the 4. Pretend that they're more centered in the quadrants of the image.

If we wanted to draw the entire image, our texture coordinates would be:
1  
2  
3  
4  
GL11.glTexCoord2f(0,0); //Top left
GL11.glTexCoord2f(0,1); //Top right
GL11.glTexCoord2f(1,1); //Bottom right
GL11.glTexCoord2f(1,0); //Bottom left

Pretty simple, right? You're making your texture coordinates match your vertex coordinates in terms of which index you're looking at.

Now when you want to show just the 1, you keep the same vertex values but change your texture coordinates.
1  
2  
3  
4  
GL11.glTexCoord2f(0,0); //Top left
GL11.glTexCoord2f(0,0.5f); //Top right-side of '1'
GL11.glTexCoord2f(0.5f,0.5f); //Bottom right-side of '1'
GL11.glTexCoord2f(0.5f,0); //Bottom left-side of '1'


So, to show the 2 you would use:
1  
2  
3  
4  
GL11.glTexCoord2f(0.5f,0); //Starts to the right of '1'
GL11.glTexCoord2f(1,0); //Then goes to the end of the image
GL11.glTexCoord2f(1,0.5f); //Goes down half the image
GL11.glTexCoord2f(0.5f,0.5f); //Ends at the center


From there, you should be able to figure out how to show 3 and 4.

An easy way to find the tex coords of any rect in an image would be something like this:
1  
2  
3  
4  
5  
6  
7  
8  
9  
public Vector2f[] getTexCoords(int imageX, int imageY, int imageWidth, int imageHeight, int atlasWidth, int atlasHeight)
{
    Vector2f[] results = new Vector2f[4];
    results[0] = new Vector2f( ((float)imageX) / atlasWidth, ((float)imageY) / atlasHeight );
    results[1] = new Vector2f( results[0].x + ((float)imageWidth) / atlasWidth, results[0].y );
    results[2] = new Vector2f( results[1].x, results[0].y + ((float)imageHeight) / atlasHeight );
    results[3] = new Vector2f( results[0].x, results[2].y  );
    return results;
}

Where all those values are related to the atlas image itself - where, in pixels, the image you want starts, how big it is, and how big your whole atlas is.

See my work:
OTC Software
Offline agm_ultimatex

Senior Newbie





« Reply #4 - Posted 2010-06-09 23:56:40 »

Thanks a lot, that really gave me a clear picture of how the textcoords work. It's still not perfect. I may want to modify my image so it has the sprites in the quadrants evenly. Make it more of a spritesheet.
Offline Eli Delventhal

JGO Kernel


Medals: 42
Projects: 11
Exp: 10 years


Game Engineer


« Reply #5 - Posted 2010-06-10 16:56:56 »

1  
2  
3  
4  
5  
6  
7  
8  
[quote author=agm_ultimatex link=topic=22587.msg186545#msg186545 date=1276127800]
Thanks a lot, that really gave me a clear picture of how the textcoords work. It's still not perfect. I may want to modify my image so it has the sprites in the quadrants evenly. Make it more of a spritesheet.
[/quote]
Well an uneven atlas gives you a hell of a lot more flexibility, if you can get around to doing it. I have an atlas class that has an image coupled with a text file like this:

[code]
SpriteA 45 68 110 110
Monkey 155 200 250 250


Which is:
1  
SpriteName SpriteX SpriteY SpriteWidth SpriteHeight


Then you just read in each line, split it via spaces, and parse out the data into an object. Store that object in a HashMap and then access it via its SpriteName, then you draw it sort of like this:

1  
2  
SpriteAtlas atlas;
atlas.draw("SpriteName", x, y, width, height);

[/code]

See my work:
OTC Software
Offline agm_ultimatex

Senior Newbie





« Reply #6 - Posted 2010-06-10 22:46:37 »

Was working on it a bit last night, and I found that since the texture coords took the image and stretched it across, I ended up with the same problem. So i put together a method to essentially tile it, but I don't feel like it's very efficient or perfect.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
for(int i = 0; i < levels.size(); i++) {
         ArrayList<Sprite> tempGrounds = levels.get(i).getGrounds();
         for(int g = 0; g < tempGrounds.size(); g++) {
            Sprite ground = tempGrounds.get(g);
            Image groundGraphic = ground.getGraphic();
            int gWidth = groundGraphic.getWidth();
            int gHeight = groundGraphic.getHeight();
            int xTimes = (int)ground.getSizeX() / gWidth;
            int yTimes = (int)ground.getSizeY() / gHeight;
            if(xTimes <= 0) {
               xTimes = 1;
            }
            if(yTimes <= 0) {
               yTimes = 1;
            }
            for(int x = 0; x < xTimes; x++) {
               for(int y = 0; y < yTimes; y++) {
                  groundGraphic.draw(ground.getX() + (gWidth * x), ground.getY() + (gHeight * y), gWidth, gHeight);
               }
            }            
         }
      }


Due to the fact im dividing intergers, I know there will be a loss of accuracy, and therefore rendered images will actually be in some cases shorter than the actual block. I think this has a bigger problem of leading to a lot of computation when more and more gets added as a process.
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Pippogeek (39 views)
2014-09-24 16:13:29

Pippogeek (30 views)
2014-09-24 16:12:22

Pippogeek (19 views)
2014-09-24 16:12:06

Grunnt (45 views)
2014-09-23 14:38:19

radar3301 (27 views)
2014-09-21 23:33:17

BurntPizza (63 views)
2014-09-21 02:42:18

BurntPizza (33 views)
2014-09-21 01:30:30

moogie (41 views)
2014-09-21 00:26:15

UprightPath (50 views)
2014-09-20 20:14:06

BurntPizza (54 views)
2014-09-19 03:14:18
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!