Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Помогите сделать игру "змейка"


Автор: Lehon 7.10.2009, 19:13
Добрый день. Подскажите пожалуйста, как сделать так, что бы при нажатии стрелок обьект (например обычная кнопка) перемещался по форме? И вообще как назначать приложению кнопки? (Если нажата W то, если -> то...). 

(Гугл не рулит. Точнее рулит под dos приложения. Исходники обычной тупой змейки даже под консоль...)

+вопрос который я задавал ранее, но мне не ответили...
Не могу задать переменные сразу на всю программу. Вот: 

Код

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
double x=Edit1->Text*1;
double y=Edit2->Text*1;
double z;
double z1;
double z2;
double z3;
z=x*y;
z1=x/y;
z2=x-y;
z3=x+y;


[C++ Error] Unit1.cpp(11): E2451 Undefined symbol 'Edit1'
[C++ Error] Unit1.cpp(12): E2451 Undefined symbol 'Edit2'
[C++ Error] Unit1.cpp(17): E2303 Type name expected
[C++ Error] Unit1.cpp(17): E2238 Multiple declaration for 'z'
[C++ Error] Unit1.cpp(13): E2344 Earlier declaration of 'z'
[C++ Error] Unit1.cpp(18): E2303 Type name expected
и т.д. однотипные ошибки, затем
[C++ Warning] Unit1.cpp(46): W8004 'z3' is assigned a value that is never used
[C++ Warning] Unit1.cpp(46): W8004 'z2' is assigned a value that is never used
[C++ Warning] Unit1.cpp(46): W8004 'z1' is assigned a value that is never used
и тд

Автор: SVN74 7.10.2009, 19:19
Цитата(Lehon @  7.10.2009,  19:13 Найти цитируемый пост)
double x=Edit1->Text*1;
double y=Edit2->Text*1;
double z;
double z1;
double z2;
double z3;
z=x*y;
z1=x/y;
z2=x-y;
z3=x+y;


Это надо поместить во внутрь класса

Автор: Lehon 7.10.2009, 19:30
Внутрь кнопки? Так потому и хочу сразу задать глобальные переменные - слишком неэкономично в каждой кнопке писать переменные.

Автор: Anikmar 7.10.2009, 19:42
Цитата(SVN74 @  7.10.2009,  19:19 Найти цитируемый пост)
Это надо поместить во внутрь класса


Цитата(Lehon @  7.10.2009,  19:30 Найти цитируемый пост)
Внутрь кнопки? 


Можно создать класс для глобальных переменных. И глобальным сделать один его экземпляр.
Цитата(Lehon @  7.10.2009,  19:13 Найти цитируемый пост)
(Гугл не рулит. Точнее рулит под dos приложения. Исходники обычной тупой змейки даже под консоль...)

Вы сначала попробуйте змейку написать хоть под ДОС. Поверьте двигать кнопку намного проще, чем написать змейку.

Автор: Lehon 7.10.2009, 20:03
"Вы сначала попробуйте змейку написать хоть под ДОС. Поверьте двигать кнопку намного проще, чем написать змейку."

Ну, мне кнопка и нужна ) А не змейка. Я не понимаю ничего в консольном программировании, пусть это и один и тот же с++, мне именно приложение нужно ) С кнопкой двигающийся стрелками.

"Можно создать класс для глобальных переменных. И глобальным сделать один его экземпляр."

Попробую...

Автор: Usper 8.10.2009, 11:06
Переменные можно объявить и глобально вне класса, однако присваивать им значения надо в конструкторе формы:
Код

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
double x;
double y;
double z;
double z1;
double z2;
double z3;
z=x*y;
z1=x/y;
z2=x-y;
z3=x+y;


__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    x=Edit1->Text*1;
    y=Edit2->Text*1;
}

А двигать кнопку так:
Разместить на форме кнопку, свойство формы KeyPreview установить в true, в обработчик FormKeyDown формы написать код:
Код

............
if(Key==VK_RIGHT)
    {
        Button1->Left++;
        Key=0;
    }
............


Автор: Lehon 8.10.2009, 15:42
Благодарю, Помогло! )

ПС
Вроде бы движение кнопки билдер нереализует. Шейпы двигаются, баттоны нет.

Автор: Anikmar 8.10.2009, 15:49
Цитата(Lehon @  8.10.2009,  15:42 Найти цитируемый пост)
Шейпы двигаются, баттоны нет.

 smile  smile А шкрабы ботают?  smile 

Посмотрите - не включено ли в кнопках автовыравнивание и привязка к родительскому контролу.

Добавлено через 55 секунд
Бедный русский язык. Был бы он реальным монстром - первым делом сожрал бы всех программистов.

Автор: Usper 8.10.2009, 16:02
В примере было почему-то Key==0; надо, конечно же, Key=0; и вообще эту строчку можно выкинуть smile
А кнопка нормально двигается.

Автор: Lehon 8.10.2009, 16:02
Еще вопрос! smile
Вот код. Компилятор ругается (и правильно делает) на то что я вписал кеи в таймер, а так же не понимает что на месте x как раз должно быть имя члена Тшейп. Вопрос  в том как правильно написать что б все работало? А именно:
1. Если жмем кнопку *** то на месте х в Shape1->x; Ставиться Top либо Left; Следовательно, в зависимости от того какую кнопку мы нажали, шейп раз в **милисекунд сдвигается в ту сторону какую кнопку мы нажали.
2. Как сдвигать не на ++ а на +20 к примеру? (У меня такое не работает...).


Код

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
char x;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
if(Key==VK_RIGHT)
{Shape1->Left++; Key==0;}
if(Key==VK_LEFT)
{Shape1->Left--; Key==0;}
if(Key==VK_UP)
{Shape1->Top--; Key==0;}
if(Key==VK_DOWN)
{Shape1->Top++; Key==0;}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
if (Key=VK_UP) x=Top;
if (Key=VK_DOWN) x=Top;
if (Key=VK_LEFT) x=Left;
if (Key=VK_RIGHT) x=Left;
Shape1->x;
}
//---------------------------------------------------------------------------


[C++ Error] Unit1.cpp(34): E2451 Undefined symbol 'Key'
[C++ Error] Unit1.cpp(38): E2316 'x' is not a member of 'TShape'

Автор: Anikmar 8.10.2009, 16:26
Ох...  smile 
Лучше скажите, что вы хотите при помощи таймера сделать?

Добавлено через 3 минуты и 40 секунд
Если я правильно понял, то заведите 2 переменные в классе:
DirectionX и DirectionY

По перехвату соответствующей кнопки заносите в них значение сдвига, например:
нажата кнопка влево - DirectionX=-1, кнопка вправо - DirectionX = 1
и т.п.

Можно еще фичу сделать:
Нажали кнопку влево - уменьшили DirectX на 1, а вправо - увеличили. Тогда скорость движения менять будем.

А по таймеру - просто прибавляем к Left - DirectionX, а к Top DirectionY


Автор: Lehon 8.10.2009, 16:49
Вообще я хотел научиться управлять клавишами обьектом, а теперь уже захотел написать змейку ) Таймер - обеспечение постоянного движения с постоянной скоростью, желательно так: каждые 0,5 или 1 секунду (пока не решил) происходит сдвиг на 1 длину сегмента змейки ( в моем случае 20). А стрелками теперь я задаю лишь направление движения по идее...
Про DirectionX и Y непонял, но попробую...

Автор: Anikmar 8.10.2009, 17:05
Цитата(Lehon @  8.10.2009,  16:49 Найти цитируемый пост)
Про DirectionX и Y непонял, но попробую...

Если не поняли, то как вы собираетесь пробовать?  smile  На вкус?  smile 

Лучше скажите что непонятно - дабы не плодить лишнего кода. 

Автор: Lehon 8.10.2009, 17:38
"Если не поняли, то как вы собираетесь пробовать?    На вкус?   

Лучше скажите что непонятно - дабы не плодить лишнего кода. "

Да, ни на вкус ни на цвет не получилось ) Гугл вообще мне директх предлагает )))
Мне непонятно что за переменные такие DirectionX и Y и как вообще это запрогать. Я работал раньше тока с дабле и инт... Прогаю 3или 4ый день всего )

Автор: Usper 8.10.2009, 17:59
Anikmar, предлагает создать переменные DirectionX и DirectionY и в обработчике FormKeyDown присваивать им соответствующие значения. А по таймеру, в соответствии со значениями в этих переменных, делать соответствующий сдвиг. Я в своё время при написании змейки тоже руководствовался похожим принципом, только у меня была одна переменная (см. вложение). За код прошу не пинать, писалось всё на заре программерской деятельности  smile Впрочем сейчас ситуация не сильно улучшилась :-(.

Автор: Lehon 8.10.2009, 18:52
У меня родилась идея как сделать. Компилируется, работает, но само не двигается. вообще. только нажатием кнопки...


Код

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
int x;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
if(Key==VK_RIGHT)
{Shape1->Left++; x=1;}
if(Key==VK_LEFT)
{Shape1->Left--; x=2;}
if(Key==VK_UP)
{Shape1->Top--; x=3;}
if(Key==VK_DOWN)
{Shape1->Top++; x=4;}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
if (x=1) Shape1->Left++;
else return;
if (x=2) Shape1->Left--;
else return;
if (x=3) Shape1->Top++;
else return;
if (x=4) Shape1->Top--;
else return;

}

Автор: Anikmar 8.10.2009, 19:55
Цитата(Lehon @  8.10.2009,  18:52 Найти цитируемый пост)
if (x=1) Shape1->Left++;
else return;
if (x=2) Shape1->Left--;
else return;
if (x=3) Shape1->Top++;
else return;
if (x=4) Shape1->Top--;
else return;

 Оххх. Еще бы вам немного синтаксис языка изучить....
В Cи операция сравнения на равенство кодируется как ==



Автор: Lehon 8.10.2009, 20:56
Спасибо ) Заработало )

Автор: Lehon 11.10.2009, 11:22
Всем привет! У меня опять вопрос )

Вот код. Проблема в последнем блоке. Вроде как синтаксическая ошибка, хотя не понимаю почему, вроде как взял инфу из книги...
Ошибки выделил жирным.
Что я пытался сделать? Создать случайное число от 0  до 9 (к сож не знаю как сделать от 1 до 9 (ну это только для сотен) - если кто знает тоже подскажите плз), и к нему прибавить 0, ну, т.е. из допустим 3х сделать 30, т.к. мне нужны десятки и сотни. Но! Есть еще момент который я не реализовал - десятки мне нужны через 20. т.е. 00, 20, 40, 60, 80. 
Все это должно перемещать яблоко по случайным координатам. И еще момент - у меня яблоко перемещается каждые n секунд и быстро скрывается из виду. Да, это из за того что я все вписал в таймер, но нигде больше перемещение не работает. Может как то можно создать отдельное событие о пересечении координат головы змеи и яблока?


Код

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#include <stdlib.h>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
int x;

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
if(Key==VK_RIGHT)//Çàäàåì óïðàâëåíèå êëàâèøàìè íàïðàâëåíèåì äâèæåíèÿ
{x=1;}
if(Key==VK_LEFT)
{x=2;}
if(Key==VK_UP)
{x=3;}
if(Key==VK_DOWN)
{x=4;}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
if (x==1) Shape1->Left=Shape1->Left+20; //Êàæäûå n ñåêóíä øåéï ñäâèãàåòñÿ íà 20 ïèêñåëåé.
else 0;
if (x==2) Shape1->Left=Shape1->Left-20;
else 0;
if (x==3) Shape1->Top=Shape1->Top-20;
else 0;
if (x==4) Shape1->Top=Shape1->Top+20;
else 0;
Label3->Caption=Shape1->Left; //Ïîêàçûâàåì êîîðäèíàòû øåéïà ïîëüçîâàòåëþ â ëåéáëàõ.
Label4->Caption=Shape1->Top;
Label9->Caption=Shape2->Left;
Label10->Caption=Shape2->Top;

int u=Shape1->Left;
int i=Shape2->Left;
int l=Shape1->Top;
int d=Shape2->Top;

int o;
int s;
int e;

int a;
int c;
int r;
int r1;
int r2;
int f;

r=rand ()%9;
r1=rand ()%9;
c=rand ()%9;
r2=r1+"0"+; // çíà÷åíèÿ îò 0 äî 90
a=r+r2+"00"+; // çíà÷åíèÿ îò 000 äî 900 + r2
f=c+r2+"00"+;


Label11->Caption=r;

if (u==i, l==d) {Shape2->Top=Shape2->Top+a; Shape2->Left=Shape2->Left+f;}
}
//---------------------------------------------------------------------------



[C++ Error] Unit1.cpp(74): E2188 Expression syntax
[C++ Error] Unit1.cpp(75): E2188 Expression syntax
[C++ Error] Unit1.cpp(76): E2188 Expression syntax
Дальше варнинги о обьявленых но неиспользованных переменных.

Автор: Usper 11.10.2009, 16:17
А что вы пытаетесь сделать в этих строках? Фактически получается прибавление строки к числу. А это недопутимо. Да ещё и знак "+" зачем-то перед ";" стоит. Нужно справа добавить нулей к числу? Можно просто умножить число на 10^n, где n - необходимое число нулей.

Автор: Lehon 11.10.2009, 16:40
Умножить на 10? Не подумал даже... действительно простейший выход )
Да, я хотел к числу которое выдал рандом добавить нули.
А ошибка как я понял в том что я не написал StrToFloat.
Попробую умножением... А что насчет других вопросов?

Автор: Lehon 11.10.2009, 17:27
Получилось, но с ошибочкой. Все вроде как верно, но! Посмотрите на код:

if (u==i, l==d) {Shape2->Top=a; Shape2->Left=f;};

Когда по Топ перемещаемся, все норм работает, но когда пересекаем Лефт, на котором лежит яблоко, оно перемещается - хотя я до него еще и не доехал.
Т.е. Если я иду к яблоку по Топ, то оно перемещается когда совпадают обе координаты, а когда по Лефт, то сразу. И вот я не пойму в чем дело... Может где ошибка, или я не так указал? Нужно ведь что бы if выполнялся когда совпадают ОБА условия.

Автор: Anikmar 11.10.2009, 20:27
Может надо
if ((u==i)&& (l==d)) 

Автор: Lehon 11.10.2009, 22:50
Спасибо! Начало работать. И у меня еще вопросы назрели )))

Вот я создаю новый шейп, такой же как и голова змеи, прямо рядом с ней. Все хорошо, но! С какой бы я стороны не зашел, голова змеи при сьедании яблока меняет свое направление на "вниз", и новый сегмент змеи образуется так же только с одной стороны.  И конечно же главный вопрос - как сделать так что бы сегменты перемещались за головой, новый возникали за последними сегментами, и повторяли движение головы по очереди?




Код


//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#include <stdlib.h>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
int x;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
if(Key==VK_RIGHT)//Çàäàåì óïðàâëåíèå êëàâèøàìè íàïðàâëåíèåì äâèæåíèÿ
{x=1;}
if(Key==VK_LEFT)
{x=2;}
if(Key==VK_UP)
{x=3;}
if(Key==VK_DOWN)
{x=4;}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
if (x==1) Shape1->Left=Shape1->Left+20; //Êàæäûå n ñåêóíä øåéï ñäâèãàåòñÿ íà 20 ïèêñåëåé.
else 0;
if (x==2) Shape1->Left=Shape1->Left-20;
else 0;
if (x==3) Shape1->Top=Shape1->Top-20;
else 0;
if (x==4) Shape1->Top=Shape1->Top+20;
else 0;
Label3->Caption=Shape1->Left; //Ïîêàçûâàåì êîîðäèíàòû øåéïà ïîëüçîâàòåëþ â ëåéáëàõ.
Label4->Caption=Shape1->Top;
Label9->Caption=Shape2->Left;
Label10->Caption=Shape2->Top;

int u=Shape1->Left;
int i=Shape2->Left;
int l=Shape1->Top;
int d=Shape2->Top;

int o;
int s;
int e;

int a;
int c;
int r;
int r2;

int f;
int t1;

r=rand ()%9;

t1=rand ()%4;

if (t1=0) r2=00;
if (t1=1) r2=20;
if (t1=2) r2=40;
if (t1=3) r2=60;
if (t1=4) r2=80;

c=rand ()%8;
a=r*100+r2; // çíà÷åíèÿ îò 000 äî 900 + r2
f=c*100+r2;

Label11->Caption=f;

if ((u==i)&& (l==d))  {
Shape2->Top=a; Shape2->Left=f; // Çàäàåì íîâûå êîîðäèíàòû ÿáëîêà.

TShape *shp;  // Ñîçäàåì íîâûé øåéï ê ãîëîâå çìåè.
  for (int m = 0; m < 1; m ++)
       {
          shp = new TShape (this);
          shp->Parent = Panel1;
          shp->Width = 20;
          shp->Height = 20;
          shp->Shape=stRoundRect;
          shp->Brush->Color=clMoneyGreen;


         if (x=1) shp->Top=Shape1->Top+20;  // óêàçûâàåì êîîðäèíàòû íîâîãî øåéïà.
         if (x=2) shp->Top=Shape1->Top-20;
         if (x=3) shp->Left=Shape1->Left+20;
         if (x=4) shp->Left=Shape1->Left-20;





       }

};

if (Shape1->Left<=0) Shape1->Left=980; // Змея при столкновении с левым краем, перемещается в правый.


}
//---------------------------------------------------------------------------



Билдер выдает на этот код много варнингов такого вида: 
[C++ Warning] Unit1.cpp(94): W8060 Possibly incorrect assignment
Хотя, к счастью, ни одного еррора.

Автор: xvr 12.10.2009, 13:39
Правильно выдает - у тебя опять куча присваиваний в if'ах, вместо сравнений  smile 

Автор: Lehon 12.10.2009, 14:58
Хы, ну да ) Исправил, теперь голова продолжает движение в заданном направлении при сьедании яблока. Но новые сегменты змеи стелятся по верхнему и левому краю ) И опять же, неясно что делать что бы образовывалась змейка а не набор разбросаных шейпов )

Автор: xvr 12.10.2009, 17:58
Для 'змейки' у тебя неправильная логика всей программы. Тело змейки состоит из НАБОРА шейпов, которые надо хранить (например в std::deque). На каждом шаге перемещения создается новая голова змеи на основе координат старой головы (при этом надо вычислять И top И left координаты, а не одну из них). Новая голова добавляется в очередь (deque::push_front). Далее удаляется элемент из хвоста (deque::pop_back). Если змея съедает яблоко, то удаление хвоста блокируется на заданное количество 'тиков' таймера (змея при этом будет расти)
Одна оптимизация - если на данном шаге элемент хвоста должен удаляться, то его можно использовать как новую голову, что бы не удалять/создавать TShape.
 

Автор: Lehon 13.10.2009, 16:04
Буду думать... А как создать событие которое происходит через n милисекунд (Речь о вышеописанном "блокируется на заданное количество тиков таймера").

Автор: xvr 13.10.2009, 16:23
Цитата(Lehon @ 13.10.2009,  16:04)
А как создать событие которое происходит через n милисекунд (Речь о вышеописанном "блокируется на заданное количество тиков таймера").

'Тики таймера' имеются в виду вызовы TForm1::Timer1Timer() (по 1 вызову на 1 тик)

Автор: Lehon 13.10.2009, 16:55
Не, это у меня уже есть, там описано почти все движения головы и яблока. Мне надо узнать как сделать грубо говоря
          shp->Top=Shape1->Top через 100 милисекунд;
          shp->Left=Shape1->Left через 100 милисекунд;

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

Автор: xvr 13.10.2009, 21:22
Цитата(Lehon @ 13.10.2009,  16:55)
Не, это у меня уже есть, там описано почти все движения головы и яблока. Мне надо узнать как сделать грубо говоря
          shp->Top=Shape1->Top через 100 милисекунд;
          shp->Left=Shape1->Left через 100 милисекунд;

Настроить таймер на 100ms и в его OnTimer это и делать

Цитата

Есть мысль просто хранить шейпы вне поля видимости, а потом вызывать. 
Не надо их хранить. Их надо создавать по мере необходимости, я же писал как

Цитата

Но, много кода получается - описывать придется каждый шейп, и не дай бог юзер сможет сьесть 100 яблок, когда я максимум предусмотрел 98...
Для этого существует очередь (std::deque). Она вполне резиновая   smile 

Автор: Anikmar 13.10.2009, 22:05
 smile 
Цитата(Lehon @  7.10.2009,  19:13 Найти цитируемый пост)
(Гугл не рулит. Точнее рулит под dos приложения. Исходники обычной тупой змейки даже под консоль...)


Вот вам и обычная змейка.  smile 

Под консоль или под что еще - но можно было посмотреть в этих исходниках как организован таймер и движение удава. Кстати под ДОС это даже несколько хлопотнее. Под виндами мне кажется намного проще змейку писать.

Эта тема переросла из движения кнопки в "Я пишу змейку".  smile 


Автор: Lehon 13.10.2009, 22:06
Цитата

Настроить таймер на 100ms и в его OnTimer это и делать



Именно так реализовано перемещение шейп1 (голова), но мне не нужно что бы хвост повторял движение  головы в тот же миг что голова двигается, мне нужно что бы хвост повторил движение через 1 ход головы (через 100 мс, через 1 тик таймера, именно повторяя движение головы за прошлый "тик"-"ход") Именно потому и пишу - через 100 милисекунд после движения Шейп1.

Добавлено через 3 минуты и 1 секунду
Цитата

Вот вам и обычная змейка.   


 smile 

Цитата

Под консоль или под что еще - но можно было посмотреть в этих исходниках как организован таймер и движение удава. Кстати под ДОС это даже несколько хлопотнее. Под виндами мне кажется намного проще змейку писать.


Смотрел, читал, сломал мозг ничего не поняв ))) Наверно потому что все было реализовано радикально не так как я это себе представляю )))

 smile 

Автор: Anikmar 13.10.2009, 22:43
Цитата(Lehon @  13.10.2009,  22:06 Найти цитируемый пост)
Именно так реализовано перемещение шейп1 (голова), но мне не нужно что бы хвост повторял движение  головы в тот же миг что голова двигается, мне нужно что бы хвост повторил движение через 1 ход головы (через 100 мс, через 1 тик таймера, именно повторяя движение головы за прошлый "тик"-"ход") Именно потому и пишу - через 100 милисекунд после движения Шейп1.

Ну так в одном тике и двигайте сразу и голову и хвост. В чем проблема?

Автор: Usper 14.10.2009, 08:09
А вы мой http://forum.vingrad.ru/index.php?showtopic=275781&view=findpost&p=1989462 на первой странице читали? Там исходники моей реализации змейки, НЕ под ДОС. Размер исходника довольно небольшой, разобраться, как мне кажестя, труда не составит. Там, правда, никаких очередей (я тогда про STL вообще понятия не имел smile) и отрисовка идёт на канве а не шейпами. А по поводу длинной змейки, а нужна вам змейка длинной в 100 сегментов и более? Во всех подобных играх, которые я видел, после того как змейка вырастала до какой-то длинны, игра переходила на новый уровень.

Автор: Anikmar 14.10.2009, 09:31
Цитата(Usper @  14.10.2009,  08:09 Найти цитируемый пост)
Там, правда, никаких очередей (я тогда про STL вообще понятия не имел ) и отрисовка идёт на канве а не шейпами.

Я свою змейку написал в 1989 году на бейсике еще на БК0010  smile Там с очередями и с STL была капитальная проблема. (Как впрочем и с таймерами)

Автор: Lehon 14.10.2009, 15:48
Цитата

Ну так в одном тике и двигайте сразу и голову и хвост. В чем проблема?


Тык нет проблемы - если устраивает змеюга ходящая на хвосте как на ногах, и следовательно растущая вверх ))) Координаты то в таком случае будут одинаковые.


Цитата

А вы мой пост на первой странице читали? Там исходники моей реализации змейки, НЕ под ДОС. Размер исходника довольно небольшой, разобраться, как мне кажестя, труда не составит. Там, правда, никаких очередей (я тогда про STL вообще понятия не имел ) и отрисовка идёт на канве а не шейпами. А по поводу длинной змейки, а нужна вам змейка длинной в 100 сегментов и более? Во всех подобных играх, которые я видел, после того как змейка вырастала до какой-то длинны, игра переходила на новый уровень.


У вас нет файла проекта? Код то из юнит1.кпп я вижу, разобраться пытался, но так и не смог понять что такое DrawQvadrat, azimut, и пара других страшных слов ) ( пытался даже воссоздать форму - одни ерроры ))) Сейчас посмотрел еще раз - что то ясно, что то лес ) В частности я совсем не вижу места реализации создания нового сегмента змеи, и главное - его движения. С головой все ясно, а вот хвост ))) Неясно совсем как его двигать правильно...

Автор: Lehon 14.10.2009, 15:48
Цитата

Ну так в одном тике и двигайте сразу и голову и хвост. В чем проблема?


Тык нет проблемы - если устраивает змеюга ходящая на хвосте как на ногах, и следовательно растущая вверх ))) Координаты то в таком случае будут одинаковые.


Цитата

А вы мой пост на первой странице читали? Там исходники моей реализации змейки, НЕ под ДОС. Размер исходника довольно небольшой, разобраться, как мне кажестя, труда не составит. Там, правда, никаких очередей (я тогда про STL вообще понятия не имел ) и отрисовка идёт на канве а не шейпами. А по поводу длинной змейки, а нужна вам змейка длинной в 100 сегментов и более? Во всех подобных играх, которые я видел, после того как змейка вырастала до какой-то длинны, игра переходила на новый уровень.


У вас нет файла проекта? Код то из юнит1.кпп я вижу, разобраться пытался, но так и не смог понять что такое DrawQvadrat, azimut, и пара других страшных слов ) ( пытался даже воссоздать форму - одни ерроры ))) Сейчас посмотрел еще раз - что то ясно, что то лес ) В частности я совсем не вижу места реализации создания нового сегмента змеи, и главное - его движения. С головой все ясно, а вот хвост ))) Неясно совсем как его двигать правильно...
А насчет длины - эт разные змейки бывают ) В моем сотовом семилетней давности уровней не было, а макс длина у меня получалась 30 сегментов, но и экранчик был совсем маленький - в компе сотня проблемой не будет думаю ) Уровни это хорошо, и их я тоже хочу сделать, но потом, не все сразу ) От простого к сложному. Только вот простое какое то непростое )

Автор: xvr 14.10.2009, 17:17
Цитата(Lehon @ 14.10.2009,  15:48)
Цитата

Ну так в одном тике и двигайте сразу и голову и хвост. В чем проблема?


Тык нет проблемы - если устраивает змеюга ходящая на хвосте как на ногах, и следовательно растущая вверх ))) Координаты то в таком случае будут одинаковые.

Ну и фиг с ними  smile Не надо вообще ДВИГАТЬ ни голову ни хвост. Надо создавать НОВЫЙ шейп с головы и удалять старый с хвоста.

Автор: Usper 14.10.2009, 20:53
Ой, и правда, вместе с грязной водой выплеснул и ребёнка (вместе с временными файлами из папки удалил и пару нужных)  smile Поправил вложение в том http://forum.vingrad.ru/index.php?showtopic=275781&view=findpost&p=1989462.

Автор: Anikmar 14.10.2009, 21:55
Цитата(xvr @  14.10.2009,  17:17 Найти цитируемый пост)
Ну и фиг с ними   Не надо вообще ДВИГАТЬ ни голову ни хвост. Надо создавать НОВЫЙ шейп с головы и удалять старый с хвоста.


А вот и нет. Надо в хвостовом шейпе поменять координаты - и он станет башкой  smile 

Автор: xvr 15.10.2009, 11:08
Цитата(Anikmar @ 14.10.2009,  21:55)
Цитата(xvr @  14.10.2009,  17:17 Найти цитируемый пост)
Ну и фиг с ними   Не надо вообще ДВИГАТЬ ни голову ни хвост. Надо создавать НОВЫЙ шейп с головы и удалять старый с хвоста.


А вот и нет. Надо в хвостовом шейпе поменять координаты - и он станет башкой  smile

Уже предлагал

Цитата

Одна оптимизация - если на данном шаге элемент хвоста должен удаляться, то его можно использовать как новую голову, что бы не удалять/создавать TShape.

Автор: Lehon 15.10.2009, 21:41
Цитата

Ой, и правда, вместе с грязной водой выплеснул и ребёнка (вместе с временными файлами из папки удалил и пару нужных)   Поправил вложение в том посте.


Он просит файлы
RaizeComponentsVcl.bpi
RaizeComponentsVclDb.bpi

  smile  Может лучше всю папочку?  smile 


Пока не совсем понимаю мысль про поменять координаты хвоста и головы - точней как умная собака, понимаю а написать не могу. Что то вырисовывается, попробую но в результате сомневаюсь...

Автор: xvr 15.10.2009, 21:51
Цитата(Lehon @ 15.10.2009,  21:41)
Пока не совсем понимаю мысль про поменять координаты хвоста и головы - точней как умная собака, понимаю а написать не могу. 

Смотри:
Код

 TShape* tail = queue.back(); queue.pop_back(); // Взяли хвост
 delete tail; // Удалили
 TShape* head = new TShape(this); head->..... // Создали новую голову, проинициализировали
 head->Left = ...; head->Top = ...;
 queue.push_front(head);
Как видим тут удаляется и тут же создается TShape. Можно это не делать:
Код

 TShape* tail_head = queue.back(); queue.pop_back(); // Взяли хвост
 tail_head->Left = ...; tail_head->Top = ...; // Переиспользуем хвост под новую голову
 queue.push_front(tail_head);

Автор: Usper 16.10.2009, 07:51
Lehon, это и есть вся папочка. Всё дело в сторонних компонентах, которые установлены у меня. Даже если они не используются, билдер зачем-то при создании нового проекта запихивает в файл проекта ссылку на эти компоненты. Я поправил файл проекта (*.bpr), удалив из него эти ссылки. Надеюсь теперь заработает. Также запихнул в архив исполняемый файл проекта, чтобы можно было посмотреть на результат.  В очередной раз поправил http://forum.vingrad.ru/index.php?showtopic=275781&view=findpost&p=1989462.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)