22 / 22 / 8
Регистрация: 05.01.2012
Сообщений: 282
1

Алгоритм движения объекта в 2D игре

15.03.2014, 23:53. Показов 2799. Ответов 7
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте! Захотелось написать какую то простенькую игру в 2D на C++, почитал статьи, научился рисовать в Canvas. Но столкнулся с багом, квадрат, которым я двигаю, двигается не корректно, он может двигаться в 4 направления от изначальной позиции, но только на 1 шаг хотя должен идти и дальше. Да и то, не удаляя свою прошлую позицию, только изначальная удаляется. Уже второй день ломаю себе голову, не могу найти причину, помогите разобраться.

Вот код:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
//---------------------------------------------------------------------------
 
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
#include <conio.h> //Библиотека содержит функцию getch
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
// Описываем области в которые будем помещать картинки.
Graphics::TBitmap*Buf;        // Buffer - Окно в котором будут отображаться все картинки.
                             // В Буфер никаких картинок грузить не нужно.
 
Graphics::TBitmap*BackGround;// BackGround (Фон)  - Загружаем картинку с фоном.
 
Graphics::TBitmap*Cross;     // Cross (Перекрестие) - Загружаем любу
                             // картинку карторая будет перекрестием.
 
int Cells[10][10]={
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 0, 1, 1, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 1, 0, 1, 0, 0, 0, 1},
{1, 0, 1, 0, 0, 0, 1, 0, 0, 1},
{1, 0, 0, 0, 0, 1, 0, 0, 0, 1},
{1, 0, 1, 1, 1, 1, 0, 0, 0, 1},
{1, 1, 1, 0, 0, 0, 1, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
};
 
enum Direction {LEFT, UP, RIGHT, DOWN};
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
class PlayerClass //Клас персонажу
{
int x, y;
public:
PlayerClass();
void DrawPlayer();
void CleanPlayer();
void MovePlayer(int Cells[10][10], Direction dir,TLabel *Label);
};
//---------------------------------------------------------------------------
PlayerClass::PlayerClass()
{
x=2;
y=1;
}
//---------------------------------------------------------------------------
void PlayerClass::DrawPlayer()
{
Buf->Canvas->Brush->Color=clBlack;
Buf->Canvas->Rectangle(x*20,y*20,x*20+20,y*20+20);
}
//---------------------------------------------------------------------------
void PlayerClass::CleanPlayer()
{
Buf->Canvas->Brush->Color=clWhite;
Buf->Canvas->Rectangle(x*20,y*20,x*20+20,y*20+20);
}
//---------------------------------------------------------------------------
void PlayerClass::MovePlayer(int Cells[10][10], Direction dir, TLabel *Label)
{
CleanPlayer();
switch(dir)
        {
        case LEFT: if ((x > 0) && Cells[x - 1][y] != 1) x--; break;
        case UP: if (y > 0 && Cells[x][y - 1] != 1) y--; break;
        case RIGHT: if (x < 20 && Cells[x + 1][y] != 1) x++; break;
        case DOWN: if (y < 20 && Cells[x][y + 1] != 1) y++; break;
        }
DrawPlayer();
Label->Caption=x;
}
//---------------------------------------------------------------------------
void __fastcall DrawField()
{
Form1->Canvas->Draw(0,0,Buf);
Buf->Canvas->Brush->Color=clSkyBlue;
for (int i=0;i<10;i++) //Проектування лабіринту
        {
        for (int j=0;j<10;j++)
                {
                if (Cells[i][j]==1)
                        {
                        Buf->Canvas->Rectangle(j*20,i*20,j*20+20,i*20+20);
                        }
                }
        }
 
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
//ShowCursor (Показать курсор) (False (Лож)) (True (Истина)).
//ShowCursor(false); // Скрываем курсор.
 
BackGround = new Graphics::TBitmap(); // Объявляем новую картинку.
//BackGround->LoadFromFile(".\\BackGround\\BackGround1.bmp"); // Загружаем картинку в область BackGround.
 
Cross = new Graphics::TBitmap(); // Объявляем новую картинку
//Cross->LoadFromFile(".\\Cross\\RedCross.bmp"); // Загрузить картику в область Cross.
//Cross->Transparent = 1;
 
//Width (Ширина).
//Height (Высота).
Buf = new Graphics::TBitmap();  // Объявляем новую область.
Buf->Width=Form1->Width;        // Выравниваем окно области картинки по ширине формы.
Buf->Height=Form1->Height;      // Выравниваем окно области картинки по высоте формы
//
//
 
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
// Enabled (Включено) (false или true) - включаем на всякий случай.
// Interval (Интервал в миллисекундах ) - выставляем 10.
Timer1->Enabled = true;
Timer1->Interval = 10;
 
 
// TPoint (Точка) - позиция.
// mp (MapPoint (Точка на карте)) - позиция на форме.
// ScreenToClient (Экран клиента).
// Mouse (Мышка).
// CursorPos (Cursor Position (Позиция курсора)).
 
TPoint mp=Form1->ScreenToClient(Mouse->CursorPos);
 
// int (Integer (Целое число))
// MouseX - Движение мыши по координате X = Позиции на форме координаты X = 0.
// MouseY - Движение мыши по координате Y = Позиции на форме координаты Y = 0.
int MouseX=mp.x;
int MouseY=mp.y;
 
//Теперь переходим к рисованию на форме.
// Canvas (Холст).
// Draw (Рисовать) - Начинает рисовать по координатам X, Y. в данном случае равные 0.
 
//Buf->Canvas->Draw(0,0,BackGround);
//Buf->Canvas->Draw(MouseX,MouseY,Cross);
 
//Buf->Canvas->Brush->Style=bsCross;
//Buf->Canvas->Rectangle(0,0,Form1->Width-16,Form1->Height-39);
 
DrawField();
}
//---------------------------------------------------------------------------
 
//---------------------------------------------------------------------------
 
 
void __fastcall TForm1::Button1Click(TObject *Sender)
{
DrawField();
}
//---------------------------------------------------------------------------
 
 
//---------------------------------------------------------------------------
 
void __fastcall TForm1::Button2Click(TObject *Sender)
{
PlayerClass Player;
Player.MovePlayer(Cells, UP, Label1);
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::Button4Click(TObject *Sender)
{
PlayerClass Player;
Player.MovePlayer(Cells, LEFT, Label1);
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::Button5Click(TObject *Sender)
{
PlayerClass Player;
Player.MovePlayer(Cells, DOWN, Label1);
}
//---------------------------------------------------------------------------
 
 
void __fastcall TForm1::Button3Click(TObject *Sender)
{
PlayerClass Player;
Player.MovePlayer(Cells, RIGHT, Label1);
}
//---------------------------------------------------------------------------
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
15.03.2014, 23:53
Ответы с готовыми решениями:

Направления движения движения кнопок в игре пятнашки
Ребят подскажите как можно задать перемещение кнопок . по какому признаку или действию Заранее...

Реализация движения в 2D игре на Unity3D
Приветствую! Делаю 2D игру на unity. игрок ходит влево/вправо и прыгает. Возникла проблема с...

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

Слишком быстрое воспроизведение звука и движения в игре
привет всем! у меня в некоторых играх диалог между персонажами происходит почти одновременно, а...

7
1090 / 588 / 121
Регистрация: 11.11.2008
Сообщений: 1,544
19.03.2014, 12:28 2
Лучший ответ Сообщение было отмечено Gelo123321 как решение

Решение

при каждом нажатии кнопки направления, создается новый объект с координатами 2,1
так что движением пока и не пахнет
1
4043 / 2332 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
19.03.2014, 13:29 3
То бишь "PlayerClass Player;" надо объявлять глобально, а не внутри каждого обработчика. Должен быть всего один экземпляр класса PlayerClass в твоей программе. Ну, поначалу по крайней мере...

И не забываем про деструктор формы или событие OnClose, где нужно освобождать все, что навыделяли с помощью new в событии FormCreate или конструкторе формы...
1
22 / 22 / 8
Регистрация: 05.01.2012
Сообщений: 282
21.03.2014, 23:34  [ТС] 4
BRcr, я уже смог сам разобраться в своей ошибке, все дело было в переменних х и у, которые были обьявлени в классе, а надо было их обьявить как глобальные переменные. Но все равно спасибо за внимание. А что там по поводу освобождения? Что именно надо освобождать?

Добавлено через 19 секунд
И как именно?


Добавлено через 16 секунд
AntonChik, да, все дело было именно в х и у, спасибо.
0
4043 / 2332 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
22.03.2014, 06:51 5
Я правильно понимаю, что код сейчас выглядит как-то так?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
int x, y;
 
class PlayerClass //Клас персонажу
{
 
public:
PlayerClass();
void DrawPlayer();
void CleanPlayer();
void MovePlayer(int Cells[10][10], Direction dir,TLabel *Label);
};
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
PlayerClass Player;
Player.MovePlayer(Cells, UP, Label1);
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::Button4Click(TObject *Sender)
{
PlayerClass Player;
Player.MovePlayer(Cells, LEFT, Label1);
}
//---------------------------------------------------------------------------
Если да, то это все равно неправильно, хоть и отрабатывает.

А освобождать надо вот это:
C++
1
2
3
BackGround = new Graphics::TBitmap(); // Объявляем новую картинку. 
Cross = new Graphics::TBitmap(); // Объявляем новую картинку
Buf = new Graphics::TBitmap();  // Объявляем новую область.
1
22 / 22 / 8
Регистрация: 05.01.2012
Сообщений: 282
22.03.2014, 13:26  [ТС] 6
BRcr, и как именно освобождать битмапи? И разве после закрития Программи они не очистятся?
Код сейчас виглядит иначе. Потом скину, как зайду с пк.
0
4043 / 2332 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
22.03.2014, 18:53 7
Цитата Сообщение от Gelo123321 Посмотреть сообщение
и как именно освобождать битмапи? И разве после закрития Программи они не очистятся?
И после закрытия и очистятся - но после завершения процесса, а не после закрытия формы. Если форма главная и единственная и если битмапы нужны все время, то можно и не освобождать... но в любом случае лучше взять себе за правило, выделил память - освободи ее, так будет меньше проблем в будущем. А еще лучше использовать std::auto_ptr или unique_ptr, если есть возможность.

Как освобождать, в любой книжке по с++ написано...
C++
1
2
3
delete BackGround;
delete Cross;
// и тд...
1
1090 / 588 / 121
Регистрация: 11.11.2008
Сообщений: 1,544
24.03.2014, 05:30 8
Цитата Сообщение от Gelo123321 Посмотреть сообщение
все дело было в переменних х и у, которые были обьявлени в классе, а надо было их обьявить как глобальные переменные.
неверно мыслите. вообще остерегайтесь и старайтесь избегать глобальности.
правильнее оставить x,y в классе PlayerClass, а Player объявить в классе формы.
0
24.03.2014, 05:30
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.03.2014, 05:30
Помогаю со студенческими работами здесь

Можно ли установить колебания движения курсора в 2d игре?
Курсор выглядит как круглый прицел.Возможно ли сделать так,чтобы после перемещения он не сразу...

Как нарисована гибкая линия маршрута движения главного круглишка в игре Osmos?
Как нарисована гибкая линия маршрута движения главного круглишка в игре Osmos? ...

Передвижение объекта в игре
В моей игре объект(бот) передвигаеться с помощью таймера(pygame.time.set_timer()) каждые 10...

Исследование движения объекта
Необходимо найти функцию расстояния (d) между положением объекта при движении по прямолинейной...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru