![]() |
|
:: СОДЕРЖАНИЕ НОМЕРА
:: Газетные рубрики
:: АВТОРЫ
:: Поиск
:: Поддержка проекта
Webmoney:
|
:: №20 (27.06.2004) Просмотров: 5162
![]() Автор: Александр Шушков / axor / Perspective. Рубрика: В помощь разработчику. Номер: №20 (27.06.2004). Направление движенияВ данный момент я занимаюсь созданием игры, и в один прекрасный момент передо мной возникла задачка: по направлению движения героя необходимо найти нужный спрайт (или группу спрайтов).Для начала введу в курс дела. Итак, сначала у меня производится поиск кратчайшего пути (за что отдельное спасибо одному человеку) некоего персонажа, следствием которого является линейная запись (таблица) из координат героя по которым тот должен достигнуть указанной точки. Затем происходит преобразование этих координат в направление героя, которое получается путем вычитания последующих координат из предыдущих. Таким образом, получается одно из восьми чисел: #FFFF, #0101, #00FF, #0001, #0100, #FF00, #01FF, #FF01. Это при условии, что герой может перемещаться по карте в восьми направлениях. Так же нетрудно заметить, что в списке направлений отсутствует комбинация #0000. Почему? А все потому, что если бы она получилась в результате вычитания, это означало бы, что герой просто стоит на месте, т.е. никуда не двигается, следовательно учитывать эту комбинацию не нужно. Например, в регистре BC, есть одно из восьми указанных выше чисел. Необходимо сделать процедуру, которая преобразует эти числа в число от 0 до 7, которое в свою очередь будет означать то или иное направление героя. Порядок чисел (что естественно) может быть любым. Например, BC=#FFFF. Делаем CALL Calc. На выходе из этой процедуры в регистре A пусть будет число 0. И так для каждого из этих восьми чисел. Сначала я сделал процедурку, которая просто (и тупо) перебирает все варианты. Но что-то мне подсказывало, что эту задачку можно решить более красиво и аккуратно. К сожалению, сам я так ничего и не придумал, поэтому обратился к друзьям по переписке и вот что из этого вышло. Станислав Юдин Вот такая мысль посетила. Набираю сразу в письме... Преобразуем двухбайтное число в четырехбитное. CALC1 LD A,B
AND %00000011
LD B,A
LD A,C
AND %00000011
SLA B
SLA B
OR B
;находим по таблице нужное значение
LD C,A
LD B,0
LD HL,TABLE-1
ADD HL,BC
LD A,(HL)
RET
TABLE DB 3 ;1
DB 0 ;2
DB 2 ;3
DB 4 ;4
DB 1 ;5
DB 0 ;6
DB 6 ;7
DB 0 ;8
DB 0 ;9
DB 0 ;10
DB 0 ;11
DB 5 ;12
DB 7 ;13
DB 0 ;14 ;ОБРЕЗАТЬ НЕЛЬЗЯ!
DB 0 ;15 ;ОБРЕЗАТЬ НЕЛЬЗЯ!Может быть где-то и есть ошибки, но суть надеюсь ясна. Что скажешь? Или плохое решение? Влад Сотников Поскольку в последовательности чисел я не заметил четкой закономерности, то иначе, как перебором, не сделать. Но перебор можно постараться сделать красивым и компактным. В предлагаемом варианте искомое число должно быть в data, иначе из цикла мы не выйдем. В противном случае вариант можно модифицировать. CALC2
;IN: [BC] - NUMBER
XOR A
LD HL,DATA
LOOP LD E,(HL)
INC HL
LD D,(HL)
INC HL
EX DE,HL
AND A
SBC HL,BC
RET Z
EX DE,HL
INC A
JR LOOP
DATA DW #FFFF
DW #00FF
DW #01FF
DW #FF00
DW #0100
DW #0101
DW #FF01
DW #0001Еще вариант... Я, как всегда, экономлю на памяти, а не на тактах. CALC3
;IN: [BC]
;OUT: [D]
XOR A
LD D,A
LD HL,DATA
LOOP2 LD A,C
CP (HL)
INC HL
JR NZ,LOOP_12
LD A,B
CP (HL)
LD A,D
RET Z
LOOP_12 INC HL
INC D
JR LOOP2Павел Стахов Мой вариант считает свои числа в следующей последовательности: ;#ffff=0 (#0000)
;#ff00=1 (#0001)
;#ff01=2 (#0002)
;#00ff=3 (#0100)
;#0000=4 (#0101) - Нужна ли эта комбинация?
;#0001=5 (#0102)
;#01ff=6 (#0200)
;#0100=7 (#0201)
;#0101=8 (#0202)
CALC4 INC C
INC B
LD A,B
ADD A,A
ADD A,B
ADD A,C
;Все, в A номер. Если тебе не нужна комбинация 4, то еще:
CP 5 ;5,6,7,8 NC
CCF ;C
SBC A,00 ;A=A-1
RET
Дмитрий Быстров
Ты точно не забыл вариант #0000? Если нет, то:
CALC5 LD A,C
ADD A,A
ADD A,C ;-3..3
ADD A,B ;-4..4, 0 НЕЛЬЗЯ
ADD A,4 ;0..8, 4 НЕЛЬЗЯ
CP 4
ADC A,-1 ;0..7
RETИван Рощин Можно использовать такое преобразование: ; BC B+1,C (B+1)*3+C
; #FFFF #00FF #FF
; #0101 #0201 7
; #00FF #01FF 2
; #0001 #0101 4
; #0100 #0200 6
; #FF00 #0000 0
; #01FF #02FF 5
; #FF01 #0001 1
;Соответствующий фрагмент программы:
CALC6 INC B
LD A,B
ADD A,A
ADD A,B
ADD A,C
;После чего заменяем #FF на 3:
CP #FF
JR NZ,$+4
LD A,3
RETЕсли изменять B нельзя, добавляем команду DEC B. * * * Далее с регистром A можно делать все что угодно. Я, например, его использовал следующим образом: ADD A,A ;A=A*8
ADD A,A
ADD A,A
LD HL,TABL
LD E,A
LD D,0
ADD HL,DE ;Теперь HL указывает на табличку адресов спрайтов нужного направления.
; Далее ваши действия...
TABL
UP DW SPRu1 ;Шаг левой ногой
DW SPRu2 ;Промежуточный шаг
DW SPRu3 ;Шаг правой ногой
DW SPRu2 ;Промежуточный шаг
DOWN DW SPRd1 ;Шаг левой ногой
DW SPRd2 ;Промежуточный шаг
DW SPRd3 ;Шаг правой ногой
DW SPRd2 ;Промежуточный шагБлагодарю всех откликнувшихся, я рад, что у меня есть такие друзья! Если у кого-то возникнут какие-либо вопросы или предложения, я с удовольствием их выслушаю. |