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

Đây là phần hơi nâng cao một chút, 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 1)
Màn hình, bàn phím, âm thanh trong Pascal (Phần 1)


I - Màn hình văn bản

Để xử lý màn hình văn bản, bàn phím và âm thanh, Turbo Pascal viết sẵn một số thủ tục và hàm có chứa trong Unit Crt.

1. Tọa độ màn hình:

Màn hình văn bản thường gặp ở chế độ 80 cột, 25 dòng. Mỗi vị trí trên màn hình xác định bởi tọa độ cột và tọa độ dòng, chỉ chứa được một trong số 256 kí tự chuẩn của bảg mã ASCII.

Ví dụ :

_ Điểm (1, 1) nằm ở vị trí góc trên bên trái nhất của màn hình.

_ Điểm (20, 2) nằm ở vị trí cột thứ 20, hàng thứ 2 của màn hình.

2. Một số thủ tục xử lý màn hình:


GotoXY(X, Y : Byte); đưa vị trí con trỏ tới tọa độ (X, Y).

Ví dụ sau sẽ viết ra màn hình dòng chữ " Dong 20, Cot 20 " tại tọa độ (20, 20) :



Code:
Uses Crt ;

Begin

GotoXY(20, 20);

Write (' Dong 20, Cot 20 ') ;

Readln ;

End. 



WhereX; WhereY; là 2 thủ tục cho ta biết cột, dòng hiện tại của con trỏ.

ClrScr; xóa toàn bộ màn hình và đặt con trỏ vào vị trí góc trên, bên trái(cột 1, hàng 1). Để xóa từ vị trí con trỏ đến hết dòng(không di chuyển con trỏ), ta dùng ClrEoLn.

DelLine; xoá một dòng tại vị trí của con trỏ và mọi dòng ở phía dưới sẽ được dịch lên một dòng.

InsLine; chèn thêm một dòng trống vào vị trí của con trỏ trên màn hình.


Window(X1, Y1, X2, Y2); thủ tục để vẽ một cửa sổ trên màn hình có tọa độ :

_ Góc trên bên trái là cột X1, hàng Y1.

_ Góc dưới bên phải là cột X2, hàng Y2.


Bây giờ, ta nhập chương trình sau đây vào máy để xem màu của Pascal nhảy nhót tung tăng trên màn hình.


Code:
 Uses Crt ;

Var

  X, Y : Byte ;

BEGIN

  TextBackground(Black);  (* Xóa màn hình *)

  ClrScr ;

  Repeat

  X := Succ(Random(80)); (* Vẽ các cửa sổ ngẫu nhiên *)

  Y := Succ(Random(25));

  Window(X, Y, X + Random(10), Y + Random(8));

  TextBackground(Random(16)); (* Tạo màu ngẫu nhiên *)

  ClrScr ;

  Until KeyPressed ;

END.

II – Thể hiện màu sắc

Trên màn hình màu, mỗi ô chữ có hai loại màu là màu chữ và màu nền. Để thể hiện màu chữ và màu nền, ta dùng 2 thủ tục sau :

TextColor ( Color : Byte ); thủ tục này đặt màu cho chữ, số và các kí hiệu khác.

TextBackground ( Color : Byte ); là thủ tục đặt màu nền.

* Để thể hiện một màu nào đó, ta có thể sử dụng một trong hai cách :


Code:
TextColor ( Yellow ) ;

  hoặc TextColor ( 14 ) ;


Những màu văn bản được biểu diễn bằng các số giữa khoảng 0 tới 15, để nhận dạng một cách dễ dàng, bạn có thể dùng tên các màu này thay cho việc dùng số rất khó nhớ. Trong các chế độ văn bản màu, màu kí tự được chọn là 16 màu, còn màu nền là 8 màu.

* Mầu kí tự có thể cho nhấp nháy bằng cách cộng với hằng Blink, có giá trị là 128.

Sau đây là một ví dụ đầy đủ về cách sử dụng màu nền và màu chữ, bạn hãy chạy thử để biết được khả năng thể hiện màu sắc của Turbo Pascal.


Code:
Uses Crt ;

BEGIN

  ClrScr ;

  (* Kí tự màu xanh lá cây và nền đen *)

  TextColor ( Green ) ;

  TextBackground ( Black ) ;

  WriteLn (' Hey there ! ') ;

  (* Kí tự màu đỏ nhạt và sáng lấp láy *)

  (* Nền xám nhạt *)

  TextColor ( LightRed + Blink ) ;

  TextBackground ( LightGray ) ;

  WriteLn (' Hi there ! ') ;

  (* Kí tự có màu vàng, nền xanh dương *)

  TextColor ( 14 ) ; (* Yellow = 14 *)

  TextBackground ( Blue ) ;

  Writeln (' Ho there ! ') ;

  NormVideo ; (* Chế độ sáng thông thường *)

  WriteLn (' Back to normal... ') ;

  Readln ;

END.



Trong ví dụ trên, bạn thấy có một thủ tục lạ là NormVideo. Đây là thủ tục xác định chế độ màn hình :

LowVideo; bắt đầu chế độ sáng thấp. Sau khi gọi thực hiện thủ tục này thì mọi dữ liệu xuất ra trên màn hình đều có màu với độ sáng thấp.

HighVideo; bắt đầu chế độ sáng cao, các dữ liệu xuất ra trên màn hình sẽ có màu sáng chói hơn.

NormVideo; bắt đầu chế độ sáng thông thường sau khi gọi thực hiện.

III – Xử lí bàn phím

Để xử lý bàn phím, Turbo Pascal cung cấp cho bạn hai hàm cơ bản :


KeyPressed : Boolean; là hàm trả lại giá trị True nếu một phím được ấn và False nếu không có. Tuy nhiên, hàm KeyPressed không thể xử lý các phím nóng như Shift, Alt, NumLock...


Ví dụ:


Code:
Uses Crt ;

BEGIN

(* Điền đầy màn hình bằng kí tự Xxcho đến khi gõ phím *)

Repeat

  Write(' Xx ') ;

Until KeyPressed ;

END.

ReadKey : Char; đọc kí tự từ bàn phím. Nếu biến KeyPressed là True trước khi gọi tới ReadKey, kí tự được đọc vào ngay lập tức, không chờ ấn Enter. Nếu KeyPressed là False, tức không có một phím nào được ấn,ReadKey sẽ đợi cho đến khi có một phím được ấn và nhận diện phím được ấn đó.


Kí tự được đọc không hiện lên trên màn hình, cho dù các kí tự đó thuộc bảng chữ cái hay là các chữ số từ 0 đến 9.

Khi một phím đặc biệt được ấn, đầu tiên ReadKey trả lại giá trị không (Nul #0), và sau đó trả lại mã quét mở rộng.

Một đoạn chương trình dưới đây đọc kí tự hay mã phím mở rộng vào trong biến Ch và đặt biến Boolean có tên là FuncKey tới giá trị True nếu kí tự là một phím đặc biệt :


Code:
Ch := ReadKey ;

If Ch <> Then

Begin

  Writeln (' Khong phai phim dac biet ') ;

  FuncKey := False ;

End

Else

Begin

  FuncKey := Key ;

  Ch := ReadKey ;

End ;

Sau đây là một ví dụ ngắn thể hiện cách sử dụng hàm ReadKey:

Code:
Uses Crt ;

Var

  Ch: Char ;

BEGIN

  Writeln (' Hien thi cac gia tri ma ki tu ASCII ') ;

  Writeln (' An Ecs de thoat ') ;

  Writeln ;

  Repeat

  Writeln (' Ki tu ? ') ;

  Ch := Readkey ;

  Writeln ( Ch,' : gia tri ma ASCII la ', Ord( Ch ) );

  Until Ch = Chr ( 27 ) ;

END.

IV – Tạo âm thanh

Loa của máy PC (Personal Computer : máy tính cá nhân) làm theo nguyên lý chuyển mạch bật tắt. Trong trường hợp bật sẽ tạo âm thanh ở một tần số nào đó, còn trường hợp chuyển mạch tắt sẽ tắt luôn âm thanh.

Công cụ cơ bản của Turbo Pascal để xử lý loa là các thủ tục Sound, Nosound và Delay. Tất cả các thủ tục này đều là thành phần của unit Crt.Sound nhận một tham biến là tần số của tone cần phát ra. Ví dụ nốt Đô trung có tần số 512 Hertz, trong khi nốt Đô ở quảng tám thấp hơn có tần số 256 Hertz và nốt Đô ở quảng tám cao hơn có tần số 1024 Hertz.

Đi kèm với thủ tục Sound là thủ tục Nosound. Mỗi khi bật tắt loa để phát một tone nào đó, loa sẽ tiếp tục phát tone cho đến khi bạn dùngNosound. Để ấn định thời khoảng phát tone, bạn dùng thủ tục Delay. Delay nhận một tham biến cho biết thời khoảng trễ (tính bằng mili giây).


Ví dụ sau đây sẽ cho loa phát ra âm thanh có tần số 500 Hertz trong khoảng thời gian 1000 mili giây (1 giây) :



Code:
Program Am_thanh ;

Uses Crt ;

BEGIN

  Sound ( 500 ) ;

  Delay ( 1000 ) ;

  Nosound ;

END.

V – Các hiệu ứng của âm thanh

Đối với một số ngôn ngữ lập trình hướng đối tượng mạnh như Visual Basic hoặc Visual C++, thì việc quản lý âm thanh như chuyển âm thanh, chuyển nhạc (nhạc MP3, audio) ra Soundcard là không có gì khó. Nhưng đối với Pascal, đó là một công việc phức tạp và mất thời gian.

Ở bài này, tôi chỉ đề cập đến việc tạo hiệu ứng âm thanh trên loa nội bộ của máy PC.

1. Beep (bíp):

Tiếng bíp thường dùng để báo lỗi trong các chương trình. Để phát tiếng bíp, bạn dùng tần số xấp xỉ 150 Hertz trong khoảng thời gian 400 mili giây.


Ví dụ sau đây sẽ phát ra tiếng bip để báo lỗi nếu bạn nhập sai số liệu :



Code:
Program Bip ;

Uses Crt ;

Var

  MyNum : Integer ;

(* ----------------------------------------------------- *)

Procedure Beep ;

Begin

  Sound ( 150 ) ;

  Delay ( 400 ) ;

  Nosound ;

End ;

(* ----------------------------------------------------- *)

BEGIN

  Clrscr ;

  Write (' Cho mot so tu 1 đen 5 : ') ;

  Readln ( MyNum ) ;

  If ( MyNum < 1 ) Or ( MyNum > 5 ) Then

  Begin

  Beep ;

  Write (' Ban vao sai roi ! ') ;

  End

  Else Write (' So lieu duoc chap nhan ! ') ;

  Readln ;

End.

2. Buzz (tiếng rù rù):

Để tạo tiếng rù rù, bạn dùng tần số 100 Hertz và thời khoảng 30 mili giây


Code:
Program Ru_ru ;

Uses Crt ;

Var

  Counter : Integer ;

BEGIN

  For Counter := 1 To 30 Do

  Begin

  Sound ( 100 ) ;

   Delay ( 30 ) ;

  Nosound ;

  Delay ( 30 ) ;

  End ;

END.

3. Tiếng banh nảy:

Để tạo tiếng banh nảy bạn thay đổi giữa 2 tone thấp và cao như quả banh nảy lên rồi lại rơi xuống. Mỗi lần banh nảy sẽ giảm độ nảy so với lần trước nghĩa là tiếng banh ngày càng gần nhau. Ví dụ sau đây cho thấy điều đó :


Code:
 Program Ban_nay ;

Uses Crt ;

Var

  Hight, Low : Integer ;

(* ---------------------------------------------------------- *)

Procedure BoucingBall ( Hight, Low : Integer ) ;

Var

  Count : Integer ;

Begin

  Count := 20 ;

  While Count > 1 Do

  Begin

  Sound ( Low - Count * 2 ) ;

  Delay ( (Count * 500) Div 20 ) ;

  Nosound ;

  Sound ( Hight ) ;

  Delay ( (Count * 500) Div 15 ) ;

  Nosound ;

  Delay ( 150 ) ;

  Count := Count - 2 ;

  End ;

End ;

(* ---------------------------------------------------------- *)

BEGIN

  BoucingBall ( 350, 200 ) ;

END.


4. Tiếng bỏ bom:

Ví dụ sau tạo ra tiếng bỏ bom. Thủ tục BombsAway có 3 tham biến Hight, Low, Altitude. Tham biến Hight, Low cho tần số cao và thấp, tham biến Altitude kiểm soát thời khoảng của tone :


Code:
Program Bo_bom ;

Uses Crt ;

Var

  Hight, Low, Altitude : Integer ;

(* ------------------------------------------------------------ *)

Procedure BombsAway ( Hight, Low, Altitude : Integer ) ;

Var

  Count : Integer ;

Begin

  Count := Low ;

  While Count <= Hight Do

  Begin

  Sound ( Count ) ;

  Delay ( (Altitude Div Count) * 75 ) ;

  Count := Count + 10 ;

  End ;

  For Count := 1 To 3 Do

  Begin

  Nosound ;

  Sound ( 40 ) ;

  Delay ( 500 ) ;

  Nosound ;

  Delay ( 100 ) ;

  End ;

  Sound ( 40 ) ;

  Delay ( 3000 ) ;

  Nosound ;

End ;

(* ------------------------------------------------------------ *)

BEGIN

  BombsAway ( 1200, 200, 500 ) ;

END.


5. Tiếng báo động:

Ví dụ sau đây sẽ tạo ra tiếng báo động cho đến khi bạn gõ phím bất kì :

Code:
Program Bao_dong ;

Uses Crt ;

(* ----------------------------------------------------------- *)

Procedure RedAlert ( Hight, Low : Integer ) ;

Var

  Ch :Char ;

Begin

  Clrscr ;

  Write(' An phim bât ki de cham dut bao dong ! ') ;

  Repeat

  Sound ( Hight ) ;

  Delay ( 400 ) ;

  Sound ( Low ) ;

  Delay ( 400 ) ;

  Until KeyPressed ;

  Ch := Readkey ;

  Nosound ;

End ;

(* ----------------------------------------------------------- *)

BEGIN

  RedAlert ( 359, 200 ) ;

END.


Trên đây, tôi đã trình bày các hiệu ứng của âm thanh được lập trình bởi Pascal. Tuy nhiên do sử dụng kĩ thuật phối âm chưa cao nên âm thanh chưa gây được ấn tượng cho người nghe

VI – Âm nhạc

Khi chạy chương trình của mình, có lẽ ai cũng muốn chèn vào một đoạn nhạc ngắn và vui tai để chương trình thêm sinh động. Với kiến thức mà chúng ta đang có, điều đó có thể thực hiện được. Bạn có thể dùng thủ tục Sound và các tần số của nốt nhạc để tạo ra các đoạn nhạc theo ý muốn của mình, miễn là ta phải nắm chút ít về nhạc lí.


Ta đã biết, để thể hiện cao độ của nốt nhạc, ta dùng thủ tục Sound, còn đối với trường độ của nốt nhạc, ta dùng thủ tục Delay.

Trường độ của nốt nhạc do ta tự qui định tùy thuộc vào bản nhạc đó nhanh hay chậm. Chẳng hạn ta lấy nốt móc đơn làm mốc và cho nốt này một giá trị trường độ là 1/10 giây, thì


Nốt trắng = 4/10 giây Þ Delay ( 400 )

Nốt đen = 2/10 giây Þ Delay ( 200 )

Nốt móc đơn = 1/10 giây Þ Delay ( 100 )

Nốt móc đôi = 5/100 giây Þ Delay ( 50 )

Nốt móc ba = 25/1000 giây Þ Delay ( 25 )


* ĐỌC VÀ CHƠI NHẠC TỪ TẬP TIN VĂN BẢN :


Có một cách để chương trình chơi nhạc của bạn trở nên đơn giản và suôn sẽ hơn. Đó là đọc và chơi nhạc từ tập tin văn bản. Bạn chỉ việc tạo file chứa các giá trị ấn định mức độ nhanh chậm của bản nhạc theo quy tắc có sẵn do chương trình đặt ra. Sau đó, bạn nhập đường dẫn để chương trình tìm và chơi bản nhạc có chứa trong file đã được chỉ định.


Chương trình sau đây sẽ phát ra giai điệu bài "Cho con” của Phạm Trọng Cầu. Bản nhạc được ghi trong Text file theo mẫu :


5 C D

5 C MD

5 D MD

4 G D

5 M D

5 D T

...


Mỗi nốt nhạc được ghi trên một dòng theo thứ tự : quãng tám, tên nốt ( kí hiệu ) và kí hiệu trường độ phân cách nhau bởi một khoảng trắng.

Với bản nhạc này, ta lấy nốt móc đơn làm mốc và có giá trị trường độ là 250. Chữ T kí hiệu nốt trắng (Duration = 1000 ), chữ D - nốt đen ( Duration = 500 ), chữ MD - móc đơn ( Duration = 250 )...


Sau đây là chương trình Chơi nhạc từ Text file



Code:
Program Choi_nhac ; (* Bai hat 'Cho con' cua Pham Trong Cau *)

Uses Crt;

Const Notes: Array [0..12] Of String

  = ('L','C','CF','D','DF','E','F','FF','G','GF','A','AF','B') ;

  A0 = 32.625 ;

  T=1000 ; D=500 ; MD=250 ;

Var f : Text ;

  S, N : String ;

  O, Du, Code : Integer ;

Procedure Play ( Octave : Integer ; Note : String ; Duration : Integer) ;

Var Fr : real ; I : Integer ;

Begin

  Fr := A0 ;

  For I := 1 To Octave Do Fr := Fr * 2 ;

  I := 0 ;

  While Notes[ i ] <> Note Do

  Begin

  Fr := Fr * Exp ( Ln(2) / 12 ) ; Inc ( i ) ;

  End ;

  If Note <> 'L' Then

  Begin

  Sound ( Round( Fr ) ) ;

  Delay ( Duration ) ;

  NoSound ;

  Delay ( 50 ) ;

  End

  Else

  Begin

  Nosound ; Delay( Duration + 50 ) ;

  End ;

End ;

BEGIN

  Assign ( f,'CHOCON.OUT' ) ; Reset ( f ) ;

  Repeat

  Read ( f, O) ;

  Readln ( f, S ) ;

  While S[ 1 ] = ' ' do Delete( S, 1, 1 ) ;

  While S[ Length( S ) ] = ' ' Do Delete( S, Length( S ),1 ) ;

  N := Copy ( S, 1, Pos( ' ', s ) -1 ) ;

  Delete( S, 1, Pos( ' ', s ) ) ;

  While S[1]=' ' Do Delete( S, 1, 1 ) ;

  If S = 'T' Then Du := T ;

  If S = 'D' Then Du := D ;

  If S = 'MD' Then Du := MD ;

  Play ( O, N, Du ) ;

  Until EOF ( f ) ;

  Close ( f ) ;

END.

Nhận xét

Đăng nhận xét

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