Siêu thị PDFTải ngay đi em, trời tối mất

Thư viện tri thức trực tuyến

Kho tài liệu với 50,000+ tài liệu học thuật

© 2023 Siêu thị PDF - Kho tài liệu học thuật hàng đầu Việt Nam

C++ Programming for Games Module II phần 5 doc
MIỄN PHÍ
Số trang
31
Kích thước
916.7 KB
Định dạng
PDF
Lượt xem
1725

C++ Programming for Games Module II phần 5 doc

Nội dung xem thử

Mô tả chi tiết

131

15.2 Shape Primitives

15.2.1 Drawing Lines

Line drawing is done with two functions. The first function moves the “virtual pen” to the starting point

of the line. The second function draws a line from the previously specified starting point, to a newly

specified second point:

// Following two functions draws a line from (startX, startY)

// to (endX, endY).

MoveToEx(hdc, startX, startY, 0);

LineTo(hdc, endX, endY);

Both functions take a handle to the device context, as all drawing must be done through the device

context. The second and third parameters for both functions are the x- and y-coordinates of a point,

which is relative to the client area rectangle. For MoveToEx, that point is the starting point of the line.

For LineTo, that point is the ending point of the line. The fourth parameter of MoveToEx returns a

POINT object of the last “start” point that was specified, via a pointer parameter. If this value is not

needed, you can specify null.

The program we will write to illustrate line drawing allows the user to define the line’s “start” point by

pressing the left mouse button. The user holds the left mouse button down and moves the mouse to a

new point. When the user has found the point where he/she wants the line’s “end” point to be, the user

raises the left mouse button up. Figure 15.3 shows the program after some lines were drawn.

Figure 15.3: The line drawing program. Users can draw lines by holding the left mouse button down

132

As the user moves the mouse around looking for the “end” point, he/she will expect to see the new line

being drawn in real-time. That is, a line from the “start” point to the current mouse position should

constantly be drawn and updated interactively. In this way, the user can see exactly how the line will

look before raising the left mouse button to make the line permanent. This functionality requires some

special code. Let us get started.

First, we have the following global variables (and also a structure definition):

struct Line

{

POINT p0;

POINT p1;

};

vector<Line> gLines;

Line gLine;

bool gMouseDown = false;

A Line is simply defined by two points, p0, and p1, where p0 is the “start” point and p1 is the “end”

point.

We recall that Windows does not save our drawn data if a part of the client area gets obscured.

Therefore, we need to save all the data ourselves so that we can redraw it all when a WM_PAINT message

occurs. To facilitate this, we maintain a global vector of Lines, called gLines, which will store the

lines we create. The global variable gLine is our temporary line; that is, it is the line we will draw as

the user moves the mouse around when deciding where the “end” point of the line should be. We do not

actually add a line to gLines until the user has lifted the left mouse button. Finally, gMouseDown is a

Boolean variable that denotes whether or not the left mouse button is currently down or not.

The first message we need to handle is the WM_LBUTTONDOWN message, which is where the line’s

“starting” point is defined.

case WM_LBUTTONDOWN:

// Capture the mouse (we still get mouse input

// even after the mouse cursor moves off the client area.

SetCapture(hWnd);

gMouseDown = true;

// Point that was clicked is stored in the lParam.

gLine.p0.x = LOWORD(lParam);

gLine.p0.y = HIWORD(lParam);

return 0;

Note that we set the “start” point in our temporary line. We do not actually add the line to our global

line container gLines until the user lifts the left mouse button.

133

A new API function in this message handler is the SetCapture function. This function “captures” the

mouse for the specified window. Capturing means that the window will continue to receive mouse

messages even if the mouse moves off the window’s client area. As long as the user has the left mouse

button down, we would like to have the mouse captured—we free the mouse when the user lifts the left

mouse button. Finally, if a WM_LBUTTONDOWN message occurs, we know the mouse is now down, so we

set our flag gMouseDown to true.

The next message we handle is the WM_MOUSEMOVE message. This message is sent whenever the mouse

moves.

case WM_MOUSEMOVE:

if( gMouseDown )

{

// Current mouse position is stored in the lParam.

gLine.p1.x = LOWORD(lParam);

gLine.p1.y = HIWORD(lParam);

InvalidateRect(hWnd, 0, true);

}

return 0;

Notice that we only care about this message if the left mouse button is down (if( gMouseDown )). If it

is not, we do not care about the WM_MOUSEMOVE message and do not execute any code.

So, assuming the left mouse button is down, as the mouse moves we obtain the current mouse position

(given in the lParam for the WM_MOUSEMOVE message) and set it as the “end” point for the temporary

line. We then invalidate the window’s client rectangle so that it is forced to repaint itself. In this way,

the new temporary line will be redrawn interactively as the mouse moves. Also note that here we

invalidate the rectangle with true specified for the third parameter—this will cause the background to

be erased, which is necessary since we need to erase any previously drawn temporary lines. That is,

every time the mouse moves we will draw a temporary line, but we do not want to accumulate these

lines; we just want to draw the latest temporary line. Therefore, we must erase any old lines.

The third message we handle is the WM_LBUTTONUP message. This message is generated when the left

mouse button is lifted up.

case WM_LBUTTONUP:

// Release the captured mouse when the left mouse button

// is lifted.

ReleaseCapture();

gMouseDown = false;

// Current mouse position is stored in the lParam.

gLine.p1.x = LOWORD(lParam);

gLine.p1.y = HIWORD(lParam);

gLines.push_back( gLine );

Tải ngay đi em, còn do dự, trời tối mất!