How can I make scrollable gamefield in Lazarus? - pascal

I would like make a small RTS game in Lazarus and therefore I would like make a scrollable gamefield with arrow keys in it.
Now I created a bigger TBitmap (a big blue image) on the smaller TForm1 and I draw the game elements on this TBitmap. Although I can move this TBitmap and the elements on it with the arrow keys, but I can't delete the moving units from the previous place.
Maybe the canvas of a TBitmap is can't be deleted? But in this case how can I make a scrollable gamefield?

Related

Is it possible to change the position of a p5 text element after it is drawn?

Can you change the position of a p5 text element after it is draw without redrawing the entire canvas? If so, how would I be able to?
I'm trying to make text appear under players set to their current position, but when they move I want it to change its position to the player's position. I have the events with that setup, I just don't know how to change the position of the element.
Unlike some libraries, such as fabric.js, graphical elements in p5.js are not persistent objects that can be moved or modified once they are drawn. Instead, everything in p5.js is drawn in immediate mode. So when you are drawing text you specify it's attributes at the time you draw it, using the Typography functions, and the text(). In order to "move" text you would clear the canvas, or re-paint the background (using clear() or background() respectively, and then re-drawing the text with different settings or parameters.

Lazarus: stacking images, paint order

I want to design a simple game (lazarus 1.8.4) with an image as playing field and some figures (transparent images) over it, created on runtime. So typically more than one images are at the same position. How can I make sure, that the figures are above the playing field?
TControl has a function called BringToFront which will move the Control to the first position in the Z-Axis (the opposing function would be SendToBack). As TImage is derived from TControl the function applies to TImage as well.

Fabricjs object controls visible outside canvas

I am using fabric.js for html 5 interactive canvas app. If the object scales larger than the canvas, the controls go invisible outside canvas. How to make it visible outside the canvas or is there a way to style those controllers in css.
So, in fabricjs controls are rendered on the canvas, so having controls outside canvas it is not possible.
You can still obtain the effect in this way, this is just a trace.
Make canvas big as 100% of window, or anyway very bigger than drawing area.
Then you can clip the drawing canvas with a rectangle.
If you need borders to define the drawing area you can still put an overlay image as fabricjs allow you.
If you need to have controls near the drawing canvas you will have to position them OVER the non drawing part of the canvas.
This will give you some additional tasks:
When you create some object you have to be sure that they go in the drawing area. If you consider position of objects, you have to consider that a translation has to be applied, because you have absolute position while user will position the object watching a fake top left corner of a drawing area and not the top left corner of the canvas.
The best thing you can do is make a larger canvas, but limit the drawing area to a limited part, like a margin. Not easy because after that you always need to consider the margin when making other calculations, but it is possible.

NSView -drawRect and mouse hover performance

I have a custom NSView that draws (with -drawRect) a graph. It also tracks the mouse position (with -mouseMoved and the like) and draws the cursor position/coordinates relative to the axes.
The graph is big and (potentially) slow to draw, and doesn't depend on the mouse position. The mouse-over effect is tiny, and always fast to draw. I don't want to have to redraw everything when the mouse moves a couple pixels, because it feels sluggish.
I'm sure I can make my own private graphics context (doubled in size, if on a 2x display), draw the chart data into that once, and then have -drawRect simply blit that into the view's drawing context. Alternatively, I could split my NSView subclass into two classes, and have one just the chart data, and one just the overlay, and place them exactly on top of each other (though they have to share a bit of data, so this seems awkward).
Is there a built-in method to make this easier, or is there a more idiomatic way of handling this?
Take a look at these NSWindow methods:
Bracketing Drawing Operations
– cacheImageInRect:
– restoreCachedImage
– discardCachedImage
Normally, with a view, you define a drawRect: method that draws contents on-demand. You can, however, do on the spot drawing in a view as result of events for example, by locking focus on the view, performing the drawing, then unlocking focus. The missing link in this on-the-spot drawing, is somehow undoing it without calling your potentially heavy drawRect: via setNeedsDisplay:
This is where the Bracketed drawing operations on NSWindow come into play. Before locking focus on the view and doing some on-the-spot drawing, cache an image of the view in the area you intend to draw. When you next want to update your drawing (while tracking events, perhaps) then restore the cached image, rinse, and repeat.

User interaction in Processing

I have a general question (I know I should present specific code with a problem, but in my case the problem is of a more general nature).
In Processing, let's say I make an ellipse:
ellipse(30, 30, 10, 10);
Now, is there a way to get the pixels where this ellipse is on the canvas? The reason would be to have a way of creating user interaction with the mouse (for instance). So when someone clicks the mouse over the ellipse, something happens.
I thought of turning everything into objects and use a constructor to somehow store the position of the shape, but this is easier said than done, particularly for more complex shapes. And that is what I am interested in. It's one thing to calculate the position of an ellipse, but what about more complex shapes? Are there any libraries?
Check out the geomerative library. It has a way to check whether the mouse is inside any SVG shape. I can't remember off the top of my head but it works something like you make a shape:
myShape = RG.loadShape("shape.svg");
and a point:
RPoint p = new RPoint(mouseX, mouseY);
and the boolean function contains() will tell you if the point is inside the shape:
myShape.contains(p);
It's better to use a mathematical formula than pixel-by-pixel checking of the mouse position (it's much faster, and involves less code).
For a perfect circle, you can calculate the Euclidean distance using Pythagoras' theorem. Assume your circle is centred at position (circleX,circleY), and has a radius (not diameter) of circleR. You can check if the mouse is over the circle like this:
if(sq(mouseX-circleX)+sq(mouseY-circleY) <= sq(circleR)) {
// mouse is over circle
} else {
// mouse is not over circle
}
This approach basically imagines a right-angled triangle, where the hypotenuse (the longest side) runs from the centre of the circle to the mouse position. It uses Pythagoras' theorem to calculate the length of that hypotenuse, and if it's less than the circle's radius then the mouse is inside the circle. (It includes a slight optimisation though -- it's comparing squares to avoid doing a square root, as that can be comparatively slow.)
An alternative to my original mathematical answer also occurred to me. If you can afford the memory and processing power of drawing all your UI elements twice then you can get good results by using a secondary buffer.
The principle involves having an off-screen graphics buffer (e.g. using PGraphics). It must be exactly the same size as the main display, and have anti-aliasing disabled. Draw all your interactive UI elements (buttons etc.) to this buffer. However, instead of drawing them the normal way, give each one a unique colour which it uses for fill and stroke (don't add any text or images... just solid colours). For example, one button might be entirely red, and another entirely green. Any other RGB value works, as long as each item has a unique colour. Make sure the background has a unique colour too.
The user never sees that buffer, so don't draw it to the screen (unless you're debugging or something). When you want to detect what item the mouse is over, just lookup the mouse position on that off-screen buffer. Get the pixel colour at that location, and match it to the UI element.
After you've done all that, just go ahead and draw everything to the main display as normal.
It's worth noting that you can cut-down the processing time of this approach a lot if your UI elements never (or rarely) move. You only need to redraw the secondary buffer when something appears/disappears, animates, or changes size/position.

Resources