Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АрхитектураБиологияГеографияДругоеИностранные языки
ИнформатикаИсторияКультураЛитератураМатематика
МедицинаМеханикаОбразованиеОхрана трудаПедагогика
ПолитикаПравоПрограммированиеПсихологияРелигия
СоциологияСпортСтроительствоФизикаФилософия
ФинансыХимияЭкологияЭкономикаЭлектроника

Создание кнопок

Построение графиков элементарных функций | В случайных местах | Движение двоичного образа по фоновой картинке | В динамических приложениях | Перемещение картинок | События от мыши | Движение образа по удерживанию левой кнопки мыши | Код клавиши | По нажатию клавиши со стрелкой | Совмещение управляемого и неуправляемого движений. |


Читайте также:
  1. Creating and using arrays Создание и использование массивов
  2. Creating constants Создание константы
  3. Creating loops in Swift Создание петель в Swift
  4. Creating optional variables Создание дополнительных переменных
  5. Defining and instantiating classes Определение и создание экземпляра классы
  6. IV. Создание сбалансированного портфеля
  7. Using inheritance Создание вычисляемых свойств

5.1.1. Проект «Лохотрон»

Постановка задачи. Создать четыре кнопки, пронумеровать кнопки, дать им имя. Программа загадывает случайное число, а играющий должен угадать, какое это число. Для этого он мышью кликает по соответствующей кнопке. Данный проект – это простейший пример динамического создания кнопок и их методов.

Реализация. Положим на форму только одну кнопку «Старт». На рис. 27 дана форма проекта «Лохотрон».

 

Рис. 27. Форма для проекта «Лохотрон»

 

Понадобится одна глобальная переменная LuckyNumber

var LuckyNumber:integer;

В обработчике события OnClick кнопки Button 1 напишем такой код:

 

procedure TForm1.Button1Click(Sender: TObject);

Var TB: TButton;

i: Integer;

begin

Randomize;

LuckyNumber:=Random(4)+1; {Загадали случайное число}

For i:=1 To 4 Do

Begin

{ Ищем объект по имени.

Примечание: для TSpeedButton и некоторых других объектов FindChildControl () не работает – необходимо использовать FindComponent () - работает точно с такими же параметрами – именем объекта }

TB:=TButton(Form1.FindChildControl('B'+IntToStr(i)));

If TB<>Nil Then

TB.Free; { Уничтожили кнопку, если она есть }

End;

For i:=1 To 4 Do

Begin

{ Создаём экземпляр класса TButtonForm 1

(параметр Owner – хозяин) – объект, отвечающий за удаление кнопки.

Если кнопка не была уничтожена вручную, то при удалении Owner (хозяина) он обходит все принадлежащие ему объекты и удаляет их сам }

TB:=TButton.Create(Form1);

{ Parent – родитель, т. е. объект, на котором будет нарисована кнопка }

TB.Parent:=Form1;

{ На имя объекта накладываются такие же ограничения,

как на имена переменных, т.е. оно должно начинаться с буквы }

TB.Name:='B'+IntToStr(I); {B1, B2, B3... }

TB.Left:=i*50; { Чтобы не накладывались друг на друга }

TB.Top:=20;

TB.Width:=30;

TB.Caption:=IntToStr(i);

TB.OnClick:=BTN; { Указание собственного метода }

TB.Tag:=i; { Присваиваем свойству Tag номер кнопки }

End;

end;

 

Событие OnClick созданных кнопок подключает метод BTN, код которого приведен ниже. В этом методе анализируется, какая кнопка была нажата. Если номер кнопки равен загаданному числу,
то выводится сообщение «Победа», все кнопки прячутся (свойство Hide) и можно начинать сначала. Если номер кнопки не равен загаданному числу, то эта кнопка прячется. Заголовок метода BTN помещается в раздел public:

 

type

TForm1 = class(TForm)

Button1: TButton;

procedure Button1Click(Sender: TObject);

private

{ Private declarations }

public

procedure BTN(Sender: TObject);

{ Public declarations }

end;

 

procedure TForm1.BTN(Sender: TObject);

Var TB: TButton;

i: Integer;

Begin

{ Sender - объект, у которого произошло событие, вызвавшее данный метод }

TB:=TButton(Sender); { Преобразовываем объект класса TObject в кнопку }

If TB.Tag = LuckyNumber Then

Begin

ShowMessage('Победа!');

For i:=1 To 4 Do

Begin

{Ищем кнопки по имени и прячем их}

TB:=TButton(Form1.FindChildControl('B'+IntToStr(I)));

If TB<>Nil Then TB.Hide;

End;

End

Else

Begin

ShowMessage('Не угадали.');

{ Скрываем кнопку, на которую нажали }

TB.Hide;

End;

End;

На рис. 28 показан результат после нажатия кнопки «Старт».

 

Рис. 28. Кнопки, созданные в проекте «Лохотрон»

 

Задание. Вместо кнопок TButton используйте кнопки TBitBtn,
у которых свойство Glyph позволяет загрузить картинки на поверхность кнопки. Картинки размещайте на кнопки случайным образом. Изначально картинки не видны. Рядом положите такие же картинки. Загадайте одну из них, пометив ее щелчком, а потом поищите ее
на кнопках.

 

5.1.2. Игра «Пятнадцать»

Постановка задачи. Реализуйте известную игру «Пятнадцать», используя двумерный массив. Изначально числа расположены на 15 кнопках случайно. Результат работы после необходимых перестановок приведен на рис. 29. Надо учесть, что в данной игре не при всяком случайном расположении чисел возможен выигрыш.

Реализация. Опишем массив кнопок типа TButton и массив целых чисел. Глобальные данные:

 

const

n=4;

h=40; // Размер кнопки

x0=10; // Координаты левого верхнего угла поля

y0=10;

var a: array [1..n,1..n] of integer;

bt: array [1..n,1..n] of TButton;

i0, k0:integer; // Координаты пустого места

 

Рис. 29. Выигрыш в игре «Пятнадцать»

 

Процедура zapolnenie заполняет массив числами от 1 до 15, располагая их в случайные клетки поля.

 

procedure zapolnenie;

var i,j,k,m:integer;

zap:boolean;

begin

for i:=1 to n do

for j:=1 to n do

a[i,j]:=0;

for i:=1 to n*n-1 do

begin

zap:=false;

repeat

k:=random(n)+1;

m:=random(n)+1;

if a[k,m]=0 then

begin

a[k,m]:=i;

zap:=true;

end;

until zap;

end;

end;

Процедура swap () меняет значения двух переменных.

 

procedure swap(var a,b:integer);

var r:integer;

begin

r:=b;

b:=a;

a:=r;

end;

 

Метод FMD нажатия на кнопку находит координаты нажатой кнопки, проверяет, свободно ли рядом, и если свободно, то меняет число с пустой кнопкой. В процедуре FMD числа i 0, k 0 – это координаты пустой кнопки.

 

procedure TForm1.FMD(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

var i,k:integer;

begin

k:=((Sender as TControl).Left-x0) div h +1;

i:=((Sender as TControl).Top-y0)div h +1;

if ((abs(i-i0)=1)and(k=k0))or((abs(k-k0)=1)and(i=i0))then

begin // Рядом свободно

swap(a[i,k],a[i0,k0]);

bt[i,k].Caption:=' ';

bt[i0,k0].Caption:=inttostr(a[i0,k0]);

i0:=i;

k0:=k;

end;

end;

 

Наконец, обработчик TForm1.FormCreate заполняет массив чисел от 1 до 15 в случайном порядке, создает массив кнопок, задает размеры кнопок, устанавливает свойства шрифта, размещает кнопки
на форме в виде таблицы.

 

procedure TForm1.FormCreate(Sender: TObject);

var i,j:integer;

begin

randomize;

zapolnenie;

// Создадим массив кнопок

for i:=1 to n do

for j:=1 to n do

begin

bt[i,j]:=TButton.Create(Form1);

bt[i,j].Parent:=Form1;

bt[i,j].Width:=h;

bt[i,j].Height:=h;

bt[i,j].Left:=x0+(j-1)*h;

bt[i,j].Top:=y0+(i-1)*h;

bt[i,j].Font.Size:=18;

bt[i,j].Font.Style:=[fsBold];

if a[i,j]<>0 then

bt[i,j].Caption:=inttostr(a[i,j])

else

begin // Запомним кнопку, где пусто

i0:=i;

k0:=j;

end;

bt[i,j].Visible:=True;

bt[i,j].OnMouseDown:=FMD;

end;

end;

 

Задание. Организуйте проверку, получилось ли выигрышное расположение. Также для удобства положите на форму кнопку «Начать заново» и напишите соответствующий код.

5.2. Создание компонентов TImage

5.2.1. Проект «Угадай картинку»

Постановка задачи. На форме в ряд расположены четыре разные картинки (рис. 30). Сначала они открыты какое-то время, потом закрываются. Около них появляется одна из спрятанных картинок. Надо угадать такую же картинку в этом ряду. Проект развивает зрительную память. Это простейший пример динамического создания массива компонентов TImage.

 

Рис. 30. Проект «Угадай картинку»

Реализация. Нарисуйте в графическом редакторе четыре картинки размером примерно 60 х 60. Положите на форму две кнопки «Старт» и «Выход». Положите компоненты ТTimer и ТImage для отдельной картинки. Форма проекта приведена на рис. 31.

Для размещения четырех картинок необходимо программным путем создать массив из четырех компонентов TImage.

Глобальные данные

 

const n=4;

dx=60;dy=70; // Размеры картинок

type mas=array [1..n] of string;

mas_int=array [1..n] of integer;

const fname:mas=('Вишня.bmp','яблоко.bmp','апельсин.bmp',

'ананас.bmp');

var x0,y0,i: integer;

nom_picture:integer;

Im:array [1..n] of TImage;

number: mas_int;

 

Рис. 31. Форма проекта «Угадай картинку»

 

Ниже приведен код основных процедур.

 

procedure pole;

var i,x,y:integer; {Поле}

begin

y:=y0;

for i:=1 to n do

begin

x:=x0+(i-1)*dx;

with Form1.canvas do

begin

pen.Color:=clblack;

pen.Width:=2;

brush.Color:=Form1.Color;

rectangle(x,y,x+dx,y+dy);

end;

end;

end;

 

procedure ris;

{Выбор случайной картинки и показ ее на экране}

begin

nom_picture:=random(4)+1;

Form1.Image1.Picture.LoadFromFile(fname[nom_picture]);

Form1.Image1.Left:=5;

Form1.Image1.Top:=20;

Form1.Image1.Transparent:=true;

Form1.Image1.Visible:=true;

end;

 

procedure zapolnenie; {Заполнение массива числами от 1 до 4}

var i,k:integer;

b:boolean;

begin

randomize;

b:=false;

for i:=1 to n do

number[i]:=0;

for i:=1 to n do

begin

b:=false;

repeat

k:=random(n)+1;

if number[k]=0 then

begin

number[k]:=i;

b:=true;

end;

until b;

end;

end;

 

procedure TForm1.FormCreate(Sender: TObject);

var i:integer;

begin

x0:=100;

y0:=20;

Timer1.Enabled:=false;

Timer1.Interval:=50;

randomize;

zapolnenie;

for i:=1 to n do // Создание массива TImage

begin

Im[i]:=TImage.Create(Form1);

Im[i].Parent:=Form1;

Im[i].Picture.LoadFromFile(fname[number[i]]);

Im[i].Height:=60;

Im[i].Width:=45;

Im[i].OnClick:=Imclick;

Im[i].left:=x0+(i-1)*dx+5;

Im[i].Top:=y0+5;

Im[i].Transparent:=true;

Im[i].Visible:=false;

end;

end;

 

procedure TForm1.Timer1Timer(Sender: TObject);

begin // Некоторое время видны все картинки

Timer1.Interval:=Timer1.Interval-1;

if Timer1.Interval=0 then

begin

Timer1.Enabled:=false;

pole; // Картинки закрываются

ris; // Видна одна случайная картинка

end;

end;

 

procedure TForm1.Button1Click(Sender: TObject);

var i:integer; {Кнопка «Старт»}

begin

Label1.Caption:='';

Timer1.Enabled:=true;

Timer1.Interval:=50;

Image1.Visible:=false;

zapolnenie;

pole;

for i:=1 to n do

begin

Im[i].Picture.LoadFromFile(fname[number[i]]);

Im[i].Visible:=true;

end;

end;

 

procedure TForm1.ImClick(Sender: TObject);

var k:integer;

begin

k:=((Sender as TControl).Left-x0) div dx +1;

Label1.Caption:='';

If Im[k]<>Nil Then

Im[k].Hide;

im[k].Visible:=true;

if number[k]=nom_picture then

Label1.Caption:='Вы угадали'

else

Label1.Caption:='Не угадали';

end;

 

Задание. Усовершенствуйте проект так, чтобы можно было только один раз кликать на картинку, т. е. исключить возможность угадывания.

5.2.2. Проект «Собери картинку»

Постановка задачи. Данная программа релизует известную игру Puzzle и направлена на освоение типов TBitmap, TRect, метода CopyRect и навыков работы с двумерными массивами. Вид картинки до сборки и после перемешивания показан на рис. 32. Цель работы
с приложением – собрать картинку.

 

Рис. 32. Проект «Собери картинку»

 

Реализация. Подберите фотографию и сохраните ее в папке проекта как растровый рисунок типа bmp. Положите на форму два компонента TPaintBox, один TImage и две кнопки «Показать картинку» и «Перемешать картинку». При создании формы (процедура FormCreate) создайте компонент Puzzle класса TBitmap, загрузите
в него картинку из файла, установите размер формы, равный двум Puzzle.Width + 30 (30 пикселей на зазоры), установите размер компонентов PaintBox 1 и PaintBox 2, равным размеру Puzzle.

Картинку будем «резать» на 16 клеток (4 х 4). Размер одного фрагмента обозначим dx и dy.

dx:= Puzzle.Width div 4;

dy:= Puzzle.Height div 4;

Для хранения одного фрагмента картинки используйте компонент TImage. Сделайте его размер равным размеру фрагмента,
т. е. dx и dy. Сделайте Image 1 невидимым.

Также задайте начальное значение переменной click 1, которая подсчитывает число «кликов»:

click1:= 1; {Номер "клика": первый клик и далее нечетный клик выбирает первый фрагмент, второй – четный, выбирает второй фрагмент и меняет их местами}

Опишите глобальные переменные:

 

var

puzzle:TBitmap;

rect1,rect2:Trect;

click1,i,j,dx,dy:integer;

pole: array[1..4,1..4] of integer;

 

Обработчик кнопки «Показать картинку» выводит исходный рисунок в Paintbox 1.

 

procedure TForm1.Button1Click(Sender: TObject);

begin

paintbox1.Canvas.Draw(0,0,puzzle);

end;

 

В следующей процедуре создаем перемешанный рисунок. Разбиваем рисунок на 16 квадратных фрагментов и перемешиваем их. «Перемешанный» рисунок помещаем в Paintbox 2.

procedure TForm1.Button2Click(Sender: TObject);

var k,n,x,y:integer;

begin

{Заполняем двумерный массив нyлями. С помощью массива будем определять, помещен ли в соответствующую клетку фрагмент рисунка. Если в массиве 0, то это свободное поле, где еще не поставлен фрагмент.}

for i:= 1 to 4 do

for j:= 1 to 4 do

pole[i,j]:=0; //Весь массив заполнили нулями

for i:= 1 to 4 do

for j:= 1 to 4 do

begin // Ищем свободное поле

repeat

k:=random(4)+1;

n:=random(4)+1;

until pole[k,n]=0;

pole[k,n]:=1; //Заполняем его единицей

x:=(j-1)*dx; //Координаты фрагмента, который мы

//скопируем из PaintBox 1 в Paintbox 2

//на случайно выбранное место

y:=(i-1)*dy;

rect1:=bounds(x,y,dx,dy); //Границы этого фрагмента

//сохраняем в переменной rect 1

x:=(n-1)*dx; //Координаты случайно выбранного

y:=(k-1)*dy; // фрагмента в Paintbox 2

rect2:=bounds(x,y,dx,dy); //Границы этого фрагмента

//сохраняем в переменной rect 2

//Копируем фрагмент из Paintbox 1 в Paintbox 2

paintbox2.Canvas.CopyRect(rect2,paintbox1.Canvas,rect1);

end;

//Чертим клетки на Paintbox 2

with paintbox2.Canvas do

begin

pen.Color:=clblack;

pen.Width:=1;


for i:=1 to 3 do

begin

moveto(0, dy*i);

lineto(paintbox2.Width,dy*i);

moveto(dx*i,0);

lineto(dx*i,paintbox2.Height);

end;

end; end;

 

В обработчике события OnMouseDown на компоненте PaintBox 2 напишите следующий код.

 

procedure TForm2.PaintBox2MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

var u,v:integer; rect3:Trect;

procedure XYtoUV(x,y:integer; var u,v:integer);

//Процедура находит номер строки и столбца, в которых

// находится фрагмент c координатами Х и Y

begin

u:=(x div dx)*dx;

v:=(y div dy)*dy;

end;

begin

XYtoUV(x,y,u,v);

rect2:=bounds(0,0,dx,dy); //Границы фрагмента,

// скопированного в Image1

// Если это нечетный "клик",

if click1 mod 2=1 then

begin

//Копируем фрагмент в Image1.

rect1:=bounds(u,v,dx,dy);

image1.Canvas.CopyRect(rect2,paintbox2.Canvas,rect1);

end

else

// Если это четный "клик"

begin

//Меняем местами два фрагмента

rect3:=bounds(u,v,dx,dy);


paintbox2.Canvas.CopyRect(rect1,paintbox2.Canvas,rect3);

paintbox2.Canvas.CopyRect(rect3,Image1.Canvas,rect2);

end;

click1:=click1+1;

end;

 

Задание 1. На титульном листе сделайте меню, в котором заведите позиции «Помощь играющему» и «Выбор картинки из файлов». Предложите на выбор около 5 картинок.

 

Задание 2. Сделайте программную проверку правильности сборки картинки с положительной похвалой.

 

Задание 3. Можно завести таблицу рекордов, в которую помещать минимальные количества кликов, необходимых для сборки картинки.

 

Задание 4. Положите таймер и сделайте на форме свой таймер с тем, чтобы на сборку картинки установить ограничение по времени.

 


 


Дата добавления: 2015-08-20; просмотров: 79 | Нарушение авторских прав


<== предыдущая страница | следующая страница ==>
В графических приложениях| Сортировка массива

mybiblioteka.su - 2015-2024 год. (0.048 сек.)