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

Принятый ответ

делать свою систему движения
желательно хорошее владение алгоритмами и стаками, а еще лучше жассом. тогда можем поговорить
`
ОЖИДАНИЕ РЕКЛАМЫ...
1
26
5 лет назад
Отредактирован Hate
1
делать свою систему движения
желательно хорошее владение алгоритмами и стаками, а еще лучше жассом. тогда можем поговорить
Принятый ответ
0
1
5 лет назад
0
Hate:
делать свою систему движения
желательно хорошее владение алгоритмами и стаками, а еще лучше жассом. тогда можем поговорить
Мде, к такому я еще не готов, а нет способа попроще?
0
26
5 лет назад
0
так или иначе вы упретесь в триггеры если захотите сделать что то иначе чем стандарт
0
1
5 лет назад
0
Hate:
так или иначе вы упретесь в триггеры если захотите сделать что то иначе чем стандарт
Я не готов к джассу, а что насчёт триггеров можно попробовать
0
29
5 лет назад
0
Я не готов к джассу, а что насчёт триггеров можно попробовать
Я вас огорчу, но триггеру выливаются в jass, vjass-zinc, cjass)
0
27
5 лет назад
Отредактирован MpW
0
ну тут сложностей больше чем обычно. Надо подумать, надо ли лишать юнита возможность самостоятельного передвижения.
Если вы не хотите лишать движения, придется как-то ловить приказы (какие игрок отдает приказы, запоминать). Думаю, что тогда нужно таймером двигать как-то кораблик по дуге, и одновременно изменяя угол поворота. пример проще двигать таймером. есть формула в базе хгм, у NazarPunk видел и др. тут еще надо рассчитать скорость угла поворота (не тек угол дуги, а угол юнита)
Как-то делал систему отлова приказов. Она делала кучу проверок: отдавал ли игрок левый (не нужный) приказ юниту или нет. Если игрок выдергивал юнита, то система выключалась пример это мб пригодиться, если во время искусственного движения таймером выдернет, то таймер прервется. но тебе нужно самому такую же сделать
Еще мб пригодится это ну для проверки попала точка в конус или нет
Загруженные файлы
0
29
5 лет назад
0
Steal nerves, если будут препятствия, проблем возникнет намного больше)
0
27
5 лет назад
Отредактирован MpW
0
NazarPunk, ну не знал. не подумал об этом. ну надо проверить есть ли они. циклом проверяешь опирается ли дуга в препятствие. Если да, мб стоит по-другому кораблю движение обрисовать (высоту дуги выше или ниже брать, и снова циклом проверить. возможно тут будут свои рамки (пределы высоты). если препятствие все равно лишает перемещению, возможно стоит дать приказ стоп и выдать сообщение. или ...?).
Я не знаю, а как настоящие корабли в таких ситуациях поступали, на мель точно не посадили бы (тут игра, не знаю что автору надо). наверн веслами дали назад
твои варианты какие? ну или летающим сделать
0
29
5 лет назад
0
твои варианты какие?
Вариант писать свою систему движения, но это накладно. Можно хитрить и тамером корректировать движение юнита, но тогда он может тупо упереться в берег и остаться там.
Steal nerves:
а как настоящие корабли в таких ситуациях поступали
Настоящие корабли заранее траекторию просчитывали)
0
27
5 лет назад
Отредактирован MpW
0
у Hate вроде же есть система. попросите у него (но автор вряд ли это сможет)
Можно хитрить и тамером корректировать движение юнита, но тогда он может тупо упереться в берег и остаться там.
тоже можно заранее просчитать путь весь с проверками
0
29
5 лет назад
0
Steal nerves:
у Hate вроде же есть система. попросите у него (но автор вряд ли это сможет)
Там же простая система без инерции, просто таймром двигается юнит, только угол ограничен.
Загруженные файлы
0
27
5 лет назад
Отредактирован MpW
0
NazarPunk,
как попасть в эту точку?
отдать приказ в эту точку
просто
Загруженные файлы
0
1
5 лет назад
0
Мда, не думал, что это будет так сложно, может кто-нибудь кинуть карту с примером данной системы, попробую там разобраться...
0
26
5 лет назад
0
А это не просто ли маленькая скорость поворота?
В редакторе объектов есть либо скорость поворота, либо время поворота, ставь туда значение побольше и смотри.
0
1
5 лет назад
0
8gabriel8:
А это не просто ли маленькая скорость поворота?
В редакторе объектов есть либо скорость поворота, либо время поворота, ставь туда значение побольше и смотри.
До этого я уже и сам додумался, но дело в том, что там приходится самому эту дугу огибать, а хотелось бы, чтобы юнит делал это сам.
1
26
5 лет назад
1
BrokkGrungsson:
8gabriel8:
А это не просто ли маленькая скорость поворота?
В редакторе объектов есть либо скорость поворота, либо время поворота, ставь туда значение побольше и смотри.
До этого я уже и сам додумался, но дело в том, что там приходится самому эту дугу огибать, а хотелось бы, чтобы юнит делал это сам.
вперед, разбирайтесь
library Movement initializer Init requires MISC//, WeaponDatabase

//globals
    private ShipMoveData ShipStack[MAX]
    private MovingObject ObjS[MAX]
    public int Current_Objects = 0
    public int CurrentShip = 0
    public timer UpdateTimer = CT
    private timer ObjectsUpdateTimer = CT
    private group TemporaryGroup = CG
    private unit Ordered = null
    

define {
    private PERIOD = 0.021
    private MAX = 300
    private DUMMY = 'h00G'
    private INI_ACCELERATION = 1.0311
    private BREAK_ACCELERATION = -1.221
    private START_TURNRATE = 0.3311
    private CUTOFF_DISTANCE = 35.
    private BREAKING_DISTANCE = 250.
}


    real GetZ(real X, real Y)  {
        MoveLocation(Loc,X,Y)
        return GetLocationZ(Loc)
    }

    struct ShipMoveData 
        real vx = 0.
        real vy = 0.
        real tx, ty
        real angle
        real ang
        real turnrate
        real current_acc
        unit owner
        bool stop = false, side
        bool force_stop
        
        static ShipMoveData create(unit a){
            ShipMoveData data = ShipMoveData.allocate()
            data.owner = a
            data.turnrate = 0.
            data.stop = false
            data.force_stop = false
            return data
        }
        
    endstruct
    
    
    struct MovingObject
        real vx
        real vy
        unit owner
        
            static thistype new(unit u){
                thistype data = thistype.allocate()
                data.owner = u
                return data
            }
            
    endstruct
    
//Пиначет: безалкогольное пиво - как секс с сестрой. ощущения похожи, но это неправильно!
    
    
    public void Remove(unit u){
        int i = 0
        
            while(i++ < CurrentShip) {
                if u == ShipStack[i].owner {
                    ShipStack[i].destroy()
                    ShipStack[i] = ShipStack[CurrentShip]
                    CurrentShip--
                    return 
                }
            }
            
    }
    
    
    public void Stop(unit u){
        int i = 0
        
            while(i++ < CurrentShip) {
                if u == ShipStack[i].owner {
                    ShipStack[i].force_stop = true
                }
            }
    }
    
    
    private void ShipMovementUpdate(){
        Spaceship ship
        int c = 0
        real x, y, d, asd, angle
            
            while(c++ < CurrentShip) {
                ship = GetData(ShipStack[c].owner)
                    if (ship.move_speed < 10. and ShipStack[c].current_acc < 1.) {
                        ship.stop_order_lock = true
                        IssueImmediateOrderById(ShipStack[c].owner, order_stop)
                        ResetAnimation(ship.owner)
                        ShipStack[c].destroy()
                        ShipStack[c] = ShipStack[CurrentShip]
                        CurrentShip--
                        ship.move_speed = 0.
                    }
            }
        
            c = 0
            while(c++ < CurrentShip){
                ship = GetData(ShipStack[c].owner)
                x = Gx(ShipStack[c].owner); y = Gy(ShipStack[c].owner)
                    // ROTATION
                    if ShipStack[c].ang > 0. {
                        d = SquareRoot((ShipStack[c].tx-x)*(ShipStack[c].tx-x) + (ShipStack[c].ty-y)*(ShipStack[c].ty-y))
                        
                        // TODO: turn speed not tied to clock tick
                        
                            if ShipStack[c].turnrate < ship.engine.max_turn_speed { 
                                ShipStack[c].turnrate = ShipStack[c].turnrate + ship.engine.turn_speed 
                            }
                            elseif ShipStack[c].turnrate > ship.engine.max_turn_speed { 
                                ShipStack[c].turnrate = ship.engine.max_turn_speed  
                            }
                            
                        ShipStack[c].ang -= ShipStack[c].turnrate
                        
                        if ShipStack[c].ang < 0. { ShipStack[c].ang = 0. }
                        
                            if ShipStack[c].side { 
                                angle = Ga(ShipStack[c].owner) -  ShipStack[c].turnrate }
                            else { 
                                angle = Ga(ShipStack[c].owner) +  ShipStack[c].turnrate 
                            }
                            
                        SetUnitFacing(ShipStack[c].owner, angle)
                        ShipStack[c].tx = x + Rx((d + (ShipStack[c].ang / 6.)), angle)
                        ShipStack[c].ty = y + Ry((d + (ShipStack[c].ang / 6.)), angle)
                    }
                    // NEED ROTATION ?
                    else {
                        angle = ShipStack[c].angle; if angle < 0. { angle += 360. }
                        // NO
                        if (Ga(ShipStack[c].owner) <= angle + 1.5 and Ga(ShipStack[c].owner) >= angle - 1.5) { 
                            SetUnitFacing(ShipStack[c].owner, angle) 
                        }
                        // YES
                        else  { 
                                if ShipStack[c].turnrate < ship.engine.max_turn_speed { 
                                    ShipStack[c].turnrate = ShipStack[c].turnrate + ship.engine.turn_speed 
                                }
                                elseif ShipStack[c].turnrate > ship.engine.max_turn_speed { 
                                    ShipStack[c].turnrate = ship.engine.max_turn_speed  
                                }
                                
                            ShipStack[c].ang = ShipStack[c].turnrate 
                        }
                    }
                    
                d = SquareRoot((ShipStack[c].tx-x)*(ShipStack[c].tx-x) + (ShipStack[c].ty-y)*(ShipStack[c].ty-y))
                    // POSITIVE ACCELERATION
                    if (d > CUTOFF_DISTANCE and ShipStack[c].current_acc > 1. and !ShipStack[c].force_stop) {
                        if ship.move_speed < ship.engine.max_speed {
                        
                                if ShipStack[c].current_acc < ship.engine.max_acceleration {
                                    ShipStack[c].current_acc = ShipStack[c].current_acc + ship.engine.acceleration
                                    //msg("not max acceleration")
                                }
                                elseif ShipStack[c].current_acc > ship.engine.max_acceleration {
                                    ShipStack[c].current_acc = ship.engine.max_acceleration 
                                }
                                
                            ship.move_speed = ship.move_speed + ShipStack[c].current_acc
                            
                                if ship.move_speed > ship.engine.max_speed { 
                                    ship.move_speed = ship.engine.max_speed 
                                }
                            //debug msg("acceleration " + R2S(ShipStack[c].current_acc))
                        }
                        else { 
                            ship.move_speed = ship.engine.max_speed 
                        }
                        
                        asd = ((ship.move_speed * UPDATE_PERIOD) / d)
                        ShipStack[c].vx = (ShipStack[c].tx - x) * asd
                        ShipStack[c].vy = (ShipStack[c].ty - y) * asd
                        
                            if (x + ShipStack[c].vx + 25. > GetRectMaxX(gg_rct_PlayableArea) or \
                                x + ShipStack[c].vx + -25. < GetRectMinX(gg_rct_PlayableArea) or \
                                y + ShipStack[c].vy + 25. > GetRectMaxY(gg_rct_PlayableArea) or \
                                y + ShipStack[c].vy + -25. < GetRectMinY(gg_rct_PlayableArea)) 
                            { /*MAP BOUNDS*/ }
                            else {
                                //SetUnitPosition(ShipStack[c].owner, x + ShipStack[c].vx, y + ShipStack[c].vy)
                                SetUnitX(ShipStack[c].owner, x + ShipStack[c].vx)
                                SetUnitY(ShipStack[c].owner, y + ShipStack[c].vy)
                            }
                    }
                    // NEGATIVE ACCELERATION
                    else {
                            if ShipStack[c].stop { }
                            else {
                                // START BRAKING
                                ShipStack[c].stop = true
                                ShipStack[c].force_stop = false
                                ShipStack[c].current_acc = BREAK_ACCELERATION
                                ShipStack[c].tx = x + Rx(BREAKING_DISTANCE, ShipStack[c].angle)
                                ShipStack[c].ty = y + Ry(BREAKING_DISTANCE, ShipStack[c].angle)
                                d = SquareRoot((ShipStack[c].tx-x)*(ShipStack[c].tx-x) + (ShipStack[c].ty-y)*(ShipStack[c].ty-y))
                                debug msg("STOP")
                            }
                        
                            ShipStack[c].current_acc = ShipStack[c].current_acc - (ship.engine.acceleration * 6.5)
                            ship.move_speed = ship.move_speed + ShipStack[c].current_acc
                                if ship.move_speed < 10. { /*STOP*/ }
                                else {
                                    // BRAKING
                                    if d < 55. { d = 100. }
                                    asd = ((ship.move_speed * UPDATE_PERIOD) / d)
                                    ShipStack[c].vx = (ShipStack[c].tx - x) * asd
                                    ShipStack[c].vy = (ShipStack[c].ty - y) * asd
                                        if (x + ShipStack[c].vx + 25. > GetRectMaxX(gg_rct_PlayableArea) or \
                                            x + ShipStack[c].vx + -25. < GetRectMinX(gg_rct_PlayableArea) or \
                                            y + ShipStack[c].vy + 25. > GetRectMaxY(gg_rct_PlayableArea) or \
                                            y + ShipStack[c].vy + -25. < GetRectMinY(gg_rct_PlayableArea)) 
                                        { /*MAP BOUNDS*/  }
                                        else {
                                            //SetUnitPosition(ShipStack[c].owner, x + ShipStack[c].vx, y + ShipStack[c].vy)
                                            SetUnitX(ShipStack[c].owner, x + ShipStack[c].vx)
                                            SetUnitY(ShipStack[c].owner, y + ShipStack[c].vy)
                                        }
                                }
                    }
                }
    }
    
    private void OrderDebug(){
        int h = H2I(GetExpiredTimer())
        Spaceship st = GetData(LoadUnitHandle(hash, h, 0))
        
            st.stop_order_lock = true
            IssueImmediateOrderById(st.owner, order_stop)
            FlushChildHashtable(hash, h)
            DT(GetExpiredTimer())
    }
    
    
    
    private void ObjMovementUpdate(){
        int i = 0
        real x, y
        
            while(i++ < Current_Objects) {
                if IsUnitType(ObjS[i].owner, UNIT_TYPE_DEAD) {
                    ObjS[i].destroy()
                    ObjS[i] = ObjS[Current_Objects]
                    Current_Objects--
                }
            }
            
            i = 0
            while(i++ < Current_Objects){
                x = Gx(ObjS[i].owner); y = Gy(ObjS[i].owner)
                if (x + ObjS[i].vx + 25. > GetRectMaxX(gg_rct_PlayableArea) or \
                    x + ObjS[i].vx + -25. < GetRectMinX(gg_rct_PlayableArea) or \
                    y + ObjS[i].vy + 25. > GetRectMaxY(gg_rct_PlayableArea) or \
                    y + ObjS[i].vy + -25. < GetRectMinY(gg_rct_PlayableArea)) 
                { KillUnit(ObjS[i].owner) }
                else {
                    SetUnitX(ObjS[i].owner, x + ObjS[i].vx)
                    SetUnitY(ObjS[i].owner, y + ObjS[i].vy)
                
                }
            }
    }
    
    
    void RandomMoving(unit source, real angle){
        real mod
            Current_Objects++
            ObjS[Current_Objects] = MovingObject.new(source)
            mod = ((RndR(15., 40.) * UPDATE_PERIOD) / (GetRectMaxX(gg_rct_PlayableArea) * 2.))
            ObjS[Current_Objects].vx = ((Gx(source) + Rx(100., Ga(source))) - Gx(source)) * mod
            ObjS[Current_Objects].vy = ((Gy(source) + Ry(100., Ga(source))) - Gy(source)) * mod
                if Current_Objects == 1 {
                    TimerStart(ObjectsUpdateTimer, UPDATE_PERIOD, true, function ObjMovementUpdate)
                }
    }
    
    
    
    void MoveShip(unit source, real x, real y){
        Spaceship ship = GetData(source)
        real start_x = Gx(source), start_y = Gy(source)
        real angle = ABUC(source, x, y), distance = SquareRoot((x-start_x)*(x-start_x) + (y-start_y)*(y-start_y))
        int c = 0
        timer t = CT
           // Ordered = source
            SaveUnitHandle(hash, GetHandleId(t), 0, source)
            TimerStart(t, 0., false, function OrderDebug)
            t = null
            //SetUnitAnimation(source, "walk")
            //msg(R2S(distance))
            
                if ship.move_speed > 0. {
                
                    //msg("already moving")
                    
                    while(c++ < CurrentShip){
                        if ShipStack[c].owner == source {
                            ShipStack[c].angle = angle
                            ShipStack[c].side = WhichSide(source, x, y)
                            if angle < 0. { angle += 360. }
                            
                                if Ga(source) < angle { 
                                    ShipStack[c].ang = angle - Ga(source)
                                        if ShipStack[c].ang > 180. {
                                            ShipStack[c].ang = (Ga(source) - angle + 360.)
                                        }
                                }
                                else { 
                                    ShipStack[c].ang = Ga(source) - angle 
                                        if ShipStack[c].ang > 180. {
                                            ShipStack[c].ang = (angle - Ga(source) + 360.)
                                        }
                                }
                                
                            ShipStack[c].tx = x; ShipStack[c].ty = y
                            if ShipStack[c].current_acc < 1. { ShipStack[c].current_acc = INI_ACCELERATION }
                            ShipStack[c].stop = false
                            break
                        }
                    }
                }
                else {
                    ship.move_speed = 1. 
                    CurrentShip++
                    ShipStack[CurrentShip] = ShipMoveData.create(source)
                    ShipStack[CurrentShip].current_acc = INI_ACCELERATION
                    ShipStack[CurrentShip].angle = angle
                    ShipStack[CurrentShip].side = WhichSide(source, x, y)
                    
                        if angle < 0. { angle += 360. }
                            if Ga(source) < angle { 
                                ShipStack[CurrentShip].ang = angle - Ga(source)
                                    if ShipStack[CurrentShip].ang > 180. {
                                        ShipStack[CurrentShip].ang = (Ga(source) - angle + 360.)
                                    }
                            }
                            else {
                                ShipStack[CurrentShip].ang = Ga(source) - angle 
                                    if ShipStack[CurrentShip].ang > 180. {
                                        ShipStack[CurrentShip].ang = (angle - Ga(source) + 360.)
                                    }
                            }
                            
                    ShipStack[CurrentShip].turnrate = START_TURNRATE
                    x = start_x + Rx(distance, Ga(source))
                    y = start_y + Ry(distance, Ga(source))
                    ShipStack[CurrentShip].tx = x; ShipStack[CurrentShip].ty = y
                    ShipStack[CurrentShip].vx = (x - start_x) * ((ship.move_speed * UPDATE_PERIOD) / distance)
                    ShipStack[CurrentShip].vy = (y - start_y) * ((ship.move_speed * UPDATE_PERIOD) / distance)
                        //if CurrentShip == 1 {
                            //TimerStart(UpdateTimer, PERIOD, true, function ShipMovementUpdate)
                       // }
                }
    }
    
    
    public void StartClock(real period){
        TimerStart(UpdateTimer, period, true, function ShipMovementUpdate)
    }
    

    private void Init(){
        
        
    }

endlibrary
Там же простая система без инерции, просто таймром двигается юнит, только угол ограничен.
как бы нет, с инерцией
3
32
5 лет назад
3
Hate, а без этого будет работать?
раскрыть
Пиначет: безалкогольное пиво - как секс с сестрой. ощущения похожи, но это неправильно!
3
26
5 лет назад
3
Bergi_Bear:
Hate, а без этого будет работать?
раскрыть
Пиначет: безалкогольное пиво - как секс с сестрой. ощущения похожи, но это неправильно!
это самая мастхевная часть, без нее ничего не будет работать
Чтобы оставить комментарий, пожалуйста, войдите на сайт.