Создание меню для игры
Вторая часть создания игры, (для тех кто в танке вот ссылка )начинается с меню, и поэтому логично будет начать с создания именно его. Выглядеть оно будет примерно так:
Сразу хочу сделать акцент на том, что расширение экрана у игр Dendy 256x224. Надеюсь вы уже установили компоненты DelphiX т.к. на их установке я не буду останавливаться. Если вы не знаком с этим движком, то перед началом лучше прочитайте основы здесь http://students.uni-vologda.ac.ru/pages/pm99/leo/delphix.htm Создаем новый проект, называем его LodeRunner, модуль нызываем uMain и меняем класс формы с TForm на TDXForm. Будем использовать следующие компоненты:
Form Height: 732 Width: 808 Position: poScreenCenter Caption: Lode Runner DXDraw - графическая область для DirectX, то на что будет выводиться графика Align: alClient AutoSize: False Display: 800x700x24 Height: 700 Width: 800 Option: [doStretch,doCenter,doFlip,doHardware] SurfaceHeight: 224 SurfaceWidth: 256
Размер 800x700 потому, что, как я уже писал, в играх dendy расширение экрана 256x224, и наше расширение д.б. пропорциональным для лучшего отображения.
DXTimer – таймер, который собственно и производит отрисовку. ActiveOnly: True Enable: False (включать его мы будем самостоятельно) Interval: 0 DXSpriteEngine – спрайтовый движок DXDraw: DXDraw1 DXImageList – коллекция для хранения изображений и спрайтов DXDraw: DXDraw1 Должно получиться нечто похожее:
Теперь инициализируем и финализируем DXDraw
procedure TForm1.DXDraw1Finalize(Sender: TObject); begin DXTimer1.Enabled := False; // выклюючакм таймер end; procedure TForm1.DXDraw1Initialize(Sender: TObject); begin DXTimer1.Enabled := True; // вклюючакм таймер (отрисовку) end;
Теперь можно запустить и проверь, что все нормально работает. Важным компонентом является DXImageList. В нем можно хранить все используемые изображения и спрайты. Смотрим на вид меню (сверху) и пытаемся сделать такое же. Выделяем DXImageList, щелкакм на свойство Items и добавляем новые элементы в TpictureCollection
1)Фон меню
Name: Menu PatternHeight: 0 PatternWidth: 0 Transparent: False Picture:
2)Кнопка одиночной игры
Name: MenuPlayer1 PatternHeight: 8 PatternWidth: 72 Transparent: True Picture:
3)Кнопка игры вдвоем
Name: MenuPlayer2 PatternHeight: 8 PatternWidth: 80 Transparent: True Picture:
4)Кнопка перехода в редактор
Name: MenuEditMode PatternHeight: 8 PatternWidth: 80 Transparent: True Picture:
Как можно заметить, изображения кнопок состоят из двух частей: изображение для выделенной кнопки и не выделенной. Тут нам понадобиться модуль intf, который содержит описания классов для создания кнопок, чекбоксов, эдитов и т.д. для DelphiX. Скачать его можно в прикрепленных файлах. Добавляем модуль intf в uses. По желанию можете добавить еще кнопок, например кнопку Exit (выход) и Option(настройки). Теперь определим новый тип:
type TGameState = (stMenu, stGamePlayer1, stGamePlayer2, stGameEditMode);
Он будет определять, в каком состоянии мы сейчас находимся-будет это меню, или игра в однопользовательском режиме, или другое.
TMenuBackSprite = class(TBackgroundSprite) public constructor Create(AParent: TSprite); end; { TMenuBackSprite } constructor TMenuBackSprite.Create(AParent: TSprite); begin inherited Create(AParent); SetMapSize(1, 1); // устанавливаем размеры 1 к 1 image := Form1.DXImageList1.Items.Find('Menu'); // изображением берем из DXImageList1 end;
Данный класс описывает фоновый спрайт. Можно было и не писать класс, но так лучше.
В private секцию формы добавляем следующие переменные { Private declarations } DXMenu: TMenuBackSprite; // фон меню DXButtonPlayer1, DXButtonPlayer2, DXButtonEditMode: TdxImageButton; // кнопки в меню MenuButtonList: TList; // коллекция, хрянящая кнопки для более быстрой обработки ButtonSelectIndex: Integer; // индекс выделенной кнопки GameState: TGameState; // состояние, в котором находится игра И при создании формы создаем кнопки procedure TForm1.FormCreate(Sender: TObject); begin Screen.Cursor := CrNone; // скрываем курсор fsurface := DXDraw1.Surface; // определяем поверхность для вывода кнопок (для модуля intf) DXMenu := TMenuBackSprite.Create(DXSpriteEngine1.Engine); // создаем фон меню // создаем кнопки и настраиваем их свойства DXButtonPlayer1 := TdxImageButton.Create; with DXButtonPlayer1 do begin X := 88; Y := 104; image := DXImageList1.Items.Find('MenuPlayer1'); width := image.width; height := image.height; Selected := True; end; DXButtonPlayer2 := TdxImageButton.Create; with DXButtonPlayer2 do begin X := 88; Y := 120; image := DXImageList1.Items.Find('MenuPlayer2'); width := image.width; height := image.height; Selected := False; end; DXButtonEditMode := TdxImageButton.Create; with DXButtonEditMode do begin X := 88; Y := 136; image := DXImageList1.Items.Find('MenuEditMode'); width := image.width; height := image.height; Selected := False; end; // создаем коллекцию и заносим в нее кнопки MenuButtonList := TList.Create; MenuButtonList.Add(DXButtonPlayer1); MenuButtonList.Add(DXButtonPlayer2); MenuButtonList.Add(DXButtonEditMode); ButtonSelectIndex := 0; // выделенная кнопка - 1 player GameState := stMenu; // игра в состоянии "Меню" end; А при уничтожении формы удаляем их procedure TForm1.FormDestroy(Sender: TObject); begin DXButtonPlayer1.Free; DXButtonPlayer2.Free; DXButtonEditMode.Free; MenuButtonList.Free; end;
Теперь перейдем к непосредственной отрисовке. Т.к. за это отвечает таймер, на событии OnTimer пишем
procedure TForm1.DXTimer1Timer(Sender: TObject; LagCount: Integer); begin if not DXDraw1.CanDraw then exit; fsurface := DXDraw1.Surface; // определяем поверхность для вывода кнопок (для модуля intf) // очищает экран, заливая черным цветом DXDraw1.Surface.Fill(0); if GameState = stMenu then begin // отрисовываем кнопки DXMenu.DoDraw; DXButtonPlayer1.DoDraw; DXButtonPlayer2.DoDraw; DXButtonEditMode.DoDraw; end; // выводит буфер на экран DXDraw1.Flip; end;
Запускаем и смотрим что у нас получилось.
И в завершение осталось сделать так, чтобы была возможность перемещаться по меню и нажимать кнопки. Для этого воспользуемя событие OnKeyDown формы:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin if Key = VK_DOWN then if GameState = stMenu then // если нажата клавиша вверх и мы находимся в меню begin // снимаем выделение с активной кнопки TdxImageButton(MenuButtonList[ButtonSelectIndex]).Selected := False; // и делаем выделенной следующую inc(ButtonSelectIndex); // если ниже кнопок нет, то возвращаемся к первой if ButtonSelectIndex > MenuButtonList.Count - 1 then ButtonSelectIndex := 0; TdxImageButton(MenuButtonList.Items[ButtonSelectIndex]).Selected := True; end; if Key = VK_UP then if GameState = stMenu then begin TdxImageButton(MenuButtonList[ButtonSelectIndex]).Selected := False; dec(ButtonSelectIndex); if ButtonSelectIndex < 0 then ButtonSelectIndex := MenuButtonList.Count - 1; TdxImageButton(MenuButtonList.Items[ButtonSelectIndex]).Selected := True; end; if Key = VK_RETURN then if GameState = stMenu then //
если мы нажимаем Enter в меню, то переходим в состояние, соответствующее кнопке
begin if DXButtonPlayer1.Selected then begin GameState := stGamePlayer1; ShowMessage('DXButtonPlayer1'); end; if DXButtonPlayer2.Selected then begin GameState := stGamePlayer2; ShowMessage('stGamePlayer2'); end; if DXButtonEditMode.Selected then begin GameState := stGameEditMode; ShowMessage('DXButtonEditMode'); end; end; end;
Похожие материалы
- Delphi исходники - Игра шашки 2
- Delphi исходники - карточный покер
- Delphi исходники игр - собери мусор
- Delphi исходник - игра теннис
- Delphi исходник - игра Магнит
Последние из рубрики
- Определении пинга (ping) в Delphi.
- Создание скриншотера на Delphi
- Создание игры на Delphi X (Часть 1)