В этом уроке я научу вас как можно передвигать обьекты по форме с помощью клавиш...
--------------------------
Начнём.
1)Создайте новый проект File> New> Application
2)Теперь киньте на форму объект TShape
3)После этого выбираем в Object TreeView форму (Form1)
4)В Object inspector на вкладке Events ищем свойство OnKeyDown и щёлкаем на него 2 раза.
5)В созданной процедуре пишем код (я рекомендую вам не просто копировать а понять как это работает!)
if key=VK_UP then Shape1.Top:=Shape1.Top-2;
Этот код будет двигат фигуру Shape1 на 2 пиксела вверх!
---------------------------
Попробуйте сами написать движение вниз, вправо, влево...
Позже и это будет показано!
Урок #2 Двигаем фигуру как хотим!!!
Добавьте в свою программу этот код и ваша фигура будет двигаться по всей форме!
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls;
type
TForm1 = class(TForm)
Shape1: TShape;
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if key=VK_UP then Shape1.Top:=Shape1.Top-2;
if key=VK_LEFT then Shape1.Left:=Shape1.Left-2;
if key=VK_DOWN then Shape1.Top:=Shape1.Top+2;
if key=VK_RIGHT then Shape1.Left:=Shape1.Left+2;
end;
end.
Урок №3
--------------------
Как вы уже поняли фигура может двигаться куда попало...даже за пределы формы... а это не очень то и хорошо =)...
Давайте вместе напишем код который будет ограничевать движение фигуры влево и вправо...
---------------------
Попробуйте написать вашу программу вот так:
Код:
unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls;type TForm1 = class(TForm) Shape1: TShape; procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); private { Private declarations } public { Public declarations } end;var Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);begin if( Key = VK_RIGHT ) and ( shape1.Left + shape1.Width <= Form1.ClientWidth-7 ) then shape1.Left := shape1.Left+7; if (key = VK_LEFT)and(shape1.Left>=3) then shape1.Left:=shape1.Left-7;end;end.
---------------------
и уже TShape не будет убегать за границы формы! Но будет двигаться только влево и вправо...попробуйте сделать самостоятельно так чтобы TShape не выходил за границы формы сверху и снизу + самостоятельно разберите код...возникнут вопросы задавайте их в этой теме...
---------------------
Сначала хотелось бы сказать спасибо модератору за эту тему т.к. лично мне она очень помогает. =)
Теперь, собственно, к вопросам.()
1.Я не понял смысла этого кода, можешь объяснить?. У меня по оси x объект стал двигаться быстрее, а когда начинал выходить за пределы формы двигался с обычной скоростью. Не надо ли вставить что-то подобное ,чтобы он не мог выйти за пределы формы:
Код:
if (Key=VK_RIGHT) and (Shape1.Left+Shape1.Width)>=Form1.ClientWidth then Shape1.Left:=Shape1.Left if (Key=VK_LEFT) and (Shape1.Left<0) then Shape1.Left:=Shape1.Left
Или же переписать основной код вот так:
Код:
if (key=VK_UP) and (Shape1.Top>=0) then Shape1.Top:=Shape1.Top-2; if (key=VK_LEFT) and (Shape1.Left>=0) then Shape1.Left:=Shape1.Left-2; if (key=VK_DOWN) and (shape1.Top + shape1.Height <= Form1.ClientHeight) then Shape1.Top:=Shape1.Top+2; if (key=VK_RIGHT) and (shape1.Left + shape1.Width <= Form1.ClientWidth) then Shape1.Left:=Shape1.Left+2;
У меня это работает.
2.Можно по-подробнее о событии OnKeyDown ? В частности что за параметры передаются переменными Key, Shift?
Key - код клавиши, UNICOD вроде передаётся.
Shift - передаётся состояние клавишь Shift, Alt, Ctrl (нажаты или нет)
Нажми f1 (справка в делфе) и введи OnKeyDown,TWinControl там полностью описание есть + есть ссылка Virtual Key codes - там тоже много полезного.
немного усложнив эту конструкцию становится интереснее
Код:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);begin case Key of VK_LEFT: begin Image1.Picture.Bitmap.LoadFromFile(left.bmp); if image1.Left > 0 then image1.Left:=Image1.Left-image1.Width; end; VK_RIGHT: begin Image1.Picture.Bitmap.LoadFromFile(right.bmp); if image1.Left+image1.Width < ClientWidth then image1.Left:=Image1.Left+image1.Width; end; VK_UP: begin Image1.Picture.Bitmap.LoadFromFile(top.bmp); if image1.Top > 0 then image1.Top:=Image1.top-image1.Height; end; VK_DOWN: begin Image1.Picture.Bitmap.LoadFromFile(bottom.bmp); if not (image1.Top+Image1.Height > ClientHeight) then image1.top:=Image1.Top+image1.Height; end; VK_SPACE: begin paintbox1.Canvas.Rectangle(image1.Left+2,image1.top+2, image1.Left+image1.Width-1,image1.Top+image1.Height-1); end; VK_ESCAPE: begin Sendmessage(handle,WM_CLOSE,0,0); end; end; caption:=X: +IntToStr(image1.Left div image1.Width)+ Y: + IntToStr(image1.top div image1.Height);end;procedure TForm1.Timer1Timer(Sender: TObject);vari: Integer;cols,rows: Byte;beginif sender is ttimer thenpaintbox1.Canvas.Create;paintbox1.Canvas.Brush.Color:=clLime;cols:=(panel1.Width div 50)+1;rows:=(panel1.Height div 50)+1;for i:=0 to cols dobeginPaintBox1.Canvas.MoveTo((i mod cols)*50,0);PaintBox1.Canvas.LineTo((i mod cols)*50,panel1.Height);end;for i:=0 to rows dobeginPaintBox1.Canvas.MoveTo(0,(i mod rows)*50);PaintBox1.Canvas.LineTo(panel1.Width,(i mod rows)*50);end; timer1.Enabled:=false;end;procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);begincase ord(key) of 49: paintbox1.Canvas.Brush.Color:=clRed; 50: paintbox1.Canvas.Brush.Color:=clBlack; 51: paintbox1.Canvas.Brush.Color:=clYellow; 52: paintbox1.Canvas.Brush.Color:=clLime; 53: paintbox1.Canvas.Brush.Color:=clWhite; end;end;
рисуем 4 имаги, пусть стрелочки, в разных направлениях, вверх, вниз, лево, право.. Х=50, Y=50
таймер для избежания падения фокуса на какой-нить из контролов, потом стрелочка ваша ездить не будет.
в конечном итоге ваша стрелочка будет бегать по клеточному полю и принажатии на пробел будет закрашивать клеточки цветом. ах да! на форму кинуть панель а на неё paintbox не забудте и image -- ваша стрелочка!
зы-Shift это прежде всего множество из (ssShift, ssAlt, ssCtrl,
ssLeft, ssRight, ssMiddle, ssDouble), обращаться надо к ним через квадратные скобочки -- if shift = [ssShift] then ... if shift = [ssShift,ssAlt] then...
пробуй
У меня назрел такой вопрос: при движении объекта с помощью клавиш появляется такой эффект, что, когда я зажимаю кнопку (например стрелочку), то объект сдвинется на n пикселов (где n это шаг, который задаётся заранее), затем остановится на, приблезительно, 0.5 с, а потом начинает нормально двигаться. Разумеется в игре такое движение неприемлемо, и хотелось бы знать как это устранить.
И второй вопрос заключается в том, что двигается объект слишком отрывисто (я предполагаю, что это из-за медленного действия компьютера, несмотря на то, что у меня очень мощная машина). Хотелось бы узнать, как сделать движение более плавным.
причина задержки скорее всего в настройках винды (есть иакой параметр - сколько времени держиться клавиша зажатой прежде чем применить к ней залипание) Выход я вижу в том что бы отключить опцию в настройках виндовс (скорее всего через реестр), а по выходу из игры снова включать. Или создать обработчик OnKeyDown, который приводит логическую переменную движения в соответствуующую сторону в True и OnKeyUp - все переменные движения в False, а движения обрабатывать в таймере.
А торможением возможно называешь мерцание объекта, если да попробуй использоватьпараметр
Form1.AlphaBlend:=True;
У меня назрел такой вопрос: при движении объекта с помощью клавиш появляется такой эффект, что, когда я зажимаю кнопку (например стрелочку), то объект сдвинется на n пикселов (где n это шаг, который задаётся заранее), затем остановится на, приблезительно, 0.5 с, а потом начинает нормально двигаться. Разумеется в игре такое движение неприемлемо, и хотелось бы знать как это устранить.
http://programmersforum.ru/showthread.php?t=982
Посмотри там последний пост, мож подойдет...
Сообщение от Speeker
А торможением возможно называешь мерцание объекта, если да попробуй использоватьпараметр
Form1.AlphaBlend:=True;
Я попробовал вставить это в процедуру, но единственым изменением стало то, что форма 1 раз моргнула черным цветом и всё. Всё остальное осталось без изменений.
Далее назрел вопрос. Как сделать, чтобы можно было вставить в программу какой-то код (не в процедуры, которые находятся в модуле). Например, я сделал пятнашки и нужно, чтобы условие победы отслеживалось не при каком-то событии, а постоянно.
Например, я сделал пятнашки и нужно, чтобы условие победы отслеживалось не при каком-то событии, а постоянно
Хм... Я что-то не понимаю: как может наступить победа, если ничего не произошло? Ну в крайнем случае через таймер можно.
У меня может быть огромное кол-во различных событий, которые приводят к победе, при этом в случае победы реализуется большой механизм. Это получается, что мне в каждую процедуру надо вствить один и тот же код? Даже если оформить это все в отдельную процедуру и вставлять только её название, но если событий более ста?
Значит перемудрил
2Yogurt:
Попробую, вам уважаемый помочь! Представив вам разсосанный сорец пятнашек! Назовём это урок №4 для начинающего!
Код:
{ Игра "15"}unit game15_;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs;type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); procedure FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormPaint(Sender: TObject); // эти объявления вставлены сюда вручную procedure ShowPole; procedure Mixer; private { Private declarations } public { Public declarations } end;var Form1: TForm1;implementation{$R *.dfm}const H = 4; W = 4; // размер поля - 4х4 CH = 64; CW = 64; // размер клеток - 16х16var // правильное расположение фишек stp : array[1..H, 1..W] of byte = (( 1, 2, 3, 4),( 5, 6, 7, 8),( 9,10,11,12),(13,14,15, 0)); // игровое поле pole: array[1..H, 1..W] of byte; ex,ey: integer; // координаты пустой клетки// новая играprocedure NewGame;var i,j: integer;begin // исходное (правильное) положение for i:=0 to H+1 do for j:=0 to W+1 do pole[i,j] := stp[i,j]; Form1.Mixer; // перемешать фишки Form1.ShowPole; // отобразить полеend;// проверяет, расположены ли// фишки в нужном порядкеfunction Finish: boolean;var row,col: integer; i: integer;begin row :=1; col :=1; Finish := True; // пусть фишки в нужном порядке for i:=1 to 15 do begin if pole[row,col] <> i then begin Finish:= False; break; end; // к следующей клетке if col < 4then inc(col) else begincol :=1;inc(row); end; end;end; // "перемещает" фишку в соседнюю пустую клетку,// если она есть, конечноprocedure Move(cx,cy: integer);// cx,cy - клетка, в которой игрок сделал щелчокvar r: integer; // выбор игрокаbegin // проверим, возможен ли обмен if not (( abs(cx-ex) = 1) and (cy-ey = 0) or ( abs(cy-ey) = 1) and (cx-ex = 0)) then exit; // Обмен. Переместим фишку из x,y в ex,ey Pole[ey,ex] := Pole[cy,cx]; Pole[cy,cx] := 0; ex:=cx; ey:=cy; // отрисовать поле Form1.ShowPole; if Finish then begin r := MessageDlg(Цель достигнута!+ #13+ Еще раз?,mtInformation,[mbYes,mbNo],0); if r = mrNo then Form1.Close; // завершить работу программы end;//end;end;// щелчок в клеткеprocedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);var cx,cy: integer; // координаты клеткиbegin // преобразуем координаты мыши в координаты клетки cx := Trunc(X / CW) + 1; cy := Trunc(Y / CH) + 1; Move(cx,cy);end;// выводит игровое полеprocedure TForm1.ShowPole;var i,j: integer; x,y: integer; // x,y - координаты вывода // текста в клеткеbegin // сетка: вертикальные линии for i:= 1 to W - 1 do begin Canvas.MoveTo(i*CW,0); Canvas.LineTo(i*CW,ClientHeight); end; // сетка: горизонтальные линии for i:= 1 to H - 1 do begin Canvas.MoveTo(0,i*CH); Canvas.LineTo(ClientWidth,i*CH); end; // содержимое клеток // x,y - координаты вывода текста for i:= 1 to H do begin y:=(i-1)*CH + 15; for j:=1 to W do begin x:= (j-1)*CW + 15; case Pole[i,j] of 0: Canvas.TextOut(x,y,); 1..9: Canvas.TextOut(x,y, +IntToStr(Pole[i,j])+ ); 10..15: Canvas.TextOut(x,y,IntToStr(Pole[i,j])); end; end; end;end;// "перемешивает" фишкиprocedure TForm1.Mixer;var x1,y1: integer; // пустая клетка x2,y2: integer; // эту переместить в пустую d: integer;// направление, относительно пустой i: integer;begin x1:=4; y1:=4; randomize; for i:= 1 to 150 do begin repeat x2:=x1; y2:=y1; d:=random(4)+1; case d of 1: dec(x2); 2: inc(x2); 3: dec(y2); 4: inc(y2); end; until (x2>=1) and (x2<=4) and (y2>=1) and (y2<=4); // здесь определили фишку, которую // надо переместить в пустую клетку Pole[y1,x1] := Pole[y2,x2]; Pole[y2,x2] := 0; x1:=x2; y1:=y2; end; // запомним координаты пустой клетки ex:= x1; ey:= y1;end;// обработка события OnCreateprocedure TForm1.FormCreate(Sender: TObject);begin ClientWidth := CW * W; ClientHeight := CH * H; Canvas.Font.Name := Times New Roman; Canvas.Font.Size := 22; NewGame;end;// обработка события OnPaintprocedure TForm1.FormPaint(Sender: TObject);begin Form1.ShowPole;end;end.
Урок № 5
Отдельный класс игрушек прадставлен, так называемыми игрушками на развитие памяти! Вот попробуем написать одну из таких! Что она будет делать!? А практически ни чего особенно сложно, просто запускаем прогу она на секунду показывает число, а потом число пропадает и появляется окно для ввода числа, там мы его по памяти вводим и если мы правильно ввели, то показывается следующее, а если неправильно, то следующее число будет показано после звукового сигнала об ошибке! Вот откоментированный исходник игры а ниже архив с исходником! Код:
unit memory_;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls;type TForm1 = class(TForm) Label1: TLabel; Button1: TButton; Edit1: TEdit; Timer1: TTimer; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure Edit1KeyPress(Sender: TObject; var Key: Char); private { Private declarations } public { Public declarations } end; var Form1: TForm1;implementationconst KC = 5; // разрядность числа (кол-во цифр) LT = 10; // количество чисел (длинна теста)var numb: integer; // число, которое должен запомнить испытуемый right: integer; // количество правильно запомненных чисел n: integer;// счетчик чисел{$R *.dfm}// генерирует k - разрядное числоfunction GetNumb(k: integer) : integer;var n: integer; // генерируемое число i: integer;begin // процедура генерирует число по разрядам // начиная со старшего n:= Random(9)+1; // старший разряд не может быть нулем // остальные разряды for i := 1 to (k-1) do n := n*10 + Random(10); GetNumb := n;end;// создание формыprocedure TForm1.FormCreate(Sender: TObject);begin Edit1.Visible := False; // скрыть поле ввода Edit1 Edit1.MaxLength := KC; // кол-во символов, которое можно ввести Label1.WordWrap := True; // разрешить перенос слов на следующую строку Label1.Caption := Сейчас на экране будут появляться числа. + Вы должны запомнить число, набрать его на клавиатуре и нажать <Enter>; Button1.Caption := Начать; Timer1.Enabled := False; // таймер остановлен Timer1.Interval := 1000; // время показа числа - 1 секунда right := 0; // кол-во правильных n := 0; // счетчик чисел Randomize;// инициализация ГСЧend;// щелчок на кнопке "Начать/Завершить"procedure TForm1.Button1Click(Sender: TObject);begin if Button1.Caption = Завершить thenForm1.Close; // закрыть окно программы if Button1.Caption = Начать then begin Button1.Caption := Завершить; Button1.Visible := False; // скрыть кнопку // кнопка Button1 станет доступной после того // как испытание закончится Label1.Caption := ; Label1.Font.Size := 24; // размер шрифта поля Label1 Edit1.Font.Size := 24; // размер шрифта поля Edit1 // сгенерировать и вывести число numb := GetNumb(KC); Label1.Caption := IntToStr(numb); Timer1.Enabled := True; // запуск таймера // процедура обработки сигнала от таймера // "сотрет" число end;end;// обработка события таймераprocedure TForm1.Timer1Timer(Sender: TObject);begin Timer1.Enabled := False; // остановить таймер Label1.Visible := False; // скрыть число Edit1.Visible := True; // сделать доступным поле Edit1 Edit1.SetFocus;// установить курсор в поле Edit1end;// нажатие клавиш в поле Edit1procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);var igrok: integer; // число, которое ввел испытуемыйbegin case Key of 0..9,#8: ; // клавиши "0"-"9",<Backspace> #13: // клавиша <Enter> begin igrok := StrToInt(Edit1.Text); if (igrok = numb) then right := right + 1; n := n + 1; // счетчик чисел Edit1.Text := ; Edit1.Visible := False; // скрыть поле Edit1 if n < LT then beginnumb := GetNumb(KC); // сгенерировать следующее числоLabel1.Caption := IntToStr(numb); // отобразить числоLabel1.Visible := True;Timer1.Enabled := True; // пуск таймера end else begin// испытание закончено// вывести результатLabel1.Font.Size := 10;Label1.Caption := Результат: + #13 + Показано чисел: + IntToStr(LT) + #13 + Правильных: + IntToStr(right);Label1.Visible := True;Button1.Visible := True; // показывается кнопка "Завершить" end; end; else Key := Chr(0); end;end;end.
Урок №6!
Теперь попробуем написать игрушку развивающую реакцию! Суть её заключается в следующем, на экране появляются смайлики и на м нужно успавать по ним кликать курсором! В конце выдаётся результат о попаданиях и промахах!
Вот откоментированный исходник игры "Тир":
Код:
unit tir_;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls;type TForm1 = class(TForm) Timer: TTimer; Label1: TLabel; Button1: TButton; procedure TimerTimer(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } { ***************************** объявление процедур помещено сюда, чтобы процедуры имели прямой доступ к форме, на которой они рисуют ****************************** } procedure PaintFace(x,y: integer); // рисует рожицу procedure EraseFace(x,y: integer); // стирает рожицу end;var Form1: TForm1; fx,fy: integer; // координаты рожицы n: integer; // количество щелчков кнопкой мыши p: integer; // количество попаданийimplementation// рисует рожицуprocedure TForm1.PaintFace(x,y: integer);begin Canvas.Pen.Color := clBlack;// цвет линий Canvas.Brush.Color := clYellow; // цвет закраски // рисуем рожицу Canvas.Ellipse(x,y,x+30,Y+30); // лицо Canvas.Ellipse(x+9,y+10,x+11,y+13); // левый глаз Canvas.Ellipse(x+19,y+10,x+21,y+13); // правый глаз Canvas.Arc(x+4,y+4,x+26,y+26,x,y+20,x+30,y+20); // улыбкаend;// стирает рожицуprocedure TForm1.EraseFace(x,y: integer);begin // зададим цвет границы и цвет закраски, // совпадающий с цветом формы. По умолчанию // цвет формы - clBtnFace (см. в Object Inspector) Canvas.Pen.Color := clBtnFace; // цвет окружности Canvas.Brush.Color := clBtnFace; // цвет закраски Canvas.Ellipse(x,y,x+30,y+30);end; {$R *.dfm}procedure TForm1.TimerTimer(Sender: TObject);begin EraseFace(fx,fy); // новое положение рожицы fx:= Random(ClientWidth-30); // 30 - это диаметр рожицы fy:= Random(ClientHeight-30); PaintFace(fx,fy);end;procedure TForm1.FormCreate(Sender: TObject);begin // исходное положение рожицы fx:=100; fy:=100; Randomize; // инициализация генератора // случайных чиселend;// нажатие клавиши мышиprocedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);begin inc(n); // кол-во щелчков if (x > fx) and (x < fx+30) and(y > fy) and (y < fy+30) then begin // щелчок по рожице inc(p); end; if n = 10 then begin // игра закончена Timer.Enabled := False; // остановить таймер ShowMessage(Выстрелов: 10. Попаданий: + IntToStr(p)+.); EraseFace(fx,fy); Label1.Visible := True; Button1.Visible := True; // теперь кнопка и сообщение снова видны end;end;// щелчок на кнопке Okprocedure TForm1.Button1Click(Sender: TObject);begin Label1.Visible := False; // скрыть сообщение Button1.Visible := False; // скрыть кнопку Timer.Enabled := True; // пуск таймераend;end.
А это полностью исходник игры!
Урок №7
Практчески любой и каждый уважающий себя человек в своей жизни хотя бы раз играл в эту занимательную стратегическую игрушку - Морской бой! Исходник не такой простой, как в предыдущих примерах, но и не сложный, разобраться при желании можно! При желании вы можете дороботать игру добавив новые стили игры (их существует огромное множество)! Можно доработать стратегию компа! А можно просто оптимизировать (а скорей адаптировать) интерфейс под себя!
Игра в принципе работает, но компьютер довольно просто рвёт!...
Урок №8
Немного теории по особенностям создания игр разных жанров!
Anim_Games.rar - Анимация в компьютерных играх;
Arcade_Games.rar - Аркадные игры;
Prikluch_Games.rar - Приключеньческие игры.
Урок №9
А вот исходник более серьёзной и весьма увлекательной игрухи! Игра называется "Линии"! Цель игры методом передвиженя кружков необходимо поставить в ряд 4 и более кружка одного цвета, при этом они исчезают! При каждом ходе появляется несколько новых кружков. Игра заканчивается когда заканчивается место на игровом поле! Что бы передвинуть кружок, надо по нему щёлкнуть, а потом щёлкнуть по месту назначения, но при том условии что кружок сможет доехать до места назначения не перепрыгивая (хотя можно обходить) через другие кружки! В общем кому интересно разберитесь с исходником, он там не сложный, а кому не очень это интересно, советую поиграть!!!
Урок №10
Вот пример того как можно работать с возможностями 3D в Delphi!
Простенький мануальнчик с примером исходника!
Сообщение от execom
Урок №10
Вот пример того как можно работать с возможностями 3D в Delphi!
Простенький мануальнчик с примером исходника!
Заинтересовало, а готовых исходников нет?
Урок №11
Вот исходник программы работы с 3D объектом, его можно вращать, и изменять его размер!
Урок №12
Что такое OpenGL?
В этом уроке мы поговорим о том, что вообще такое OpenGL, для чего это нужно. Для начала, вы должны неплохо знать ОС Windows, а также язык Си++ (в данном случае, Visual C++, так как мы будем работать именно в этой среде разработки).
Итак, OpenGL (Открытая Графическая Библиотека) - это программный интерфейс (API) для разработки приложений с использованием 2D и 3D графики.
OpenGL стоит как бы между аппаратным обеспечением, и пользовательским уровнем.
Основные особенности этой библиотеки являються:
Стабильность:
Это означает, что дополнение в OpenGL реализуется так, что бы сохранить совместимость с более старым программным обеспечением.
Переносимость (независимость):
Код программы, которую вы написали, скажем, под Windows, можно легко перенести на Linux и другие ОС. То есть, OpenGL не зависит от какой ни будь операционной системы, как, например DirectX.
Простота в использовании:
Приложения, написанные с помощью OpenGL, имеют сравнительно небольшой объем кода. Также эта библиотека имеет понятный интерфейс. И разобраться в коде программы очень просто.
Ну и наконец OpenGL это отраслевой стандарт, т.е. вы можете взять исходники и сделать на их юызе что-нибудь своё.
Основные возможности OpenGL:
· Набор базовых примитивов: точки, линии, многоугольники и т.п.
· Видовые и координатные преобразования
· Удаление невидимых линий и поверхностей (z-буфер)
· Использование сплайнов для построения линий и поверхностей
· Наложение текстуры и применение освещения
· Добавление специальных эффектов: тумана, изменение прозрачности, смешивание цветов (blending), устранение ступенчатости (anti-aliasing). Я думаю, что всех этих достоинств достаточно для того, чтобы выбрать OpenGL для создания 3D графики (игр, в частности).
Урок №13
Основные термины и понятия компьютерной графики.
Рендеринг- это процесс подготовки, выдачи (прорисовки) изображения на экран. В общем, это все действия, которые связаны с выдачей картинки на экран.
Буфер- это область для временного хранения данных.
Двойная буферизация- это один из способов рендеринга, при котором существует два буфера. Содержимое первого (переднего) буфера (front buffer) показываеться на экран и вы видите какое то изображение. В это время на заднем буфере (back buffer) подготавливается следующий кадр (рисуется). Когда кадр на заднем буфере готов, тогда передний и задний буфер меняются местами. И затем все это повторяется. С помощью такой технологии избегается мерцание экрана.
Пиксель- это наименьшая точка, которую можно различить на экране. Он является единицей двухмерного изображения.
Камера- это не то, что вы подумали… Камера- это место, из которого вы смотрите на экран.
Трансформация- нахождение координат точки в заданной системе координат, используя координаты точки в другой системе (это переносы, или вращения). При трансформации положение точки не меняется.
Мировая система координат- это система координат, которая считается неподвижной. Обычно относительно этой системы координат задаются положение камеры, и объектов.
Примитив- это основная единица, из которой строятся сложные объекты. Примитивом может быть: точка, линия, треугольник, или что ни будь подобное…
Z-buffer- также часто вместо этого слова употребляется слово Буфер Глубины (Depth Buffer). Это буфер величиной с экран, в котором хранятся Z координаты пикселей. Z-ось добавляет третью величину- глубину.
Матрица- в компьютерной графике, это массив чисел (обычно 4х4), который содержит значения векторов систем координат.
Проекция- это перевод координат из пространства (камеры) на экран, или с 3х мерных координат в 2х мерные.
Урок 15
Интересный пример по проецированию курсора мыши на 3-х мерную поверхность! Данный пример будет интересен как новичкам, так и профессионалам.
Урок №16
Данный исходник программы для игры в Русские шашки! Причем соперник имеет достаточно высокий интелект!
Я пытаюсь сделать арканоид, уже прописал физику мяча, но не могу теперь описать движение платформы.
записал всё как в вашем первом уроке в том же юните, и ничего не происходит.
З.Ы: в чистом юните всё работает.
Памагити!!!
unit Horray;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, Buttons, XPStyleActnCtrls, ActnList, ActnMan;
type
TForm1 = class(TForm)
Shape1: TShape;
Shape2: TShape;
ZGMI: TButton;
procedure ZGMIClick(Sender: TObject);
private
public
procedure HandleMessages(var Msg: tMsg; var Handled: Boolean);
procedure FormCreate(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.ZGMIClick(Sender: TObject);
begin
while (Shape1.Left + Shape1.Width < Form1.Width) and (shape1.Top > 5) do
begin
shape1.Top := shape1.top -5;
Shape1.Left:= Shape1.Left + 5;
Sleep(10);
Form1.Refresh;
end;
if Shape1.Left + Shape1.Width < Form1.Width then
while Shape1.Left + Shape1.Width < Form1.Width do
begin
shape1.Top := shape1.top +5;
Shape1.Left:= Shape1.Left + 5;
Sleep(10);
Form1.Refresh;
end
else
while shape1.Top > 5 do
begin
shape1.Top := shape1.top -5;
Shape1.Left:= Shape1.Left -5;
Sleep(10);
Form1.Refresh;
end;
if Shape1.Left + Shape1.Width = Form1.Width then
while shape1.top< form1.height - shape1.height do
begin
shape1.Top := shape1.top +5;
Shape1.Left:= Shape1.Left -5;
Sleep(10);
Form1.Refresh;
end
else
while (shape1.top< form1.height - shape1.height) and (Shape1.Left > 0) do
begin
shape1.Top := shape1.top +5;
Shape1.Left:= Shape1.Left -5;
Sleep(10);
Form1.Refresh;
end;
while shape1.top< form1.height - shape1.height do
begin
shape1.Top := shape1.top +5;
Shape1.Left:= Shape1.Left +5;
Sleep(10);
Form1.Refresh;
end;
end;
procedure tForm1.HandleMessages(var Msg: tMsg; var Handled: Boolean);
begin
if (Msg.Message = WM_KeyDown) and
(Msg.wParam in [VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT]) then
begin
case Msg.wParam of
VK_UP: ShowMessage;
VK_DOWN: ShowMessage;
VK_LEFT: ShowMessage;
VK_RIGHT: ShowMessage;
end;
Handled := True;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnMessage := HandleMessages;
end;
end.
Остальное сам допишешь
ПАСИИИИБ!!!!!!!!!!!!!
ну а с моей то что?
люди, да что с вами, при всём желании у вас не получится создать более или менее нормальную игру используя VCL, идеальный вариат - это DirectDraw, но для некоторых он может показаться сложным, для 2D игр есть альтернатива, для начала учите WinApi, затем создаете форму сами(то есть пишете всё ручками) при этом у вас не будет ненужных бордеров и в полноэкранном режипе панель задач не будет вам мешать, затем создаёте переменные в которые вы будете грузить картинки, и пользуемся функцией BitBlt() для копирования фрагментов изображений, при этом у вас не будет ни остановок ни мерцания (если вы создаёте "оконную" игру форму сами можете не писать, но вот размер вашего приложения будет о-го-го какой)
Horny, я с вами полностью согласен насчет создания игр с помощью средств DX, но для начинающих игроделов очень тяжело сразу взять и начать писать своё детище на DX, я веду к тому, что следует начинать с простого и постепенно двигаться к большему.
Тоже согласен с комрадом Kostia, ...начинается все с элементарного Image, затем переход на Canvas (буферизация, вставка Bitmap), затем Win API (GDI), а уже к концу DirectX, вершина - ассемблер. Почему так? , ...потому, что нужно пройти весь путь, только тогда можно понять принципы и выбрать методы для решения конкретной задачи. Иногда можно обойтись и приметивными методами, если они удовлетворяют условию.
А где же OpenGL? Ей нет места в вашей иерархии?
Да, и мне кажется не стоит путать понятия создание игр и создание графических библиотек.
Какое имеет отношение ассемблер к созданию игр???
Сообщение от mutabor
А где же OpenGL? Ей нет места в вашей иерархии?
Иерархии небыло, просто пример продвижения. Эт как захочется, но основные части показаны ИМХО.
Сообщение от mutabor
Какое имеет отношение ассемблер к созданию игр???
Самое прямое, там где нужна скорость, там и ассемблер, отрицать глупо
Подскажите плз как сделать так, чтобы при нажатии на форму персонаж шел туда куда было нажато))???
Есть событие OnMouseUp в нем переменные х и у в которые передаются координаты мыши. Соответственно туда и перемещаеш своего персонажа...
Спс нада будет попробывать
Подскажите как обрабатывать сразу несколько клавишь, вот например в аркаде, надо одновременно жать W и D (вперёд и вправо). Как это реализовать?
Сообщение от Speeker
Есть событие OnMouseUp в нем переменные х и у в которые передаются координаты мыши. Соответственно туда и перемещаеш своего персонажа...
Спс помогло! Но у меня еще вопрос) Как сделать что бы обьект плавно шел к точке в которую нажал?? просто может я неправильно написал:
if button = mbleft
then
shape1.Left:=x;
shape1.Top:=y;
или нужно воспользоваться таймером?
если да то как?
Сообщение от Simply-Art
Подскажите как обрабатывать сразу несколько клавишь, вот например в аркаде, надо одновременно жать W и D (вперёд и вправо). Как это реализовать?
Код:
var Key: tkeyboardstate; i: integer;begin form1.Caption:=; windows.GetKeyboardState(key); for i:=0 to 255 do if (key[i]=128)or(key[i]=129)then form1.Caption:=form1.Caption+ +inttostr(i);end;
Попробуй в таймере.
Pfent, вот примерчик. Все грубо, установи смещение на картинку и будет идти туда куда ткнул мышью.
Огромное спасибо за пример
Пользоваться таймером. там прописать что то типа если координата х больше левфт то лефт=лефт+1.... то же самое с у, кроме того может быть такое что добавлять надо не единицу... можно попробовать реализовать это через уравнение прямой...
Вот вам в качестве урока по созданию логических игр (это не РПГ =).
Исходник игры кликомания (коллапс) на Дельфи.
http://www.programmersforum.ru/attac...4&d=1196863119