Просмотр полной версии : Изометрия и механизм определения столкновения в играх
writerer
22.05.2006, 01:28
Здравствуйте!
Каков принцип написания подобных вещей:
в изометрии представлено некое пространство и там клавишами курсора перевигаем объект, а из хмл грузится инфа о том, где есть какие стены или другие объекты, и этот наш объект знает что нельзя пройти сквозь стену и пр.
---------
хотелось бы хотябы в общих чертах. или может какие примеры есть или сырцы
ну например так :D
this._y += 40;
{/* Шаблон пола */
this.createEmptyMovieClip ("p", 0);
p.createEmptyMovieClip ("p0", 0);
p.p0._alpha = 25;
p.p0.lineStyle (0, 0xCFCFCF);
p.p0.beginFill (0x9F9F9F, 100);
p.p0.moveTo (0, -20);
p.p0.lineTo (40, 0);
p.p0.lineTo (0, 20);
p.p0.lineTo (-40, 0);
p.p0.lineTo (0, -20);
p.p0.endFill ();
}
{/* Шаблон стены */
this.createEmptyMovieClip ("w", 2);
w.createEmptyMovieClip ("w0", 0);
w.w0._alpha = 50;
w.w0.lineStyle (0, 0x666666);
w.w0.beginFill (0xB6DADA, 100);
w.w0.moveTo (0, -40);
w.w0.lineTo (40, -20);
w.w0.lineTo (0, 0);
w.w0.lineTo (-40, -20);
w.w0.lineTo (0, -40);
w.w0.endFill ();
w.w0.beginFill (0x7CBEBD, 100);
w.w0.moveTo (0, 0);
w.w0.lineTo (40, -20);
w.w0.lineTo (40, 0);
w.w0.lineTo (0, 20);
w.w0.lineTo (0, 0);
w.w0.endFill ();
w.w0.beginFill (0x99CCCC, 100);
w.w0.moveTo (0, 0);
w.w0.lineTo (-40, -20);
w.w0.lineTo (-40, 0);
w.w0.lineTo (0, 20);
w.w0.lineTo (0, 0);
w.w0.endFill ();
w.w0.duplicateMovieClip("m",1500);
new Color (w.m).setTransform ({gb:-153, bb:-246});
w.m._alpha = 100
}
a = []; gb = []
for (i = 0; i < 10; i++){
a[i] = [];
for (j = 0; j < 10; j++) {
a[i][j] = 1;
if (!(i == 0 and j == 0)) {
p.p0.duplicateMovieClip ("p" + (i * 10 + j), i * 10 + j);
bb = random (20);
if ((i == 0 or j == 0 or i == 9 or j == 9 or bb < 3) and !(i == 1 and j == 1)) {
a[i][j] = 1;
w.w0.duplicateMovieClip ("w" + (i * 10 + j), j * 10 - i);
} else if (bb == 5){
p["p" + (i * 10 + j)]._alpha = 100;
a[i][j] = 2;
} else {
gb[gb.length] = [40 + i * 40 + j * 40,200 - i * 20 + j * 20]
a[i][j] = 0;
}
}
p["p" + (i * 10 + j)]._x = w["w" + (i * 10 + j)]._x = 40 + i * 40 + j * 40;
p["p" + (i * 10 + j)]._y = w["w" + (i * 10 + j)]._y = 200 - i * 20 + j * 20;
}
}
k = [];
k[37] = [-40, 20];
k[38] = [-40, -20];
k[39] = [40, -20];
k[40] = [40, 20];
w.m._x = 120;
w.m._y = 200;
w.m.swapDepths ((2 * w.m._y + w.m._x - 440) / 8 - (2 * w.m._y + w.m._x - 440) / 80 + (w.m._y - 200) / 20);
w.m.onKeyUp = function () {
if (k[Key.getCode ()] and a[(2 * (this._y + k[Key.getCode ()][1]) + (this._x + k[Key.getCode ()][0]) - 440) / 80 - ((this._y+ k[Key.getCode ()][1]) - 200) / 20][(2 * (this._y + k[Key.getCode ()][1]) + (this._x + k[Key.getCode ()][0]) - 440) / 80] != 1) {
this._x += k[Key.getCode ()][0];
this._y += k[Key.getCode ()][1];
if (a[(2 * this._y + this._x - 440) / 80 - (this._y - 200) / 20][(2 * this._y + this._x - 440) / 80] == 2) {
r = random (gb.length);
this._x = gb[r][0];
this._y = gb[r][1];
}
this.swapDepths ((2 * this._y + this._x - 440) / 8 - (2 * this._y + this._x - 440) / 80 + (this._y - 200) / 20);
}
}
Key.addListener (w.m);
по скольку данный код был адаптирован под конкурс swf<1024 байта, то сжимал все что только можно было
Cvazimodo
22.05.2006, 14:52
http://vl.nn.ru/graf/test_graf.html
Вчера только повернул карту (изометрия).
writerer
22.05.2006, 22:35
to iNils:
Спасиба. буду разбираться....
если можно хотябы немножко коментариев добавьте ))
to Cvazimodo:
красива...
а может кто-нибудь ещё набросает алгоритм ... вкратце так .. ))
если можно хотябы немножко коментариев добавьте ))
http://www.flasher.ru/forum/showthread.php?t=78628&highlight=offset
Cvazimodo
22.05.2006, 23:59
Я делаю так (в моём примере):
есть админка для рисования карт, там каждой клетке соответствуют 8 клеток соседей (это максимум; для крайних клеток, естественно, меньше). Сохраняется в виде XML (как не буду говорить, это понятно).
Для тех клеток, на которых есть препятствие я не ставлю ссылки на "соседей" и от "соседей", соответственно, на эту клетку тоже не ставлю ссылку.
Это всё идёт в клиентскую часть. Есть массив (одномерный) объектов, типа:
var Relations:Array = new Array();
Relations[0].id = "cell_10"; // уникальное имя для ячейки. зачем делал - не помню :)
Relations[0].children = new Array(); // массив "соседей" - клеток, на которые я могу перейти.
Relations[0].children[0].id // уникальное имя для ячейки-соседа
Это примерный пример структуры. Можно оптимизировать, можно изменить, просто я делал разными алгоритмами пока не выбрал самый быстрый.
Не понятно зачем хранить ссылки на соседей, они и так ясны.
Cvazimodo
23.05.2006, 12:00
Не понятно зачем хранить ссылки на соседей, они и так ясны.
Если рядом стоит стена, то ссылки на неё нет, соответственно эта ячейка и не проверяется. Примерно 35% ячеек заставлены (в моём примере), соответственно во всех циклах меньшее количество клеток идёт на проверку. Якобы быстрее... (не факт).
К тому же, у меня одномерный массив, в нём тяжело определить ряд и колонку :) Все координаты этих ячеек формируются один раз в админке (при рисовании карты) и в клиенте просто подгружаются в указанные места без дополнительных расчетов.
К тому же, используя систему "ячейка-сосед" можно делать большие переходы (ака телепортация)...
В общем, мне так захотелось, это моя первая работа в подобном направлении, возможно и не самая правильная.
Если рядом стоит стена, то ссылки на неё нет, соответственно эта ячейка и не проверяется. Примерно 35% ячеек заставлены (в моём примере), соответственно во всех циклах меньшее количество клеток идёт на проверку. Якобы быстрее... (не факт).
К тому же, у меня одномерный массив, в нём тяжело определить ряд и колонку :) Все координаты этих ячеек формируются один раз в админке (при рисовании карты) и в клиенте просто подгружаются в указанные места без дополнительных расчетов.
К тому же, используя систему "ячейка-сосед" можно делать большие переходы (ака телепортация)...
В общем, мне так захотелось, это моя первая работа в подобном направлении, возможно и не самая правильная.
Посмотри мой пример в посте 2, при минимуме кода, там даже телепорты есть и проверки на стены.
Cvazimodo
23.05.2006, 14:09
Действительно, очень хороший пример. Спорить глупо :)
Если не возражаете, некоторые вещи позаимствую (может быть). Я, правда, до конца не разобрался, на работе тяжело отвлекаться. Дома вот попробую "разобрать" этот код по частям.
Нет предела оптимизации :)
Обалденно.
не знаю сколько сотен строк кода я бы потратил на это :-)
Научите простой веще, пожалуйста! я это делал, но забыл!
Значит есть кадрат. надо квадрат повернуть на 45 градусов и сжать по вертикали (после поворота). кажется я это делал дублируя один клип внутрь другого и потом сжимая, но сейчас не получается...
Ground1 - квадрат, не повернутый на 45%
duplicateMovieClip("Ground1","mc" + i, i);
setProperty("mc" + i, _rotation, 45); // повернули в изометрический вид
setProperty("mc" + i, _height,100); // сжали по вертикали.
setProperty("mc" + i, _width, 200); //
setProperty("mc" + i, _x, xx);
setProperty("mc" + i, _y, yy);
Вот так - он сжимается неправильно.
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.