В этой статье мы разберём реализацию классической игры на запоминание цветов (Memory Game) с использованием языка Object Pascal в среде Delphi. Игра не только развлекает, но и тренирует память, что полезно для когнитивного здоровья.
Основные компоненты игры
Представленный код реализует игру с 16 карточками (4x4), где нужно находить пары одинаковых цветов. Рассмотрим ключевые аспекты реализации:
1. Структура данных
type
TCard = record
ImageIndex: Integer;
IsFlipped: Boolean;
IsMatched: Boolean;
Rect: TRect;
end;
Каждая карточка хранит: - Индекс цвета - Флаг перевёрнутого состояния - Флаг совпадения с другой карточкой - Прямоугольник для отрисовки
2. Инициализация игры
Процедура Reset выполняет начальную настройку:
procedure TForm1.Reset;
var
i, j, k: Integer;
indexList: array of Integer;
begin
SetLength(CardImages, 8);
for i := 0 to 7 do
CardImages[i] := TBGRABitmap.Create(CardWidth, CardHeight, CardColors[i]);
BackImage := TBGRABitmap.Create(CardWidth, CardHeight, BGRA(155, 155, 100));
SetLength(indexList, 16);
for i := 0 to 15 do indexList[i] := i div 2;
// Перемешивание карточек
for i := 0 to 15 do
begin
j := Random(16);
k := indexList[i];
indexList[i] := indexList[j];
indexList[j] := k;
end;
// Распределение карточек по сетке
k := 0;
for i := 0 to GridCols-1 do
for j := 0 to GridRows-1 do
begin
Cards[i,j].ImageIndex := indexList[k];
Cards[i,j].IsFlipped := False;
Cards[i,j].IsMatched := False;
Cards[i,j].Rect := Rect(i*(CardWidth+CardSpacing), j*(CardHeight+CardSpacing),
i*(CardWidth+CardSpacing)+CardWidth,
j*(CardHeight+CardSpacing)+CardHeight);
Inc(k);
end;
// Сброс переменных
playsound('snds/restart.wav',0, soundsflag);
FirstCardX := -1;
FirstCardY := -1;
SecondCardX := -1;
SecondCardY := -1;
Reste := 8;
Coup := 0;
Score := 0;
end;
3. Обработка кликов по карточкам
procedure TForm1.BGRAVirtualScreen1MouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
i, j: Integer;
begin
if CardsFlipped = 2 then Exit;
for i := 0 to GridCols-1 do
for j := 0 to GridRows-1 do
begin
if (X >= Cards[i,j].Rect.Left) and (X < Cards[i,j].Rect.Right) and
(Y >= Cards[i,j].Rect.Top) and (Y < Cards[i,j].Rect.Bottom) and
(not Cards[i,j].IsFlipped) and (not Cards[i,j].IsMatched) then
begin
Cards[i,j].IsFlipped := True;
if CardsFlipped = 0 then
begin
FirstCardX := i;
FirstCardY := j;
end
else if CardsFlipped = 1 then
begin
SecondCardX := i;
SecondCardY := j;
Timer1.Enabled := True;
end;
Inc(CardsFlipped);
BGRAVirtualScreen1.DiscardBitmap;
Exit;
end;
end;
end;
4. Проверка совпадения карточек
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled := False;
if (FirstCardX >= 0) and (FirstCardY >= 0) and
(SecondCardX >= 0) and (SecondCardY >= 0) then
begin
if Cards[FirstCardX, FirstCardY].ImageIndex = Cards[SecondCardX, SecondCardY].ImageIndex then
begin
Cards[FirstCardX, FirstCardY].IsMatched := True;
Cards[SecondCardX, SecondCardY].IsMatched := True;
playsound('snds/hit.wav',0, soundsflag);
Inc(Score);
Dec(Reste);
end
else
begin
playsound('snds/lost.wav',0, soundsflag);
Cards[FirstCardX, FirstCardY].IsFlipped := False;
Cards[SecondCardX, SecondCardY].IsFlipped := False;
end;
end;
Inc(coup);
if Reste = 0 then
begin
inc(partie);
Memo1.Lines.Add('Round : '+IntToStr(Partie)+ ' Move : ' + IntToStr(Coup));
Sleep(2000);
reset;
end;
FirstCardX := -1;
FirstCardY := -1;
SecondCardX := -1;
SecondCardY := -1;
CardsFlipped := 0;
BGRAVirtualScreen1.DiscardBitmap;
end;
Возможные улучшения игры
Добавление изображений вместо цветов:
// Загрузка изображений вместо цветных прямоугольников
for i := 0 to 7 do
CardImages[i] := TBGRABitmap.Create('images/card_' + IntToStr(i) + '.png');
Анимация переворота карточек:
// Пример процедуры анимации
procedure AnimateCardFlip(x, y: Integer);
var
step: Integer;
begin
for step := 1 to 10 do
begin
// Промежуточные состояния анимации
Sleep(20);
BGRAVirtualScreen1.DiscardBitmap;
Application.ProcessMessages;
end;
end;
Разные уровни сложности:
// Изменение размера сетки
procedure SetDifficulty(level: Integer);
begin
case level of
1: begin GridCols := 4; GridRows := 4; end; // Легкий
2: begin GridCols := 6; GridRows := 6; end; // Средний
3: begin GridCols := 8; GridRows := 8; end; // Сложный
end;
Reset;
end;
Система рекордов:
// Сохранение результатов
procedure SaveScore(name: string; score: Integer);
var
sl: TStringList;
begin
sl := TStringList.Create;
try
if FileExists('scores.dat') then
sl.LoadFromFile('scores.dat');
sl.Add(Format('%s=%d', [name, score]));
sl.SaveToFile('scores.dat');
finally
sl.Free;
end;
end;
Заключение
Представленная реализация игры на запоминание демонстрирует: - Работу с графикой через BGRABitmap - Обработку пользовательского ввода - Логику игрового процесса - Использование таймера для задержки действий
Исходный код можно расширять, добавляя новые функции, улучшая графику и увеличивая сложность. Такие проекты отлично подходят для изучения Delphi и принципов игровой разработки.
Как отметил пользователь Guva, на базе этого кода можно создавать более сложные вариации игры, например, с шейдерными эффектами и тематическим оформлением.
Реализация классической игры на запоминание цветов в Delphi с использованием BGRABitmap для графики, обработкой кликов и логикой поиска парных карточек.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.