Как сделать?
…
Millstream,
я имела в виду окно “Выполнить при посещении”, которое справа находится.
Итак. Есть нпс, они передвигаются по карте. Игрок тоже передвигается по карте и все передвижения отслеживаются через координаты. x[индекс] y[индекс] z[индекс]. Сам индекс означает номер нпс, все массивы устроены таким образом что индекс и определяет нпс. Например $name[i]это имя нпс с индексом i. you это индекс который обозначает главного героя.
Есть массив areatipe[’<<X[you]>>,<<Y[you]>>’] если его значение больше 0 то этот массив пригоден для передвижения, например 1 это поле, 2 лес итд итп. Если значение равно 0, то это море и передвигаться по нему нельзя.
Огромная проблема даже не с отслеживанием нпс, а с тем ,что бы можно было составить список нпс на локации.
Вот например
Spoiler
$areaNPCsResult = ""
areaNPCsLoop_i = 1
:areaNPCsLoop
if X[areaNPCsLoop_i] = X[you] and Y[areaNPCsLoop_i] = Y[you] and Z[areaNPCsLoop_i] = Z[you] and areaNPCsLoop_i!you:
if npcIsDead[areaNPCsLoop_i] = 0 :
$areaNPCsResult += "<br>"
$areaNPCsResult += "<a href='exec: gt""androidWithIndex"", <<areaNPCsLoop_i>>'><b><<$name[areaNPCsLoop_i]>></b></a>"
end
end
areaNPCsLoop_i += 1
if areaNPCsLoop_i < arrsize('X'): jump 'areaNPCsLoop'
if $areaNPCsResult!'':"Тут: <<$areaNPCsResult>>"
Этот код прогоняет в лоб всех нпс и выводит их на экран. Но этот способ не применим если нпс очень много например на моем компе 3500 нпс уже сильно тормозят комп. И самое главное, при использовании этого способа нпс слепые, совершенно не возможно никаким образом передать нпс список других нпс на локации. Если начать для каждого нпс прогонять весь список нпс что бы выяснить кто на локации то кусп зависает намертво. Но даже если обойти эту проблему, то это все равно не выход, так как нпс должны обрабатывать встречи не только в той локации где расположен игрок.
Я решил сделать какое то отслеживание в механизме передвижения. Вот сам механизм передвижения нпс.
Spoiler
if i>=total_npc:i = 1
poisk_error=0
:moveNPCsLoop
cikl_npc_max-=1
if npcIsDead[i] = 0 and i!you:
oldX[i]=X[i]
oldY[i]=Y[i]
oldZ[i]=Z[i]
:mark_terrain_end
napravlenie=rand(0,7)
if napravlenie=0:
if areatipe['<<X[i]>>,<<Y[i]+1>>']>0:
!север
X[i]=X[i]
Y[i]=Y[i]+1
else
poisk_error+=1
if poisk_error<50:
jump'mark_terrain_end'
else
stop_move=1
end
end
end
if napravlenie=1:
if areatipe['<<X[i]-1>>,<<Y[i]>>']>0:
!запад
X[i]=X[i]-1
Y[i]=Y[i]
else
poisk_error+=1
if poisk_error<50:
jump'mark_terrain_end'
else
stop_move=1
end
end
end
if napravlenie=2:
if areatipe['<<X[i]+1>>,<<Y[i]>>']>0:
!восток
X[i]=X[i]+1
Y[i]=Y[i]
else
poisk_error+=1
if poisk_error<50:
jump'mark_terrain_end'
else
stop_move=1
end
end
end
if napravlenie=3:
if areatipe['<<X[i]>>,<<Y[i]-1>>']>0:
!юг
X[i]=X[i]
Y[i]=Y[i]-1
else
poisk_error+=1
if poisk_error<50:
jump'mark_terrain_end'
else
stop_move=1
end
end
end
if napravlenie=4:
if areatipe['<<X[i]-1>>,<<Y[i]+1>>']>0:
!северо запад
X[i]=X[i]-1
Y[i]=Y[i]+1
else
poisk_error+=1
if poisk_error<50:
jump'mark_terrain_end'
else
stop_move=1
end
end
end
if napravlenie=5:
if areatipe['<<X[i]+1>>,<<Y[i]+1>>']>0:
!северо восток
X[i]=X[i]+1
Y[i]=Y[i]+1
else
poisk_error+=1
if poisk_error<50:
jump'mark_terrain_end'
else
stop_move=1
end
end
end
if napravlenie=6:
if areatipe['<<X[i]-1>>,<<Y[i]-1>>']>0:
!юго запад
X[i]=X[i]-1
Y[i]=Y[i]-1
else
poisk_error+=1
if poisk_error<50:
jump'mark_terrain_end'
else
stop_move=1
end
end
end
if napravlenie=7:
if areatipe['<<X[i]+1>>,<<Y[i]-1>>']>0:
!юго восток
X[i]=X[i]+1
Y[i]=Y[i]-1
else
poisk_error+=1
if poisk_error<50:
jump'mark_terrain_end'
else
stop_move=1
end
end
end
dynamic $dy_main_move
end
if i < ARRSIZE('X') and cikl_npc_max>0: jump 'moveNPCsLoop'
Динамик dynamic $dy_main_move должен был по идее работать следующим образом. Добавлять нпс который переместился в массив на новой локации и удалять его со старой. Попробовал 2 версии, но получается какая то чушь.
Spoiler
1я версия
$dy_main_move={
if stop_move=0:
!удаление со старой локации
oldlocnpctime=locnpc['<<oldX[i]>>,<<oldY[i]>>,<<oldZ[i]>>']
locnpcnum['<<oldX[i]>>,<<oldY[i]>>,<<oldZ[i]>>,<<oldlocnpctime>>']=0
n=loknpcpor['<<oldX[i]>>,<<oldY[i]>>,<<oldZ[i]>>,<<oldlocnpctime>>']
t=locnpcnum['<<oldX[i]>>,<<oldY[i]>>,<<oldZ[i]>>,<<oldlocnpctime>>']
killvar 'loknpcpor',n
killvar 'locnpcnum',t
locnpc['<<oldX[i]>>,<<oldY[i]>>,<<oldZ[i]>>']-=1
!создание на новой локации
locnpc['<<X[i]>>,<<Y[i]>>,<<Z[i]>>']+=1
locnpctime=locnpc['<<X[i]>>,<<Y[i]>>,<<Z[i]>>']
loknpcpor['<<X[i]>>,<<Y[i]>>,<<Z[i]>>,<<locnpctime>>']=locnpctime
locnpcnum['<<X[i]>>,<<Y[i]>>,<<Z[i]>>,<<locnpctime>>']=i
else
stop_move=0
X[i]=oldX[i]
Y[i]=oldY[i]
Z[i]=oldZ[i]
end
}
И когда эта версия не сработала, то попробовал решить задачу в лоб.
$dy_main_move={
if stop_move=0:
!удаление со старой локации
oldlocnpctime=locnpc['<<oldX[i]>>,<<oldY[i]>>,<<oldZ[i]>>']
locnpcnum['<<oldX[i]>>,<<oldY[i]>>,<<oldZ[i]>>,<<oldlocnpctime>>']=0
loknpcpor['<<oldX[i]>>,<<oldY[i]>>,<<oldZ[i]>>,<<oldlocnpctime>>']=0
!создание на новой локации
locnpc['<<X[i]>>,<<Y[i]>>,<<Z[i]>>']+=1
locnpctime=locnpc['<<X[i]>>,<<Y[i]>>,<<Z[i]>>']
loknpcpor['<<X[i]>>,<<Y[i]>>,<<Z[i]>>,<<locnpctime>>']=locnpctime
locnpcnum['<<X[i]>>,<<Y[i]>>,<<Z[i]>>,<<locnpctime>>']=i
else
stop_move=0
X[i]=oldX[i]
Y[i]=oldY[i]
Z[i]=oldZ[i]
end
}
Отслеживал нпс кроме базового способа методом перебора еще так
Spoiler
$areaNPC=''
if locnpc['<<X[you]>>,<<Y[you]>>,<<Z[you]>>']>0:
loknpc_p=locnpc['<<X[you]>>,<<Y[you]>>,<<Z[you]>>']
cikl_lnp=loknpc_p
:markcikllnp
cikl_res=locnpcnum['<<X[you]>>,<<Y[you]>>,<<Z[you]>>,<<cikl_lnp>>']
if $name[cikl_res]>0:$areaNPC += "<a href='exec: gt""androidWithIndex"", <<cikl_res>>'><b><<$name[cikl_res]>></b></a>
"
cikl_lnp-=1
if cikl_lnp>0:jump'markcikllnp'
'<<$areaNPC>>'
end
И так
Spoiler
testcikl=0
i=0
$areaNPCs=''
cikl=locnpc['<<X[you]>>,<<Y[you]>>,<<Z[you]>>']
:mark_i
if locnpcnum['<<X[you]>>,<<Y[you]>>,<<Z[you]>>,<<i>>']>0:
is=locnpcnum['<<X[you]>>,<<Y[you]>>,<<Z[you]>>,<<i>>']
if X[you]=X[is] and Y[you]=Y[is] and Z[you]=Z[is]:
$areaNPCs += "<br>"
$areaNPCs += "<a href='exec: gt""androidWithIndex"", <<is>>'><b><<$name[is]>></b></a>"
end
end
i+=1
testcikl+=1
if i<cikl:jump'mark_i'
'<<$areaNPCs>>'
'<<testcikl>> прогонов'
И оба эти способы получились не очень. 1й способ очень часто либо не видит какого то нпс, либо видит нпс который уже давно ушел с локации. А второй способ не чуть не лучше решения в лоб, количество циклов в нем слишком велико, для того, что бы использовать его.
Подскажите, как сделать вменяемое отслеживание нпс, таким образом, что бы был постоянно четкий список нпс находящихся на локации. Тут нужен какой то массив, куда будет передаваться индекс нпс, и при этом должны будут хранится и координаты локации. Так же нужно удалять из этого массива нпс который ушел и добавлять этого нпс в массив на новой локации. И иметь способ быстро получить доступ ко всем индексам нпс находящимся на локации.
Вложил файл в котором и есть весь код ,если с объяснений не будет понятно.
igra.qsp
Ллур,
Ну и схема, как ты это понял?
Oliver:
Ллур,
Ну и схема, как ты это понял?
Да ничего сложного. Все на одной локации и отображение происходит тогда ,когда координаты героя и нпс совпадают. Такой же принцип и у описания локации и у домов. Все работает через координаты. Но не выходит сделать систему которая бы создавала список нпс на локации. Я плаваю в работе с массивами. Недостаток образования сказывается.
Moran,
выложи свой генератор. Разберёмся.
Lisichka,
у тебя неправильная ссылка в сообщении 2790.
Ллур,
зачем тебе столько нпс? Что за игру ты делаешь, что тебе понадобилось такое количество действующих персонажей?
В любом случае, разобраться в твоей задачке — выше способностей моего интеллекта. Дождись, пожалуйста, когда тебе ответит кто-нибудь из экспертов (Byte, Nex, werewolf, Olegus t.Gl., Aleks Versus или, может быть, Mioirel вернётся…)
Удачи!
snail:
Ллур,
зачем тебе столько нпс? Что за игру ты делаешь, что тебе понадобилось такое количество действующих персонажей?
Да обыкновенная рпг, где нпс шарахаются по местности и лупят друг друга. Кого лупить и с кем дружить можно определить фракциями. Что плохого если будет рпг в которой все противники не статичны, а передвигаются по местности и могут качаться вместе с героем? Объединятся в пати, лазить по данжам. Практически новое слово в рпг. А если учесть что те же нпс могут и динамически изменять местность, например строить дома итд. Да и саму карту без труда можно сделать генерируемой, или заранее прописанной или скомбинировать оба способа. Да еще учесть что всех нпс можно наделить системами при помощи которых можно будет взаимодействовать, то есть разговаривать, учится у них или обучать, торговать или враждовать, дружить или ненавидеть. К тому же сама система предполагает возможность в любое время взять под управление любого нпс, для этого всего лишь нужно сменить номер идентификатора you. То игра получится такой ,какой еще не было никогда.
Ллур,
Может я, конечно, не разобралась в задаче, но, я бы делала так - масив нпц и изначальные места их расположения. Нужны ещё функции обработки перемещения, разумеется в зависимости от условий. К примеру, у меня в зеркалах каждый нпц может перемещаться по нескольким локациям в зависимости от надобности. К примеру, травница может уйти в лес за травами, или к подруге на чай. Обработка идёт в локации онньюлок - там я размещаю функция движения нпц и проверочный цикл, в зависимости от локации, на которой мы находимся вывожу результаты.
У тебя может быть состояние игры, когда все 3500 нпц и герой находятся на одно локации? Подумай, наверняка они так же не могут у тебя бродить везде. Это ни к чему. Лучше разбить их на группы, вроде, город, деревня, лес, может с переносом из группы в группу, но тогда в любом случае обработка станет легче.
Ajenta:
Ллур,
Может я, конечно, не разобралась в задаче, но, я бы делала так - масив нпц и изначальные места их расположения. Нужны ещё функции обработки перемещения, разумеется в зависимости от условий. К примеру, у меня в зеркалах каждый нпц может перемещаться по нескольким локациям в зависимости от надобности. К примеру, травница может уйти в лес за травами, или к подруге на чай. Обработка идёт в локации онньюлок - там я размещаю функция движения нпц и проверочный цикл, в зависимости от локации, на которой мы находимся вывожу результаты.У тебя может быть состояние игры, когда все 3500 нпц и герой находятся на одно локации? Подумай, наверняка они так же не могут у тебя бродить везде. Это ни к чему. Лучше разбить их на группы, вроде, город, деревня, лес, может с переносом из группы в группу, но тогда в любом случае обработка станет легче.
Это все само собой, все эти группы которые не могут выйти за определенный тип территории (для того и нужно это дробление по типам), но без списка нпс находящихся на локации затея все равно не имеет смысла. При больших количествах нпс все равно придется каким то образом узнавать находится ли кто нибудь в одной локации с нпс. А без этого списка это однозначно цикл в котором опять прогоняются все нпс. К тому же у меня задача стоит проводить обработку при перемещении нпс в любую локацию ,а не только в ту в которой игрок. Это нужно для симуляции боев, разговоров итд, что бы жизнь происходила не только с появлением героя в локации.
У меня одна локация и вся разница в координатах на этой локации. Те 3500 нпс гуляло на карте в которой было 10000 разных координат. Ну как бы 10000 локаций, которые были сгенерированны. Такой системой можно сгенерировать хоть землю целиком. Единственное условие нужно прерывать цикл генерации, что бы он не завис. Потому в спортлото проще выиграть, чем 3500 нпс собратся на одной локации.
Собираешься продавать? Тогда зачем столько сил?
SneakBug8:
Собираешься продавать? Тогда зачем столько сил?
Не собираюсь я ничего продавать. Просто нет ни одной игры в которой мир жил бы сам по себе, а игрок имел бы настоящую свободу действий, а не был бы очередным избранным пупом земли. И почему бы не сделать самому ту игру которую хочешь? Никто ведь ее не сделает, если сам не сделаешь. Тут осталась совсем ерунда, все остальные системы у меня отработаны, я просто в разных файлах разные вещи отрабатываю, что бы было ясно видно откуда идут баги. И осталась такая плевая мелочь, что самому смешно, всего то сделать 2 кусочка кода, в 1м будет удалятся нпс из старого списка, и добавляться в новый, и 2й код отображение на локации. И никак не могу, хотя прекрасно понимаю что надо делать. Да и гляжу тут никто ни бум бум. Привыкли делать рассказики с кнопками, а как увидели, что на куспе можно запилить хоть землю целиком, растерялись.
Почти удалось сделать отслеживание этих списков. Но опять почти, в некоторых локациях все же есть нпс, которых список в упор не видит. Почему то на локации с максимальными координатами всегда есть нпс, который отслеживается в лоб, но не существует в списке и не передвигается. Тут явно какая то мелкая ошибка.
Код передвижения нпс
Spoiler
$dy_main_move={
if stop_move=0:
!старые координаты
$loc_old='<<oldX[i]>>,<<oldY[i]>>,<<oldZ[i]>>'
!новые координаты
$loc='<<X[i]>>,<<Y[i]>>,<<Z[i]>>'
!удаление нпс из старого списка
if areanpc_total['<<$loc_old>>']>0:
cikl_temp=areanpc_total['<<$loc_old>>']
:markcikltempdel
if areanpc_num['<<$loc_old>>,<<cikl_temp>>']!i and cikl_temp>0:
cikl_temp-=1
jump'markcikltempdel'
end
if areanpc_num['<<$loc_old>>,<<cikl_temp>>']=i:
areanpc_num['<<$loc_old>>,<<cikl_temp>>']=0
end
end
!добавление нпс в список локации
if areanpc_total['<<$loc>>']>0:
cikl_temp=areanpc_total['<<$loc>>']
:markcikltempdob
if areanpc_num['<<$loc>>,<<cikl_temp>>']>0 and cikl_temp>0:
cikl_temp-=1
jump'markcikltempdob'
end
if areanpc_num['<<$loc>>,<<cikl_temp>>']=0 and cikl_temp>0:
areanpc_num['<<$loc>>,<<cikl_temp>>']=i
end
if cikl_temp=0:
areanpc_total['<<$loc>>']+=1
cikl_res=areanpc_total['<<$loc>>']
areanpc_num['<<$loc>>,<<cikl_res>>']=i
end
end
if areanpc_total['<<$loc>>']=0:areanpc_total['<<$loc>>']+=1&areanpc_num['<<$loc>>,1']=i
else
stop_move=0
X[i]=oldX[i]
Y[i]=oldY[i]
Z[i]=oldZ[i]
end
}
if i>=total_npc:i = 1
poisk_error=0
move_test=0
:moveNPCsLoop
cikl_npc_max-=1
if npcIsDead[i] = 0 and i!you:
oldX[i]=X[i]
oldY[i]=Y[i]
oldZ[i]=Z[i]
:mark_terrain_end
napravlenie=rand(0,7)
if napravlenie=0:
if areatipe['<<X[i]>>,<<Y[i]+1>>']>0:
!север
X[i]=X[i]
Y[i]=Y[i]+1
move_test+=1
else
poisk_error+=1
if poisk_error<50:
jump'mark_terrain_end'
else
stop_move=1
end
end
end
if napravlenie=1:
if areatipe['<<X[i]-1>>,<<Y[i]>>']>0:
!запад
X[i]=X[i]-1
Y[i]=Y[i]
move_test+=1
else
poisk_error+=1
if poisk_error<50:
jump'mark_terrain_end'
else
stop_move=1
end
end
end
if napravlenie=2:
if areatipe['<<X[i]+1>>,<<Y[i]>>']>0:
!восток
X[i]=X[i]+1
Y[i]=Y[i]
move_test+=1
else
poisk_error+=1
if poisk_error<50:
jump'mark_terrain_end'
else
stop_move=1
end
end
end
if napravlenie=3:
if areatipe['<<X[i]>>,<<Y[i]-1>>']>0:
!юг
X[i]=X[i]
Y[i]=Y[i]-1
move_test+=1
else
poisk_error+=1
if poisk_error<50:
jump'mark_terrain_end'
else
stop_move=1
end
end
end
if napravlenie=4:
if areatipe['<<X[i]-1>>,<<Y[i]+1>>']>0:
!северо запад
X[i]=X[i]-1
Y[i]=Y[i]+1
move_test+=1
else
poisk_error+=1
if poisk_error<50:
jump'mark_terrain_end'
else
stop_move=1
end
end
end
if napravlenie=5:
if areatipe['<<X[i]+1>>,<<Y[i]+1>>']>0:
!северо восток
X[i]=X[i]+1
Y[i]=Y[i]+1
move_test+=1
else
poisk_error+=1
if poisk_error<50:
jump'mark_terrain_end'
else
stop_move=1
end
end
end
if napravlenie=6:
if areatipe['<<X[i]-1>>,<<Y[i]-1>>']>0:
!юго запад
X[i]=X[i]-1
Y[i]=Y[i]-1
move_test+=1
else
poisk_error+=1
if poisk_error<50:
jump'mark_terrain_end'
else
stop_move=1
end
end
end
if napravlenie=7:
if areatipe['<<X[i]+1>>,<<Y[i]-1>>']>0:
!юго восток
X[i]=X[i]+1
Y[i]=Y[i]-1
move_test+=1
else
poisk_error+=1
if poisk_error<50:
jump'mark_terrain_end'
else
stop_move=1
end
end
end
dynamic $dy_main_move
!'<<move_test>> движений'
end
i+=1
if i <= total_npc and cikl_npc_max>=0:jump 'moveNPCsLoop'
Код определяющий нпс находящихся на одной локации с игроком.
Spoiler
$areaNPC=''
kolvo_cikl_test=0
$loc='<<X[you]>>,<<Y[you]>>,<<Z[you]>>'
cikl_lnp=areanpc_total['<<$loc>>']
:markcikllnp
if areanpc_num['<<$loc>>,<<cikl_lnp>>']>0:
it=areanpc_num['<<$loc>>,<<cikl_lnp>>']
$areaNPC += "<br>"
$areaNPC += "<a href='exec: gt""androidWithIndex"", <<it>>'><b><<$name[it]>></b></a>"
end
cikl_lnp-=1
kolvo_cikl_test+=1
if cikl_lnp>=0:jump'markcikllnp'
'<<$areaNPC>>'
'Количество циклов <<kolvo_cikl_test>>'
MainFile.qsp Вот файл.
Ллур:
Да и гляжу тут никто ни бум бум.
Ллур,
пожалуйста, не надо нервничать. Ещё не высказывались наши многоуважаемые эксперты.
Ллур:
Привыкли делать рассказики с кнопками
Такова специфика платформы QSP.
Ллур:
на куспе можно запилить хоть землю целиком
Согласен. Но здесь к подобным экзерсисам относятся, мягко говоря, не с восторгом.
Я боюсь сморозить глупость, но, по-моему, для твоей задачи нужно ООП. Советую изучить тему Открытый мир в текстовой игре.
Не нужно ему ооп, ему нужно, чтобы код кто-то посмотрел-поправил или ещё лучше написал за него. :)
И неправда, что тут плохо к такому относятся, здесь прекрасно к такому относятся, просто мало кто доделывает такое до конца, ибо много сил нужно.
Ллур:
Почти удалось сделать отслеживание этих списков. Но опять почти, в некоторых локациях все же есть нпс, которых список в упор не видит. Почему то на локации с максимальными координатами всегда есть нпс, который отслеживается в лоб, но не существует в списке и не передвигается. Тут явно какая то мелкая ошибка.
Я бы попыталась помочь, но ненавижу в чужом коде копаться. Легче свой написать под задачу. Может, правда Некса дождаться или Вервольфа.
snail:
Ллур:
на куспе можно запилить хоть землю целиком
Согласен. Но здесь к подобным экзерсисам относятся, мягко говоря, не с восторгом.
Я в курсе, что тут песочницы не одобряют. Но я во общем то не ради одобрения делаю или чьих то там восторгов.