Абзац
:: Поиск
:: Поддержка проекта
Webmoney:
  • Z610389805629
  • R427996570517
  • E023541002978
  • :: №20 (27.06.2004) Просмотров: 4738

    Автор: Александр Шушков / 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  ;Промежуточный шаг

    Благодарю всех откликнувшихся, я рад, что у меня есть такие друзья! Если у кого-то возникнут какие-либо вопросы или предложения, я с удовольствием их выслушаю.

    © 2004-2013 Perspective group