p5. js Функция не вызывается рекурсивно при необходимости - PullRequest
0 голосов
/ 07 февраля 2020

У меня есть небольшая программа, которая потребовала, чтобы я написал две функции, которые вызываются другой функцией, которую я не могу изменить. Программа должна отображать автомобиль, проезжающий две полосы движения traffi c, и когда наша машина приближается слишком близко к одной впереди, она должна менять полосы снова и снова. Тем не менее, в настоящее время он переключает полосы движения на первой машине, с которой встречается, но однажды на новой полосе движения он не продолжает это делать. Я полагаю, что он обходит массив других автомобилей один раз и правильно идентифицирует первую полосу смены, но после смены полосы он не пересекает массив снова, чтобы выяснить, когда менять снова. Вот две функции, которые я написал.

function change_lanes(vehicle)
{

    if (vehicle.Coord_X == Lane_PositionB) {
            vehicle.Coord_X = Lane_PositionA;
    }

    if (vehicle.Coord_X == Lane_PositionA) {
            vehicle.Coord_X = Lane_PositionB;
    }

    return vehicle;

    /*
    This function should do the following: 
     - move vehicle from one lane to the other.
     - do the move in a single step without any extra animation.
     - use Lane_PositionA and Lane_PositionB to effect the change.
     - finally you should return vehicle at the end of the function.
     hint: You will need to modify the Coord_X property of vehicle.
    */
}


function vehicle_infront( TargetVehicleA, TargetVehicleB )
{    
    if (TargetVehicleB.Dist_Amnt - TargetVehicleA.Dist_Amnt < 200 && TargetVehicleB.Coord_X == 
    TargetVehicleA.Coord_X) {
        return TargetVehicleB.Licence_Plate;
    }

    else {
        return false;
    }
    /*
    This function should do the following: 
    - determine if TargetVehicleA is in the same lane and less than 200px behind TargetVehicleB.
    - do this by comparing the two cars' Dist_Amnt properties
    - if these requirements are met then return the Licence_Plate property for TargetVehicleB. Otherwise 
    return false.
    */
}

А вот программа в целом, большинство из которых я не могу изменить, за исключением функций move_car, change_lanes и vehicle_infront. Функция move_cars работает так, как задумано.

function move_car()
{
    SleuthPI_CarObject.Dist_Amnt += SleuthPI_CarObject.Speed_Amount;
    SleuthPI_CarObject.Shudder_Amt += random(-0.09, 0.09);
    SleuthPI_CarObject.Shudder_Amt = constrain(SleuthPI_CarObject.Shudder_Amt, 0.01, 0.86);
    drive_car_engine(SleuthPI_CarObject);
    /*
    This function should do the following: 
     - increment SleuthPI_CarObject's Dist_Amnt property by its Speed_Amount property 
     - add a random amount between -0.09 and 0.09 to SleuthPI_CarObject's Shudder_Amt property
     - use the constrain function to constrain SleuthPI_CarObject's Shudder_Amt property to values between 0.01 and 0.86
     - call the drive_car_engine function passing SleuthPI_CarObject as an argument
    */
}


function change_lanes(vehicle)
{

    if (vehicle.Coord_X == Lane_PositionB) {
            vehicle.Coord_X = Lane_PositionA;
    }

    if (vehicle.Coord_X == Lane_PositionA) {
            vehicle.Coord_X = Lane_PositionB;
    }

    return vehicle;

    /*
    This function should do the following: 
     - move vehicle from one lane to the other.
     - do the move in a single step without any extra animation.
     - use Lane_PositionA and Lane_PositionB to effect the change.
     - finally you should return vehicle at the end of the function.
     hint: You will need to modify the Coord_X property of vehicle.
    */
}


function vehicle_infront( TargetVehicleA, TargetVehicleB )
{    
    if (TargetVehicleB.Dist_Amnt - TargetVehicleA.Dist_Amnt < 200 && TargetVehicleB.Coord_X == TargetVehicleA.Coord_X) {
        return TargetVehicleB.Licence_Plate;
    }

    else {
        return false;
    }
    /*
    This function should do the following: 
     - determine if TargetVehicleA is in the same lane and less than 200px behind TargetVehicleB.
     - do this by comparing the two cars' Dist_Amnt properties
     - if these requirements are met then return the Licence_Plate property for TargetVehicleB. Otherwise return false.
    */
}


//////////////DO NOT CHANGE CODE BELOW THIS LINE//////////////////

var SleuthPI_CarObject;

var roadWidth;
var roadLeftEdge;
var Lane_PositionA;
var Lane_PositionB;
var carImages = {};

var TrafficObjectsData = [
{ Coord_X: 500, Coord_Y: 0, Dist_Amnt: -200, Vehicle_Category: 'whiteCar', Licence_Plate: 'LXG3I1', Speed_Amount: 2, exhaust: [  ]} , { Coord_X: 500, Coord_Y: 0, Dist_Amnt: 200, Vehicle_Category: 'whiteCar', Licence_Plate: 'KGBH8P', Speed_Amount: 2, exhaust: [  ]} , { Coord_X: 300, Coord_Y: 0, Dist_Amnt: 600, Vehicle_Category: 'redCar', Licence_Plate: 'HAYYY4', Speed_Amount: 2, exhaust: [  ]} , { Coord_X: 500, Coord_Y: 0, Dist_Amnt: 1000, Vehicle_Category: 'greenCar', Licence_Plate: 'RWT7GJ', Speed_Amount: 2, exhaust: [  ]} , { Coord_X: 500, Coord_Y: 0, Dist_Amnt: 1400, Vehicle_Category: 'greenCar', Licence_Plate: '1S5RC2', Speed_Amount: 2, exhaust: [  ]} , { Coord_X: 300, Coord_Y: 0, Dist_Amnt: 1800, Vehicle_Category: 'blueCar', Licence_Plate: 'PK1VGR', Speed_Amount: 2, exhaust: [  ]} , { Coord_X: 300, Coord_Y: 0, Dist_Amnt: 2200, Vehicle_Category: 'redCar', Licence_Plate: 'WSKG7D', Speed_Amount: 2, exhaust: [  ]} , { Coord_X: 300, Coord_Y: 0, Dist_Amnt: 2600, Vehicle_Category: 'redCar', Licence_Plate: 'M3E4RE', Speed_Amount: 2, exhaust: [  ]} , { Coord_X: 300, Coord_Y: 0, Dist_Amnt: 3000, Vehicle_Category: 'whiteCar', Licence_Plate: 'WGWU9B', Speed_Amount: 2, exhaust: [  ]} , { Coord_X: 500, Coord_Y: 0, Dist_Amnt: 3400, Vehicle_Category: 'redCar', Licence_Plate: '8VUW7S', Speed_Amount: 2, exhaust: [  ]} , { Coord_X: 500, Coord_Y: 0, Dist_Amnt: 3800, Vehicle_Category: 'redCar', Licence_Plate: '61LUIW', Speed_Amount: 2, exhaust: [  ]} , { Coord_X: 500, Coord_Y: 0, Dist_Amnt: 4200, Vehicle_Category: 'redCar', Licence_Plate: 'Z29GC3', Speed_Amount: 2, exhaust: [  ]} , { Coord_X: 300, Coord_Y: 0, Dist_Amnt: 4600, Vehicle_Category: 'blueCar', Licence_Plate: 'QAXRM5', Speed_Amount: 2, exhaust: [  ]} , { Coord_X: 300, Coord_Y: 0, Dist_Amnt: 5000, Vehicle_Category: 'redCar', Licence_Plate: 'OMEXAG', Speed_Amount: 2, exhaust: [  ]} , { Coord_X: 500, Coord_Y: 0, Dist_Amnt: 5400, Vehicle_Category: 'greenCar', Licence_Plate: 'INLMJB', Speed_Amount: 2, exhaust: [  ]} , { Coord_X: 300, Coord_Y: 0, Dist_Amnt: 5800, Vehicle_Category: 'whiteCar', Licence_Plate: '9WQSGY', Speed_Amount: 2, exhaust: [  ]} , { Coord_X: 300, Coord_Y: 0, Dist_Amnt: 6200, Vehicle_Category: 'whiteCar', Licence_Plate: 'YJ0KV3', Speed_Amount: 2, exhaust: [  ]} , { Coord_X: 300, Coord_Y: 0, Dist_Amnt: 6600, Vehicle_Category: 'blueCar', Licence_Plate: 'L2AY0Q', Speed_Amount: 2, exhaust: [  ]} , { Coord_X: 500, Coord_Y: 0, Dist_Amnt: 7000, Vehicle_Category: 'blueCar', Licence_Plate: 'ZV0CUT', Speed_Amount: 2, exhaust: [  ]} , { Coord_X: 500, Coord_Y: 0, Dist_Amnt: 7400, Vehicle_Category: 'whiteCar', Licence_Plate: 'Y4P174', Speed_Amount: 2, exhaust: [  ]} 
];



function preload()
{
    var carTypes = [
        "detective",
        "redCar",
        "greenCar",
        "blueCar",
        "whiteCar"
    ];

    for(var i = 0; i < carTypes.length; i++)
    {
        carImages[carTypes[i]] = loadImage("cars/" + carTypes[i] + ".png");
    }
}

function setup()
{
    createCanvas(800,800);

    roadWidth = 400;
    roadLeftEdge = 200;
    Lane_PositionA = 300;
    Lane_PositionB = 500;

    SleuthPI_CarObject = 
    {
        Coord_X: roadLeftEdge + roadWidth/4,
        Coord_Y: 550,
        Dist_Amnt: 0,
        Speed_Amount: 3,
        Shudder_Amt: 0,
        Vehicle_Category: 'detective',
        Licence_Plate: '5L3UTH',
        exhaust: []
    }


}



function draw()
{
    background(0);



    drawRoad();
    drawCars();

    ////////////////////// HANDLE DETECTIVE /////////////////////////


    move_car();
    for(var i = 0; i < TrafficObjectsData.length; i++)
    {
        var b2b = vehicle_infront(SleuthPI_CarObject, TrafficObjectsData[i]);
        if (b2b) {
            change_lanes(SleuthPI_CarObject);
        }
    }


    //////////////////////HANDLE THE OTHER CARS//////////////////////

    for(var i = 0; i < TrafficObjectsData.length; i++)
    {
        TrafficObjectsData[i].Dist_Amnt += TrafficObjectsData[i].Speed_Amount;
        TrafficObjectsData[i].Coord_Y = SleuthPI_CarObject.Coord_Y - TrafficObjectsData[i].Dist_Amnt + SleuthPI_CarObject.Dist_Amnt;
    }

}

/////////////////////////DRAWING FUNCTIONS////////////////////////

function drawRoad()
{
    stroke(100);
    fill(50);
    rect(roadLeftEdge,0,roadWidth,800);
    stroke(255);

    for(var i = -1; i < 20; i++)
    {
        line(
        roadLeftEdge + roadWidth/2 , i * 100 + (SleuthPI_CarObject.Dist_Amnt%100),
        roadLeftEdge + roadWidth/2 , i * 100 + 70 + (SleuthPI_CarObject.Dist_Amnt%100)
        );
    }
}

function drawCars()
{
    //draw the detective car

    image
    drawExhaust(SleuthPI_CarObject);
    image
    (
        carImages["detective"],
        SleuthPI_CarObject.Coord_X - carImages["detective"].width/2 + random(-SleuthPI_CarObject.Shudder_Amt, SleuthPI_CarObject.Shudder_Amt),
        SleuthPI_CarObject.Coord_Y + random(-SleuthPI_CarObject.Shudder_Amt, SleuthPI_CarObject.Shudder_Amt)
    );

    //draw all other cars

    for(var i = 0; i < TrafficObjectsData.length; i ++)
    {
        if(TrafficObjectsData[i].Coord_Y < height && TrafficObjectsData[i].Coord_Y > -height/2)
        {
            image(
            carImages[TrafficObjectsData[i].Vehicle_Category],
            TrafficObjectsData[i].Coord_X - carImages[TrafficObjectsData[i].Vehicle_Category].width/2,
            TrafficObjectsData[i].Coord_Y
            );
            drive_car_engine(TrafficObjectsData[i]);

            drawExhaust(TrafficObjectsData[i]);
        }
    }

}

function drive_car_engine(car)
{

    car.exhaust.push({size: 2, x: car.Coord_X, y: car.Coord_Y + carImages[car.Vehicle_Category].height});

    for(var i = car.exhaust.length -1; i >= 0 ; i--)
    {

        car.exhaust[i].y  += max(0.75, car.Speed_Amount/3);
        if(car.Vehicle_Category != "detective")car.exhaust[i].y += (SleuthPI_CarObject.Speed_Amount - car.Speed_Amount);
        car.exhaust[i].x += random(-1,1);
        car.exhaust[i].size += 0.5;

        if(car.exhaust[i].y  > height || car.exhaust[i].y < 0)
        {
            car.exhaust.splice(i,1);
        }
    }
}


function drawExhaust(car)
{
        noStroke();
        for(var i = 0; i < car.exhaust.length; i++)
        {
                var alpha = map(car.exhaust[i].size, 0, 40, 50,0);
                fill(125,alpha);
                ellipse(car.exhaust[i].x + 20, car.exhaust[i].y , car.exhaust[i].size);

        }
}

Любые идеи, в которых мои логики c не могут продолжать менять дорожки, приветствуются.

...