Màn hình, bàn phím, âm thanh trong Pascal (Phần 2)

Như đã ở phần 1 trước. Hôm nay, mình sẽ tiếp tục hướng dẫn phần 2, vậy bạn nào có niềm đam mê thì hãy cùng Wiki Pascal tìm hiểu nhé !

Man hinh, ban phim, am thanh trong Pascal (Phan 2)
Màn hình, bàn phím, âm thanh trong Pascal (Phần 2)


I – Thiết lập màu đồ họa

1. Hằng biểu diễn màu:

Mỗi vĩ đồ họa và mỗi chế độ đồ họa đều cho phép vẽ với một số màu khác nhau. Các màu này đã được Turbo Pascal đặt tên cho dễ nhớ thay vì phải dùng các mã số. 

2. Bảng màu (Palette):

Là tập hợp các màu để ta có thể chọn một trong các màu của bảng màu này để vẽ. Bảng màu chính là khái niệm hộp đựng bột màu vẽ của họa sĩ : đó là các ô chứa màu trong một bảng đựng màu. Ô màu đó có thể thay đổi nội dung, có thể chứa màu vàng, có thể chứa màu đỏ..., nghĩa là có thể thay đổi các màu trong một bảng màu.


3. Các thủ tục thiết lập màu:

Để thiết lập màu vẽ và màu nền, ta có 2 thủ tục SetColor và SetBkColor :

SetColor ( Color : Word ); là thủ tục đặt màu vẽ hiện tại trong khi dùng bảng màu cho các thủ tục vẽ. Màu số 0 là màu nền.

SetBkColor ( Color : Word ); là thủ tục xác lập màu nền.

SetBkColor(N) làm cho màu có thứ tự N thành màu nền hiện tại. Chỉ trừ SetBkColor(0) luôn đặt màu nền là đen.

Ví dụVẽ các đường ngang dọc màu đỏ trên nền xanh


Code:
 Uses Crt, Graph ;

Var

  Gd, Gm : Integer ;

Begin

  Gd := Detect ;

  InitGraph ( Gd, Gm,' ' ) ;

  If GraphResult <> GrOk Then Halt( 1 ) ;

  (* Đặt màu vẽ là đỏ *)

  SetColor ( Red ) ;

  (* Đặt màu nền là xanh *)

  SetBkColor ( Blue ) ;

  Repeat

   Line ( Random( GetMaxX ), Random( GetMaxY ),

  Random( GetMaxX ), Random( GetMaxY ) ) ;

  Delay ( 50 ) ;

  Until KeyPressed ;  CloseGraph;

End. 


Lưu ýĐoạn chương trình

Code:
Gd := Detect ;

InitGraph ( Gd, Gm,' ' ) ;

If GraphResult <> GrOk Then Halt( 1 ) ;


sẽ yêu cầu máy tự tìm chế độ màn hình thích hợp và khởi động chế độ đồ họa của Turbo Pascal. Nếu bạn muốn khởi động chế độ đồ hoạ, bạn có thể sử dụng đoạn mã trên.


II – Các thủ tục vẽ


1. Các thủ tục vẽ điểm:

PutPixel ( X, Y : Integer, Color : Word ); vẽ một điểm sáng có màu là Color tại điểm có tọa độ (X, Y).

GetPixel ( X, Y : Integer ) : Word; là hàm cho ta biết màu hiện tại tại điểm(X, Y).

Về nguyên tắc, với thủ tục vẽ điểm, thí dụ nhưPutPixel, ta có thể vẽ bất cứ hình gì. Tuy nhiên Pascal cũng cung cấp cho người dùng nhiều thủ tục vẽ có sẵn, ta cần khai thác hết.


2. Các thủ tục vẽ đường thẳng:

Line ( x1, y1, x2, y2 : Integer ); là thủ tục vẽ đường thẳng nối liền hai điểm có tọa độ tương ứng là(x1, y1)(x2, y2). Thủ tục vẽ đường thẳng này không phụ thuộc vào vị trí ban đầu của con trỏ màn hình. Sau khi vẽ song, con trỏ màn hình ở vị trí điểm(x2, y2).

LineTo ( X, Y : Integer ); là thủ tục vẽ từ vị trí con trỏ đồ họa hiện tại tới điểm(X, Y).

LineRel ( dX, dY : Integer ); là thủ tục vẽ đường thẳng từ vị trí con trỏ đồ họa hiện tại(X, Y) tới điểm mới có tọa độ(X + dX,Y + dY).Sau khi vẽ, con trỏ đồ họa rời tới điểm mới(X + dX, Y + dY).

3. Các thủ tục vẽ đường tròn:

Circle ( X, Y : Integer ; R : Word ); là thủ tục vẽ đường tròn có tâm tại điểm ( X, Y ), có bán kính là R.

4. Các thủ tục vẽ hình chữ nhật :

Rectangle ( x1, y1, x2, y2 : Integer ); vẽ hình chữ nhật với (x1, y1) là tọa độ điểm phía trên - bên trái, còn(x2, y2) là tọa độ điểm phía dưới - bên phải.

Bar ( x1, y1, x2, y2 : Integer ); vẽ hình chữ nhật song có thể tô màu đặc ở trong. Do đó bạn có thể dễ dàng vẽ các biểu đồ theo kiểu cột chữ nhật. Một điều đặc biệt khác là cách thức và mẫu tô đặc bên trong hình chữ nhật này có nhiều loại và được xác định bằng thủ tục SetFillStyle. Thủ tục vẽ hình chữ nhật Bar khác với thủ tục Rectangle ở chỗ Rectangle chỉ vẽ đường viền hình chữ nhật, không có tô bên trong được.

Ngoài các thủ tục để vẽ hình chữ nhật, Turbo Pascal còn cung cấp cho bạn một thủ tục để vẽ các đa giác bất kì như hình tam giác, lục giác.

DrawPoly ( NumPoints : Word ; Var PolyPoints ); vẽ một đường đa giác dùng màu và kiểu đường vẽ hiện thời.

PolyPoints là một tham số không kiểu chứa tọa độ các đỉnh của đa giác.NumPoints chỉ ra số tọa độ trong PolyPoints ( chính là số đỉnh của đa giác ). Một tọa độ bao gồm hai giá trị kiểu Word : một giá trị tọa độ X, một giá trị tọa độ Y.

DrawPoly sử dụng kiểu nét vẽ là màu vẽ hiện hành.

Chú ý rằng để vẽ một đa giác kín với N cạnh, bạn phải truyền N+1 tọa độ tới DawPoly, và tọa độ thứ N+1 phải trùng với tọa độ đầu tiên của đa giác đó. Bạn có thể thấy được điều này qua ví dụ vẽ hình tam giác sau :


Code:
Uses Graph ;

Const

  (* 4 tọa độ của tam giác *)

  Triangle : Array[ 1.. 4 ] Of PointType = ( (X : 50 ; Y : 100), (X : 100 ; Y :100),

     (X : 150 ; Y : 150), (X : 50 ; Y : 100) ) ;

Var

  Gd, Gm : Integer ;

Begin

  Gd := Detect ;

  InitGraph ( Gd, Gm, ' ' ) ;

  If GraphResult <> GrOk Then Halt( 1 ) ;

  DrawPoly ( SizeOf( Triangle ) Div SizeOf( PointType ), Triangle) ;

  Readln ;

  CloseGraph ;

End.


III – Văn bản đồ họa

Trong đồ họa, hai thủ tục Write và Writeln sẽ không được phù hợp cho lắm vì chúng dùng đơn vị tọa độ là số kí tự chuẩn trên màn hình. Có 2 thủ tục hiện ăn bản trong màn hình đồ họa một cách chính xác đến từng điểm màn hình và phong phú kiểu chữ hơn.

OutText ( St : String ); cho hiện nội dung của xâu St tại vị trí hiện tại của con trỏ đồ họa.

OutTextXY ( X, Y : Integer ; St : String ); cho hiện nội dung của xâu St nhưng tại tọa độ đồ họa (X, Y).

Như vậy, việc thực hiện lệnhOutTextXYcũngtương đương với việc thực hiện 2 lệnh :

MoveTo ( X, Y ) ;

OutText ( St ) ;

Kiểu chữ hiện ra trên màn hình nhờ 2 thủ tục trên sẽ có thể thay đổi vì có nhiều kiểu Font được chứa trong các file*.Chr.

SetTextStyle ( Font, Direction, CharSize : Word ); xác lập kiểu chữ với :

Kiểu Font chữ:

DefaultFont = 0

Triplex Font = 1

SmallFont = 2

SansSerifFont = 3

GothicFont = 4

Chiều viết ( Direction ):

HorizDir = 0 là nằm ngang

VertDir = 1 là thẳng đứng

Kích thước chữ ( CharSize ):

Nhận giá trị từ 1 đến 10, là kích thước của chữ.

SetTextJustify ( Hort, Vert : Word ); là thủ tục xác định vị trí dòng văn bản viết ra theo hai thủ tục OutText nói ở trên. Tham số Hort có các giá trị như sau :

LeftText = 0 văn bản xuất hiện ở bên phải con trỏ đồ họa

CenterText = 1 văn bản xuất hiện với tâm là vị trí con trỏ đồ họa

RightText = 2 văn bản xuất hiện ở bên phải con trỏ

Còn Vert là tham số có thể nhận các giá trị sau :

BottomText = 0 văn bản xuất hiện ở phía trên của con trỏ

CenterText = 1 văn bản xuất hiện ở quanh con trỏ

TopText = 2 văn bản xuất hiện ở phía dưới của con trỏ

Thí dụ sau sẽ xuất chữ“HELLO World !”ra màn hình với các font chữ, cách căn lề và hướng viết chữ khác nhau :


Code:
Uses Graph ;

Var

  Gd, Gm : Integer ;

BEGIN

  Gd := Detect ;

  InitGraph ( Gd, Gm, ' ' ) ;

  If GraphResult <> GrOk Then Halt( 1 ) ;

  (* Viết chữ HELLO theo chiều dọc *)

  SetTextStyle ( DefaultFont, VertDir, 2 ) ;

  SetTextJustify ( CenterText, CenterText ) ;

  OutTextXY ( 50, 50, ' HELLO ' ) ;

  (* Viết chữ World ! theo chiều dọc *)

  SetTextStyle ( GothicFont, HorizDir, 2 ) ;

  SetTextJustify ( RightText, CenterText ) ;

  OutTextXY ( 150, 50, ' World ! ' ) ;

  Readln ;

END.


IV – Mẫu tô, kiểu vẽ, màu tô

SetFillStyle ( Pattern : Word ; Color : Word ); trong đó mẫu tô là các hằng số nguyên có tên và giá trị được định nghĩa sẵn.

EmptyFill = 0 ; (* mầu nền đen *)

SolidFill = 1 ; (* vùng tô có màu tô *)

LineFill = 2 ; (* mẫu tô --- *) ;

LtslashFill = 3 ; (* mẫu tô / / / *)

SlashFill = 4 ; (* mẫu tô / / / với các nét nhỏ *)

BkSlashFill = 5 ; (* mẫu tô \ \ \ với các nét dày *)

LtBkSlashFill = 6 ; (* mẫu tô \ \ \ *)

HatchFill = 7 ; (* nét chải thưa *)

XHatchFill = 8 ; (* nét chải dày *)

InterLeaveFill = 9 ; (* các đường xen kẽ *)

WideDotFill = 10 ; (* chấm thưa *)

CloseDotFill = 11 ; (* chấm dày *)

UserFill = 12 ; (* tô theo mẫu của người dùng *)

Thật khó mô tả hết các mẫu vẽ trên giấy, vì vậy khi dùng bạn cần thử thay các giá trị của Patern từ 0 tới 11, thay Color để chọn màu, để nhìn thấy hết các mẫu tô.

Thí dụ sau sẽ cho bạn xem qua về 12 mẫu tô mà bạn có thể sử dụng trong công việc đồ họa :


Code:
Uses Graph ;

Var

  Gd, Gm : Integer ;

  X1, Y1, X2, Y2, i, Color : Integer ;

BEGIN

  Gd := Detect ;

  InitGraph ( Gd, Gm, ' ' ) ;

  If GraphResult <> GrOk Then Halt( 1 ) ;

  X1 := 0 ; Y1 := 0 ;

  X2 := 50 ; Y2 := 50 ;

  Color := 8 ;

  SetBkColor ( 15 ) ;

  (* Hàng thứ nhất trên màn hình chứa 6 mẫu đầu tiên *)

  For I := 1 To 6 Do

  Begin

  SetFillStyle ( i, Color ) ;

  Bar ( X1, Y1, X2, Y2 ) ;

  X1 := X1 + 60 ; X2 := X1 + 50 ;

   End ;

  X1 := 0 ; Y1 := 100 ;

  X2 := 50 ; Y2 := 150 ;

  (* Hàng thứ hai trên màn hình chứa 6 mẫu tiếp theo *)

  For I := 7 To 12 Do

  Begin

  SetFillStyle ( i, Color ) ;

  Bar ( X1, Y1, X2, Y2 ) ;

  X1 := X1 + 60 ; X2 := X1 + 50 ;

   End ;

  Readln ;

  CloseGraph ;

END.


Turbo Pascal có cung cấp cho bạn khả năng tự định nghĩa mẫu tô, nhưng lý thuyết về phần này hơi khó hiểu nên tôi không trình bày ở đây, tuy nhiên bạn có thể tham khảo thêm trong một số sách Pascal.


FloodFill ( X, Y : Integer ; Border : Word ); tô đầy một hình có đường bao kín với mẫu tô hiện hành, nghĩa là hình bao kín đó chứa tọa độ của điểm(X, Y), điểm(X, Y)gọi là điểm gieo. Mẫu tô hiện hành được thủ tụcSetFillStylehaySetFillPaternthiết lập, được dùng để làm đầy hình bao kín bởi màu đường biên Border (có giá trị từ 0 đến 15). Nếu điểm được khảo sát(X, Y)nằm trong hình bao, vùng bên trong được tô đầy còn nếu điểm đó nằm ngoài hình bao thì toàn bộ vùng bên ngoài hình bao được tô đầy.

Ví dụ sau sẽ tô đầy hình tròn bởi màu nhận được từ hàm GetMaxColor :

Code:
Uses Graph ;

Var

  Gd, Gm : Integer ;

Begin

  Gd := Detect ;

  InitGraph ( Gd, Gm, ' ' ) ;

  If GraphResult <> GrOk Then Halt ( 1 ) ;

  SetColor ( GetMaxColor ) ;

  Circle ( 50, 50, 20 ) ;

  FloodFill ( 50, 50, GetMaxColor ) ;

  Readln ;

  CloseGraph ;

End.


FillPoly ( NumPoints : Word ; Var PolyPoints ); vẽ một hình đa giác có tô màu bên trong.

PolyPoints là một tham số không kiểu chứa tọa độ các đỉnh của đa giác. NumPoints chỉ ra số tọa độ trong PolyPoints (chính là số đỉnh của đa giác). Một tọa độ bao gồm hai Word: một giá trị tọa độ X, một giá trị tọa độ Y.

FillPoly tính toán tất cả các chỗ cắt ngang và sau đó tô đa giác bằng kiểu tô và màu hiện hành được xác định bởi SetFillStyle haySetFillPatern. Đường bao ngoài của đa giác được vẽ với kiểu đường và màu hiện hành được thiết lập với SetLineStyle.

Code:
 Uses Graph;

Const

  Triangle: Array[ 1..3 ] Of PointType = ( (X : 50 ; Y : 100),

    (X : 100 ; Y : 100), (X : 150 ; Y : 150) ) ;

Var

  Gd, Gm: Integer;

Begin

  Gd := Detect ;

  InitGraph ( Gd, Gm, ' ' ) ;

  If GraphResult <> GrOk Then Halt( 1 ) ;

  FillPoly ( SizeOf( Triangle ) Div SizeOf( PointType ), Triangle ) ;

  Readln ;

  CloseGraph ;

End.


V – Khái niệm Viewport

ViewPort ( cửa để nhìn ) là một vùng chữ nhật trên màn hình để bạn có thể thực hiện các thủ tục đồ họa trên đó như là một màn hình nhỏ.


SetViewPort ( x1, y1, x2, y2 : Integer ; Clip : Boolean ); là thủ tục sẽ xác lập một ViewPort trong màn hình với(x1, y1, x2, y2)là tọa độ của ViewPort. Sau khi gọi thủ tục này, tọa độ (0, 0) của tất cả các thủ tục vẽ sẽ là góc trên-bên trái (x1, y1) của ViewPort chứ không phải là góc trên-bên trái của màn hình.


Tham số Clip có thể có giá trị True = ClipOn: cho phép hiện lên các nét vẽ vượt ra ngoài khung ViewPort,còn ClipOff sẽ không cho hiện lên các nét vẽ vượt ra ngoài ViewPort.


Bạn có thể thay đổi ViewPort ở mọi nơi trong chương trình để có được tọa độ vẽ, khung vẽ cho thích hợp.


Thí dụ, bạn muốn vẽ đồ thị hàm số với gốc tọa độ ở giữa màn hình :


SetViewPort ( GetMaxX Div 2, GetMaxY Div 2, GetMaxX, GetMaxY, ClipOn ) ;


ViewPort này sẽ nằm ở góc phần tư dưới phải, với tọa độ được tính qua hàm GetMaxX và GetMaxY. Do tham số Clip có giá trị là True nên bạn có thể vẽ cho toàn màn hình.

VI – Tạo hình chuyển động

Có 3 trình xử lý ImageSize, GetImage, PutImage để chép các điểm ảnh vào biến và về sau trình bày chúng ở bất kì nơi nào trên màn hình.


ImageSize ( x1, y1, x2, y2 : Integer ); trả về số byte cần thiết để lưu trữ hình trong phạm vi hình chữ nhật có góc trên-bên trái là (x1, y1), và góc dưới - bên phải là (x2, y2).


GetImage ( x1, y1, x2, y2 : Integer ; Var Pbitmap ); chép các điểm ảnh và các thông tin về bề rộng, cao của hình chữ nhật vào biến có kiểu Bitmap.


PutImage ( X, Y : Integer ; Var PBitmap ; CopyMode : Word ); chép ảnh trong biến có kiểu Bitmap ra màn hình tại vị trí ( X, Y ). Tham biến CopyMode chỉ định một trong các hằng :

CopyPut = 0 sao chép đè lên bộ nhớ màn hình. Nghĩa là hình cũ trên màn hình sẽ bị mất đi.

XorPut = 1 các điểm ảnh trong PBitmap sẽ kết hợp với các điểm ảnh trên màn hình với phép toán logic XOR. Dùng phép toán này có lợi là nếu ta lặp lại một lần nữa thì phần nền bị hình đè lên sẽ được khôi phục lại.

OrPut = 2 là các phép toán logic tương ứng

AndPut = 3 với các kiểu đặt màu ảnh

NotPut = 4 vào màu nền.


Tóm lại, các bước mấu chốt bạn cần nhớ để có thể tạo hình chuyển động là :

* Vẽ hình, lưu ảnh vào một biến động không định kiểu.

* Tạo trễ ( Delay ).

* Xóa hình đó, khôi phục lại nền cũ với thủ tục PutImage có dùng phép XorPut.

* Vẽ hình ở vị trí mới.


Hi vọng những kiến thức trong loạt bài này sẽ góp phần nâng cao kiến thức cơ bản cho các bạn về lập trình. Chúc các bạn học tập tốt và thành công trên con đường mình đã chọn. Xin chào và hẹn gặp lại ở những bài học sau.

Nhận xét

Bài đăng phổ biến từ blog này