Линия между 2 точками в партии - PullRequest
0 голосов
/ 14 декабря 2018

У меня есть двумерный массив, подобный этому:

%v[0][0]%%v[0][1]%%v[0][2]%%v[0][3]% ........

%v[1][0]%%v[1][1]%%v[1][2]%%v[1][3]% .........

и 4 переменные, которые сохраняют координаты 2 точек (A и B) в массиве: xa, ya, xb, yb

Как бы я нарисовал линию пикселя (установив значения в массиве для символа) между двумя точками в пакетном скрипте, даже если точки находятся на разных линиях?

Я работаю над редактором карт для чистого пакетного движка 2D-шутеров.

У меня есть функция, которая рекламирует точки по заданным координатам, одна для квадратов и одна для линий, которая работает толькокогда концы линии (заданные точки) имеют одинаковое значение X или одинаковое значение Y.Для этого я использую:

for /L %%i in (%xa%,1,%xb%) do set v[%coord_ya%][%%i]=*

Теперь мне нужен фрагмент кода, который рисует линию # между двумя точками, расположенными на разных осях.Если бы это было сделано в программе для пиксельной графики, это выглядело бы так:

enter image description here

, где зеленые точки - это заданные точки (с координатами: A(1,1) и B(4,7)) и желтые точки представляют то, что мне нужно нарисовать с помощью #.

1 Ответ

0 голосов
/ 16 декабря 2018

Что-то для использования в качестве базы

@echo off
    setlocal enableextensions enabledelayedexpansion

    set "xMax=75"
    set "yMax=23"

    call :clearBoard
    call :drawLine 1 23 75 2 *
    call :drawLine 1 1 75 23 #
    call :drawLine 1 12 75 12 -
    call :drawLine 39 1 39 23 "|"
    call :drawLine 1 16 60 2 "."
    call :drawLine 1 6 23 20 :
    call :drawLine 1 1 4 7 @
    call :dumpBoard
    goto :eof


:clearBoard 
    for /l %%x in (0 1 %xMax%) do for /l %%y in (0 1 %yMax%) do set "v[%%x][%%y]= "
    goto :eof

:drawLine xa ya xb yb char
    rem Retrive arguments
    set "xa=%1"
    set "ya=%2"
    set "xb=%3"
    set "yb=%4"
    set "char=%~5"

    rem Calulate difference between coordinates start/end and its absolute values
    set /a "dx=xb-xa", "dy=yb-ya", "adx=(dx>>31|1)*dx", "ady=(dy>>31|1)*dy"

    rem Not having decimals, from here we will handle all coordinates 
    rem multiplied by 1000 and later divide to determine real coordinate

    rem For the axis with the greater difference we will move 1 cell in each step 
    rem and increment the other coordinate proportinally
    if %adx% gtr %ady% (
        set /a "ix=1000*(dx>>31|1)", "iy=dy*1000/adx", "dMax=adx"
    ) else (
        set /a "iy=1000*(dy>>31|1)", "ix=dx*1000/ady", "dMax=ady"
    )

    rem just for debugging
    if defined debug (
        for %%a in ( xa ya xb yb dx dy adx ady ix iy dMax x y ) do echo %%a = !%%a!
        pause
    )

    rem For each step in what ever axis selected
    for /l %%d in (0 1 %dMax%) do (
        rem Determine board coordinates where to draw
        set /a "vx=(xa*1000+ix*%%d)/1000", "vy=(ya*1000+iy*%%d)/1000"
        rem "Draw" point in board
        set "v[!vx!][!vy!]=%char%"
    )
    goto :eof

:dumpBoard    
    cls
    for /l %%y in (0 1 %yMax%) do (
        set "line[%%y]="
        for /l %%x in (0 1 %xMax%) do set "line[%%y]=!line[%%y]!!v[%%x][%%y]!"
    )
    echo ...:0         1         2         3         4         5         6         7
    echo ...:0123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789   
    for /l %%y in (0 1 %yMax%) do (
        set /a "l=1000+%%y"
        echo(!l:~-3!:!line[%%y]!
    )
    goto :eof

Вывод:

...:0         1         2         3         4         5         6         7
...:0123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
000:
001: @###                                  |
002: @   ###                               |                .....           ****
003:  @     ####                           |            ....             ***
004:  @         ###                        |        ....             ****
005:   @           ###                     |    ....              ***
006: ::@              ####                 .....              ****
007:   :@                 ###          ....|               ***
008:     :                   ###   ....    |           ****
009:      ::                   ....#       |       ****
010:        :              ....     ###    |    ***
011:         ::       .....            ####|****
012: ----------::-....---------------------|------------------------------------
013:          ...:                   ****  |  ###
014:      ....    ::              ***      |     ####
015:  ....          :         ****         |         ###
016: .               ::    ***             |            ###
017:                   :***                |               ####
018:                *** ::                 |                   ###
019:            ****      ::               |                      ###
020:         ***                           |                         ####
021:     ****                              |                             ###
022:  ***                                  |                                ####
023: *                                     |

Этот код определяет, по какой оси находится большее расстояние.Для каждой точки вдоль этой большой оси расстояние персонаж будет размещен на доске.Вторая координата на оси более короткого расстояния вычисляется путем деления расстояния по этой оси между количеством точек, которые мы будем размещать вдоль большой оси.

Поскольку арифметика пакетного файла не обрабатывает десятичные дроби, все операции выполняются со значениями, умноженными на 1000. Как только нам нужно перейти к действительным координатам, значения делятся на 1000.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...