How to display a large scrolling level on a small viewport? - c++

I asked a question yesterday about a problem I was having displaying a level in a C++ 2D GameBoy Advance game when the level is larger than the screen size. However, I may have been slightly too specific, and so I want to ask this more generally.
What is the simplest way to go about trying to display a scrolling level which is large (512x512 pixels) on a screen which is much smaller (240x160 pixels)?
A brief description of my code structure so far: I have a base class called Object which defines (x, y) position and a width and height, there is an Entity class which inherits from Object and adds velocity components, and a Character class which inherits from Entity and adds movement functions. My player is a Character object, and boxes I want the player to pick up are an array of Entity objects. Both the player and cubes array are members of the Level class, which also inherits from Object.
So far I have implemented a game which works very well when the level is the same size as the screen - all the objects' positions are stored relative to their position in the level. However, I am having serious trouble trying to work out how to display the objects in the correct place when the level is offset on the screen. I want the viewport to never extend out of the level, and if the viewport is not against the edge of the level, display the player in the middle of the screen.
Should I try to work it out using a couple of simple offset variables to move the background? If so, in what order should the offsets be calculated and applied? How would the offsets differently apply to the player and boxes? Or instead, should I try creating another Object as a member of the Level class for the viewport? How would I go about calculating the offsets using that?
Any advice provided wilil be greatly appreciated.

Related

How to handle mouse hovering for object [Allegro5/C++]

I want to be able to register/de-register Objects to a list and check if the mouse is hovering over them to display tool-tips. However I'm stumbling at the beginning.
I'm going to use: al_get_pixel & al_unmap_rgba to retrieve the alpha of each pixel and decide if it's visible enough to count as a hit when hovering over it with the mouse.
The major problem I'm having is working out how best to store this individual "hitmap" & the reference to the object that generated it; As many different types objects (as struct's) of different sizes may need hitmaps generated. I was hoping I could do something similar to checking if the complex object 'extends' the base object but I don't see how I can achieve this in c++.
Ps; I know I could create an array the size of the screen for each object, but I'm doing this mainly with the purpose of maximizing efficiency. I'd make dynamic sized arrays but...
al_get_pixel will work, but it will be terribly slow, even if you lock all your bitmaps, unless you use something like a picking buffer. The basic idea is to render every interactive area on each object with a different color id. This means you need to draw your scene twice, once normally, and once with picking colors. Then when you need to read back a mouse position, you can use the picking buffer to read a single pixel and get its color id.
You might also want to try different methods of collision detection, such as bounding boxes, bounding circles, or other easily collision detectable shapes.
There is a third option, which is pixel perfect collision. It involves making 1bpp masks out of all your objects and then checking for collision between those.

Best way to detect the window coordinates of a drawn line in c++ Builder

Using moveto and lineto to draw various lines on a window canvas...
What is the simplest way to determine at run-time if an object, like a bit map or a picture control is in "contact" (same x,y coordinates) with a line(s) that had been drawn with lineto on a window canvas?
A simple example would be a ball (bitmap or picture) "contacting" a drawn border and rebounding... What is the easiest way to know if "contact" occurs between the object, picture or bitmap and any line that exists on the window?
If I get it right you want collision detection/avoidance between circular object and line(s) while moving. There are more option to do this I know of...
Vector approach
you need to remember all the rendered stuff in vector form too so you need list of all rendered lines, objects etc ... Then for particular object loop through all the other ones and check for collision algebraically with vector math. Like detecting intersection between bounding boxes and then with particular line/polyline/polygon or what ever.
Raster approach
This is simpler to mplement and sometimes even faster but less acurate (only pixel precision). The idea is to clear object last position with background color. Then check all the pixels that would be rendered at new position and if no other than background color present then no colision occurs so you can render the pixels. If any non background color present then render the object on the original position again as collision occur.
You can also check between old and new position and place the object on first non collision position so you are closer to the edge...
This approach need fast pixel access otherwise it woul dbe too slow. Standard Canvas does not allow this without using BitBlt from GDI. Luckily VCL GRaphics::TBitmap has ScanLine[] property allowing direct pixel access without any performance hit if used right. See example of it in your other question I answered:
bitmap rotate using direct pixel access
accessing ScanLine[y][x] is as slow as Pixels[x][y] but you can store all the pointers to each line of bitmap once and then just use that instead which is the same as accessing your own 2D array. So you really need just bitmap->Height calls of ScanLine[y] for entire image rendering after any resize or assigment of bitmap...
If you got tile based scene you can use this approach on tiles instead of pixels something like this:
What is the best way to move an object on the screen? but it is in asm ...
Field approach
This one is also considered to be a vector approach but does not require collision checks. Instead each object creates repulsive force the bigger the closer you are to it which is added to the Newton/D'Alembert physics driving force. When coefficients set properly it will avoid collisions on its own. This is used also for automatic placement of items etc... for more info see:
How to implement a constraint solver for 2-D geometry?
Hybrid approach
You can combine any of the above approaches together to better suite your needs. For example see:
Path generation for non-intersecting disc movement on a plane

VTK abstract picker for multiple actors of different opacity value

I am new to VTK. I would like to know how VTK abstract picker behaves for multiple actors of different opacity values. Let's consider two actors, with one
inside another. When I set the opacity of the outer surface to 0.3, while
keeping the opacity of the inner one 1.0.Since the outer one is semi-transparent, I can see the inner actor in the overlap region of the two actors. When I perform picking in that region,the resulting coordinates is from the inner surface itself, and when I pick some point other than the overlap region,I am getting outer surface coordinates. How can I perform picking operation based on opacity values? Such that i want to pick one actor at a time. Anybody please help..
vtkAbstractPicker is, as the name suggest, just as an abstract class that defines interface for picking, but nothing more. When choosing actual pickers, you basically have a choice between picking based on ray casting or "color picking" using graphical hardware (see the linked documentation for actual vtk classes that implement those).
Now to the actual problem, if I understood what you wrote correctly, you are facing a rather simple sorting problem. The opacity can be seen as kind of a priority - the actors with higher opacity should be picked even if they are inside others with lower opacity, right? Then all you need to do is get all the actors that are underneath your mouse cursor and then choose the one with highest opacity, or the closest one for cases when they have the same opacity.
I think the easiest way to implement this is using the vtkPropPicker (vtkProp is a parent class for actor so this is a good picker for picking actors). It is one of the "hardware" pickers, using the color picking algorithm. The basic algorithm is that each pickable object is rendered using a different color into a hidden buffer (texture). This color (which after all is a 32-bit number like any other) serves as an ID of that object: when the user clicks on a screen, you read the color of the pixel from the picking texture on the clicked coordinates and then you simply look into the map of objects under the ID that is equal to that color and you have the object. Obviously, it cannot use any transparency - the individual colors are IDs of the objects, blending them would make them impossible to identify.
However, the vtkPropPicker provides a method:
// Perform a pick from the user-provided list of vtkProps
// and not from the list of vtkProps that the render maintains.
// If something is picked, a 1 is returned, otherwise 0 is returned.
// Use the GetViewProp() method to get the instance of vtkProp that was picked.
int PickProp (double selectionX, double selectionY,
vtkRenderer *renderer, vtkPropCollection *pickfrom);
What you can do with this is simply first call PickProp(mouseClickX, mouseClickY, renderer of your render window, pickfrom) providing only the highest-priority actors in the pickfrom collection i.e. the actors with the highest opacity. Underneath, this will do a render of all the provided actors using the color-coding algorithm and tell you which actor is underneath the specified coordinates. If it picks something (return value is 1, you call GetViewProp on it and it gives you the pointer to your picked actor), you keep it, if it does not (return value is 0), you call it again, this time providing actors with lower opacity and so on until you pick something or you test all the actors.
You can do the same with the ray-casting pickers like vtkPicker as well - it cast a ray underneath your mouse and gives you all intersections with everything in the scene. But the vtkPicker's API is optimized for finding the closest intersection, it might be a bit of work to get all of them and then sorting them and in the end, I believe the solution using vtkPropPicker will be faster anyway.
If this solution is good, you might want to look at vtkHardwareSelector, which uses the same algorithm, but unlike the vtkPropPicker allows you to access the underlying picking texture many times, so that you don't need to re-render for every picking query. Depending on how your rendering pipeline is set up, this might be a more efficient solution (= if you make a lot of picking without updating the scene).

Data structures: alternatives to logic bitmap/pixmap

I have decided to rewrite an old Zatacka clone of mine. The old thing, running under Allegro 4, utilizes logic bitmap, that is a bitmap used for non-display purposes, reflecting directly the visible "what's on the screen and doesn't move" bitmap, but the integers stored in it represent logical meaning of things on screen, because the game got quite colorful. So the things that players see may be of any color possible, but game just remembers what kind of object each pixels represents.
The new clone is not supposed to use Allegro, so I could write the logic bitmap code myself. That said, I would appreciate if someone suggested some more efficient and precise alternatives.
Structure must be able to be kept up with bitmap/texture visible to players. Think about Worms game, but utilizing player invisible ground type variations, or something. In addition, following methods must be implemented:
Checking if all pixels in a circle belong to a small (~6) set of "colors" given as a parameter.
Painting all pixels in a circle with a single "color".
Painting all pixels in a circle, (except/only) ones in small set of "colors" provided as a parameter, with a single "color".
Painting a silhouette of rotated, preprocessed if you wish so, bitmap with a single "color". (That's the tricky one: would interpreting the bitmap as a stupid polygon with loads of right angles do the job?)
This is the minimum. If your structure supports shapes other than circles, that's great.

Centring Sprite or moving camera? C++/Opengl

I'm self learning C++ and playing around 2D tile mapping.
I have been reading through this scrolling post here, which is based on this tiling tutorial.
Using the above tutorial and some help from the Pearson, Computer Graphics with OpenGL book I have written a small program that draws a 40x40 tiled world and a Sprite (also a tile).
In terms of drawing/render order, the map(or world) itself is that back layer and the Sprite is the forward most (or top) layer. I'm assuming that's a good way of doing it as its easier for 2 tiles to interact than a tile and a custom sprite or rectangle. Is that correct?
I have implemented a Keyhandling() function that lets you move the map inside the viewport using the keyboards arrow keys. I have a variable called offsetx, offsety that when a key is pressed increases or decreases. Depending on whether I assign the variable to the map or sprite, I can more one or the other in any direction on the screen.
Neither seems to work very well, so I assigned the variables to both (map and sprite) but with positive values for the sprite, and negative for the map. So upon a key press, this allows my Sprite to move in one direction whilst the map moves in the opposite direction.
My problem is, the sprite soon moves enough to leave the window and not enough to bring the more of the map into the scene. (The window only shows about 1/8th of the tiles at any one time).
I've been thinking all day, and I think an efficient/effective way to solve this issue would be to fix the sprite to the centre of the screen and when a key is pressed the map moves around... I'm unsure how to implement this though.
Would that be a good way? Or is it expected to move the viewport or camera too?
You don't want to move everything relative to the Sprite whenever your character moves. Consider a more complicated world where you also have other things on the map, eg other sprites. It's simplest to keep the map fixed, and move each sprite relative to the map, (if it's a movable sprite). It just doesn't make much sense to move everything in the world whenever your character moves around in the world.
If you want to render your world with your character always at the center, that's perfectly fine. The best thing to do is move the camera. This also allows you to zoom your camera in/out, rotate the camera, etc. with very little hassle in keeping track of all the objects in the world.
Be careful with your usage of the word "viewport". It means a very specific thing in OpenGL. (ie, look at the function glViewport). If your book uses it differently, that's fine. I'm just pointing this out because it's not 100% clear to me what you mean by it.