Samapico Posted May 11, 2006 Report Posted May 11, 2006 I'm dreaming of being able to select multiple parts of the map at once with shift and/or exclude some parts of the selection with ctrl... to have selections with weird shapes.... That'd be awesome... but first, selection needs to be made layer-like, so it can be flipped/rotated/whatever... then it would be possible to do itI think the hardest part won't be to tell the program which tile is part of the selection and which isnt... but to draw a dotted line around them ô.o mhm... end of my dream... back to work
»SOS Posted May 11, 2006 Report Posted May 11, 2006 Photoshop-like selections? Would be neat. But not very important. Get WallTiles done first!
Drake7707 Posted May 11, 2006 Report Posted May 11, 2006 Actually it's a good thing you mentioned this before i changed the selection, as this method will replace any normal selection) i've also thought about that, but some polygon shape != rectangle, thus in my mind: "too hard, forget it" and about the line around it, maybe this will work for each tile in the area, test left up down and right if they are outside the area, that way you know if the tile you currently have is at a side of the area or not. But that would make (if there are n tiles in the area) = n*(n-1) as complexity just to check where the sides are Optimize nr 1: find 1 side, and instead of picking the next one in the array of the area, take the ones surrounding the one you had, so you iterate over the sides. Note that this requires some not just an array with tiles, but sorted somehow. Well i would think of a 1024*1024 array of booleans, the size of a boolean array is much much smaller anyway so (1024bit*1024bit = 131072bytes ~~ 131kb, which is acceptable). now you have like 0 0 0 0 0 0 1 1 0 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 soooooooooo start searching for a side, the first one will be the X 0 0 0 0 0 0 X 1 0 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 as the test gives true that current is 1 but left is 0, so a side (note that it could also be a corner if above was 0 but let this aside for now) so you got a side, draw the selection according to the 0's surrounding now to the next side/corner whatever if you're lucky one of the surrounding tiles are 1 and pick one of those (or all of them in a recursive way) and repeat (8 ways not so you have diagonally too !!!). Now if there can be like 0 0 0 0 0 0 X 1 0 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 where the selection exists of 2 parts, you can only handle one part in the way above, so at one point you'll have 0 0 0 0 0 0 X X 0 X X 0 0 0 0 0 0 0 X 1 1 X 1 1 X 0 0 0 1 0 0 0 X 1 X X 1 X 0 0 0 1 1 0 0 0 X 0 0 X X 0 0 0 0 0 0 0 0 0 0 0 0 0 0 soooo you'll have to look further for a next area but you'll also have to see that you don't have the same part over and over again. Actually come to think of it, when drawing a selection it's way easier, because you actually click the tile where the surrounding tiles become sides or become non-sides so when you draw the selection, or append it, you adapt the array on the fly, so when you draw a new selection: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + - - - - + 0 0 0 0 0 0 0 | 0 0 0 0 | 0 0 0 0 0 0 0 | 0 0 0 0 | 0 0 (i know my ascii skills suck) 0 0 0 0 0 + - - - - + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 this will be the array once you mouse up 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 so you know exactly which tiles will be the sides (you'll have to iterate over the sides of the rectangle of the selection in about the same way i did to check if the selection contains special objects) now when you do another selection for sel+ (add a part) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 + - - - - + 1 1 1 1 0 0 0 | 0 0 0 1 | 1 1 1 1 0 0 0 | 0 0 0 1 | 1 1 1 1 0 0 (my ascii skills still suck) 0 + - - - - + 0 0 0 0 0 0 you do pretty much the same thing, you check the sides of the rectangle as these are the tiles that could change to sides or fall back to non sides and now my brain hurts i know that after seeing this post the topic will change to wet nightmare
Drake7707 Posted May 11, 2006 Report Posted May 11, 2006 although a selection around stuff is standard, there are other ways to show to the user which tiles are selected tho, like highlighting the tiles (make them a little lighter) That would involve a secondary picturebox that makes the tileset lighter (e.g raise every r, g and b value with 50-100), this tileset is prerendered so it doesn't have to be regenerated at each selection (just create it once the tileset is loaded)that shouldn't take too much time to do, a tileset isn't that big now not only my brain hurts, my arms also hurt note to self: don't type pages of text while laying on my bed, resting on my elbows ----- alrighty pseudo code here we come in selection class: dim selectedtiles(1024,1024) as boolean 'array that tells if tile is selected or not dim seltiles() as integer 'array that stores all tiles that are selected (actually all tiles that are in the bounding box of the polygon from the selection) dim moved as boolean dim boundaries as RECT 'where RECT is a struct with left top right and bottom sub mousedown() start: 'selection must be set to drawing if we use sel+ or sel- if shift or ctrl is down and not moved then 'cant change a selection anymore once it moved, becuase it's copied to the seltiles array selection = drawing end if if selection drawing then 'we'll start drawing a selection 'init a selection shpselection visible and such things else if selection appending then 'we only come here if the user didn't use sel+ or sel- 'so first thing to check: did we click in the selection to move it ? ' yes ? ok we'll prepare for moving the selection if not clicked in selection then ' or rather if not selectedtile(curenttilex,currenttiley) then ' no ? remove the current selection and start drawing a new one stopselecting updatepreview 'now that we removed the other selection, go back to start goto start else 'we'll move the selection, don't don't do anything just yet end if end if end sub sub mousemove() if selection drawing then 'draw the selection as usual, regardless if there are already other tiles selected call DrawRectangleOnPreview updatepreview else if selection appending then ' we're moving a selection ' check if we have actually moved it by a tile, if so if moved then 'this is true when we have moved the selection before, not if we actually moved it else 'we havent moved it until now 'copy the entire portion of tiles within the boundaries to the seltiles for each tile within boundaries seltiles(i-boundaries.left, j-boundaries.top) = tile(i,j) next end if 'change the offset of the boundaries with the moving boundaries= boundaries+ nrOfTilesMovedSinceMouseDown 'can also be negative if moving to the left or top 'create the picture of the selection in the picselection 'the picselection size = the size of the picpreview (duh visible part) 'so we need to know what the offset is of the selection at the left side of the picpreview, so we can know which tiles 'are out of sight at the left side, same for top offset CreateVisibleSelectionRegion 'THIS could also be in the updatepreview section: 'actually it's better to move this in the updatepreview, because when you scroll left or right or up or down the 'selection is still active and still needs to be drawn 'draw picselection onto the picpreview 'the tiles that are not in the selection won't be drawn onto the picselection, and the background of picselection 'is white so: transparentblt picpreview.hdc, 0,0, picpreview.width, picpreview.height, picselection,0,0, rgb(255,255,255) 'END THIS end if end sub sub mouseup() if selection drawing then 'now we have a rectangle, the problem is that it could contain parts of a object such as wormhole 'so adapt the current offsets of the selection first CheckAndChangeSelectionForPartlySelectedObjects() if selection+ then 'there hasn't been tiles selected 'add the selected region to the selectedtiles for each tile selected (selstartx/y --> selendx/y) selectedtiles(i,j) = true next else if selection- then 'put selected tiles back to non-selecting for each tile selected (selstartx/y --> selendx/y) selectedtiles(i,j) = false next else 'uhhh nothing else end if 'calculate the bounding box of the selected part ( min left, min top, max right, max bottom of all selected tiles) 'and store them calcBoundaries 'set to appending, if we press shift or ctrl when we mousedown we do selection=drawing back selection = appending else if selection appending then if right click then applySelection else ' just stopped moving the selection end if end if end sub sub CreateVisibleSelectionRegion() 'calculate previewoffset (leftprev, topprev) selOffsetLeft = leftprev - boundaries.left 'same for top selOffsetTop = topprev - boundaries.top 'if selOffsetleft > 0 means the selection is outside the preview on the left side 'if selOffsetLeft < 0 means selection is -selOffset tiles from the leftprev 'same for top for j = selOffsetTop to selOffsetTop + (bottomprev- topprev) for i = selOffsetLeft to selOffsetLeft + (rightprev- leftprev) if selectedtile(seloffsetleft, seloffsettop) then 'only if the tile is selected bitblt ' bitblt the tile onto picselect 'tile offset in picselect = 0 .... (rightprev-leftprev) soo ' = seloffsetleft-i 'same for j bitblt picselect.hdc, seloffsetleft-i, seloffsettop-j, tileW*zoom, tileH*zoom, pictileset.hdc, tilefromtilesetX (same as everywhere, tilesfromtilesetY, vbsrccopy end if next next 'note that this is not optimal: when either selOffsetleft or top are < 0 it will draw outside the picturebox and do unnecessary drawing, so there can be a few loops skipped there, but for the sake of simplicity for explaining for now, i'll let it like this next next end sub .... ugh ... pain ... can't think clear anymore ...... *faints*, hope you're happy with this
Samapico Posted May 11, 2006 Author Report Posted May 11, 2006 wha... dude... i was just throwing out an idea there... but uh... you seem to have fun lol.. so... good luck :S oh.. just saw something:if shift or ctrl is down and not moved then 'cant change a selection anymore once it moved, becuase it's copied to the seltiles array it would be nice to still be able to modify it... say there is a floating selection that has been moved... you unselect a part of it with ctrl + drag, and it drops that part of the selection... you could also add something to the selection ... floating or not if the selection is made of some kind of 'other layer' , I think it wouldnt be much harder to do that. And making it a separate layer would allow us to make the rendering of a floating selection perfectly in any condition... when moving map around, with transparent / under paste on, etc... you'd have map tiles AND selection tiles over each other, and each time the preview is updated, it renders desired tiles
Drake7707 Posted May 11, 2006 Report Posted May 11, 2006 yes, but that means that every seltiles array has to be 1024x1024 in size, as the selection can grow as big as that
Samapico Posted May 11, 2006 Author Report Posted May 11, 2006 could be resized every time it changes
Samapico Posted May 12, 2006 Author Report Posted May 12, 2006 the point of this would be to make it faster I guess... moving a 1024x1024 boolean array + 1024x1024 integer array... or... just screw the booleans if it stays at 1024x1024... just put 0 as integer... even if the array is resized we wouldnt need boolean array that way.. hmm
Drake7707 Posted May 12, 2006 Report Posted May 12, 2006 0 is no good, as 0 will replace every tile with tile 0 when you apply the selection
»SOS Posted May 12, 2006 Report Posted May 12, 2006 Too bad this is VB6 or I might have been able to help you out with keeping things fast I can't make heads or tails of non-trivial VB6 anymore Although, do you KNOW it would be slow or are you just guessing?If you have no proof of slowness, go with the slow but easy way.Also, do not worry about using any memory. 1024x1024x4=4B is TINY. Even if there is a ton of it.
Drake7707 Posted May 12, 2006 Report Posted May 12, 2006 redrawing a picture takes some time, so it might be slow, depends on how big the picpreview is and how much you zoomed out, now that i think of it, you also need a picselection1024 to store the pixels in it, actually, just bitblt from the normal pic1024 and you're set (almost forgot that)
Recommended Posts