Slick Forums

Discuss the Slick 2D Library
It is currently Sat May 25, 2013 12:26 pm

All times are UTC




Post new topic Reply to topic  [ 23 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Wed May 30, 2007 3:49 am 
Offline
Slick Zombie

Joined: Sat Jan 27, 2007 7:10 pm
Posts: 1469
Hey there. I believe the geom package is in need of some reworking.

Here are some problems I'm having with it:
Code:
- Unlike the rest of Slick, the framework hard to understand and extend. I wanted to create my own RoundedRectangle shape but I didn't have a clue where to start.
- Shape classes are expensive. They gather all the points at creation-time. RoundedRectangle and Ellipse both use ArrayLists and primitive type wrappers to build the array of points. Translating and resizing shapes (such as a Circle) is costly since every point must be changed. This seems unnecessary when you only wish to use shapes for simple tasks such as Circle to Circle collision.
- Shape variables are public (x, y, radius, width, etc) but changing them directly will do nothing.
- Line doesn't implement Shape, but if it did there would be confusion with method names (setX1/setY1 etc).
- Certain shapes have limitations because of the point gathering. RoundedRectangle can't have it's width/height changed, for example.
- Shape.contains(int,int) is broken (see PolygonTest webstart).


I personally like the way AWT handles geometry. It renders points using a PathIterator that is very flexible.

Just my two cents...


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 30, 2007 4:55 am 
Offline
Oldbie

Joined: Tue Nov 28, 2006 6:18 pm
Posts: 429
Although I'm personally satisfied with using Phys2D for this, there needs to be a richer set of functionality for collision detection, more than just "does it collide or not?" kind of collision detection, which is hardly adequate for most games.

- Jon


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 30, 2007 6:05 am 
Offline
Site Admin
User avatar

Joined: Thu Jan 01, 1970 12:00 am
Posts: 3143
I'm sure Cap has some feedback too.

Quote:
- Shape classes are expensive. They gather all the points at creation-time. RoundedRectangle and Ellipse both use ArrayLists and primitive type wrappers to build the array of points. Translating and resizing shapes (such as a Circle) is costly since every point must be changed. This seems unnecessary when you only wish to use shapes for simple tasks such as Circle to Circle collision.


The geom classes are intended to be stateful, i.e. you hand on to them and reuse.

Quote:
- Unlike the rest of Slick, the framework hard to understand and extend. I wanted to create my own RoundedRectangle shape but I didn't have a clue where to start.


That's a bit of a matter taste I think. I found the API pretty easy to get on with. It all seemed to flow pretty nicely.

Quote:
- Shape variables are public (x, y, radius, width, etc) but changing them directly will do nothing.
- Line doesn't implement Shape, but if it did there would be confusion with method names (setX1/setY1 etc).
- Certain shapes have limitations because of the point gathering. RoundedRectangle can't have it's width/height changed, for example
- Shape.contains(int,int) is broken (see PolygonTest webstart).


All sound like Bugs or RFEs

Quote:
Although I'm personally satisfied with using Phys2D for this, there needs to be a richer set of functionality for collision detection, more than just "does it collide or not?" kind of collision detection, which is hardly adequate for most games.


Anthing more than that and you're deliving into game specifics which Slick tries to stay well away from. I also can't help but chuckle at "hardly adequate for most games" - that's a very specific set of "most games" you've got there. It's more than adequate for a hell of a lot of games! :)

Kev


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 30, 2007 7:28 am 
Offline
Game Developer

Joined: Sun Nov 12, 2006 11:18 pm
Posts: 890
Location: Germany
I think the geom package is pretty good. It has a few bugs (see my other thread) but it's the first committed version...
For the Shape.contains(int, int) - the implementation of this method is simply missing at the moment (at least for polygons).

I found a nice link http://www.visibone.com/inpoly where some implementations of "point in polygon" are mentioned, the author's version even in source code (44 lines, 1 loop, 3 if statements, 2 multiplies and no divide :wink: ).

Maybe we can port one of those implementations (simple C or Tcl) to Java and add it to Shape/Polygon.

_________________
Right Angle Games | Marte Engine
Back to the past | Star Cleaner | SpiderTrap


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 30, 2007 7:35 am 
Offline
Oldbie

Joined: Tue Nov 28, 2006 6:18 pm
Posts: 429
kevglass wrote:
It's more than adequate for a hell of a lot of games! :)

Kev


Really? Just about every kind of game I have my eyes upon needs more than just an on/off detection for collision, including the following:

- Jump and Run (Mario)
- Action RPG's like Zelda (i.e. hitting an enemy from one side pushes them in that direction)
- Action titles (Mega Man) - Same reasons as above.
- Overhead Shooters (Virium) - Same reasons as above. Now, you didn't use it, but had you gotten further, you would have needed it for more realistic reponses to being hit by weapons for example.
- Fighting Games
- Racing Games - Probably a good idea to know more than just on/off collisions...
- Sports Games (Golf, Tennis, Football, Table Hockey) - Definitely need to know things like direction here.

Basically, anything with physical action demands it, and the kinds of games that do not require it are puzzle games, shmups, and simpler overhead games that just need walking around.

It just so happens that the types of games I cite are games aren't being made with Slick to date. The few exceptions being those that are are made by you, and you used Phys2D for them. ;)

Just as a little fun exercise, I have a list of genres and subgenres that people have thrown at me in the past month. Virtually all of them would require a lot more than just on/off collisions, and a ton of genres are reflected here.

http://forums.stencyl.com/showthread.php?tid=1006

- Jon


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 30, 2007 8:37 am 
Offline
Site Admin
User avatar

Joined: Thu Jan 01, 1970 12:00 am
Posts: 3143
No they all *could* require more than on/off - you could just entity position, reflection of velocities or anything else thats game specific for this.

All of the games listed above could be written with simple on/off collision.

All of the above *may* need direction etc. But that has nothing to do with geometry.

OOI, how many of the game genres lists in the forum post have you (or the team) implemented to a more than demo level?

EDIT: Rethought the above, sounds a bit offensive. Not really intended that way. Either way the things you're talking about don't require changes to the geometry package, they require a collision package with some generic handling which you've already done in SlickSet as I understand. So there's no beef here at all. I do still disagree the *most* games require more than this given how many games were written when it wasn't computationally possible to get the info - but I guess we'll just have to disagree.


Kev


Last edited by kevglass on Wed May 30, 2007 8:56 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Wed May 30, 2007 10:04 am 
Offline
User avatar

Joined: Fri May 04, 2007 5:58 pm
Posts: 72
kevglass wrote:
All of the games listed above could be written with simple on/off collision.


kevglass wrote:
Either way the things you're talking about don't require changes to the geometry package, they require a collision package with some generic handling which you've already done in SlickSet as I understand.


I think you're right. Geometry package just need to fix the bugs (and possibly polish the RFEs) that davedes has found, and limit to answer to "is this point inside this shape?" or "are these shapes intersecting?". A _possible_ expansion would be "what shape is the intersection of these two", but while it's not needed I expect nobody to do it. :D A collision mechanism, then, will use the point-in-shape test and compare location/velocities/etc. of the game-specific actors (or your engine-specific ones) to add more info to the collision (from what direction? What's the resulting velocities of the crash?). Of course, this can be abstracted too, it just doesn't fit in basic geometry.


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 30, 2007 10:20 am 
Offline
User avatar

Joined: Fri May 04, 2007 5:58 pm
Posts: 72
davedes wrote:
Translating and resizing shapes (such as a Circle) is costly since every point must be changed. This seems unnecessary when you only wish to use shapes for simple tasks such as Circle to Circle collision.


What is the best OO hierarchy por geometry sistems is the subject of tons of scientific articles, I've read some of them and found no perfect solution.

For efficiency, I'd make two broad categories of shapes, with all its members subclassing Shape itself:

-"Easy" shapes: Circle, Ellipse, Rectangle, (possibly) Square, etc. These don't have to maintain a list of points. They will be needed for render... then let them be calculated there. And if you want you can keep that list cached within the object and in every render look if it's needed to be rebuilt and/or adjusted or you can just use it as-is, for maximum efficiency (a circle used just for collisions won't have its points calculated EVER, why should they be?). But however these inner-workins don't have to be in the interface.

-"Complex" shapes: ArbitraryPolygon. Have a list of points that has to be updated every time you change the polygon, because it can be consulted always. (Perhaps could make the top/left point the 0,0 and then translations don't have to update the points... or perhaps not.) This list will have to be in the public interface, because it can be useful to the coder for whatever.

The trick here is that some transformations will change the type from one easy shape to the complex one, for example, Circle.transform(Matrix m) would return ArbitraryPolygon, even if it's not needed (m is simply a translation matrix), but if we can assure the result we can do better, like Circle.translate(float x, float y) return Circle and Circle.scale(float xFactor, float yFactor) return Ellipse. Note that it's difficult (that means, I wouldn't even try to do it) to return from a complex shape to a easy one... Sound almost philosophical. xD

And in the superclass it is simply Shape.translate(x, y) that returns Shape, of course.

My two cents (love these SW engineering subjects :D).


Top
 Profile  
 
PostPosted: Wed May 30, 2007 12:27 pm 
Offline
Regular

Joined: Wed Feb 07, 2007 4:04 am
Posts: 107
Quote:
- Unlike the rest of Slick, the framework hard to understand and extend. I wanted to create my own RoundedRectangle shape but I didn't have a clue where to start.

There is already a RoundedRectangle in the package. (Just went in a couple of days ago)
Quote:
- Shape classes are expensive. They gather all the points at creation-time. RoundedRectangle and Ellipse both use ArrayLists and primitive type wrappers to build the array of points. Translating and resizing shapes (such as a Circle) is costly since every point must be changed. This seems unnecessary when you only wish to use shapes for simple tasks such as Circle to Circle collision.

There is a trade off here. The reason all the points are generated at creation is for transformations to work properly. On the plus side, rendering will be faster since the points are not generated every frame.
Quote:
- Shape variables are public (x, y, radius, width, etc) but changing them directly will do nothing.

They should not have been made public. I will have to fix that.
Quote:
- Line doesn't implement Shape, but if it did there would be confusion with method names (setX1/setY1 etc).

setX/setY specifically say they set the left/top of the shape.(This translates the shape, not change its shape.) So there would be no confusion if Line were included in Shape since setX1/2 setY1/2 sets the points of the line.
Quote:
- Certain shapes have limitations because of the point gathering. RoundedRectangle can't have it's width/height changed, for example.

Actually it can, but not from the general Shape class. It would have to be done in the RoundedRectangle specifically.(I will have to add this since it is not in there right now.) Unfortunately that does mean the points will have to regenerated.
Quote:
- Shape.contains(int,int) is broken (see PolygonTest webstart).

I'll look into this.
Quote:
I personally like the way AWT handles geometry. It renders points using a PathIterator that is very flexible.

I don't know how PathIterator works. I will look at it to see.


Last edited by CaptainJester on Wed May 30, 2007 12:32 pm, edited 2 times in total.

Top
 Profile  
 
 Post subject:
PostPosted: Wed May 30, 2007 12:29 pm 
Offline
Regular

Joined: Wed Feb 07, 2007 4:04 am
Posts: 107
Tommy wrote:
I think the geom package is pretty good. It has a few bugs (see my other thread) but it's the first committed version...
For the Shape.contains(int, int) - the implementation of this method is simply missing at the moment (at least for polygons).

I found a nice link http://www.visibone.com/inpoly where some implementations of "point in polygon" are mentioned, the author's version even in source code (44 lines, 1 loop, 3 if statements, 2 multiplies and no divide :wink: ).

Maybe we can port one of those implementations (simple C or Tcl) to Java and add it to Shape/Polygon.


:oops: Yeah, I just saw that I forgot to implement that. Thanks.

Thanks for the link, I'll check it out.


Top
 Profile  
 
PostPosted: Wed May 30, 2007 1:43 pm 
Offline
User avatar

Joined: Fri May 04, 2007 5:58 pm
Posts: 72
CaptainJester wrote:
There is a trade off here. The reason all the points are generated at creation is for transformations to work properly.


But we could generate them _when_ a transformation that needs them is applied or _when_ a shape is rendered... And if we don't use that (for example, bounding spheres) we don't. And if I translate the shape twenty times before rendering we only calculate the points once, at the render, not every single time.

The best of two worlds, isn't it?

CaptainJester wrote:
On the plus side, rendering will be faster since the points are not generated every frame.


We can have a list of points (possibly uninitialized) and a dirty flag. There is absolutely no need to generate the list every frame if it's not needed, just when somebody read it and it's dirty.


Top
 Profile  
 
PostPosted: Wed May 30, 2007 7:55 pm 
Offline
Regular

Joined: Wed Feb 07, 2007 4:04 am
Posts: 107
Serandel wrote:
We can have a list of points (possibly uninitialized) and a dirty flag. There is absolutely no need to generate the list every frame if it's not needed, just when somebody read it and it's dirty.


That sounds like a good plan. What do you think Kev? It won't be much work to set it up that way.


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 30, 2007 8:55 pm 
Offline
Site Admin
User avatar

Joined: Thu Jan 01, 1970 12:00 am
Posts: 3143
Seems sound to me :) I'm a little worry we're changing the API here which might have knock on effects for people already using this stuff. Go ahead and make the changes for sure, but could we have something that describes what might change from say build 144 (or somewhere around there).

Kev


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 30, 2007 8:59 pm 
Offline
Slick Zombie

Joined: Sat Jan 27, 2007 7:10 pm
Posts: 1469
Quote:
The geom classes are intended to be stateful, i.e. you hand on to them and reuse.

All I'm saying is that Slick's geom has become extremely expensive compared to what it used to be.

In my current RPG, I've had to ditch the current geom package and revert back to the old stuff. In my game, Circles aren't used for rendering, only for bound checks. When a missile spell is cast, a new Circle needs to be created for its bounds.
Since there can be hundreds of Circles at once, new ones being created constantly, and each Circle moving independently, things can get slow. I'm only using Circle for bound checking, so all this extra stress isn't necessary.

Quote:
We can have a list of points (possibly uninitialized) and a dirty flag. There is absolutely no need to generate the list every frame if it's not needed, just when somebody read it and it's dirty.

This is a great idea which could boot performance all around.

Quote:
The reason all the points are generated at creation is for transformations to work properly.

From my understanding, AWT transforms shapes when rendering. For example, it would look something like:
Code:
public void draw(Graphics g, Shape s) {
    Transform trans = g.getTransform();
    PathIterator p = shape.getPathIterator(trans);
    while (!p.isDone()) {
        // process each iteration of points
    }
}


Serandel's idea seems more efficient for Slick though. :)


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 31, 2007 3:04 am 
Offline
Regular

Joined: Wed Feb 07, 2007 4:04 am
Posts: 107
kevglass wrote:
Seems sound to me :) I'm a little worry we're changing the API here which might have knock on effects for people already using this stuff. Go ahead and make the changes for sure, but could we have something that describes what might change from say build 144 (or somewhere around there).

Kev


This shouldn't affect anything except performance. I'll just move the creation of the points to a different spot, plus have the dirty flag, of course.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 23 posts ]  Go to page 1, 2  Next

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