Переменные. Как сделать проигрыш на любой локации?
Вопрос.
Мне нужно, чтобы персонаж умирал на любой локации, если здоровье у него становится меньше 10?
Aleks Versus:
почему неверный?
Nex:
появляется зависимость от реалтайма
Ну вот представь. На ГГ в игре, допустим, упало дерево. Отнялось 50 жизней, было 40. Итого у тебя стало жизней < 0. Если проверка у нас в каунтере, то полсекунды или около того мы будем видеть на экране то, что должно нам показываться, если мы выжили, а потом экран поменяется на соответствующий смерти игрока. Если делать вызов каунтера чаще, сути это не изменит. Допустим, у нас на следующей локации какой-нибудь “родник силы”, который полностью исцеляет игрока. Получится, что несмотря на то, что дерево убило игрока, труп дошел до источника и исцелился. Таким образом, это в любом случае приводит к багам.
Проверка должна быть там, где значение изменяется, сразу же после изменения. Если проверка простая(как в том примере что я приводил), то можно скопировать ее во все места кода, где изменяется значение переменной. Если код проверки более сложный, можно выделить отдельную локацию для проверок и вызывать ее с помощью GS, опять же во всех местах, где меняется значение.
Nex, что-то непонятно объясняешь. Зачем в onnewloc, ведь тогда придется перейти на другую локацию, чтобы умереть-то!
Winter Wolf,
ONNEWLOC - способ если изменения должны происходить при переходе между локациями. А то о чем я писал сообщением выше, никак не связано с ONNEWLOC.
Есть два приемлемых варианта:
1. делать проверку при переходе на новую локацию(ONNEWLOC)
2. делать проверку сразу же при изменении значения(описано в сообщении выше)
Какой выбрать - решать автору. Выбор зависит от того, как он строит свою игру.
Например, у ГГ с течением времени растет параметр “голод”. При голод >= 50 в описание локации пишется “вы голодны”, при голод >= 80 “вы чрезвычайно голодны”, при голод >= 90 “вы умираете от голода”, при голод >= 100 ГГ умирает. Изменение параметра, проверку на смерть от голода и вывод предупреждающих сообщений удобнее всего будет сделать в ONNEWLOC. Каждый переход с локации на локацию будет постепенно увеличивать “голод”, и игроку придется следить за тем, чтобы ГГ не голодал.
Если же реакция на изменение параметра должна быть моментальная, то и проверку следует делать сразу же после изменения переменной.
Вот так:
'На вас упало дерево.'
здоровье = здоровье - 50
IF здоровье <= 0:
XGOTO 'смерть'
END
или так:
'На вас упало дерево.'
здоровье = здоровье - 50
GS 'проверка_здоровья'
Понятно. Оставляем выбор за автором. Тут будет неправильно говорить, что проверка того или иного параметра через каунтер - это неправильный подход. Если автор уверен, что такая проверка не даст ему багов, почему бы ему не сделать через каунтер? :=D Постоянно помнить в голове, что мне нужно после каждой формулы расчёта здоровья ставить проверку здоровья, писать каждый раз пару лишних строк - спасибо, я слишком ленив :=D . А так - да, лучше проверять именно в том месте, где это необходимо.
А не является ли проблема “вписал проверку не в том месте” очередными граблями?
Тут будет неправильно говорить, что проверка того или иного параметра через каунтер - это неправильный подход.
Нет, это в корне неправильный подход. Просто ты еще не до конца разобрался в QSP.
Если автор уверен, что такая проверка не даст ему багов, почему бы ему не сделать через каунтер?
Потому что это в любом случае ведет к багам.
мне нужно после каждой формулы расчёта здоровья ставить проверку здоровья
Вообще-то в игре формула должна быть только в одном месте, иначе это архитектурная ошибка.
писать каждый раз пару лишних строк - спасибо, я слишком ленив
Во-первых, код проверки прекрасно укладывается в один оператор GS, я выше приводил пример. Можно даже короче записать, например:
GS 'здоровье', -50
в локации “здоровье” будет изменяться параметр “здоровье” и заодно будет осуществляться проверка.
Во-вторых, автор имеет право лениться писать правильный код. Пусть только помнит о том, что тем самым он обрекает игрока на встречу с багами.
А не является ли проблема “вписал проверку не в том месте” очередными граблями?
Не могу представить себе такой ситуации. Но даже если допустить, что автор поставил лишнюю проверку, то это не должно никак влиять на корректную работу игры.
Nex:
Если автор уверен, что такая проверка не даст ему багов, почему бы ему не сделать через каунтер?
Потому что это в любом случае ведет к багам.
Даже больше скажу, в Android плеере на телефона слабее, чем ПК, это будет ОЧЕНЬ тормозить и будет обидно.
Как сделать отдельную комнату для всех переменных, которые часто меняются в течении игры? Если их ставить в начале комнаты, а потом в другой комнате поменять им значение, и вновь перейти в комнату где она задавалась, то переменная принимает изначальное значение. Я сделал эти переменые в начальной комнате, но их очень много и комната захламляется переменными, это вроде не критично но не удобно. Есть ли способ?
Ну сделай спец локацию для определения переменных и вызовами её из начальной, используя gs
TeRV,
ты можешь создать локацию с любым именем, например “переменные”, вписать туда все что нужно в поле “выполнить при посещении”, а в начале игры вызвать ее вот так:
GS 'переменные'
А вообще чтобы не возникало таких ситуаций “в другой комнате поменять им значение, и вновь перейти в комнату где она задавалась, то переменная принимает изначальное значение”, нужно пользоваться таким приемом:
IF был_на_локации_лес = 0:
был_на_локации_лес = 1
...НУЖНЫЕ НАМ ОПЕРАТОРЫ(например, установка переменных для этой локации)...
END
В приведенном примере, операторы выполнятся только один раз, при первом заходе на локацию.
Спасибо, я как-то пробовал gs но он почему-то не сработал, сейчас же всё работает… странно =)
Nex:
Потому что это в любом случае ведет к багам.
Не верю. Проверю
Nex:
Нет, это в корне неправильный подход.
Из-за привязки к текущему времени? Это как-то связано с частотой процессора, шин, или чего либо ещё?
Nex:
Не могу представить себе такой ситуации
Ты только что сказал, что ставить проверку в каунтере - это в корне неверный подход. :=D Значит грабли?
Nex:
Вообще-то в игре формула должна быть только в одном месте
Логично. Можно вообще написать подпрограмму для каждой формулы, потом только вызывать их через gs|func. Однако у меня нет уверенности, что я смогу вызвать такую подпрограмму в любом месте игры (есть ведь ограничения на количество вызываемых друг из друга подпрограмм, или нет?), поэтому сначала всегда пишу формулу целиком там, где она нужна.
А вот эта идея вбить формулу расчёта и проверку в одну подпрограмму и вызывать лишь там, где нужно, - мне нравится. Почему-то не приходило в голову. Вместо постоянного health=health-x, вписывать что-то вроде gs ‘estimate_health’,x где x - отымаемое здоровье, а код локации estimate_health:
health=health-args[0]
if health<1: XGOTO 'умер'
Ведь можно и посложнее. Скажем передавать во втором, третьем и прочих аргументах различные варианты описания произведённого эффекта (”помер”, “выжил”, “держусь на силе воли”). Получается намного динамичнее, чем тупой отсыл к локации смерти через тот же каунтер, и при этом нет необходимости всякий раз прописывать одни и те же конструкции.
Это откровение! Я прозрел! И это не сарказм. Спасибо, Nex.
И всё таки, как насчёт ограничений на вложенность подпрограмм, вызываемых через gs|func?
Не верю.
Да на здоровье. Тут нужно просто хорошо понимать логику работы движка QSP, тогда это станет очевидным.
Из-за привязки к текущему времени? Это как-то связано с частотой процессора, шин, или чего либо ещё?
Не из-за привязки ко времени.
1. Как правило, игрок видит текст события, в котором “проверка выполнилась”, а потом “вдруг” экран меняется(проверка не выполнилась), получается этакий эффект “дергания”. Выглядит очень неприятно.
2. Игрок может совершить действие, когда локация-счетчик еще не выполнилась. Выше описывал пример.
3. Архитектурно это неправильно, проверять постоянно то, что должно проверяться только при изменении значения - однажды. Лишние накладные расходы на процессорное время, а если проверок очень много, это может стать критичным.
Ты только что сказал, что ставить проверку в каунтере - это в корне неверный подход. big_smile Значит грабли?
Если имелась в виду проверка с помощью каунтера - то да, это грабли. Видимо я просто не понял твой вопрос.
как насчёт ограничений на вложенность подпрограмм, вызываемых через gs|func?
У меня вложенные GS выполнялись до глубины 2745. Явно заданного ограничения нет, при превышении некого порога(2745 в моем случае) плеер просто вылетает с ошибкой. По-хорошему в играх не должно быть очень глубоких вызовов. Если они есть, значит автор неправильно спроектировал код.
Ох я тут нафлудил, однако тема животрепещущая.
Nex:
Тут нужно просто хорошо понимать логику работы движка QSP
Для понимания этой логики нужно вникать в исходный код?
Nex:
Если имелась в виду проверка с помощью каунтера - то да, это грабли. Видимо я просто не понял твой вопрос.
Я не точно выразился. Прошу прощения. Имелась ввиду именно проверка с помощью каунтера - то, что я подразумевал под словами “вписал в не том месте”.
Nex:
GS выполнялись до глубины 2745
Это с передачей аргументов? Надо тоже попробовать.
Для понимания этой логики нужно вникать в исходный код?
Нет, достаточно просто хорошо разбираться в написании QSP-игр.
health=health-args[0]
if health<1: XGOTO 'умер'
У меня похоже реализовано: есть лока отвечающая за жизнь, в неё передаются инструкции.
if $args[0]='damage':
cur_hp=cur_hp-args[1]
!тут ещё проверка на смерть
end
if $args[0]='heal':
cur_hp=cur_hp+args[1]
if cur_hp>max_hp:cur_hp=max_hp
end
if $args[0]='regen':
!эта лока вызывается по таймеру для постепенной регенерации
if cur_hp<max_hp:cur_hp=cur_hp+1
end