bearophile wrote:
> http://rosettacode.org/wiki/Animate_a_pendulum

Here's the D version using the direct to screen functions. I
ported the C# version, since the APIs were most alike. (Not
really surprising... C# and I both thinly wrapped GDI.)

===

import std.math;
import simpledisplay;

void main() {
    auto win = new SimpleWindow(512, 512);

    real angle = PI / 2;
    real angleVelocity = 0;
    immutable real dt = 0.1;
    int length = 150;

    win.eventLoop(50,
        () {
            auto anchorX = win.width / 2 - 12;
            auto anchorY = win.height / 4;
            auto ballX = anchorX + cast(int) (sin(angle) * length);
            auto ballY = anchorY + cast(int) (cos(angle) * length);

            auto angleAcceleration = -9.81 / length * sin(angle);
            angleVelocity += angleAcceleration * dt;
            angle += angleVelocity * dt;

            auto painter = win.draw();

            painter.fillColor = Color(255, 255, 255);
            painter.drawRectangle(0, 0, win.width, win.height);

            painter.outlineColor = Color(0, 0, 0);
            painter.drawLine(anchorX, anchorY, ballX, ballY);
            painter.fillColor = Color(0, 0, 0);
            painter.drawEllipse(anchorX - 3, anchorY - 4, anchorX + 3, anchorY 
+ 4);

            painter.fillColor = fromHsl(30, 0.8, 0.4);
            painter.drawEllipse(ballX - 7, ballY - 7, ballX + 7, ballY + 7);
        }
    );
}

===

Exit the program by closing the window.

Some comments. First, you'll see that the pulse timer is
implemented, allowing the animation to easily happen.

Then, there's a dozen lines to actually do the drawing, starting
with

auto painter = win.draw();

win.draw (name might change) returns a ScreenPainter struct, which
gives access to the drawing directly in the window, via a handful
of native api calls. This struct is necessary to handle some state
and cleanup that the native APIs require. (It's destructor does
it all for you though, so no need to think about it here.)

You can draw images, text, pixels (slowly), lines, rectangles,
arcs, and polygons with solid colors for filling and outline. It's
the lowest common denominator between Windows GDI and Xlib.

I agree with what Michel said earlier about it being a lot of
fairly pointless effort to go further than this. Instead, we'll
offer a rich set of cross-platform functions to draw to an image,
and simply copy those images to the windows when we want to get
fancy. (That's easy to do here: painter.drawImage(x, y, image); )

Moving on, I first clear the screen by drawing a large, white
rectangle over the window.

fillColor and outlineColor are settable properties that are
implicitly used in the drawing functions. (This reflects how
pens and brushes are tied to the HDC on Windows and foreground
and background colors are tied to the GC on X - you don't pass
colors to the individual functions on either native API either.)

Following Windows' lead, all the functions use the two separate
colors, one for the outline of the shape and one for filling it in,
hence their names. Note that only outline is used for drawline lines
and pixels.

If you want to draw a shape without filling it in, first set the
fill color to transparent:

painter.fillColor = Color.transparent;

(Color.transparent is a static method to conveniently return a
color with alpha = 0.)


Also in there, you can see me using the fromHsl helper function
to return a Color specifying HSL values instead of RGB.


Finally, I said this draws directly to the screen, but it actually
doesn't... it double buffers underneath. No need to call a
buffer.flip function though. ScreenPainter's destructor does it for
you. You don't have to think about it.

The buffer is preserved across calls and used to automatically
handle WM_PAINT/Expose messages.



======

There's still a handful of little things and a lot of error checking
needed, but I'm pretty happy with this as the screen drawing base.
It covers all the easy stuff. The hard stuff will be in platform
independent images.

Anyway, here's the updated simpledisplay.d:

http://arsdnet.net/dcode/simpledisplay.d

Reply via email to