Модераторы: Snowy, MetalFan, bems, Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Подскажите с управлением в "Змейке". 
V
    Опции темы
spamER
  Дата 17.12.2008, 21:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 14.11.2008

Репутация: нет
Всего: 1



Народ, пожалуйста помогите.
Пытаюсь написать игру "Змейка". В качестве тела змеии использую массив из компонентов TShape (создаю их в отдельной процедуре - конструктором).

Сама змейка движется, только вот когда управляешь ей, она НЕ правильно движется. Например при движении вверх все Shape'ы начинают вдигатся как в тетрисе. А нада как в обычной змейке. что бы она умела поворачивать. 

Проблема : как сделать управление змейкой (Вверх, Вниз, Вправо, Влево) что бы она правильно поворачивала???


То что я написал: 

Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, Menus;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    MainMenu1: TMainMenu;
    Main: TMenuItem;
    NewGames: TMenuItem;
    N1: TMenuItem;
    Exit: TMenuItem;
    Cpravka: TMenuItem;
    About_program: TMenuItem;
    Image1: TImage;
    procedure Timer1Timer(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure Vpravo();
    procedure VLevo();
    procedure VVerx();
    procedure Vniz();
    procedure CreateUdav();
  end;
const
  shag = 10;

var
  Form1: TForm1;
  napravlenie: string[1];
  mas:array[0..999] of TShape;
  i:integer;
implementation

uses MaskUtils, Math;

{$R *.dfm}

procedure TForm1.CreateUdav();
begin
for i:=0 to 2 do
begin
  mas[i]:=TShape.Create(self);
  mas[i].Left:=150;
  mas[i].Width:=10;
  mas[i].Height:=10;
  mas[i].Left:=mas[i].Left+i*10;
  mas[i].Top:=150;
  mas[i].Parent:=Form1;
end;
end;

procedure TForm1.Vpravo();
begin
for i:=0 to 2 do
  mas[i].Left:=mas[i].Left+shag;
end;

procedure TForm1.VLevo();
begin
for i:=0 to 2 do
  mas[i].Left:=mas[i].Left-shag;
end;

procedure TForm1.VVerx();
begin
for i:=0 to 2 do
  mas[i].Top:=mas[i].Top-shag;
end;

procedure TForm1.Vniz();
begin
for i:=0 to 2 do
  mas[i].Top:=mas[i].Top+shag;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if napravlenie = 'R' then Vpravo;
  if napravlenie = 'L' then VLevo;
  if napravlenie = 'D' then Vniz;
  if napravlenie = 'U' then VVerx;

end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
case key of
vk_RIGHT: napravlenie:='R';
VK_LEFT:  napravlenie:='L';
vk_DOWN:  napravlenie:='D';
VK_UP:    napravlenie:='U';
end;

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
napravlenie := 'L';
CreateUdav();
end;

end.
 

Вот прикрепил исходник, плз помогите.

Это сообщение отредактировал(а) spamER - 24.1.2009, 14:12
PM MAIL   Вверх
TForumUser
Дата 17.12.2008, 23:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 110
Регистрация: 7.7.2007

Репутация: 0
Всего: 0



Твоя основная ошибка: ты применяешь направление движения сразу для всех сегментов змейки:
Код
for i:=0 to 2 do
  mas[i].Left:=mas[i].Left+shag;

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

Это сообщение отредактировал(а) TForumUser - 17.12.2008, 23:55
--------------------
Экономте электроэнергию! Выключайте Num Lock!
PM MAIL ICQ   Вверх
spamER
Дата 18.12.2008, 00:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 14.11.2008

Репутация: нет
Всего: 1



Цитата(TForumUser @ 17.12.2008,  23:54)
Твоя основная ошибка: ты применяешь направление движения сразу для всех сегментов змейки:
Код
for i:=0 to 2 do
  mas[i].Left:=mas[i].Left+shag;

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

Можешь подсказать как это сделать.Если не тяжело приведи пример кода. ПЛЗ.
PM MAIL   Вверх
TForumUser
Дата 18.12.2008, 00:24 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 110
Регистрация: 7.7.2007

Репутация: 0
Всего: 0



Код

var
 i, j: integer;
procedure TForm1.Vpravo();
begin
  mas[i].Top := mas[j].Top;                //меняем положение хвоста
  mas[i].Left := mas[j].Left + shag;
  j := i;                                               //теперь i-ый элемент массива - голова
  i := i - 1;                                         //i -1 - хвост
  if i < 1 then i = 2;
end;

где i -  (хвост змейки), j - голова змейки
В начале i=2  j=1
остальные - по аналогии
работает если изображение головы не отличается от изображения хвоста
То, что смог набросать без делфи... Если не получится, завтра ещё подумаю)

Это сообщение отредактировал(а) TForumUser - 18.12.2008, 00:36
--------------------
Экономте электроэнергию! Выключайте Num Lock!
PM MAIL ICQ   Вверх
Christoph
Дата 18.12.2008, 00:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 667
Регистрация: 23.1.2008
Где: Харьков

Репутация: 5
Всего: 11



а может переменные локальные? а цикл? или без цикла?


--------------------
user posted image
PM MAIL ICQ   Вверх
spamER
Дата 18.12.2008, 00:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 14.11.2008

Репутация: нет
Всего: 1



TForumUser чет оно не работает

Добавлено через 9 минут и 8 секунд
Народ ну помогите , плз.
PM MAIL   Вверх
Christoph
Дата 18.12.2008, 16:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 667
Регистрация: 23.1.2008
Где: Харьков

Репутация: 5
Всего: 11



конечно оно не будет работать.....я ж писал выше  smile  сегодня попробую помочь


--------------------
user posted image
PM MAIL ICQ   Вверх
TForumUser
Дата 18.12.2008, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 110
Регистрация: 7.7.2007

Репутация: 0
Всего: 0



Ой, ну конечно работает, просто надо кое-то исправить
Код

var
 i, j: integer;
procedure TForm1.Vpravo();
begin
  mas[i].Top := mas[j].Top;
  mas[i].Left := mas[j].Left + shag;
  j := i;
  i := i + 1;
  if i > n then i := 1;
end;

при запусек программы i = 1, j = (количество сегментов)
n = (количество сегментов)
И переменный должны быть глобальными, потому что сама процедура должна делать только один шаг, по той же причине не нужен цикл, так что нечего минусовать сообщения... 

Это сообщение отредактировал(а) TForumUser - 18.12.2008, 17:23
--------------------
Экономте электроэнергию! Выключайте Num Lock!
PM MAIL ICQ   Вверх
spamER
Дата 19.12.2008, 17:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 14.11.2008

Репутация: нет
Всего: 1



Чет оно не работает. Мож кто знает как правильно нада ???
PM MAIL   Вверх
TForumUser
Дата 19.12.2008, 17:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 110
Регистрация: 7.7.2007

Репутация: 0
Всего: 0



как именно оно не работает? потому что у меня все норм
--------------------
Экономте электроэнергию! Выключайте Num Lock!
PM MAIL ICQ   Вверх
spamER
Дата 19.12.2008, 18:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 14.11.2008

Репутация: нет
Всего: 1



TForumUser оно даже не компилируется.

Если не тяжело прикрепи исходник(что бы уже рабочий был).
PM MAIL   Вверх
TForumUser
Дата 19.12.2008, 19:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 110
Регистрация: 7.7.2007

Репутация: 0
Всего: 0



Знаете, при ошибке во время компиляции в нижней части окна с кодом появляется окошко, в котором описана суть ошибки. Обратив внимание на это окошко, можно догадаться, что вся проблема в повторном объявлении переменной. Если немного подстроить данный код под Вашу программу, можно получить рабочую программу:
Код
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, Menus;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    MainMenu1: TMainMenu;
    Main: TMenuItem;
    NewGames: TMenuItem;
    N1: TMenuItem;
    Exit: TMenuItem;
    Cpravka: TMenuItem;
    About_program: TMenuItem;
    Image1: TImage;
    procedure Timer1Timer(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure Vpravo();
    procedure VLevo();
    procedure VVerx();
    procedure Vniz();
    procedure CreateUdav();
  end;
const
  shag = 10;

var
  Form1: TForm1;
  napravlenie: string[1];
  mas:array[0..999] of TShape;
  i, a, b, max, n: integer;
implementation

uses MaskUtils, Math;

{$R *.dfm}

procedure TForm1.CreateUdav();
begin
for i:=0 to 2 do
begin
  mas[i]:=TShape.Create(self);
  mas[i].Left:=150;
  mas[i].Width:=10;
  mas[i].Height:=10;
  mas[i].Top:=150;
  mas[i].Top:=mas[i].Top-i*10;
  mas[i].Parent:=Form1;
end;                       
a := 0;
max := 3;
b := max - 1;
n := max - 1;
end;

procedure TForm1.Vpravo();
begin
  mas[a].Top := mas[b].Top;
  mas[a].Left := mas[b].Left + shag;
  b := a;
  a := a + 1;
  if a > n  then a := 0;
end;

procedure TForm1.VLevo();
begin
  mas[a].Top := mas[b].Top;
  mas[a].Left := mas[b].Left - shag;
  b := a;
  a := a + 1;
  if a > n  then a := 0;
end;

procedure TForm1.VVerx();
begin
  mas[a].Top := mas[b].Top - shag;
  mas[a].Left := mas[b].Left;
  b := a;
  a := a + 1;
  if a > n  then a := 0;
end;

procedure TForm1.Vniz();
begin
  mas[a].Top := mas[b].Top + shag;
  mas[a].Left := mas[b].Left;
  b := a;
  a := a + 1;
  if a > n  then a := 0;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if napravlenie = 'R' then Vpravo;
  if napravlenie = 'L' then VLevo;
  if napravlenie = 'D' then Vniz;
  if napravlenie = 'U' then VVerx;

end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
case key of
vk_RIGHT: napravlenie:='R';
VK_LEFT:  napravlenie:='L';
vk_DOWN:  napravlenie:='D';
VK_UP:    napravlenie:='U';
end;

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 napravlenie := 'U';
 CreateUdav();
end;

end.

И на будущее: на форуме не делают за вас всю работу, а наталкивают на мысль, так что привыкайте. Я же пишу за Вас программу лишь из-за того, что это мое сотое сообщение и я от осознания сего факта добрею.

Это сообщение отредактировал(а) TForumUser - 19.12.2008, 19:34
--------------------
Экономте электроэнергию! Выключайте Num Lock!
PM MAIL ICQ   Вверх
NewDima
Дата 19.12.2008, 19:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 922
Регистрация: 20.2.2006
Где: <?here?>

Репутация: нет
Всего: 12



Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure CreateUdav;
    procedure Move;
    procedure goUp;
    procedure goDown;
    procedure goRight;
    procedure goLeft;
  end;
const
  startlen = 10;
  size = 10;
  step = 1;

var
  Form1: TForm1;
  currentcount: integer;
  mas:array[0..999] of TShape;
  deltax, deltay: integer;

implementation

{$R *.dfm}

procedure TForm1.CreateUdav;
var i: integer;
begin
for i:=0 to startlen-1 do
 begin
  mas[i] := TShape.Create(self);
  mas[i].Parent := self;
  mas[i].Left := i*size+3;
  mas[i].Top := 0;
  mas[i].Width := size;
  mas[i].Height := size;
 end;
 mas[0].Brush.Color := clRed;
 currentcount := startlen;
 deltax := step;
 deltay := 0;
end;

procedure TForm1.Move;
var i: integer;
begin
for i:=currentcount-1 downto 1 do
 begin
 mas[i].Left := mas[i-1].Left;
 mas[i].Top := mas[i-1].Top;
 end;
if (mas[0].Left+deltax*size<0) then mas[0].Left := ClientWidth else
if (mas[0].Left+deltax*size>ClientWidth) then mas[0].Left := 0 else
mas[0].Left := mas[0].Left + deltax*size;
if (mas[0].Top+deltay*size<0) then mas[0].Top := ClientHeight else
if (mas[0].Top+deltay*size>ClientHeight) then mas[0].Top := 0 else
mas[0].Top := mas[0].Top + deltay*size;
end;

procedure TForm1.goUp;
begin
if deltay<>0 then exit;
deltax := 0;
deltay := - step;
end;

procedure TForm1.goDown;
begin
if deltay<>0 then exit;
deltax := 0;
deltay := step;
end;
procedure TForm1.goRight;
begin
if deltax<>0 then exit;
deltax := step;
deltay := 0;
end;
procedure TForm1.goLeft;
begin
if deltax<>0 then exit;
deltax := - step;
deltay := 0;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
move();
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
CreateUdav();
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
case Key of
VK_LEFT: goLeft;
VK_RIGHT: goRight;
VK_UP: goUp;
VK_DOWN: goDown;
end;
end;

end.


Добавлено через 2 минуты и 33 секунды
а мое 111-е ))
PM ICQ   Вверх
spamER
Дата 19.12.2008, 20:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 14.11.2008

Репутация: нет
Всего: 1



1.   TForumUser ОГРОМНОЕ спасибо.  
2.   NewDima  также ОГРОМНОЕ спасибо.

Не знаю даже как вас благодарить, спасибо.


Все работает smile  smile  smile 

Это сообщение отредактировал(а) spamER - 19.12.2008, 20:29
PM MAIL   Вверх
NewDima
Дата 20.12.2008, 06:22 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 922
Регистрация: 20.2.2006
Где: <?here?>

Репутация: нет
Всего: 12



приучись закрывать тему, чтобы те, кто заходит сюда помочь, могли быстро увидеть, где еще не помогли.
Сверху надпись-ссылка есть
PM ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0886 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.