Anyone know of any custom collision map scripts?

jimfalcon

Veteran
Veteran
Joined
Oct 14, 2013
Messages
44
Reaction score
2
Primarily Uses
Isn't it supposed to be less about player pixels, and more about tile paths/collision though?
 

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,098
Reaction score
13,704
First Language
English
Primarily Uses
RMMV
Tile = 32x32


But you said basing collisions on tiles (32x32) is NOT what you want, because it forces you to stick with the paths in the first image.


I suppose if you wanted to divide each 32x32 tile up into 16 8x8 tiles, it would be better than checking at a pixel level. But you're still forcing yourself to use blocky movement, just on a smaller scale. And as tsukihime said, there's no way to set tiles passable or not at anything smaller than 32x32.
 
Last edited by a moderator:

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,564
Reaction score
3,846
First Language
English
So, let's say your pixel movement script lets you walk forward at 8 pixels each turn. That's 8x32 pixels that could be passable or impassable, and each one of those would have to be checked.
Which isn't that bad really, especially if you do something like bit-wise operators that venima suggests.


It's not like 256 comparisons is going to seriously lag things up on a modern computer; 3D games already probably do millions of computations per frame.
 
Last edited by a moderator:

jimfalcon

Veteran
Veteran
Joined
Oct 14, 2013
Messages
44
Reaction score
2
Primarily Uses
I use the word "tile" cuz I really don't know any other way to call the path the player can walk on.  But yeah, I would prefer pixel checking.

Out of curiosity when you say "I suppose if you wanted to divide each 32x32 tile up into 16 8x8 tiles" would someone need to make a script to do this?

http://rpgmaker.net/games/3082/images/38623/

This is that link eroj, posted before. Apparently this game has implemented pixel collision with a pixel movement script, but they give no clue as to how they did it.
 

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,098
Reaction score
13,704
First Language
English
Primarily Uses
RMMV
sinchross said:
The movement in the game is for pixel and the passability too. I make some tweaks using scripts made by a friend, and I don't need to use the passability of the rpgmaker editor anymore.
Yes, he has completely replaced the character movement in the engine with something custom. He's got pixel-based collision, not tile based, and not smaller than 32x32 but still tile based.

Which isn't that bad really, especially if you do something like bit-wise operators that venima suggests.


It's not like 256 comparisons is going to seriously lag things up on a modern computer; 3D games already probably do millions of computations per frame.
It's alright if you're ONLY using that for the player. If you have 20 NPC events that are also moving around, they would also have to do it.


Considering how easy it is to make an RM game lag, I'd say there's a pretty good chance that this would affect performance.
 
Last edited by a moderator:

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,564
Reaction score
3,846
First Language
English
I'd say better to write it first before commenting on performance.


20 NPC's doesn't sound like much of a big deal either.


If you think of ABS systems like Pearl ABS where you have massive enemies half the size of the screen (eg: 300x200) and your projectiles are supposed to do accurate hit-collision, they still seem to perform well.
 
Last edited by a moderator:

Venima

Treasure experiences and sensations, not progress.
Veteran
Joined
Oct 8, 2013
Messages
128
Reaction score
48
First Language
English
Primarily Uses
N/A
Using my suggestion you can get pixel accuracy with only about 35 to 70 calculations per event if those tiles have already been loaded. Almost all of which are bitwise calculations which are fast as lightning.

 

If events moved 1 pixel per tick, and there were 32 constantly moving events in the map, I've calculated on average 2000 bitwise calculations per tick, assuming a quarter are either full tiles or empty tiles. Considering 32 constantly moving events is quite a lot for a map I'd say this is pretty ok. 

So here's how it would roughly work:

Note I haven't tested this except the bitwise calculations.

First off, you create a new MapOfPixelTiles and create all its PixelTiles for the map.

Then whenever you want to check passability, call "collides?" from the MapOfPixelTiles class

class PixelTile pixelMesh = [] tileType = 0 TYPENONE = 0 TYPEALL = 1 TYPEPART = 2 # pixelmap is an array of rows of boolean values def load(pixelMap) pixelMesh = [] type = -1 for y=0; y<pixelMap.length; y++ row_int = 0 for x=0; x<y.length; x++ next if pixelMap[y][x] == false row_int += x==0 ? 1 : 2 << (x-1) end pixelMesh[y] = row_int if type != 2 case row_int when 0 type = type==1 ? 2 : 0 when -1 type = type==0 ? 2 : 1 else type = 2 end end end tileType = type end def hasloaded?() return pixelMesh.length > 0 end def collides?(rectx, recty, rectwidth, rectheight) return false if tileType == TYPENONE return true if tileType == TYPEALL rectmin = max(rectx, 0) rectmax = min(rectx+rectwidth-1, 31) start = max(recty, 0) fin = min(recty+rectheight-1, 31) bitmin = rectmin==0 ? 1 : 2 << (rectmin-1) bitmax = 2 << rectmax rect_val = bitmax - bitmin for y=start; y<fin; y++ return true if 0 != rect_val & pixelMesh[y] end return false endendclass MapOfPixelTiles pixelMap = [][] #the bitmap of collision pixels (from the image). Has to be an array of rows, not columns pixelTiles = [] #the list of tiles on the map (x+y*32 is the indexing) #pixelmap is an array of rows of boolean values def load(pixelMap, tilex, tiley) y = tilex*32; x = tiley*32 nexttilex = x + 32 nexttiley = y + 32 tile_pixelMap = [32][32] for ; y<nexttiley; y++ for ; x<nexttilex; x++ if y >= pixelMap.length || x >= pixelMap[y].length tile_pixelMap[y%32][x%32] = false else tile_pixelMap[y%32][x%32] = pixelMap[y][x] end end pixelTiles[tilex+tiley*32].load(tile_pixelMap) end def collides?(rectx, recty, rectwidth, rectheight) rectxi = rectx.to_i rectyi = recty.to_i tileminx = rectxi%32 tileminy = rectyi%32 tilemaxx = tileminx + rectwidth - 1 tilemaxy = tileminy + rectheight - 1 for y=tileminy; y<tilemaxy; y++ for x=tileminx; x<tilemaxx; x++ tile = pixelTiles[x+y*32] load(pixelMap,x,y) if !tile.hasloaded? return true if tile.collides?(rectxi-x*32, rectyi-y*32, rectwidth, rectheight) end end return false end end 
If it lags, you can instead save the PixelTiles with the game That way there's no loading mid-game.

Edit: the line "when -1" may need to change the number, depending on how Ruby stores its ints. This assumes it stores them as 32 bit, not 64 bit.
 
Last edited by a moderator:

jimfalcon

Veteran
Veteran
Joined
Oct 14, 2013
Messages
44
Reaction score
2
Primarily Uses
Seems to me like a script like this is rarer than I thought, and other than that rise of dragon souls creator, who still hasn't replied to me and doesn't seem like they will, no one knows of one :(
 
Last edited by a moderator:

Venima

Treasure experiences and sensations, not progress.
Veteran
Joined
Oct 8, 2013
Messages
128
Reaction score
48
First Language
English
Primarily Uses
N/A
I've given this some thought, and here's my conclusion:

1. I've seen tutorials of parallax map drawing, and the guy aligns trees and things "roughly" to the grid, so that grid collisions still work, but because it's rough, it still looks genuine. <- recommended option when possible

The parallax tutorial: http://www.youtube.com/watch?v=O_S36UFijr8 You probably don't need the tutorial, but just to demonstrate what I mean.

2. Another thing you could do is have scripted map movement, so when the player moves in a direction (or by mouse click?), you give them a move route to follow to the next node, etc. <- good for "town" maps with just a bunch of shops etc. and otherwise no interactivity.

3. But if you must have non-grid collisions, I recommend polygon checking:

So you construct a polygon of the moveable area like the image below by picking its points (fewer points, less chance of lag)...

PolygonExample.png

You then need to replace the standard map passability checking with a call to code like the following C++ I looted from http://stackoverflow.com/questions/217578/point-in-polygon-aka-hit-test (second answer):

This checks if a point is within a polygon.

//nvert is number of vertices in the polygon//vertx and verty are arrays of float x and y values//testx and testy is the point to test forint pnpoly(int nvert, float *vertx, float *verty, float testx, float testy){ int i, j, c = 0; for (i = 0, j = nvert-1; i < nvert; j = i++) { if ( ((verty>testy) != (verty[j]>testy)) && (testx < (vertx[j]-vertx) * (testy-verty) / (verty[j]-verty) + vertx) ) c = !c; } return c;} Note, in C++ 0 == false and 1 == true.

Rather than checking for the 4 corners of the player's boundary, you can just check the player's centre point, again, this will reduce processing required.


This will be far more efficient than pixel collisions.
 
Last edited by a moderator:

jimfalcon

Veteran
Veteran
Joined
Oct 14, 2013
Messages
44
Reaction score
2
Primarily Uses
Thanks for your info, it definitely helps, and I know you didn't have to help.

Polygon checking seems interesting. I'm wondering how I would draw out the polygon, can you do that in RPG maker VX ACE? And as for that code you provided, would I be able to just insert it into the script editor?
 
Last edited by a moderator:

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,098
Reaction score
13,704
First Language
English
Primarily Uses
RMMV
That code is C++ so you could not just paste it into the editor. And it's also just to determine if the point is in the passable area - it doesn't handle any of the actual movement.


You would need:


- a way to define the passable areas using a vertex list and save them to the map (this does not handle 'holes' in the area, so you'd need to cater for that as well)


- a pixel movement script that uses this formula to check for passability AND collision with other events and handles the actual movement


Movement would still be horizontal or vertical, unless you want to enable 8-dir movement, which requires further scripting in addition to extra sprites.


That looks very nice, Venima. My next game will require pixel movement, so I'd consider writing up something to help produce the vertex array and do the checks, but I'm not sure how to go about identifying the points along the ray that would need to be checked. Would you use a pixel movement script as a base, or write something completely from scratch?
 
Last edited by a moderator:

Venima

Treasure experiences and sensations, not progress.
Veteran
Joined
Oct 8, 2013
Messages
128
Reaction score
48
First Language
English
Primarily Uses
N/A
Essentially all you'll be doing is every time you check passability you grab the player or event's x and y, multiply by 32, add 16 to get the centre point, and call that function.

Getting the polygon points... I'll have to think about that. You could just use a paint program with your parallax in the background, draw up a polygon that fits and note down the pixel coordinates. Then you list them in the map notebox or something.
 

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,098
Reaction score
13,704
First Language
English
Primarily Uses
RMMV
But you're checking collision where you are going, not where you are now, which is going to be however many pixels away from your current location. COULD calculate the new location and just check that, instead of every point between the two, but that would allow you to cross over very narrow 'impassable' areas.
 

Venima

Treasure experiences and sensations, not progress.
Veteran
Joined
Oct 8, 2013
Messages
128
Reaction score
48
First Language
English
Primarily Uses
N/A
That shouldn't be a problem, movement speed isn't that great. But yes, I meant the future centre point.

I had a thought, if you have multiple polygons, you can first check their bounding box (rectangle that covers all points) to see which ones intersect the point, and check just those. I don't know how much more efficient that would be, but it's worth considering if it lags.
 

FenixFyreX

Fire Deity
Veteran
Joined
Mar 1, 2012
Messages
434
Reaction score
310
First Language
English
Primarily Uses
I've thought long and hard about these possibilities and I've also thought about possibly generating a vertex map of the entire map and saving it into a data file ('compiling' the map's passability into a vector-based map of sorts), using it throughout the game via a sort of 2D bitwise ray tracing.


Basically what would happen is when you need to check the passability of a move from point A to point B at X pixels away, you'd trace a line from each of the player's 'front' pixels to the final tile's, gather the map's bitwise values, bitwise AND them with the player, then calculate an average of how many pixels the player will collide with, and if less than a certain value then allow the move. (Not quite sure I explained my ideas too well here, reaaaaaly tired right now)


Another thing to think about when calculating pixel-based collision is where the player stands. Literally. The collision should happen sort of like a sprite's bush depth does, with the lower half of the sprite being taken into consideration. You can, in almost 85% of cases, ignore the top half of a sprite with collision detection. This eliminates half the amount of calculations we are expecting.


EDIT: This includes the player and event graphics, and layer 1-2 tiles as well (like the fences, etc); you can calculate their bitwise collision maps and 'compile' them into a file for a faster system. The only downfall to this is when you change the maps themselves, they'll need to be recompiled, but that shouldn't take but a few seconds to calculate (depending on size of project).


With that, good night x__x
 
Last edited by a moderator:

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Profile Posts

so hopefully tomorrow i get to go home from the hospital i've been here for 5 days already and it's driving me mad. I miss my family like crazy but at least I get to use my own toiletries and my own clothes. My mom is coming to visit soon i can't wait to see her cause i miss her the most. :kaojoy:
Couple hours of work. Might use in my game as a secret find or something. Not sure. Fancy though no? :D
Holy stink, where have I been? Well, I started my temporary job this week. So less time to spend on game design... :(
Cartoonier cloud cover that better fits the art style, as well as (slightly) improved blending/fading... fading clouds when there are larger patterns is still somewhat abrupt for some reason.
Do you Find Tilesetting or Looking for Tilesets/Plugins more fun? Personally I like making my tileset for my Game (Cretaceous Park TM) xD

Forum statistics

Threads
105,868
Messages
1,017,078
Members
137,580
Latest member
Snavi
Top