При закрытии подписчики были переданы в рассылку "Delphi - проблемы и решения" на которую и рекомендуем вам подписаться.
Вы можете найти рассылки сходной тематики в Каталоге рассылок.
Здравствуйте! Как вы думаете, какие самые игры: WarCraft, Quake? Нет! Минёр, тетрис, «шарики» – вот игры всех времён и народов. В «серьёзные» игры играют не все, а в тетрис на компьютере играл каждый! Сегодня мы напишем одну из таких “ZBest Game” – “Пятнашки”.Смысл игры: выбранная пользователем картинка разбивается на 16 кусочков, перемешивается и её ,естессно, надо собрать. Сначала займёмся интерфейсом. Поместите на форму компонент ToolBar1, и в нём разместите 5 кнопок Toolbutton. Вот какие функции они будут выполнять: ToolButton1-Новая игра ToolButton2-Показать/Спрятать оригинал ToolButton3-Заново перемешать картинку ToolButton4-О программе ToolButton5-Выход Задайте кнопкам соответствующие картинки. Для этого создайте компонент ImageList, добавьте в него иконки, и пропишите его в свойстве Images компонента ToolBar. Ещё нам понадобится компонент OpenPictureDialog и 3 компонента Image.В их свойства Width и Height поставьте 200. Один из них назовите Map и поместите на форме слева – здесь появится разрезанная картинка. Второй Image назовите Original и поместите правее первого. В нём будет оригинал картинки. Третий Image назовите StrechImage и сделайте его невидимым – это служебный Image и пользователю его видеть не положено :)).
Теперь приступим к кодерству. Объявите глобальные переменные: pic: array[1..16] of TBitMap; mass: array [1..4, 1..4] of smallint; orig:boolean; В массиве pic у на будут храниться кусочки мозайки, а в mass – индексы картинок.. Создайте процедуру Picture. procedure TMain.Picture; var i, j, count:smallint; SRS: TRect; begin OpenPictureDialog1.execute; If OpenPictureDialog1.filename<> '' then begin Original.Picture.LoadFromFile(OpenPictureDialog1.filename); StrechImage.canvas.StretchDraw(StrechImage.clientrect, Original.picture.graphic); count:=0; SRS.Left:=0; srs.Top:=0; srs.Right:=50; srs.Bottom:=50; For J:= 1 to 4 do begin For i:= 1 to 4 do begin count:=count+1; Pic[count].Canvas.CopyRect(pic[count].Canvas.ClipRect, StrechImage.canvas, SRS); srs.left:=srs.Left+50; srs.Right:=srs.Right+50; end; srs.Left:=0; srs.Right:=50; srs.Top:=srs.Top+50; srs.Bottom:=srs.bottom+50; end; pic[16].Canvas.fillrect(clientrect); end; Map.Enabled:=true; end; Эта процедура загружает выбранную пользователем картинку в Original, а затем с помощью метода StrechDraw копирует в StrechImage уже в том разрешении, которое нам и нужно: 200x200. Дальше сжатая картинка разбивается на 16 кусков, которые последовательно записываются в массив pic. Pic[16] затирается – это будет пустая ячейка, благодаря которой можно перемещать остальные кусочки. Теперь сделаем процедуру, которая в случайном порядке введёт индексы кусочков мозайки в массив mass. procedure TMain.Restart; var i, j: smallint; f: boolean; bool: array [1..16] of boolean; begin For i:= 1 to 16 do bool[i]:=false; For j:= 1 to 4 do begin For i:= 1 to 4 do begin f:=true; while f=true do begin mass[i, j]:=random(16)+1; If bool[mass[i, j]]=false then begin bool[mass[i, j]]:=true; f:=false; end; end; end; end; Draw; end; По сути дела мы перемешали кусочки мозайки. Теперь их нужно нарисовать, для этого создадим процедуру Draw. procedure TMain.Draw; var i, j, x, y: smallint; begin x:=0; y:=0; For j:= 1 to 4 do begin For i:= 1 to 4 do begin Map.canvas.draw(x, y, pic[mass[i, j]]); x:=x+50; end; x:=0; y:=y+50; end; end; Всё, с «самопальными» процедурами закончено, начнём прописывать события, связанные с интерфейсом. procedure TMain.FormCreate(Sender: TObject); var i:smallint; begin orig:=true; for i:= 1 to 16 do begin pic[i]:=TBitMap.create; //Выделяем в памяти место под наши картинки pic[i].Height:=50; pic[i].Width:=50; end; end;
//Кнопка «Новая игра» procedure TMain.ToolButton1Click(Sender: TObject); begin Picture; Restart; end;
// Кнопка «Рестарт» procedure TMain.ToolButton3Click(Sender: TObject); begin Restart; end;
//Кнопка «Показать/Спрятать оригинал» procedure TMain.ToolButton2Click(Sender: TObject); begin If orig=true then begin N10.Checked:=false; orig:=false; Main.Width:=223; ToolButton2.Hint:=’Показать оригинал’; end else begin n10.checked:=true; orig:=true; Main.Width:=436; ToolButton2.Hint:='Спрятать оригинал'; end; end; Здесь остановимся подробнее. При запуске программы оригинал картинки виден. При этом длина моей формы – 436. При нажатии кнопки «Спрятать оригинал» форма должна уменьшить свою длину, спрятав оригинал. Когда моя форма укорочена, её длина равна 223. У вас скорее всего будут другие результаты! Поэтому «померьте» свою форму в «суженном» и «расширенном» состояниях, пропишите в процедуре ToolButton2Click СВОИ ЗНАЧЕНИЯ! Теперь самое интересное – процедура обработки кликлв мышки на компоненте map. Процедура довольно громоздкая, но ничего страшного в ней нет! В переменных posX и posY мы вычисляем на каком по номеру кусочке мозаики щёлкнул пользователь, и если справа, слева, сверху или снизу есть пустой квадратик – меняет их местами. procedure TMain.MapMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var p, i, j, posX, posY: smallint; begin posX:=x div 50 +1; posY:= y div 50 +1;
If mass[posX-1, posY]=16 then begin mass[posX, posY]:= Mass[posX-1, posY]+mass[posX, posY]; mass[posx-1, posY]:=mass[posX, posY]- mass[posX-1, posY]; mass[posX, posY]:= mass[posX, posY]-mass[posX-1, posY]; end else If mass[posX+1, posY]=16 then begin mass[posX, posY]:= Mass[posX+1, posY]+mass[posX, posY]; mass[posx+1, posY]:=mass[posX, posY]- mass[posX+1, posY]; mass[posX, posY]:= mass[posX, posY]-mass[posX+1, posY]; end else If mass[posX, posY-1]=16 then begin mass[posX, posY]:= Mass[posX, posY-1]+mass[posX, posY]; mass[posx, posY-1]:=mass[posX, posY]- mass[posX, posY-1]; mass[posX, posY]:= mass[posX, posY]-mass[posX, posY-1]; end else If mass[posX, posY+1]=16 then begin mass[posX, posY]:= Mass[posX, posY+1]+mass[posX, posY]; mass[posx, posY+1]:=mass[posX, posY]- mass[posX, posY+1]; mass[posX, posY]:= mass[posX, posY]-mass[posX, posY+1]; end; Draw; p:=0; For j:= 1 to 4 do begin For i:= 1 to 4 do begin If mass[i, j]= (j*4) - (4-i) then p:=p+1; end; end; If p=16 then Application.MessageBox('Вы выиграли!', 'Поздравляю!'); end; procedure TMain.ToolButton5Click(Sender: TObject); begin close; end;
Напоследок давайте сделаем небольшой чит-код(Разработчики называют их «Easter eggs» - “Пасхальные яйца”). При нажатии клавиши «w» с зажатым Shift’ом, картинка будет складываться сама ;)) procedure TMain.FormKeyPress(Sender: TObject; var Key: Char); var i, j: smallint; begin If (key='W') and (Map.Enabled=true) then begin For j:= 1 to 4 do begin For i:= 1 to 4 do mass[i, j]:=(4*j) - (4-i); end; Draw; end; end; //Включаем генератор случайных чисел initialization randomize; По своему усмотрению прикрутите к проге секундомер, подсчёт сделанных «телодвижений» и вуаля – вполне работоспособная игрушка готова! Исходники программы здесь, а здесь – -exe.
C уважением, Valar. |
В избранное | ||