Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 16.01.2015, 03:08
Интересующийся
Отправить личное сообщение для Noobloid Посмотреть профиль Найти все сообщения от Noobloid
 
Регистрация: 16.01.2015
Сообщений: 23

Нужен совет по псевдо 3D игрушке
Привет сижу дома, от нефиг делать мучу игрушку. Ссылка(спрайты весят 15 Mb, нужно подождать пока откроет). Проблема с которой столкнулся- карявое отображение движущихся объектов. На фоне "плиток переднего плана".
Попробую объяснить человеческим языком. Картанка состоит из 3-х канвасов наложенных друг на друга, каждый канвас составлен из "плиток". На заднем плане трава, камни и т.д. На переднем плане - дом и деревья. Между ними- коровы паладины и хз что ещё. Когда корова движется и заходит за дом с верху- она как и задумано теряется из вида, но когда она подходит с низу- то она сцуко залазит под дом.
Редактор состоит из 5 глобалльных объектов
var imgObj = {};//картинки
var canObj = {};//канвасы
var unitObj = {};//движущиеся спрайты отображённые на экране(направление, текуший номер картинки в спрайте, позиция и т.д.)
var spriteObj = {};//инструкция по нарезке unitObj с imgObj (размеры фреймов, исходный img fail и т.д.)
var levelObj = {};//сама карта или левел, состоит из масива отдельных плиток, одно из свойств плитки- z-index канваса на котором она будет печататся. Второй массив- walkareas -collision detection lines.

Все объекты кроме канвасов загружаются с XML файлов
Верхний и нижний канвасы нарезаются при запуске игры и не меняются(если не тыркатся с плитками через редактор). Для загрузки используется функци:
function loadLevel() {
   canObj.canvas0.ctx.clearRect(0, 0, canObj.canvas0.canvas.width, canObj.canvas0.canvas.height);
   canObj.canvas5.ctx.clearRect(0, 0, canObj.canvas5.canvas.width, canObj.canvas5.canvas.height);
   canObj.canvas0.canvas.height = levelObj.level.size.x;
   canObj.canvas0.canvas.width = levelObj.level.size.y;
   canObj.canvas5.canvas.height = levelObj.level.size.x;
   canObj.canvas5.canvas.width = levelObj.level.size.y;
   for (var i in levelObj.level.map.tile) {
      var zisTile = levelObj.level.map.tile[i];
      if (zisTile.z_index === 0) {
         var ctx = canObj.canvas0.ctx;
      }else if (zisTile.z_index === 5) {
         var ctx = canObj.canvas5.ctx;
      }
      
      drowTile(zisTile, ctx, levelObj.level.map.tile[i].tilex, levelObj.level.map.tile[i].tiley);
   }

}

function drowTile(tile, ctx, ix, iy) {
   //console.log(ctx);
   ctx.drawImage(imgObj[tile.tileimg.obj],
      spriteObj[tile.tileimg.obj][tile.tileimg.sprtype].sx + spriteObj[tile.tileimg.obj].width * tile.tileimg.x,
      spriteObj[tile.tileimg.obj][tile.tileimg.sprtype].sy + spriteObj[tile.tileimg.obj].height * tile.tileimg.y,
      160,
      spriteObj[tile.tileimg.obj][tile.tileimg.sprtype].sheight,
      ix,
      iy,
      160,
      spriteObj[tile.tileimg.obj][tile.tileimg.sprtype].sheight);
}

Рендеринг производится с помощью requestAnimationFrame() которая дёргат функцию update() и через неё stopMoving()
function update(dt, now){
        
        canObj.canvas1.ctx.clearRect(0, 0, canObj.canvas1.canvas.width, canObj.canvas1.canvas.height);
        for(var i in unitObj){
                    if (unitObj[i].vy === 0 && unitObj[i].vx === 0) {
                        unitObj[i].action = "neutral";
                    }
                    if ((now - unitObj[i].framestart)>unitObj[i].spr[unitObj[i].action].framerate){
                        
                        unitObj[i].framestart = now;
                        if (unitObj[i].framenumber < unitObj[i].spr[unitObj[i].action].numberofframes) {
                            unitObj[i].framenumber++;
										var context = canObj.canvas2.canvas.getContext('2d');

										var position = $(canObj.canvas2.canvas).position();
										var x = unitObj[i].x + unitObj[i].vx;
										var y = unitObj[i].y + unitObj[i].vy;
 //проверяем столкновение с colision lines

										for (var j in levelObj.level.walkareas) {
										  levelObj.level.walkareas[j].mouseover = false;
										  var initx = levelObj.level.walkareas[j].initx;
										  var inity = levelObj.level.walkareas[j].inity;
										  var lastx = levelObj.level.walkareas[j].lastx;
										  var lasty = levelObj.level.walkareas[j].lasty;
										 


										  var ang = Math.atan2((inity - lasty), (initx - lastx));
										  context.beginPath();
										  context.arc(initx, inity, 5, ang - Math.PI/2, ang +Math.PI/2);
										  context.arc(lastx, lasty, 5, ang + Math.PI/2, ang -Math.PI/2, false);
										  context.closePath();
										  if (context.isPointInPath(x, y)) {
											unitObj[i].vx = 0;
                							unitObj[i].vy = 0;
											return;
										}

										}
                            
                            
                            

                            //////////////////////////
                            
                            unitObj[i].x+=unitObj[i].vx;
                            unitObj[i].y+=unitObj[i].vy;
                            }else {
                                unitObj[i].framenumber=0;}
                        }
                        //console.log(unitObj[i].framenumber);
                        canObj.canvas1.ctx.drawImage(imgObj[unitObj[i].type],
                                                    (unitObj[i].spr[unitObj[i].action][unitObj[i].direction].sx)+unitObj[i].framenumber*(unitObj[i].spr[unitObj[i].action].swidth),
                                                    (unitObj[i].spr[unitObj[i].action][unitObj[i].direction].sy),
                                                    (unitObj[i].spr[unitObj[i].action].swidth),
                                                    (unitObj[i].spr[unitObj[i].action].sheight),
                                                    unitObj[i].x - (unitObj[i].spr[unitObj[i].action].width)/2,
                                                    unitObj[i].y - (unitObj[i].spr[unitObj[i].action].height)/2,
                                                    (unitObj[i].spr[unitObj[i].action].width),
                                                    (unitObj[i].spr[unitObj[i].action].height));
        stopMoving(i);
        }
    }
    function backgroundRendering(i) {
        //code
    }
    function stopMoving(i){
        if (unitObj[i].vx!==0 || unitObj[i].vy!==0) {//if moving
            //moving up left
            if ((unitObj[i].vx<=0 && unitObj[i].vy<=0) && ((unitObj[i].x <= unitObj[i].destX) || (unitObj[i].y <= unitObj[i].destY))) {
                unitObj[i].vx = 0;
                unitObj[i].vy = 0;
            }
            //moving up right
            if ((unitObj[i].vx>=0 && unitObj[i].vy<=0) && ((unitObj[i].x >= unitObj[i].destX) || (unitObj[i].y <= unitObj[i].destY))) {
                unitObj[i].vx = 0;
                unitObj[i].vy = 0;
            }
            //moving down right
            if ((unitObj[i].vx>=0 && unitObj[i].vy>=0) && ((unitObj[i].x >= unitObj[i].destX) || (unitObj[i].y >= unitObj[i].destY))) {
                unitObj[i].vx = 0;
                unitObj[i].vy = 0;
            }
            //moving down left
            if ((unitObj[i].vx<=0 && unitObj[i].vy>=0) && ((unitObj[i].x <= unitObj[i].destX) || (unitObj[i].y >= unitObj[i].destY))) {
                unitObj[i].vx = 0;
                unitObj[i].vy = 0;
            }
        }
    }
}


С такой структурой игрушки решить проблему с коровой прячушейся под дом не решить, нужно что-то менять .
Рассматривал следующие варианты:
перемещять плитки дама на задний план если вектор движения коровы(как звучит ) под определённым углом и её позиция... это бред потому что двигатся должна не только корова, и если несколько коров будут подходить к дому с разных сторон получится месево.
второй вариант(вроде должен работать)- добавить ещё 1-н канвас поверх уже существующих и рендерить коров в зависимости от их положения относительно дома на 2-м или 4-м канвасе
Но вот что до меня не доходит так это к которой точке на спрайте коровы нужно будет привязать Collision detection, либо если эта точка должна меняться- то по какому принципу?
Ответить с цитированием
  #2 (permalink)  
Старый 16.01.2015, 03:51
Профессор
Отправить личное сообщение для caetus Посмотреть профиль Найти все сообщения от caetus
 
Регистрация: 23.09.2014
Сообщений: 197

diablo ))
Ответить с цитированием
  #3 (permalink)  
Старый 16.01.2015, 03:54
Интересующийся
Отправить личное сообщение для Noobloid Посмотреть профиль Найти все сообщения от Noobloid
 
Регистрация: 16.01.2015
Сообщений: 23

Если кто поможет то возможно диабло и будет, кстати если у каго не открывается или зависае браусер- напишите плз с чего сидите(ОС и броуер)

Последний раз редактировалось Noobloid, 16.01.2015 в 04:27.
Ответить с цитированием
  #4 (permalink)  
Старый 16.01.2015, 13:33
Любитель
Отправить личное сообщение для JsLoveR Посмотреть профиль Найти все сообщения от JsLoveR
 
Регистрация: 16.12.2009
Сообщений: 422

Необходимо хранить карту в виде матрицы, где указывать проходимые и непроходимые пути: 0 - свободно, 1 - занято(к примеру) . Для поиска пути и обхода препятствий использовать какой-нибудь матричный алгоритм(А* к примеру). Дом обозначить как непроходимую зону, чтобы можно было обойти.
Далее, необходимо сортировать по-вложенности объекты динамического холста, чтобы если герой находится между 2-х деревьев, где первое - впереди героя, второе - позади. Первое дерево перекрывает героя, а второе-перекрывается уже им самим.
Советую выкинуть эти наброски и начать заново с нуля.

Последний раз редактировалось JsLoveR, 16.01.2015 в 13:35.
Ответить с цитированием
  #5 (permalink)  
Старый 16.01.2015, 14:48
Интересующийся
Отправить личное сообщение для Noobloid Посмотреть профиль Найти все сообщения от Noobloid
 
Регистрация: 16.01.2015
Сообщений: 23

1- матрица хранится в levelObj.level.map, там 775 плиток сложено грузится с level.xml.
Плитки по вложенности отсортированны и отображаются правильно- на нулевой или пятый канвас, всё это редактируется с редактора(открывается с кропки Settings->Tile property editor->Activate Selector. Кликаем на сам канвас и видим плитки которые привязаны к этому участку матрицы, удаляем, добавляем, меняем z-index).
Проходные пути можно подсветить с Settings->Walking Areas->Highlight Stop Lines: ON.
причина по которой не привязывал пути к самим плиткам- плитка прямоугольная а картинка на ней в виде ромба или же в 10 раз выше самого прямоугольнака на катором она сидит(Settings->Background tiles->a1outdoorwals).

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

Вопрос если к герою бегут мобы то дерево которое на переднем плане долно быть подрисованно(z-index) под которого из этих мобов или под героя или перерисовывать его по (60 fps*5units = 300) раз в секунду вместе с обоими канвасами, потому что зачистить только 1 квадрат не получится?

3- Попробую ещё раз пояснить проблему, дерево на переднем плане сейчас намертво привязано к 5-му канвасу, и отображается поверх коровы(героя) когда тот движется вывше основания дерева всё ок, когда ниже- голова будет зазить под дерево. Перерисовывать дерево не вариант по причинам изложеннвм в пункте 2, нужно добавлять ещё 1-н канвас и переносить рендеринг героя(или других спрайтов) поверх всего что есть, но только на время пока его позиция "ниже" дерева или стены или дома... И собственно вопрос- от которых точкек на спрайте героя и плики отсчитывать этоп перенос и как их вычислять?
Ответить с цитированием
  #6 (permalink)  
Старый 16.01.2015, 15:23
Любитель
Отправить личное сообщение для JsLoveR Посмотреть профиль Найти все сообщения от JsLoveR
 
Регистрация: 16.12.2009
Сообщений: 422

Проблема в том, что привязка должна быть к матрице и только к ней. Какое ей дело в каком виде она представлена пользователю? Хоть в чистом 3д. Переводи ромб в прямоугольник выровненный по осям. Так ты сможешь получить необходимый индекс для прямоугольной матрицы. Ты не сдвинешься с места пока не организуешь нормальную логику.
Модели должно быть до лампочки каким образом её отображает представление.

Последний раз редактировалось JsLoveR, 16.01.2015 в 15:25.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Хочу победить jimbo конструктор. Нужен Ваш совет FlyerCyber Элементы интерфейса 0 04.10.2014 15:50
Не работает скрипт нужен совет Suro Общие вопросы Javascript 2 11.01.2014 22:50
Нужен совет по click(function) Jomhan jQuery 6 07.12.2013 00:41
Выделение активного пункта меню. Нужен совет! kirian222 Элементы интерфейса 14 17.10.2013 02:50
нужен совет по оптимизации кода выпадающего меню! Arkinsstoun jQuery 5 18.06.2012 15:33