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

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

делать свою систему движения
желательно хорошее владение алгоритмами и стаками, а еще лучше жассом. тогда можем поговорить
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
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, а без этого будет работать?
раскрыть
Пиначет: безалкогольное пиво - как секс с сестрой. ощущения похожи, но это неправильно!
это самая мастхевная часть, без нее ничего не будет работать
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.