Форум программистов
 
Контакты: о проблемах с регистрацией, почтой и по другим вопросам пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail.

Вернуться   Форум программистов > разработка игр, графический дизайн и моделирование > Gamedev - cоздание игр: Unity, OpenGL, DirectX
Регистрация

Восстановить пароль
Повторная активизация e-mail

Ответ
 
Опции темы
Старый 30.11.2009, 16:54   #1
-COREY-
Форумчанин
 
Аватар для -COREY-
 
Регистрация: 19.04.2009
Сообщений: 50
Репутация: 10
Стрелка Пишу шахматы на делфи

Уважаемые форумчане,помогите разобраться.Я пишу шахматы на делфи.Как сделать так,чтобы перемещалась только выбранная фигура,а не всё сразу?Фигура выбирается процедурой TForm1.PaintBox1MouseDown(на ПейнтБокс выводится доска)Вот кусок кода таймера
Код:

procedure TForm1.Timer1Timer(Sender: TObject);
begin
Inc(c);
KingMove;
QueenMove;
....................
end;

процедура перемещения
Код:

procedure TForm1.KingMove;
begin
kx:=kx+stepX;
ky:=ky+stepY;
Buffer.Canvas.Draw(0,0,Fon);
DrawBoard;
if c >= 25 then
  begin
  Timer1.Enabled:=False;
  kx:=Cell2X(DestCell) * CELL_SIZE;
  ky:=Cell2Y(DestCell) * CELL_SIZE;
  KnightCell:=DestCell;
  StartCell:=-1;
  DestCell:=-1;
  Buffer.Canvas.Draw(0,0,Fon);
  DrawBoard;
    end;
end;

и TForm1.FormCreate
Код:

.....
Timer1.Interval:=20;
Timer1.Enabled:=False;
.....

Подкиньте пару идей,чтоб как надо работало
(всё это пишется по образцу хода конём,приведённого выше вэтой теме)

Последний раз редактировалось -COREY-; 30.11.2009 в 16:58.
-COREY- вне форума   Ответить с цитированием
Старый 30.11.2009, 17:01   #2
Гром
Профессионал
 
Аватар для Гром
 
Регистрация: 21.03.2009
Сообщений: 2,193
Репутация: 473

icq: 482-373-277
По умолчанию

Все сразу - это как?
Надо полагать, у вас должен быть тип фигур и каждая фигура является объектом этого типа. В типе есть функция перемещения фигуры, и скорее всего - функция проверки допустимости хода. Вот эти функции вы и используете для каждой фигуры по отдельности...
Какая у вас вообще структура программы?
__________________
Простые и красивые программы - коды программ + учебник C++
Создание игры - взгляд изнутри - сайт проекта
Тема на форуме, посвященная ему же
Гром вне форума   Ответить с цитированием
Старый 30.11.2009, 17:04   #3
-COREY-
Форумчанин
 
Аватар для -COREY-
 
Регистрация: 19.04.2009
Сообщений: 50
Репутация: 10
Стрелка Пишу шахматы на делфи

Гром,а если переделать как Вы сказали.Приписать процедуры движения и проверки возможности хода к классу фигур,то как сделать,чтобы фигуры перемещались по форме?

Последний раз редактировалось -COREY-; 30.11.2009 в 17:14.
-COREY- вне форума   Ответить с цитированием
Старый 30.11.2009, 19:58   #4
Вадим Буренков
Профессионал
 
Аватар для Вадим Буренков
 
Регистрация: 06.03.2009
Сообщений: 1,346
Репутация: 383
По умолчанию

Цитата:
как сделать,чтобы фигуры перемещались по форме?
Спрайт фигуры рисуется в неуих координатах X и Y. В таймере увеличиваем/уменьшаем эти значения пока они не станут нужными. Посмотри уроки
http://www.programmersforum.ru/showthread.php?t=1206 , там в первых постах об этом написано. В шахматах лучше использовать класс для фигуры.
Вадим Буренков вне форума   Ответить с цитированием
Старый 13.12.2009, 10:52   #5
-COREY-
Форумчанин
 
Аватар для -COREY-
 
Регистрация: 19.04.2009
Сообщений: 50
Репутация: 10
По умолчанию

Всё,данная проблема решена,но возникла другая...Такая как поочерёдность хода.Вообщем дело обстоит так
Имеется процедура
Код:

procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
WhiteToMove:=true;
if start_cell >= 0 then
  begin
  if finish_cell < 0 then
    begin
    if move_check(start_cell,m_cell.num,WP1.is_moved) then
      begin
      finish_cell:=NumForCell(m_cell.x,m_cell.y);
      Timer1.Enabled:=True;
      c:=0;
      end
    else
      begin
      caption:=mess;
      start_cell:=-1;
      finish_cell:=-1;
      end;
    Buffer.Canvas.Draw(0,0,desk);
    end;
  end
else
  if NumForCell(m_cell.x,m_cell.y) = GetCell(m_cell.num) then Start_Cell:=NumForCell(m_cell.x,m_cell.y);
DrawBoard;
WhiteToMove:=false;
begin
if WhiteToMove=false then begin
ThinkAboutMove;
finish_cell:=NumForCell(b_move.x,b_move.y);
Timer1.Enabled:=True;
c:=0;
end;
Buffer.Canvas.Draw(0,0,desk);
DrawBoard;
end;
end;

move_check - делает проверку хода для белых фигур и если всё правильно включает таймер для их перемещения.
Функция ThinkAboutMove генерирует ходы для черных и тоже включает таймер для хода чёрных.Проблема в том что когда я нажимаю на клетку чтобы выбрать белую фигуру,то начинают ходить чёрные.Как это исправить?Подскажите пожалуйста
-COREY- вне форума   Ответить с цитированием
Старый 13.12.2009, 13:17   #6
Вадим Буренков
Профессионал
 
Аватар для Вадим Буренков
 
Регистрация: 06.03.2009
Сообщений: 1,346
Репутация: 383
По умолчанию

Изначально не правильная структура кода. Для любой игры можно использовать всего 1 таймер. Я шахматы не писал, но можно например сделать тип (или класс) для фигуры:

Для начала опишем варианты фигур:
TChessTypes=(пешка, ферзь,король и.т.д.)

Код:

TChess=record
//(TPoint - тип windows состоит из X и Y переменных)
Position:TPoint; //текущая позиция фигуры, по которой она рисуется
MoveTo:TPoint; //позиция, в которую двигается фигура

ChessType: TChessTypes; //тип фигуры. в зависимости от него пешка будет ходить определенным образом
                                    //и рисоваться соответствующая текстура.
DEAD:boolean;//если пешка мертва, то мы "выкидываем" ее из обработки
end;

Тепель класс игрока. Класс облегчит задачу. Мы можем сделать чтоб им управлял как AI, так и игрок.

Код:

Type
TPlayer=record;
//сами фигуры игрока:
Chess: array [0..количество фигур] of TChess;
//и другие параметры. 
active:boolean; //указывает какой игрок ходит сейчас (вообще лучше сделать указатель на TPlayer ходящего игрока через глобальную переменную)
ChessCount:integer; //кол-во оставшихся фигур
{также могут быть другие переменные, например кол-во ходов сделанных игроком}
end;

Каждый тип имеет стандартный набор процедур: создание, обработка и удаление. Есть один глобальный таймер, в нем например обрабатываются игроки:

Код:

Timer1.Timer;
begin
//обновляется тот игрок, который ходит
if player1.active then PlayerUpdate(Player1);
if player2.active then PlayerUpdate(Player2);
end;

Сама процедура обработки игрока обрабатывает фигуры этого игрока, следит за счетом своих оставшихся фигур. Также в ней реализуется AI или управление фигурами, в случае если играет человек.

Код:

PlayerUpdate(Player:TPlayer);
var i:integer;
begin
//обновляем все фигуры
for i:=0 to количество фигур do if Chess[i].dead=false {проверка не съедена ли фигура} then ChessUpdate(Chess[i]);
if ChessCount=0 then ты проиграл;

//тут AI или управление.
end;

Процедура обработки фигуры рисует данную фигуру в точке Position и двигает данную фигуру, в точку MoveTo.
Код:

ChessUpdate(chess:TChess);
begin
//обновляем позицию фигуры
if chess.Position <> chess.moveto then {прибавляем/уменьшаем координату на небольшое значение пока они не приравняются.}
//Так мы получим плавное движение всего с 1 таймером. Изменив переменную MoveTo мы автоматически заставим двигатся фигуру в эту точку.

//рисуем фигуру в зависимости от типа:
if Chess.Type=пешка then Canvas.draw(пешка,Position.x,Position.y);
if Chess.Type=король then Canvas.draw(король,Position.x,Position.y);
end;

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

Последний раз редактировалось Beermonza; 14.12.2009 в 17:38.
Вадим Буренков вне форума   Ответить с цитированием
Старый 13.12.2009, 17:00   #7
-COREY-
Форумчанин
 
Аватар для -COREY-
 
Регистрация: 19.04.2009
Сообщений: 50
Репутация: 10
По умолчанию

Фигуры у меня так и обозначены,а вот игроков через классы сделать не додумался и про таймер тоже.Спасибо за помощь)))и ещё вопрос как это всё с формой совместить?Ну для инициализации TFormCreate.Таймер тоже понятно.Когда управляет человек передам через MouseDown.А сам процесс игры, в смысле, ход человека потом ход компа и т.д.Вот это в какую процедуру формы вписать?

Последний раз редактировалось -COREY-; 13.12.2009 в 17:19.
-COREY- вне форума   Ответить с цитированием
Старый 13.12.2009, 18:57   #8
Вадим Буренков
Профессионал
 
Аватар для Вадим Буренков
 
Регистрация: 06.03.2009
Сообщений: 1,346
Репутация: 383
По умолчанию

Ход игрока происходит в PlayerUpdate, как только фигура походила то происходит нечто подобное:
Код:

Player1.active:=false;
Player2.active:=true;

и начинается обновление (ход) 2 игрока. А как конкретно делать я тебе сказать не могу, ты ведь игру пишешь. Я не знаю всех тонкостей твоего кода.
Вадим Буренков вне форума   Ответить с цитированием
Старый 13.12.2009, 19:27   #9
-COREY-
Форумчанин
 
Аватар для -COREY-
 
Регистрация: 19.04.2009
Сообщений: 50
Репутация: 10
По умолчанию

ну да вот это вот как раз я понял.А если я процесс игры сам напишу в TFormActivate у меня координаты выбранной клетки для хода передутся из MouseDown в FormActivate?Если нет,то как это сделать?
-COREY- вне форума   Ответить с цитированием
Старый 13.12.2009, 19:53   #10
Вадим Буренков
Профессионал
 
Аватар для Вадим Буренков
 
Регистрация: 06.03.2009
Сообщений: 1,346
Репутация: 383
По умолчанию

Вообще я стараюсь избегать большого кол-ва event'ов формы. Во всех моих приложениях есть OnFormCreate - инициализация проги, загрузка ресурсов, один таймер с обработкой всей игры и OnFormDestroy для деинициализации ресурсов. Как же тогда получать нажатия клавиш и координаты мыши без всяких onmousemove и onmousedown?
Нажатия клавиш можно получить так:
Код:

function FKeyPressed(key: byte): boolean;
var
  keys: TKeyboardState;
begin
  result:=false;
  GetKeyboardState(keys);
  if(keys[key]=128)or(keys[key]=129)then result:=true;
end;

Вот константы основных клавиш:
Код:


  FK_BACKSPACE  = 8;
  FK_TAB        = 9;
  FK_ENTER      = 13;
  FK_SHIFT      = 16;
  FK_CTRL       = 17;
  FK_ALT        = 18;
  FK_ESCAPE     = 27;
  FK_SPACE      = 32;

  FK_PAGEUP     = 33;
  FK_PAGEDOWN   = 34;
  FK_END        = 35;
  FK_HOME       = 36;
  FK_SNAPSHOT   = 44;
  FK_INSERT     = 45;
  FK_DELETE     = 46;

  FK_LEFT       = 37;
  FK_UP         = 38;
  FK_RIGHT      = 39;
  FK_DOWN       = 40;

  FK_0          = 48;
  FK_1          = 49;
  FK_2          = 50;
  FK_3          = 51;
  FK_4          = 52;
  FK_5          = 53;
  FK_6          = 54;
  FK_7          = 55;
  fK_8          = 56;
  FK_9          = 57;

  FK_NUMPAD0    = 96;
  FK_NUMPAD1    = 97;
  FK_NUMPAD2    = 98;
  FK_NUMPAD3    = 99;
  FK_NUMPAD4    = 100;
  FK_NUMPAD5    = 101;
  FK_NUMPAD6    = 102;
  FK_NUMPAD7    = 103;
  FK_NUMPAD8    = 104;
  FK_NUMPAD9    = 105;

  FK_MULTIPLY   = 106;
  FK_ADD        = 107;
  FK_SEPARATOR  = 108;
  FK_SUBTRACT   = 109;
  FK_DECIMAL    = 110;
  FK_DIVIDE     = 111;

  FK_A          = 65;
  FK_B          = 66;
  FK_C          = 67;
  FK_D          = 68;
  FK_E          = 69;
  FK_F          = 70;
  FK_G          = 71;
  FK_H          = 72;
  FK_I          = 73;
  FK_J          = 74;
  FK_K          = 75;
  FK_L          = 76;
  FK_M          = 77;
  FK_N          = 78;
  FK_O          = 79;
  FK_P          = 80;
  FK_Q          = 81;
  FK_R          = 82;
  FK_S          = 83;
  FK_T          = 84;
  FK_U          = 85;
  FK_V          = 86;
  FK_W          = 87;
  FK_X          = 88;
  FK_Y          = 89;
  FK_Z          = 90;

  FK_F1         = 112;
  FK_F2         = 113;
  FK_F3         = 114;
  FK_F4         = 115;
  FK_F5         = 116;
  FK_F6         = 117;
  FK_F7         = 118;
  FK_F8         = 119;
  FK_F9         = 120;
  FK_F10        = 121;
  FK_F11        = 122;
  FK_F12        = 123;

Нажатия мыши проверяются этой же функцией. константы для них такие:
Код:

 
 FMB_LEFT          = 1;
 FMB_RIGHT         = 2;

Получить координаты можно так:
Код:

Var
MousePos:TPoint;
begin
//получение мыши
GetCursorPos(MousePos);
//рассчет координат относительно окна или панели по Handle
ScreenToClient(MainForm.RenderPanel.handle, MousePos);
//MousePos - итоговые координаты.


Последний раз редактировалось Вадим Буренков; 13.12.2009 в 20:33.
Вадим Буренков вне форума   Ответить с цитированием
Ответ

Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
задача шахматы darter96 Помощь студентам 7 25.06.2009 13:43
Delphi шахматы kacky Помощь студентам 3 30.10.2008 21:09
Шахматы Shchetnev Фриланс 10 27.05.2008 00:36
Делаю сайты, пишу маленькие/большие скрипты. Пишу веб-приложения и приложения под Windows. SkyM@n Фриланс 3 29.12.2007 17:21
сама пишу на делфи...а надо... Алёна Фриланс 5 11.12.2007 22:43


12:26.


Powered by vBulletin® Version 3.8.8 Beta 2
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.

RusProfile.ru


Справочник российских юридических лиц и организаций.
Проекты отопления, пеллетные котлы, бойлеры, радиаторы
интернет магазин respective.ru