Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите сделать игру "змейка" 
:(
    Опции темы
Lehon
Дата 7.10.2009, 19:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Добрый день. Подскажите пожалуйста, как сделать так, что бы при нажатии стрелок обьект (например обычная кнопка) перемещался по форме? И вообще как назначать приложению кнопки? (Если нажата 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
и тд

Это сообщение отредактировал(а) Lehon - 7.10.2009, 19:16
PM MAIL   Вверх
SVN74
Дата 7.10.2009, 19:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 740
Регистрация: 5.5.2008
Где: Комсомольск на Дн епре

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



Цитата(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;


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

PM MAIL WWW   Вверх
Lehon
Дата 7.10.2009, 19:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Внутрь кнопки? Так потому и хочу сразу задать глобальные переменные - слишком неэкономично в каждой кнопке писать переменные.
PM MAIL   Вверх
Anikmar
Дата 7.10.2009, 19:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



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


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


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

Вы сначала попробуйте змейку написать хоть под ДОС. Поверьте двигать кнопку намного проще, чем написать змейку.
PM MAIL ICQ   Вверх
Lehon
Дата 7.10.2009, 20:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



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

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

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

Попробую...
PM MAIL   Вверх
Usper
Дата 8.10.2009, 11:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



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

#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;
    }
............



Это сообщение отредактировал(а) Usper - 8.10.2009, 16:01


--------------------
На посохе волшебном нехилый набалдашник, большой такой, огромный, нехилый набалдашник.
PM MAIL   Вверх
Lehon
Дата 8.10.2009, 15:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Благодарю, Помогло! )

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

Это сообщение отредактировал(а) Lehon - 8.10.2009, 15:43
PM MAIL   Вверх
Anikmar
Дата 8.10.2009, 15:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



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

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

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

Добавлено через 55 секунд
Бедный русский язык. Был бы он реальным монстром - первым делом сожрал бы всех программистов.
PM MAIL ICQ   Вверх
Usper
Дата 8.10.2009, 16:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



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

Это сообщение отредактировал(а) Usper - 8.10.2009, 16:03


--------------------
На посохе волшебном нехилый набалдашник, большой такой, огромный, нехилый набалдашник.
PM MAIL   Вверх
Lehon
Дата 8.10.2009, 16:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Еще вопрос! 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'
PM MAIL   Вверх
Anikmar
Дата 8.10.2009, 16:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



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

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

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

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

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


PM MAIL ICQ   Вверх
Lehon
Дата 8.10.2009, 16:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



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

Это сообщение отредактировал(а) Lehon - 8.10.2009, 16:50
PM MAIL   Вверх
Anikmar
Дата 8.10.2009, 17:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



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

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

Лучше скажите что непонятно - дабы не плодить лишнего кода. 
PM MAIL ICQ   Вверх
Lehon
Дата 8.10.2009, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



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

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

Да, ни на вкус ни на цвет не получилось ) Гугл вообще мне директх предлагает )))
Мне непонятно что за переменные такие DirectionX и Y и как вообще это запрогать. Я работал раньше тока с дабле и инт... Прогаю 3или 4ый день всего )
PM MAIL   Вверх
Usper
Дата 8.10.2009, 17:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



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

Это сообщение отредактировал(а) Usper - 16.10.2009, 07:45

Присоединённый файл ( Кол-во скачиваний: 54 )
Присоединённый файл  Udaff.zip 246,91 Kb


--------------------
На посохе волшебном нехилый набалдашник, большой такой, огромный, нехилый набалдашник.
PM MAIL   Вверх
Lehon
Дата 8.10.2009, 18:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



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


Код

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

#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;

}

PM MAIL   Вверх
Anikmar
Дата 8.10.2009, 19:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



Цитата(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и операция сравнения на равенство кодируется как ==



PM MAIL ICQ   Вверх
Lehon
Дата 8.10.2009, 20:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Спасибо ) Заработало )
PM MAIL   Вверх
Lehon
Дата 11.10.2009, 11:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Всем привет! У меня опять вопрос )

Вот код. Проблема в последнем блоке. Вроде как синтаксическая ошибка, хотя не понимаю почему, вроде как взял инфу из книги...
Ошибки выделил жирным.
Что я пытался сделать? Создать случайное число от 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
Дальше варнинги о обьявленых но неиспользованных переменных.

Это сообщение отредактировал(а) Lehon - 11.10.2009, 11:23
PM MAIL   Вверх
Usper
Дата 11.10.2009, 16:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



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


--------------------
На посохе волшебном нехилый набалдашник, большой такой, огромный, нехилый набалдашник.
PM MAIL   Вверх
Lehon
Дата 11.10.2009, 16:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Умножить на 10? Не подумал даже... действительно простейший выход )
Да, я хотел к числу которое выдал рандом добавить нули.
А ошибка как я понял в том что я не написал StrToFloat.
Попробую умножением... А что насчет других вопросов?
PM MAIL   Вверх
Lehon
Дата 11.10.2009, 17:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



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

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

Когда по Топ перемещаемся, все норм работает, но когда пересекаем Лефт, на котором лежит яблоко, оно перемещается - хотя я до него еще и не доехал.
Т.е. Если я иду к яблоку по Топ, то оно перемещается когда совпадают обе координаты, а когда по Лефт, то сразу. И вот я не пойму в чем дело... Может где ошибка, или я не так указал? Нужно ведь что бы if выполнялся когда совпадают ОБА условия.
PM MAIL   Вверх
Anikmar
Дата 11.10.2009, 20:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



Может надо
if ((u==i)&& (l==d)) 
PM MAIL ICQ   Вверх
Lehon
Дата 11.10.2009, 22:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Спасибо! Начало работать. И у меня еще вопросы назрели )))

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




Код


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

#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
Хотя, к счастью, ни одного еррора.
PM MAIL   Вверх
xvr
Дата 12.10.2009, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



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

PM MAIL   Вверх
Lehon
Дата 12.10.2009, 14:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Хы, ну да ) Исправил, теперь голова продолжает движение в заданном направлении при сьедании яблока. Но новые сегменты змеи стелятся по верхнему и левому краю ) И опять же, неясно что делать что бы образовывалась змейка а не набор разбросаных шейпов )
PM MAIL   Вверх
xvr
Дата 12.10.2009, 17:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Для 'змейки' у тебя неправильная логика всей программы. Тело змейки состоит из НАБОРА шейпов, которые надо хранить (например в std::deque). На каждом шаге перемещения создается новая голова змеи на основе координат старой головы (при этом надо вычислять И top И left координаты, а не одну из них). Новая голова добавляется в очередь (deque::push_front). Далее удаляется элемент из хвоста (deque::pop_back). Если змея съедает яблоко, то удаление хвоста блокируется на заданное количество 'тиков' таймера (змея при этом будет расти)
Одна оптимизация - если на данном шаге элемент хвоста должен удаляться, то его можно использовать как новую голову, что бы не удалять/создавать TShape.
 
PM MAIL   Вверх
Lehon
Дата 13.10.2009, 16:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Буду думать... А как создать событие которое происходит через n милисекунд (Речь о вышеописанном "блокируется на заданное количество тиков таймера").
PM MAIL   Вверх
xvr
Дата 13.10.2009, 16:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



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

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

PM MAIL   Вверх
Lehon
Дата 13.10.2009, 16:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



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

С очередью и хранением не разберусь никак. Есть мысль просто хранить шейпы вне поля видимости, а потом вызывать. Но, много кода получается - описывать придется каждый шейп, и не дай бог юзер сможет сьесть 100 яблок, когда я максимум предусмотрел 98...
PM MAIL   Вверх
xvr
Дата 13.10.2009, 21:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



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

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

Цитата

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

Цитата

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

PM MAIL   Вверх
Anikmar
Дата 13.10.2009, 22:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



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


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

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

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


PM MAIL ICQ   Вверх
Lehon
Дата 13.10.2009, 22:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата

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



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

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

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


 smile 

Цитата

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


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

 smile 
PM MAIL   Вверх
Anikmar
Дата 13.10.2009, 22:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



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

Ну так в одном тике и двигайте сразу и голову и хвост. В чем проблема?
PM MAIL ICQ   Вверх
Usper
Дата 14.10.2009, 08:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



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


--------------------
На посохе волшебном нехилый набалдашник, большой такой, огромный, нехилый набалдашник.
PM MAIL   Вверх
Anikmar
Дата 14.10.2009, 09:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



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

Я свою змейку написал в 1989 году на бейсике еще на БК0010  smile Там с очередями и с STL была капитальная проблема. (Как впрочем и с таймерами)
PM MAIL ICQ   Вверх
Lehon
Дата 14.10.2009, 15:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата

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


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


Цитата

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


У вас нет файла проекта? Код то из юнит1.кпп я вижу, разобраться пытался, но так и не смог понять что такое DrawQvadrat, azimut, и пара других страшных слов ) ( пытался даже воссоздать форму - одни ерроры ))) Сейчас посмотрел еще раз - что то ясно, что то лес ) В частности я совсем не вижу места реализации создания нового сегмента змеи, и главное - его движения. С головой все ясно, а вот хвост ))) Неясно совсем как его двигать правильно...
PM MAIL   Вверх
Lehon
Дата 14.10.2009, 15:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата

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


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


Цитата

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


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

Это сообщение отредактировал(а) Lehon - 14.10.2009, 15:52
PM MAIL   Вверх
xvr
Дата 14.10.2009, 17:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(Lehon @ 14.10.2009,  15:48)
Цитата

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


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

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

PM MAIL   Вверх
Usper
Дата 14.10.2009, 20:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



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


--------------------
На посохе волшебном нехилый набалдашник, большой такой, огромный, нехилый набалдашник.
PM MAIL   Вверх
Anikmar
Дата 14.10.2009, 21:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



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


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

PM MAIL ICQ   Вверх
xvr
Дата 15.10.2009, 11:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



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


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

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

Цитата

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

PM MAIL   Вверх
Lehon
Дата 15.10.2009, 21:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата

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


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

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


Пока не совсем понимаю мысль про поменять координаты хвоста и головы - точней как умная собака, понимаю а написать не могу. Что то вырисовывается, попробую но в результате сомневаюсь...
PM MAIL   Вверх
xvr
Дата 15.10.2009, 21:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(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);

PM MAIL   Вверх
Usper
Дата 16.10.2009, 07:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Lehon, это и есть вся папочка. Всё дело в сторонних компонентах, которые установлены у меня. Даже если они не используются, билдер зачем-то при создании нового проекта запихивает в файл проекта ссылку на эти компоненты. Я поправил файл проекта (*.bpr), удалив из него эти ссылки. Надеюсь теперь заработает. Также запихнул в архив исполняемый файл проекта, чтобы можно было посмотреть на результат.  В очередной раз поправил пост.


--------------------
На посохе волшебном нехилый набалдашник, большой такой, огромный, нехилый набалдашник.
PM MAIL   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

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

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

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

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


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

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


 




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


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

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