Slick Forums

Discuss the Slick 2D Library
It is currently Tue May 21, 2013 5:09 am

All times are UTC




Post new topic Reply to topic  [ 12 posts ] 
Author Message
 Post subject: making a pixelated game
PostPosted: Sun Jun 24, 2012 11:36 am 
Offline

Joined: Sat Jun 23, 2012 4:14 pm
Posts: 74
Location: Germany
Hello I'm new to game development and Slick2D! :D

I want to build a pixelated game, but I don't know how to achieve the following things:

  • scaling the whole game without having to call .setFilter(Image.FILTER_NEAREST) on every Image I will ever use
  • scaling without changing the game logic *

* Example: I've added the following check to the update method of the first game tutorial to ensure that the plane cannot leave the screen. Although when using g.scale(2f, 2f) the call plane.getWidth() still returns 122 despite the plane being larger. Hence the plane can leave the window and the game logic is dependent on the scaling factor.

Code:
if (x > app.getWidth()-plane.getWidth())
{
   x = app.getWidth()-plane.getWidth();
}
if (y > app.getHeight()-plane.getHeight())
{
   y = app.getHeight()-plane.getHeight();
}


I'd love to do all the calculations as if the whole game isn't scaled, because I want to keep it as simple as possible.

Please correct me if I am wrong (btw. english isn't my mother tongue).
Thanks for your help! :wink:


Top
 Profile  
 
PostPosted: Sun Jun 24, 2012 4:59 pm 
Offline
Slick Zombie

Joined: Sat Jan 27, 2007 7:10 pm
Posts: 1467
1. You can't do that. The filter is determined by OpenGL on a per-texture basis. Instead what you should be doing is setting the filter when you load a new sprite sheet. Keep in mind that since it's on a per-texture basis (not per-image), any copies/sub-images/etc of an image will share the same filtering. So you tend to do something like this:
Code:
mySpriteSheet = new Image("res/spriteSheet.png", false, Image.FILTER_NEAREST);


2. getWidth returns the width of your image -- it has no way of knowing whether the "view" or "camera" is being scaled. You need to account for this yourself, i.e. by multiplying the width by the zoom amount. How you implement this is up to you; but I'd suggest reading up on OO "design patterns" before you try and mash together a system. :)


Top
 Profile  
 
PostPosted: Mon Jun 25, 2012 3:46 pm 
Offline

Joined: Sat Jun 23, 2012 4:14 pm
Posts: 74
Location: Germany
davedes wrote:
1. You can't do that. The filter is determined by OpenGL on a per-texture basis. Instead what you should be doing is setting the filter when you load a new sprite sheet. Keep in mind that since it's on a per-texture basis (not per-image), any copies/sub-images/etc of an image will share the same filtering. So you tend to do something like this:
Code:
mySpriteSheet = new Image("res/spriteSheet.png", false, Image.FILTER_NEAREST);

Thats nice!

davedes wrote:
2. getWidth returns the width of your image -- it has no way of knowing whether the "view" or "camera" is being scaled. You need to account for this yourself, i.e. by multiplying the width by the zoom amount. How you implement this is up to you; but I'd suggest reading up on OO "design patterns" before you try and mash together a system. :)


Multiplying the width with the zoom factor didn't work, but the following did:
Code:
int bw = app.getWidth() / SCALING_FACTOR - plane.getWidth();
int bh = app.getHeight() / SCALING_FACTOR - plane.getHeight();

if (x <= 0)
{
   x = 0;
}
else if (x > bw)
{
   x = bw;
}
if (y <= 0)
{
   y = 0;
}
else if (y > bh)
{
   y = bh;
}


What sort of design patterns where you thinking about? (So I have a point to start)

Thanks for your answers!


Top
 Profile  
 
PostPosted: Sun Jul 01, 2012 1:24 pm 
Offline

Joined: Sat Jun 23, 2012 4:14 pm
Posts: 74
Location: Germany
Sorry for double post.

davedes wrote:
1. You can't do that. The filter is determined by OpenGL on a per-texture basis.


I wonder why there is no way to set the default filter, which is obviously Image.FILTER_LINEAR, so that I don't have to setFilter per texture?


Top
 Profile  
 
PostPosted: Sun Jul 01, 2012 4:30 pm 
Offline

Joined: Mon Jun 18, 2012 1:58 pm
Posts: 11
snapy666 wrote:
Sorry for double post.

davedes wrote:
1. You can't do that. The filter is determined by OpenGL on a per-texture basis.


I wonder why there is no way to set the default filter, which is obviously Image.FILTER_LINEAR, so that I don't have to setFilter per texture?


Make a static Resources class that you load all your sounds, spritesheets, and images through.

Have a method in the Resources class like this:

Code:
public static Image loadImage(String fileName)
{
Image newImage = new Image(fileName);
newImage.setFilter(Image.FILTER_NEAREST);
return newImage;
}


and when you want to load an Image do this:

Code:
Image myTexture = Resources.loadImage("resources/textures/texture1.png");


Done :)


Top
 Profile  
 
PostPosted: Sun Jul 01, 2012 4:37 pm 
Offline

Joined: Sat Jun 23, 2012 4:14 pm
Posts: 74
Location: Germany
Doomsphere wrote:
Make a static Resources class that you load all your sounds, spritesheets, and images through.

Done :)


Okay :P, thank you!


Top
 Profile  
 
PostPosted: Tue Jul 03, 2012 3:54 am 
Offline
Slick Zombie

Joined: Sat Jan 27, 2007 7:10 pm
Posts: 1467
Slick is just a wrapper around OpenGL, which uses LINEAR filtering by default. We could in theory have something like this:
Code:
Image.setDefaultFilter(Image.FILTER_NEAREST);

Which would affect all images loaded after that call. This isn't exactly 100% "clean" from a design perspective, since the texture loading is done in another area of Slick (InternalTextureLoader), but many users have asked for it as a feature...


Top
 Profile  
 
PostPosted: Tue Jul 03, 2012 1:33 pm 
Offline

Joined: Tue Jul 03, 2012 1:25 pm
Posts: 3
How would you set FILTER_NEAREST for an Animation? I'm getting the animation from a spritesheet, so I tried to set the filter with:

Code:
spritesheet = new SpriteSheet(ref, ResourceLoader.getResourceAsStream(ref), tw, th);
spritesheet.setFilter(Image.FILTER_NEAREST);


But that didn't seem to have any effect. I also tried to get every image in the animation and manually set the filter, then re-add it to the animation:

Code:
Animation tmpanimation = new Animation(spritesheet, duration);
animation = new Animation();
for (int i = 0; i < tmpanimation.getFrameCount(); i++) {
   Image img = tmpanimation.getImage(i);
   img.setFilter(Image.FILTER_NEAREST);
   animation.addFrame(img.getFlippedCopy(false, true), tmpanimation.getDuration(i));
}


But that didn't seem to change anything either. Is there a proper way to do this that I'm missing? Thanks!


Top
 Profile  
 
PostPosted: Tue Jul 03, 2012 11:34 pm 
Offline
Slick Zombie

Joined: Sat Jan 27, 2007 7:10 pm
Posts: 1467
Sprite sheets use nearest neighbour filtering by default. And setFilter works fine here... What kind of result are you getting? Try pulling from dev branch as it may be a bug with older versions of Slick.


Top
 Profile  
 
PostPosted: Wed Jul 04, 2012 1:39 pm 
Offline

Joined: Sat Jun 23, 2012 4:14 pm
Posts: 74
Location: Germany
davedes wrote:
Which would affect all images loaded after that call. This isn't exactly 100% "clean" from a design perspective, since the texture loading is done in another area of Slick (InternalTextureLoader), but many users have asked for it as a feature...


I am for it, but then I think it should be a clean implementation. (Without knowing the code, would g.setDefaultFilter or InternalTextureLoader.setDefaultFilter work?)


Top
 Profile  
 
PostPosted: Tue Jul 24, 2012 1:02 pm 
Offline

Joined: Sat Jun 23, 2012 4:14 pm
Posts: 74
Location: Germany
davedes wrote:
Slick is just a wrapper around OpenGL, which uses LINEAR filtering by default. We could in theory have something like this:
Code:
Image.setDefaultFilter(Image.FILTER_NEAREST);

Which would affect all images loaded after that call. This isn't exactly 100% "clean" from a design perspective, since the texture loading is done in another area of Slick (InternalTextureLoader), but many users have asked for it as a feature...

When (if) will you change it?


Top
 Profile  
 
PostPosted: Mon Aug 06, 2012 1:46 pm 
Offline
Slick Zombie

Joined: Sat Jan 27, 2007 7:10 pm
Posts: 1467
After consideration, I've realized it would lead to a design error. The filter is set by the Texture, not the Image. For example:
Code:
imageA = spriteSheet.getSubImage(0, 0, 25, 25);
//=> imageA and spriteSheet share the same filtering

imageA.setFilter(Image.FILTER_NEAREST);
//=> now imageA and spriteSheet both use FILTER_NEAREST

imageB = new Image(imageA);
//=> now imageB shares the same filtering as imageA, regardless of what we expect our "default filter" to be

spriteSheet.setFilter(Image.FILTER_LINEAR);
//=> now imageA, imageB and spriteSheet are all using FILTER_LINEAR


Is it really hard to add an extra parameter to your code?
Code:
new Image("path.png", false, MY_DEFAULT_FILTER);


NB: The latest push allows you to construct an image without needing the "flipped" boolean parameter.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 12 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


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:  
Powered by phpBB® Forum Software © phpBB Group