I am working on a traffic simulation package. I want to draw the road
network on the background layer and the (moving) vehicles on the foreground
layer. This would mean that when I move a vehicle (ie. delete it from its
previous location then draw it at the new location) this would not delete
parts of the network on the background.
I thought I can do this by placing 2 TImage objects on top of each other,
draw the network on the first one, and the vehicles on the second one, by
setting Image2.Transparent := True, but it does not work, ie. Image2 does
not become transparent. Then I read in the Delphi Help that "Transparent has
no effect unless the Picture property specifies a TBitmap object." So this
is not the right way.
Is there any other way?
Thanks for any suggestions.
Peter
Take a look at DtpDocuments, it will make your life easy for this
application!
What you can do with it:
- Add shapes (e.g. bitmap images of the vehicles) at any position on the
page.
- Rotate them freely (So you can give your vehicles the right heading)
- Move to front/back (vehicles passing under bridges)
- Move shapes simply by setting the position to a new value, no need to care
about how to redraw the background, this is all done automatically
- Assign background bitmap, or add static bitmap shapes
- You can also easily add lines, rectangles, ellipses, etcetera
- Apply effects to your shapes, like shadow
- Semi-transparency
- User-selectable, move shapes around with mouse
- Full persistance (save all shapes with one command)
- Printing, export to raster image
DtpDocuments is based on the very optimized Graphics32 library for fast
rendering of RGBA bitmaps (RGB + alpha channel for transparency).
Just check out this webpage:
http://www.simdesign.nl/dtpdocuments.html
And test the fully functional trial version...
Kind regards,
Nils Haeck
www.simdesign.nl
"Peter Hidas" <phi...@tpg.com.au> wrote in message
news:412a84c4$1...@newsgroups.borland.com...
thanks, I will check it out, but first I would like to know if it can be
done by using the native Delphi components, without any extras.
Regards
Peter
"Nils Haeck" <n.ha...@spamchello.nl> wrote in message
news:412a8904$1...@newsgroups.borland.com...
I have two ideas. If You don't have that much objects to draw You can do the
following. Draw Your background image on a temporary bitmap (double
buffering) then draw all Your vechicles to their new position. When drawing
is complete, copy this temporary bitmap to the visible TImage. My second
advice (if You have to draw many objects and not all of them is moving
always) would be to remember the covered area for each object and when it
needs to be moved You simply redraw the covered part, copy the newly covered
part and draw the object to it's new place. You could create a class for
your objects to achive this easily. However, I would not use this because I
think this solution costs many resources and is not so effective.
HTH,
MikKi
Then I read in the Delphi Help that "Transparent has
> no effect unless the Picture property specifies a TBitmap object." So this
> is not the right way.
>
hi Peter,
All you need to do is make small bitmaps of your cars and put each in a
timage component. In fact you only need 1 bitmap.
TImage.Loadfromfile(mycar.bmp);
Do this for as many cars as you need.
In order to set transparent to true, make sure the background around the
cars is a solid color that is not used anywhere in the image of the car.
NOTE: Although this should work, I personally don't recommend this approach
to the problem. But on the other hand, it is much easier this way.
Best Regards
Therefore I don't use bitmaps, but draw them on the Canvas directly using
filled polygons (after calculating the coordinates of each point). To move
them to a new position, I delete each vehicle from its current position (by
redrawing them with the background color), then draw them at the new
position. This happens at one second intervals during the simulation. This
works well, except that the process deletes some parts of the road network
elements (detectors, stopline, etc...). This is why I wanted to draw them on
separate canvases.
Can anyone answer precisely the following questions:
is it possible in Delphi to have two graphical objects overlaid with the top
one being transparent (so that only what is drawn on the top is covering
what is drawn on the second)?
if yes, what objects should I use, and how to make it transparent?
Thanks
Peter
"RandomAccess" <Ran...@Access.com> wrote in message
news:412ae2b6$1...@newsgroups.borland.com...
Peter,
What I have done in my own WXtrack software:
http://www.david-taylor.myby.co.uk/software/wxtrack_at_work.htm
is:
- a base map of the world as a TImage
- the grid overlaid as a TPaintBox
- the satellite paths overlaid as a TPaintBox
- the Sun, Moon and other sprites drawn using TIcon objects
- (in the current version, satellites are also drawn as icons).
So your cars, trucks etc. can be drawn as Icons, provided they are 32 x 32
pixels or less. It may work with larger icons but I haven't checked this.
You can download the software for free if you just want to see what the
screen looks like.
Cheers,
David
I can still recommend my first suggestion. I think that approach is fast
enough to draw thousands of objects in one second if it is done the way it
should be. So You'll need two more bitmaps which represent the whole map.
One of them stores the unmodified backround image (roads, lamps, etc. -
let's call it BackImg), the other one is used for preparing the image to be
shown (let's call it HelpImg). And You have a third bitmap which is the
TImage.Picture.Bitmap (or anything You use for showing the image).
At the beginning You load the background image (BackImg.LoadFromFile()), and
leave it unmodified for the whole process. In the drawing process first copy
the background image to the invisible bitmap (with HelpImg.Canvas.Draw),
then you draw all Your vechicles on the Canvas (using Polygon or anything).
When finished, copy the ready image to the TImage.Picture (using
Image1.Canvas.Draw) method.
By using this helper bitmap You can avoid flickering during the draw.
HTH,
MikKi
Keep your base picture (without any cars) in a bitmap of it's own - bmA.
When drawing, first draw this bitmap on another bitmap - bmB, then draw all
the cars on bmB, then finally draw bmB on a Paintbox.
No need to erase anything.
--
Anders Isaksson, Sweden
BlockCAD: http://w1.161.telia.com/~u16122508/proglego.htm
Gallery: http://w1.161.telia.com/~u16122508/gallery/index.htm
Thanks for all the help.
Peter
"Anders Isaksson" <isaksso...@REMOVEebox.tninet.se> wrote in message
news:412ba35b$1...@newsgroups.borland.com...
Next I put on a tTimer, and this is the code I wrote in the handler.
procedure TForm1.Timer1Timer(Sender: TObject);
var
r:trect;
begin
with Image2.Picture.Bitmap.Canvas do
begin
FillRect(rect(0,0,500,500)); //erases the overlay
r.Top:=trunc(random*400); //creates a rectangle
r.Left:=trunc(random*400);
r.Right:=r.Left+50;
r.Bottom:=r.Top+50;
pen.Width:=5; //pen width
Ellipse(r); //draw the circle.
end;
end;
This draws random circles over the background. I think you can take it from
here.
If you like I can send you the source project.
"Peter Hidas" <phi...@tpg.com.au> wrote in message
news:412bc4dc$1...@newsgroups.borland.com...
It has no point to load a bitmap if Your first action is to fill the whole
image with a solid color:
> with Image2.Picture.Bitmap.Canvas do
> begin
> FillRect(rect(0,0,500,500)); //erases the overlay
(...)
The second thing is that You didn't specify the colors to be used. In this
case it is black for the pen and white for the brush. Setting the
TImage.Transparent property to true causes the pixels which have the same
color as the lower left pixel of the image to become transparent. So this
process is very slow because the whole image has to be "checked" from pixel
to pixel (actually this is done with masking).
I would do the following:
Create one TImage, and initialize it's bitmap in the form's OnCreate event
handler, and create two more bitmaps:
type
Form1=class(TForm)
{...}
private
Back,Buffer:TBitmap;
end;
procedure TForm1.OnCreate(Sender: TObject);
begin
//initialize TImage
Image1.Picture.Bitmap:=TBitmap.Create;
Image1.Picture.Bitmap.Width:=300;
Image1.Picture.Bitmap.Height:=300;
//load background image
Back:=TBitmap.Create;
Back.LoadFromFile('background.bmp');
//initialize helper bitmap
Buffer:=TBitmap.Create;
Buffer.Width:=300;
Buffer.Height:=300;
//set colors here once if they are used always (much faster then setting
them all the time)
Buffer.Pen.Color:=clRed;
Buffer.Brush.Color:=clMaroon;
end;
Then in a timer's OnTimer event I would do the actual drawing:
procedure TForm1.Timer1Timer(Sender: TObject);
var
x,y:integer;
begin
//use Buffer to prepare the image to be shown (to avoid flickering)
with Buffer.Canvas do begin
Draw(0,0,Back); //redraw background
//place objects
x:=random(300);
y:=random(300);
Ellipse(x-30,y-30,x+30,y+30);
end;
//show created image
Image1.Picture.Bitmap.Canvas.Draw(0,0,Buffer);
end;
And finally free the allocated memory:
procedure TForm1.OnDestroy(Sender: TObject);
begin
Back.Free;
Buffer.Free;
end;
This code is just a bit more complex then then Bryan's but it is much
faster. Hope this makes my idea clear and You can do what You really want.
Regards,
MikKi
Yes.
> if yes, what objects should I use,
TGraphicControl (which TImage is derived from)
>and how to make it transparent?
It just is, its what you draw you draw on it's canvas that determines whether
or not you can see through it.
Have a look at the source for TShape. You can see it in action if you just put
2 TShapes on a form, one set to stCircle and one to stRectangle, put one over
the other, play around with BringToFront.
Gordon
--
MGCSoft Graphical and equation editors
http://www.mgcsoft.com/
I guess I am missing something, is the Sprites_Ex example not exactly
what your talking about?
Geeds
Sorry if You have misunderstood me. I didn't tell that Your code doesn't
work. I just told that You relied on default settings which is not always
the best choice. I have tested Your code too and it worked just great! And I
wanted to show another solution which I think is somewhat faster.
MikKi
"Kiss Miklós" <kissm...@freemail.hu> wrote in message
news:4130a4ad$1...@newsgroups.borland.com...