On 03/27/2011 03:22 PM, Kevin Fishburne wrote: > On 03/26/2011 03:49 AM, Doriano Blengino wrote: >> Il 26/03/2011 04:08, Kevin Fishburne ha scritto: >>> On 03/24/2011 12:05 AM, John Spikowski wrote: >>> >>>> On Wed, 2011-03-23 at 23:03 -0400, Kevin Fishburne wrote: >>>> >>>> >>>>> That will probably work, but there should be a mathematical way to >>>>> compensate for not cropping the image twice, or even once. As long as >>>>> the entire image is preserved by the rotation function (it is) and it >>>>> behaves in a predictable manner (it does), the camera's coordinates >>>>> should be able to be translated and rotated so that they are in >>>>> the same >>>>> position in the rotated image as they were in the non-rotated >>>>> image. For >>>>> the sake of efficiency that is what I'm trying to accomplish. >>>>> >>>> This thread might help. (or not) >>>> >>>> http://forums.libsdl.org/viewtopic.php?t=2983&sid=1d2c6a94470c0fd56f3f542cd702ec37 >>>> >>>> >>>> >>> No go, but thanks for trying to help. Right now my code looks something >>> like this: >>> >>> ' Convert camera coordinates to their distance from the center >>> of the >>> tile grid. >>> newcx = newcx - (bworkspace.Width / 2) >>> newcy = newcy - (bworkspace.Height / 2) >>> >>> ' Rotate camera. >>> newcx = Cos(Rad(- Client.orientation)) * newcx - Sin(Rad(- >>> Client.orientation)) * newcy >>> newcy = Sin(Rad(- Client.orientation)) * newcx + Cos(Rad(- >>> Client.orientation)) * newcy >>> >>> ' Adjust the camera coordinates to fit the rotated tile grid. >>> newcx = newcx + (brotated.Width / 2) >>> newcy = newcy + (brotated.Height / 2) >>> >>> ' Draw the rotated workspace centered on the camera and cropped by >>> the render window size. >>> Draw.Image(brotated, 0, 0, swidth, sheight, newcx - swidth / 2, >>> newcy >>> - sheight / 2, swidth, sheight) >>> >>> First I figure out the distance of the camera from the center of the >>> non-rotated image. Then I rotate the camera using those distance values >>> as the camera's coordinates. That should in effect make the center of >>> the non-rotated image the origin of rotation. I then take the rotated >>> camera values and add them to the center point of the rotated image to >>> determine the camera's position in the rotated image. >>> >>> Maybe my logic is wrong, maybe it's my math. Maybe demons are hovering >>> over my shoulder casting black magic. I'm about to hit up Facebook for >>> an old math whiz I knew in high school, as gamedev.net has failed me as >>> well.<blood curdling Arnold scream from Predator> >>> >>> > > Hi Doriano, thanks for helping. You're definitely getting your name in > the game credits when it's done. :) > >> Dear Kevin, >> >> if I well understand, you have to rotate your world around the player. >> To rotate a point around another arbitrary point (different from the >> origin), you must first translate the point, then rotate it, then >> translate it again in the original position. If you want I can give you >> a working routine to do so. Your code seems to do something similar, > > Yes, I hope that's what my code is doing. Basically I find the > distance of the camera from the center of the non-rotated image, > whether negative or positive. That should mean that when I rotate > those new coordinates, then add them to the center point of the > rotated image, that they've effectively been rotated about the center > of the rotated image. For example, if the camera in the non-rotated > image is at (10,10) and the center of the non-rotated image is at > (11,11), I'd do (10,10) - (11,11) = (-1,-1), rotate (-1,-1), then add > the rotated values to the center point of the rotated image. Maybe > that's all wrong, I don't know. > >> but... should not the player always stay in the middle of the screen? If >> so, you need not to translate anything, but just rotate the original >> image. Or, perhaps, you want to reduce scrolling, so the player is not >> always in the middle? If there is not a true motivation, due to some >> game concept, to have different x/y positions of the player inside the >> screen, then it is much simpler to always keep the player in the middle. >> I try to explain in other words. Suppose that you can't get enough >> framerate when you rotate the world, so you try to minimize this, and >> let the player move around the screen. When the player reaches the >> boundary of the screen, you update the whole screen. Doing so, you speed >> up considerably. Nevertheless, when the player reaches a boundary, you >> must invoke anyway the "slow" routines to update the world. The net >> result is a stiffy game, which alternates fast movements with slow ones. > > That is exactly what I'm doing because this is a tile-based game that > uses a complex method of drawing and blending the tiles. Here's how it > works, using real numbers this time. > > First the camera is detached from the player, so the player's position > for the sake of this discussion isn't important. The camera loosely > follows the player using an algorithm to simulate natural camera > movement. So the camera position is all that matters. > > The landscape is broken into three progressively smaller chunks: the > game world (data on server), the cell grid (data on client) and the > tile grid (image on client). The world for testing purposes is > currently 4096x4096 tiles. The cell grid is a block of 96x96 tiles > (3x3 cells of 32x32 tiles), and is all the game client is aware of at > any given time. Finally the tile grid is an image containing the > rendered tile data of a subset of the cell grid, with the camera > always being in the center tile. At 1280x720 the tile grid is 13x13 > tiles, or 1664x1664 pixels, with the camera always being somewhere in > tile (7,7). > > When the camera moves out of the center tile of the tile grid, the > tile grid is shifted one tile (128 pixels) in any of eight directions > and a new row and/or column of tiles are drawn into it. The tile grid > image is what's being rotated, and the camera never is farther than 64 > pixels in any direction from the center of the tile grid image. > > I've attached the relevant, abbreviated code. The function > CellGrid2TileGrid() is being called to convert the camera's cell grid > coordinates to tile grid coordinates. I believe the conversion > function is working properly (scrolling works fine until the screen is > rotated), but it may be worth a look. I've also recorded a video > showing what is currently happening when the screen is rotated: > > http://www.youtube.com/watch?v=iw64jcdNJY4 > >> I am also confused by our previous thread, where you rotated the player >> instead of the world. Not knowing enough, I can only say that you can, >> perhaps, gain some speed by doing calculations in the dead times >> (delays, if you have/use them). I have read that you reach speeds as >> high as 200 FPS or similar... if you reduce FPS to 25, you gain a lot of >> spare time to calculate ahead the new scenes (or perhaps not). If you >> explain better your ideas, may be I can try to give some advice. > > That's a good idea, I will definitely consider doing that.
In a half-drunken stupor I managed to correct the issue by trial and error. Hell of a miracle. Here's the abbreviated working code: Public Sub Screen_Client() ' Main client loop. ' General declarations. Dim newcx As Single ' Translated and rotated camera coordinates in the rotated tile grid. Dim newcy As Single ' Translated and rotated camera coordinates in the rotated tile grid. Dim cxoffset As Single ' Distance of the camera from the center of the tile grid. Dim cyoffset As Single ' Distance of the camera from the center of the tile grid. ' Update the camera. Camera ' Composite the landscape layer. bworkspace.Draw(blandscape, 0, 0) ' Rotate the workspace. brotated = bworkspace.Rotate(Rad(- Client.orientation)) ' Convert camera coordinates to tile grid pixel coordinates. newcx = Convert.CellGrid2TileGrid(cx, cx) * 128 newcy = Convert.CellGrid2TileGrid(cy, cy) * 128 ' Calculate camera distance from the center of the tile grid. cxoffset = newcx - (bworkspace.Width / 2) cyoffset = newcy - (bworkspace.Height / 2) ' Rotate camera about the center of the tile grid using its offset values. newcx = Cos(Rad(- Client.orientation)) * cxoffset - Sin(Rad(- Client.orientation)) * cyoffset newcy = Sin(Rad(- Client.orientation)) * cxoffset + Cos(Rad(- Client.orientation)) * cyoffset ' Draw the rotated workspace centered on the camera and cropped by the render window size. Draw.Image(brotated, 0, 0, swidth, sheight, (brotated.Width / 2) - (swidth / 2) + newcx, (brotated.Height / 2) - (sheight / 2) + newcy, swidth, sheight) End I tried about 100 things before it started working, so I don't really know what I did wrong (or right), but at least it's working now. :) Too bad my frame rate is at 6 FPS due to the rotation function. I think I may need to follow Benoit's advice about cropping the image first. Thanks Doriano. -- Kevin Fishburne Eight Virtues www: http://sales.eightvirtues.com e-mail: [email protected] phone: (770) 853-6271 ------------------------------------------------------------------------------ Enable your software for Intel(R) Active Management Technology to meet the growing manageability and security demands of your customers. Businesses are taking advantage of Intel(R) vPro (TM) technology - will your software be a part of the solution? Download the Intel(R) Manageability Checker today! http://p.sf.net/sfu/intel-dev2devmar _______________________________________________ Gambas-user mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/gambas-user
