Міністерство освіти та науки України
Національний університет “Львівська політехніка”
Кафедра АСУ
ГРАФІКО-РОЗРАХУНКОВА РОБОТА
на тему
“Створення проекту із застосуванням наслідування та поліморфізму”
Індивідуальне завдання.
Клас “нота”: назва, октава, тривалість звучання, порядковий номер.
Дочірні класи:
“звук” (частота);
“зображення” (координати на екрані лівого верхнього кута фрагмента нотного стану).
Методи для перевантаження або перевизначення:
- “інкремент” – отримання наступної ноти;
- “множення” – збільшення тривалості звучання ноти;
- “виведення” – на екран, динамік або колонки.
Діаграма Класів
Клас TNota:
Батьківській клас, який характеризує об’єкт нота і містить такі методи :
Inc_ – отримання наступної ноти
Dec_ – отримання поперед. ноти;
Клас TSound, дочірній клас від TNota, займається виведенням звуку на динаміки. Клас містить такі методи:
Song– займається виводом звуку на динамік. Метод є перевантаженим, оскільки таких методів є два. Один з них виводить „класову” ноту на динамік, тобто ноту котра є по замовчуванню, другий виводить ноту відповідно до параметру, порядковий номер ноти.
Inc_ – отримання наступної ноти
Dec_ – отримання поперед. ноти;
SetNewLen– встановлює нову тривалість звучання
Клас TGraphicMusic:
Дочірній клас від TNota, який займається відображенням ноти у нотному стані.
Клас TGraphicMusic місти такі методи:
Draw –малювання ноти.
Inc_ – отримання наступної ноти
Dec_ – отримання поперед. ноти;
Інструкція користувачу
Для виконання програми потрібно зайти у папку з програмою та запустити її. З’явиться вікно що зображено на мал. 1.
Мал.1 Зовнішній вигляд програми
Управління програмою з водиться до декількох кнопок:
UP – отримання наступної ноти ( графічно відображається нота на екрані)
DOWN – отримання поперед. ноти ( графічно відображається нота на екрані)
Приклад зображено на мал.2.
мал.2. отримання наступної ноти
Також є можливість задати нову довжину звучання. Для того потрібно задати нове значення у рядку „Довжина звуку” і натиснути кнопку „задати”. Приклад показано на мал. 3.
мал.3. Зміна довжини звучання.
Також є можливість моментального виведення звуку. Для того у стрічці Музика вводимо букви, які характеризують ноти (букви описані нижче). Окрім цього є можливість озвучення нот, які є описані у рядку. Це робиться за допомогою кнопки „Програти”.
Опис букв які відповідають нотам:
S - „до”
D - „ре”
F - „мі”
G - „фа”
H - „соль”
J - „ля”
K - „сі”
P - пауза (розміром в довжину ноти)
Висновок
Поставленою задачею було розробити програмний ужиток симуляції шахової дошки та фігур (пішака, ферзі). Основною умовою було написання програми на об’єктно-орієнтованій мові програмування Delphi з використанням класів. Універсальний підхід, що використовується у об’єктно-орієнтованому програмуванні дозволяє розкласти проблему на зв'язані між собою завдання. Кожна проблема стає самостійним об'єктом, що містить свої власні коди і дані, які відносяться до цього об'єкту. В цьому випадку початкове завдання в цілому спрощується, і програміст дістає можливість оперувати з великими за об'ємом програмами. У цьому визначенні в ООП відбувається відомий підхід до рішення складних задач, коли ми розбиваємо задачу на підзадачі і вирішуємо ці підзадачі окремо. З погляду програмування подібний підхід значно спрощує розробку і відладку програм.
Додаток
Код головної програми. (UNIT1.PAS)
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,Sound, ExtCtrls;
type
TForm1 = class(TForm)
GroupBox1: TGroupBox;
paint: TPaintBox;
Edit1: TEdit;
Button1: TButton;
Button2: TButton;
Label1: TLabel;
Label2: TLabel;
Edit2: TEdit;
Button3: TButton;
Button4: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Edit1Change(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
gm:TGraphicMusic;
Sound:TSound;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
gm:=TGraphicMusic.Create(@Paint.Canvas,paint.ClientWidth,paint.ClientHeight);
Sound:=TSound.Cerate;
Sound.Len:=100;
Sound.Song;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
gm.Inc_;
Sound.Inc_;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
gm.Dec_;
Sound.Dec_;
end;
procedure TForm1.Edit1Change(Sender: TObject);
begin
if length(Edit1.text)<>0 then
case Edit1.text[length(Edit1.text)] of
's':Sound.Song(0);//do
'd':Sound.Song(1);//re
'f':Sound.Song(2);//mi
'g':Sound.Song(3);//fa
'h':Sound.Song(4);//sol
'j':Sound.Song(5);//la
'k':Sound.Song(6);//si
'p':Sound.Song(-1);//pause
end;
end;
procedure TForm1.FormPaint(Sender: TObject);
begin
gm.Draw;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
if EDit2.Text<>'' then
Sound.Len:=StrToInt(EDit2.Text);
end;
procedure TForm1.Button4Click(Sender: TObject);
var s:str;
i:int;
begin
s:=Edit1.text;
for i:=1 to length(s)do
case s[i] of
's':Sound.Song(0);//do
'd':Sound.Song(1);//re
'f':Sound.Song(2);//mi
'g':Sound.Song(3);//fa
'h':Sound.Song(4);//sol
'j':Sound.Song(5);//la
'k':Sound.Song(6);//si
'p':Sound.Song(-1);//pause
end;
end;
end.
Код модуля роботи з звуком. (Sound.pas)
unit Sound;
interface
uses Graphics,MMSystem,SysUtils;
type
Str = string;
Int = Integer;
TNota = class // нота
private
FName:Str; // назва
FOctava:Int; // октава
FLen:int; // тривалість звучання
FNum:int; //порядковий номер.
procedure Inc_; // отримання наступної ноти;
procedure Dec_; // отримання поперед. ноти;
public
end;
//=====================================================
PWavHeader=^TWavHeader;
TWavHeader = record // структура заголовку *.WAV файлу
sigRIFF:array[0..3]of char; // має бути "RIFF"
sizeRIFFch:int;
sigWAVE:array[0..3]of char;
sigFMT:array[0..3]of char;
sizeFMTch:int;
wFormatTag:word;
wChannels:word;
dwSamplesPerSec:int;
dwAvgBytesPerSec:int;
wBlockAlign:word;
wBitPerSample:word;
sigDATA:array[0..3]of char;
sizeDATAch:int;
end;
TSound = class(TNota) // клас звуку
private
FFrequency:int; // частота
Procedure SetNewLen(Len:int); // задати нову довжину звучання
public
Constructor Cerate; // конструктор
procedure Song;overload; // звучання
procedure Song(F:int);overload; //звучання конкретної ноти
procedure Inc_; //отримання наступної ноти( зміна частоти звучання)
procedure Dec_;
property Len:int read Flen write SetNewLen; // довчина звучання
End;
//================================================
PCanvas = ^TCanvas;
TGraphicMusic = class(TNota) // графіка
private
Fx,Fy:int; //координати ноти
FGO:Pcanvas; // граф. об'єкт де мал. ноти
w,h:int; // ширина, висота граф. об'єкта
public
Constructor Create(GObj:PCanvas;width,height:int); // конструктор
procedure Draw; // мал.
procedure Inc_; //отримання наступної ноти( зміна назви ноти)
procedure Dec_;
end;
const
FDelta:int = 20; // розмір між лінійками (у пікселях)
iFrequency :array[0..6]of int =(500,600,710,800,1000,1200,1600); // масив частот
szName_nota:array[0..6]of str=('do','re','mi','fa','sol','la','si');// масив значень
implementation
uses SysConst;
{ TGraphicMusic }
constructor TGraphicMusic.Create(GObj: PCanvas;width,height:int);
begin
inherited Create; // створ. батьків. класу (TObject)
FGO:=GObj;
FGO^.Brush.Style:=bsClear;
w:=width;
h:=height;
FNum:=0;
FName:=szName_nota[FNum]; // витягуємо ім'я ноти з масиву імен
FOctava:=1;
end;
procedure TGraphicMusic.Dec_;
begin
inherited Dec_; // виклик. декремент бать. класу
FName:=szName_nota[FNum]; // обнов. ім'я ноти
Draw; // перемальовуємо
end;
procedure TGraphicMusic.Draw;
var i,y:int;
begin
with FGO^ do
begin
FillRect(ClipRect);// чистимо екран
for i:=1 to 5 do // 5 лінійок
begin
y:=FDelta*i;
MoveTo(0,y);
LineTo(w,y);
end;
Fy:=6*FDelta-(FDelta*FNum div 2);// позиція позначки
Fx:=FNum*FDelta+FDelta;
Ellipse(Fx-7,Fy-5,Fx+7,Fy+5); // мал. еліпс
if FNum=0 then // якщо нота "До" - еліпс з рискою
begin
MoveTo(Fx-15,Fy);
LineTo(Fx+15,Fy);
end;
TextOut(Fx+20,Fy-7,FName); // виводимо надпис ноти
end;
end;
procedure TGraphicMusic.Inc_;
begin
inherited Inc_; //метод батьк. класу
FName:=szName_nota[FNum];
Draw;
end;
{ FSound }
constructor TSound.Cerate;
begin
inherited Create;
FNum:=0;
FName:=szName_nota[FNum];
FOctava:=1;
FLen:=400; // початково довжина звуку
FFrequency:=iFrequency[FNum]; // задаємо частоту звуку FNum=0 => "до"
end;
procedure TSound.Dec_;
begin
inherited DEC_;
FFrequency:=iFrequency[Fnum];
Song;
end;
procedure tSound.Song;
var numSamples,size:integer;
p:Pchar;
head:PWavHeader;
i:int;
begin
if(FFrequency=0) or (FFrequency>44100) then // якщо частота "<0" або ">44100" вийти
exit;
numSamples:=44100 div FFrequency; // к-сть вибірок
size:=sizeof(TWavHeader) + numSamples;
head:=AllocMem(size); // виділ. пам. розмір. структ. та масив. вибірки
head.sigRIFF:='RIFF';
head.sigWAVE:='WAVE';
head.sizeRIFFch := size - 8;
head.sigFMT:='fmt ';
head.sizeFMTch := 16;
head.wFormatTag := 1;
head.wChannels := 1; // моно
head.dwSamplesPerSec := 44100;
head.dwAvgBytesPerSec := 44100;
head.wBlockAlign := 1;
head.wBitPerSample := 8; // 8 біт. звук
head.sigDATA:='data'; // сегмент даних
head.sizeDATAch := size;
p:=Pchar(head);
inc(p,sizeof(TWavHeader));//зміщуємося на масив даних, якій знах. за заголовком файлу
for i:=0 to numSamples-1 do // заповнюємо вибірку
p[i] := char(Round(255*sin(6.28*i/size)));
// слухаємо музику (зациклену)
PlaySound(pchar(head), 0, SND_ASYNC or SND_LOOP or SND_MEMORY);
// зачекаємо певний час
Sleep(FLen);
// і зупинемо музику
PlaySound(nil, 0, SND_ASYNC);
freemem(head);// звільнемо пам'ять
end;
procedure TSound.Song(F: int);
var tmp_f:int;
begin
if F=-1 then // якщо парам. -1 = пауза
begin
Sleep(Flen);
exit;
end;
Tmp_f:=FFrequency; // збереж. частоту
FFrequency:=iFrequency[f]; // задамо пнову
Song; // прослухаємо
FFrequency:=tmp_f; // полвернемо поперед.
end;
procedure TSound.Inc_;
begin
inherited Inc_;
FFrequency:=iFrequency[Fnum];
Song;
end;
{ TNota }
procedure TNota.Dec_;
begin
if FNum<1 then Exit;
Dec(FNum);
end;
procedure TNota.Inc_;
begin
if FNum>5 then Exit;
Inc(FNum);
end;
procedure TSound.SetNewLen(Len: int);
begin
FLen:=Len;
end;
end.
Файл Форми.
object Form1: TForm1
Left = 171
Top = 101
Width = 489
Height = 313
BorderIcons = [biSystemMenu]
Caption = 'MUSIC'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
OnPaint = FormPaint
PixelsPerInch = 96
TextHeight = 13
object Label1: TLabel
Left = 16
Top = 232
Width = 38
Height = 13
Caption = #1052#1091#1079#1080#1082#1072
end
object GroupBox1: TGroupBox
Left = 16
Top = 8
Width = 449
Height = 217
Caption = #1053#1086#1090#1085#1080#1081' '#1089#1090#1072#1085
TabOrder = 0
object paint: TPaintBox
Left = 8
Top = 16
Width = 297
Height = 145
end
object Label2: TLabel
Left = 8
Top = 168
Width = 78
Height = 13
Caption = #1044#1086#1074#1078#1080#1085#1072' '#1079#1074#1091#1082#1091
end
object Button1: TButton
Left = 328
Top = 32
Width = 75
Height = 17
Caption = 'Up'
TabOrder = 0
OnClick = Button1Click
end
object Button2: TButton
Left = 328
Top = 96
Width = 75
Height = 17
Caption = 'Down'
TabOrder = 1
OnClick = Button2Click
end
object Edit2: TEdit
Left = 24
Top = 184
Width = 105
Height = 17
TabOrder = 2
Text = '100'
end
object Button3: TButton
Left = 144
Top = 184
Width = 89
Height = 17
Caption = #1047#1072#1076#1072#1090#1080
TabOrder = 3
OnClick = Button3Click
end
end
object Edit1: TEdit
Left = 32
Top = 248
Width = 305
Height = 21
TabOrder = 1
Text = 'spdpfpgphpjpkpjphpgpfpdps'
OnChange = Edit1Change
end
object Button4: TButton
Left = 352
Top = 248
Width = 105
Height = 17
Caption = #1055#1088#1086#1075#1088#1072#1090#1080
TabOrder = 2
OnClick = Button4Click
end
end