PDA

Просмотр полной версии : Програмирование игр



ser_13
06.01.2014, 13:44
Меня интересует вопрос. Где можно "достать" полный разбор игровой програмы.
Взять программу и разобрать ее. У иеня ума не хватает.

Меня интересует игра WDW-не помню. Немогу найти. Возможно неверное наз.
Там под управлением играющего бежит чел. снизу экрана вверх, экраны меняются.
Бегает много людей и стреляют, пули летят не быстро. Есть экраны, с ямами в
которых седят люди с орудиями типа базука. На некоторых экранах по реке ездит
лодка, на некоторых экранах показана железная дорога.

null_device
06.01.2014, 13:55
ser_13, для понимания принципов написания игр, есть две замечательные книжки: "Как написать игру (на бейсике) (http://vtrdos.ru/book/WGBAS.ZIP)" и "Как написать игру на ассемблере (http://vtrdos.ru/book/WGASM.ZIP)". Сразу, "с места - в карьер" даже на основе готовой игры, понять что-то слабо получится.

Eltaron
06.01.2014, 15:49
игра WDW
Это наверна Who Dares Wins 2, она всегда на кассетах WDW называлась.
http://www.worldofspectrum.org/infoseekid.cgi?id=0005673

jerri
06.01.2014, 16:00
Меня интересует вопрос. Где можно "достать" полный разбор игровой програмы.
Взять программу и разобрать ее. У иеня ума не хватает.


Самое лучшее что существует на сегодняшний день по программированию игр на спектруме
http://zxpress.ru/book_articles.php?id=163
http://zxpress.ru/book_articles.php?id=175
http://zxpress.ru/book_articles.php?id=201
http://zxpress.ru/book_articles.php?id=212

ser_13
06.01.2014, 17:14
Who Dares Wins 2. Спасибо она. Написать хотя бы один экран.

это почти все читал.

Пытался писать Sex Crime на blitz3d все получилось, только не знаю как полицейского заставить ходить, ловить?
Самое гл. писать алгоритм это мне не получается

ser_13
06.01.2014, 17:25
Who Dares Wins 2. Экраны можно нарисовать, а вот дальше?
В книгах не написано как увязать все в единое целое и чтобы работало.

jerri
06.01.2014, 20:57
ser_13, ты ссылочки то почитай.

Andrew771
16.01.2014, 10:34
Почитал ссылочки от Jerri, одно место не понравилось от Стива Тернера:


Вот примерный список приемов плохого стиля:
...
3. Неправильное использование процедур.

Каждая процедура должна иметь один вход и один выход. Если Вам их нужно больше, то вернитесь на этап 2 и повторите проектирование.

Никогда не имитируйте вызов процедуры (CALL) путем перехода (JP) с последующей манипуляцией стеком. Прием слишком головоломный, чтобы пользоваться им часто. Всегда завершайте процедуру естественным путем (команда RET в конце процедуры).

Если бы была команда CALL (HL), то я неукоснительно соблюдал бы это правило. А так, как еще можно сделать вызов процедур по адресам, заданным в памяти блоками DEFW? Только подстановкой адреса непосредственно в машинный код после кода команды CALL? Это еще больше запутает код.
Также, иногда бывает нужно войти в середину процедуры, а не в начало, чтобы не писать второй абсолютно одинаковый кусок процедуры.
И один выход RET из процедуры - тоже жестокость. А как же выходы по условиям RET Z, RET C и прочее, если надо в середине процедуры?

jerri
16.01.2014, 10:51
Если бы была команда CALL (HL), то я неукоснительно соблюдал бы это правило. А так, как еще можно сделать вызов процедур по адресам, заданным в памяти блоками DEFW? Только подстановкой адреса непосредственно в машинный код после кода команды CALL? Это еще больше запутает код.
Также, иногда бывает нужно войти в середину процедуры, а не в начало, чтобы не писать второй абсолютно одинаковый кусок процедуры.
И один выход RET из процедуры - тоже жестокость. А как же выходы по условиям RET Z, RET C и прочее, если надо в середине процедуры?

скачай исходники любого из известных
Joffa, Медноногова, Тернера опять же и посмотри внимательно

Если написано так как советует Тернер то тебе будет все понятно.
Если написано так как пишу я, то ты ничего не поймешь.

ftp://ftp.worldofspectrum.org/pub/sinclair/games-extras/SaucerV1.17_SourceCode.zip

Hacker VBI
16.01.2014, 11:25
Andrew771, ты говоришь о "kernel", там используется такой подход.
kernel нужен для блока вызовов стандартных процедур, в частности используется для работы плагинов и для совместной с кем-то разработки. и приносит совсем другой подход: во первых : стандартное положение адресов в памяти, стандартные для всех флаги, стандартный выход, обработки и т.д. это больше подходит для каскадной модели разработки (http://ru.wikipedia.org/wiki/%D0%9C%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C_%D0%B2%D0%BE% D0%B4%D0%BE%D0%BF%D0%B0%D0%B4%D0%B0), а там сначала идёт плотная аналитическая работа, что для нас не всегда приемлемо (http://ru.wikipedia.org/wiki/%D0%A1%D0%BF%D0%B8%D1%80%D0%B0%D0%BB%D1%8C%D0%BD%D 0%B0%D1%8F_%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C)
Тёрнер даёт общие рекомендации для разработчиков - это упрощает кодирование, что облегчает разработку больших программ.
если в разных местах у тебя будут использованы разные техники - это может быть хорошо для небольших программ. в больших программах, которые долго пишутся, главная сложность держать всё в голове. поэтому лучше придерживаться одинакового подхода к кодированию везде.
сюда входит так-же стандартное по какому-то принципу наименование меток.

тебе никто не запрещает использовать любые подходы. рекомендации дают опытные люди, которые уже искали - ну почему у меня тогда работало, а как добавил сегодня ну мизерную мелочь - вылетает. и снова перекапываешь давно написанный код, восстанавливая в голове алгоритм работы.
а потом рефакторинг в уже принятую систему написания, в которой всё понятно))

psb
16.01.2014, 11:32
Также, иногда бывает нужно войти в середину процедуры, а не в начало, чтобы не писать второй абсолютно одинаковый кусок процедуры.
И один выход RET из процедуры - тоже жестокость. А как же выходы по условиям RET Z, RET C и прочее, если надо в середине процедуры?
2 пути есть: писать понятно (с возможностью дальнейшей поддержки кода, в т.ч. и другими людьми) и писать "оптимизированно" (т.н. write-only code - потом тяжело с таким кодом что-то делать). твои предложения по "оптимизации" - чисто второй вариант. иногда он полезен или даже единственно возможен (в демах или интрах), но далеко не всегда.

Andrew771
16.01.2014, 16:00
Да, в своих программах я применяю единый стиль вызовов процедур и именование меток. Но входов в процедуру может быть много и выходов тоже. При этом стек строго остается в том же состоянии, как до вызова процедуры.
Но вот в игре Эйфории появилась задача - вызов нужной процедуры обработки в зависимости от текущего юнита и имеющейся в списке для этого юнита. Вызов может производиться из нескольких мест. В базе данных это задается так (упрощенный пример):



; id=0, крестьянин

unit_peasant defb unit_peasant_end-unit_peasant ; длина данных юнита
defb s32_peasant ; код символа
defb 24 ; количество и список возможных процедур
defw c_op_pass
defw c_op_destroy
defw c_op_move_west_earth
defw c_op_move_east_earth
defw c_op_move_nord_earth
defw c_op_move_sud_earth
defw c_op_move_nord_west_earth
defw c_op_move_nord_east_earth
defw c_op_move_sud_west_earth
defw c_op_move_sud_east_earth
defw c_op_build_road
defw c_op_build_irrigation
defw c_op_build_wall
defw c_op_build_tower
defw c_op_build_house
defw c_op_build_barracks
defw c_op_build_barn
defw c_op_build_stock
defw c_op_build_shipyard
defw c_op_build_church
defw c_op_train_soldier
defw c_op_train_galley
defw c_op_take_source
defw c_op_give_source
unit_peasant_end


; id=1, солдат

unit_soldier defb unit_soldier_end-unit_soldier ; длина данных юнита
defb s32_soldier ; код символа
defb 12 ; количество и список возможных процедур
defw c_op_pass
defw c_op_destroy
defw c_op_move_west_earth
defw c_op_move_east_earth
defw c_op_move_nord_earth
defw c_op_move_sud_earth
defw c_op_move_nord_west_earth
defw c_op_move_nord_east_earth
defw c_op_move_sud_west_earth
defw c_op_move_sud_east_earth
defw c_op_take_source
defw c_op_give_source
unit_soldier_end


; id=2, галера

unit_galley defb unit_galley_end-unit_galley ; длина данных юнита
defb s32_galley ; код символа
defb 9 ; количество и список возможных процедур
defw c_op_pass
defw c_op_move_west_earth
defw c_op_move_east_earth
defw c_op_move_nord_earth
defw c_op_move_sud_earth
defw c_op_move_nord_west_earth
defw c_op_move_nord_east_earth
defw c_op_move_sud_west_earth
defw c_op_move_sud_east_earth
unit_galley_end

И как вы собираетесь вызывать эти процедуры, чтобы был понятный код?

Я делаю так:



hl = считанный из базы адрес процедуры, например c_op_destroy
ld bc,label_01_continue
push bc
jp (hl)
label_01_continue
...
ld bc,label_02_continue
push bc
jp (hl)
label_02_continue
...
ret
c_op_destroy
...
ret

psb
16.01.2014, 16:13
;hl=addr
call callhl
....

callhl jp (hl)

Andrew771
16.01.2014, 17:22
hl читается из базы - это адрес вызова нужной процедуры, может вызываться из нескольких мест. Возвращаться как?

Всё, дошло! Спасибо, psb. Исправлю в следующей версии, твой вариант намного проще и понятнее.

psb
16.01.2014, 17:32
я ниче не понял, я просто твой монструозный код сократил (теперь не надо указывать bc). массивы указателей сами по себе - ок.

Hacker VBI
16.01.2014, 17:57
Andrew771, показывай демку! :)

jerri
16.01.2014, 18:26
hl читается из базы - это адрес вызова нужной процедуры, может вызываться из нескольких мест. Возвращаться как?

Всё, дошло! Спасибо, psb. Исправлю в следующей версии, твой вариант намного проще и понятнее.


как там было у Тёрнера?
если вы чего-то не понимаете, то

вернитесь на этап 2 и повторите проектирование.

;)

goodboy
16.01.2014, 18:42
как там было у Тёрнера?
в RanaRama кстати встроен тот маленький монитор про который была статья перевод в ZXreview.
и если я не ошибаюсь статей перевели меньше чем было напечатано в оригинале

Andrew771
17.01.2014, 09:46
Andrew771, показывай демку!
Уже давно готова первая версия игры, туть (http://zx.pk.ru/showthread.php?t=20370&highlight=euphoria). Сейчас вторую делаю, но пока приостановил на пару месяцев в связи с занятостью.

jerri
17.01.2014, 11:19
Уже давно готова первая версия игры, туть (http://zx.pk.ru/showthread.php?t=20370&highlight=euphoria). Сейчас вторую делаю, но пока приостановил на пару месяцев в связи с занятостью.

а давай твою игру немного по размеру пооптимизируем?


output_more_xxx0 ld a,e
cp xmax
jp z,output_more_01
inc a
ld b,d
ld c,a
call read_cell
cp cell_sea
jp z,output_more_01

; ld a,(parameter_okruga)
; inc a
; ld (parameter_okruga),a

ld hl,parametr_okruga
inc (hl)
;-3 byte
output_more_01
; ld h,0
; ld a,(parameter_okruga)
; ld l,a

ld hl,(parametr_okruga)
ld h,0
;-1 byte
ld bc,table_more
add hl,bc
ld a,(hl)

jp output_map_region_03

я уверен твой код можно много где пооптимизировать

Andrew771
17.01.2014, 12:55
я уверен твой код можно много где пооптимизировать
да, я знаю. На быстродействие клал болт, т.к. оно не нужно, а писал как можно быстрее и понятнее, т.к. объем программирования большой.

---------- Post added at 12:55 ---------- Previous post was at 12:52 ----------

Эти процедуры output_more, output_doroga, output_stena можно сделать одной, там только параметры разные. Но некогда и незачем, ну разве что немного памяти сэкономить для увеличения количества юнитов :)