Tuesday, July 5, 2022
HomeGame Developmentarithmetic - javascript high down circle to circle easy collision detection

arithmetic – javascript high down circle to circle easy collision detection


BH
<br>
sport take a look at second<br>
<meta charset="utf-8">
<button onclick="begin()" class=wow>okay</button>
<canvas id=can>

</canvas>
<fashion>
    canvas{
        width:100%;
        peak:100%;
        place:absolute;
        high:0;  
        left:0px
    }

    .wow{
        float:proper;
        z-index:1298737198
    }

</fashion>
<script>
var aD =[]
var r
operate begin() {
    r = new CanvasRenderer(can),
        my = new scene();
    window.my = my
    eventHandler();
    my.add(new mesh({
        verts: [
            0,   0,
            100, 15,
            115, 60,
            50, 100,
            20, 75,2,8
        ],
        place: {
            x: 100,
            y:100
        },
        scale: {

            x:4,y:5
        },
        colour:"orange",
        onupdate(me) {
        //  me.place.x++
        }
    }));
    
    my.add(new mesh({
        place:{
            x:700,
            y:200
        },
        radius:70,
        colour:"yellow",
        primitive:"circle",
        collision:"circle"
    }))
    
    var g = false
    corn=false
    nv = [0,0]
    my.add(new mesh({
        primitive:"rect",
        identify: "participant",
        scale: {
            x: 50,
            y:50
        },
        place: {
            x: 311,
            y:75
        },
        origin: {
            x:0.5,
            y:0.5
        },
        onupdate(me) {
            

            aD.push( () => {
                r.ctx.beginPath()
                r.ctx.fillStyle="pink"
                r.ctx.arc(me.place.x, me.place.y, 5, 0, Math.PI*2);
                r.ctx.fill()
                r.ctx.closePath();
            })
            if(!window.pl)pl=me
            var upKey = keys[38],
                downKey = keys[40],
                rightKey = keys[39],
                leftKey = keys[37],
                drx  = 0,
                dx = 0,
                velocity = 5,
                turningSpeed = 3
            
            drx = leftKey ? -1 : rightKey ? 1 : 0
            ahead = upKey ? 1 : downKey ? -1 : 0

            me.rotation.x += (
                (drx * Math.PI / 180 * turningSpeed )
            )
            me.rotation.y = 1;

            var xDir = Math.cos(me.rotation.x)
            var yDir = Math.sin(me.rotation.x)
            
            var xvl = xDir  * ahead * velocity
            var yvl = yDir * ahead * velocity
            if(nv[0]||nv[1]){
                //xvl = -nv[0]
                //yvl = -nv[1]
            }
            me.place.y//=col.y
            me.place.x// = col.x
            me.xvl=xvl
            me.yvl=yvl
            var subsequent = {
                x:me.place.x+xvl,
                y:me.place.y+yvl
            }
            me.subsequent=subsequent
            var isColliding = []
            var lastdify = 0;
            var lastdifx = 0;
            var dify = 0
            var difx = 0
            var coll;
            var curColls = []
            me.cols=[]

            me.velocity=velocity
            me.yDir=yDir
            for(var i = 0; i < my.objects.size; i++) {
                let cur = my.objects[i];
                if(cur.identify == me.identify || cur == me) {
                    break;  
                }
                curColls = checkCollision(
                    subsequent.x,
                    subsequent.y,
                    me.radius||me.scale.x/2,
                    cur
                )
                
                
                curColls.forEach(coll=>{
                    if(!coll) return;
                    if(coll==me) {
                    //  console.log("WH")
                        return  
                    }
                    
                    
                    cur.isCol=true
                    isColliding.push({coll,object:cur}) 
                    //  console.log(2222,coll.line)

                })
            }
            
            Array.from(me.cols)
                .forEach(q=>{
                    var w=isColliding.indexOf(q)
                    if(w==-1||q.object==me){
                        me.cols.splice(me.cols.indexOf(q),1)
                    }
                    

            })
            var isme=me.cols.findIndex(q=>q.object==me)
            if(isme>-1){
                me.cols.splice(isme,1)
                var okay=isColliding.findIndex(q=>q.object==me)
                if(okay>-1){
                    isColliding.splice(okay,1)    
                }
            }
            if(!me.obs)
                me.obs=[]
            var noad=false
            if(isColliding.size > 0) {
            
                isColliding.forEach(q=>{
                    var w = me.cols.indexOf(q)
                    if(w==-1){
                        me.cols.push(q) 
                    }
                })
                
                
                
                
                
                var col =me.cols[0].coll
                var ob=me.cols[0].object
                if(!me.obs)
                    me.obs=[]
                
                //console.log("COL",col.sort,col.identify)
                ob.energetic=false
                ob.wowow=292
                var op=[0,0]
                //corn=false
            //  if(col.sort=="mesh") console.log("wow")
            //  console.log("Ok",col.x,col.y,me.cols.size,isColliding.size,isme)
                
                if(isColliding.size==1){
                    
                    if(me.obs.size>0){
                        console.log("undid")
                        me.obs.forEach(ob=>{
                            //if(ob.energetic) {
                                ob.lastPoint = null 
                                me.obs.splice(me.obs.indexOf(ob),1)
                            //}
                        })
                    }
                    var backlash = col.x
                    var backlashy = col.y
                    
                    if(col.sort=="circle"){
                        let vecBetweenX = me.place.x - ob.place.x;
                        let vecBetweenY = me.place.y - ob.place.y;
                        
                        let heading = Math.atan2(vecBetweenY, vecBetweenX);
                        
                    
                        
                        
                        var rt= me.rotation.x+heading
                        
                        
                        var ax = Math.cos(rt)*velocity*ahead
                        var ay = Math.sin(rt)*velocity*ahead
                        
                        difx = -ax
                        dify = -ay
                        
                        me.place.x +=difx
                        me.place.y += dify
                    //  return
                        
                        
                    } else {
                        difx += col.x-next.x
                        dify += col.y-next.y
                    }
                }else {
                    me.eq=false
                    me.curc=null
                    ob.energetic=true 
                    if(!col.line) return;
                    var xd = col.line.finish[0]-col.line.begin[0]
                    var slope1=slope(col.line)
                    
                    var b = findb(col.x,col.y,slope1)
                    var amy = slope1
                    var amx = Math.abs(xd)
                        
                    var y;
                    if(!ob.lastPoint) {
                        y = col.y+amy
                    } else {
                        y = ob.lastPoint.y+amy; 
                        ob.lastPoint.y+=amy;
                    }
                    var x = xatywithslope(y,slope1,b)

                    me.tst={
                        b,x,y,slope1,amx,amy    
                    }
                    
                
                    if(col.percentOfWall == 0 || col.percentOfWall == 1){
                        me.eq=true
            
                        difx += x-next.x
                        dify += y-next.y
                        
                        if(!ob.lastPoint){
                            ob.lastPoint = {
                                x:col.x+amx,
                                y:col.y+amy
                            }
                            
                            me.obs.push(ob)
                        }
                    } else {
                
                        me.curc=col;
                        difx += col.x-next.x
                        dify += col.y-next.y
                        
                        
                        lastdify = dify
                        lastdifx = difx

                        if(difx>0)
                            nv[0] = difx
                        if(dify>0)
                            nv[1]=dify

                    }


                }
                dify+=op[1]
                difx+=op[0] 
            }
            
            if(!noad) {
                //xvl+=difx
                //yvl+=dify

                me.place.x+=difx+xvl
                me.place.y+=dify+yvl

            } else {
            //  xvl+=nv[0]//*ahead
        //      yvl-=nv[1]//*ahead
            }
            if(noad) {
                
            } else {
                
            }
        }

    }));
    
    let i = setInterval(() => render(r, my), 16);
    r.on("resize", () => render(r, my));

}

operate angleOf2points(p1,p2) {
    return Math.atan2(p2[1] - p1[1], p2[0] - p1[0])
        //* 180 / Math.PI   
}
operate xatywithslope(y,slope,b){
    /*y=mx+b
    mx=y-b
    x=(y-b)/m
    
    */
    return (y-b)/slope
}
    
operate findb(x,y,s){
    /*y=mx+b
    y-mx=b
    b=y-mx
    */
    return y-s*x
}
operate slope(line){
    var p1=line.begin
    var p2=line.finish
    return (
        (p1[1]-p2[1]) /
        (p1[0]-p2[0])
    )
}
    
operate midSlope(slope1,slope2) {
    return -Math.tan(
        (
            Math.atan(slope1) +     
            Math.atan(slope2)
        ) / 2
    )
}
operate checkCollision(x1, y1,rad,ob) {
    var colls = [];
    if(ob.collision == "circle") {
        /*
            Ball 1:  heart: p1=(x1,y1)  radius: r1
            Ball 2:  heart: p2=(x2,y2)  radius: r2

            collision distance: R= r1 + r2
            precise distance:    r12= sqrt( (x2-x1)^2 + (y2-y1)^2 )

            collision vector: d12= (x2-x1,y2-y1) = (dx,dy)
            precise distance:  r12= sqrt( dx*dx + dy*dy )
        */
        
        var r1 = rad;
        var r2 = ob.radius;
        
        var p1 = [x1,y1]
        var p2 = [ob.position.x,ob.position.y]
        
        var R = r1 + r2;
        var R2 = R * R;
        
        var dx = p2[0] - p1[0]
        var dy = p2[1] - p1[1]
        
        var r12 = (
            dx * dx + dy * dy
        )
        
        var r12s = Math.sqrt(r12)
        
        var isCollision = r12s < R
        
        var colPoint = {
            x:(x1*r2 + p2[0]*r1) / 
                (r1+r2),
            y:(y1*r2+p2[1]*r1) /
                (r1+r2),
            sort:"circle"
        };

        aD.push( () => {
            r.ctx.beginPath()
            r.ctx.fillStyle="salmon"
            r.ctx.arc(colPoint.x, colPoint.y, 5, 0, Math.PI*2);
            r.ctx.fill()
            r.ctx.closePath();
        })

        if(isCollision) {
            colls.push(colPoint)
        }
    } else {
//      console.log("cecking",rad,ob)
        ob.lineSegments.forEach(l => {
            var dist = distance2(
                l.begin[0],
                l.begin[1],

                l.finish[0],
                l.finish[1]
            ),
                vec1 = [
                    x1 - l.start[0],
                    y1 - l.begin[1]
                ],

                vec2 = [
                    l.end[0] - l.begin[0],
                    l.finish[1] - l.begin[1]
                ],

                percentOfWall = (
                    Math.max(
                        0,
                        Math.min(
                            1, 
                            dot(
                                vec1[0],
                                vec1[1],

                                vec2[0],
                                vec2[1]
                            ) / dist
                        )
                    )
                ),
                projection = [
                    l.start[0] + percentOfWall * vec2[0],
                    l.begin[1] + percentOfWall * vec2[1],
                ],
                acDist = Math.sqrt(distance2(
                    x1, y1,
                    projection[0], projection[1]
                ))
            aD.push( () => {
                r.ctx.beginPath()
                r.ctx.fillStyle="inexperienced"
                r.ctx.arc(projection[0], projection[1], 5, 0, Math.PI*2);
                r.ctx.fill()
                r.ctx.closePath();
            })


            if(acDist < rad) {
                aD.push(() => {
                    r.ctx.beginPath()
                    r.ctx.fillStyle="orange"
                    r.ctx.arc(projection[0] + 

                    rad * (regular[1] ), projection[1] + 
                    rad* (-normal[0] ), 5, 0, Math.PI*2);
                    r.ctx.fill()
                    r.ctx.closePath()
                })
                var magazine = Math.sqrt(dist),
                    delt = [
                        l.end[0] - l.begin[0],
                        l.finish[1] - l.begin[1]
                    ],
                    regular = [
                        delt[0] / magazine,
                        delt[1] / magazine
                    ]

                colls.push({
                    percentOfWall,
                    sort:"mesh",
                    x: projection[0] + 

                    rad * (regular[1] ),

                    y:projection[1] + 
                    rad* (-normal[0] ),
                    projection,
                    regular,
                    line:l
                })
            }
        })
    }
    
    return colls;

                    
}

operate checkCollision1(x1, y1, rad,l) {
    var dist = distance2(
        l.begin[0],
        l.begin[1],

        l.finish[0],
        l.finish[1]
    ),
        vec1 = [
            x1 - l.start[0],
            y1 - l.begin[1]
        ],

        vec2 = [
            l.end[0] - l.begin[0],
            l.finish[1] - l.begin[1]
        ],

        percentOfWall = (
            Math.max(
                0,
                Math.min(
                    1, 
                    dot(
                        vec1[0],
                        vec1[1],

                        vec2[0],
                        vec2[1]
                    ) / dist
                )
            )
        ),
        projection = [
            l.start[0] + percentOfWall * vec2[0],
            l.begin[1] + percentOfWall * vec2[1],
        ],
        acDist = Math.sqrt(distance2(
            x1, y1,
            projection[0], projection[1]
        ))
    aD.push( () => {
        r.ctx.beginPath()
        r.ctx.fillStyle="inexperienced"
        r.ctx.arc(projection[0], projection[1], 5, 0, Math.PI*2);
        r.ctx.fill()
        r.ctx.closePath();
    })


    if(acDist < rad) {
        var magazine = Math.sqrt(dist),
            delt = [
                l.end[0] - l.begin[0],
                l.finish[1] - l.begin[1]
            ],
            regular = [
                delt[0] / magazine,
                delt[1] / magazine
            ]

        return {

            x: projection[0] + 

            rad * (regular[1] ),

            y:projection[1] + 
            rad* (-normal[0] ),
            projection,
            regular
        }
    }

                    
}


operate dot(x1, y1, x2, y2) {
    return (
        x1 * x2 + y1 * y2
    )
}

operate distance2(x1, y1, x2, y2) {
    let dx = (x1 - x2), dy = (y1 - y2);
    return (
        dx * dx + dy * dy
    );
}

operate render(r,s) {
//r.ctx.clearRect(0,0,r.ctx.canvas.width,r.ctx.canvas.peak)
    s.replace();
    r.render(s)
    aD.forEach(x=>x());
    aD = []
}

onload = begin;

operate eventHandler() {
    window.keys = {};
    addEventListener("keyup" , e=> {
        keys[e.keyCode] = false;
            
    });

    addEventListener("keydown" , e=> {
        keys[e.keyCode] = true;
    });
}

operate CanvasRenderer(dom) {
    if(!dom) dom = doc.createElement("canvas");
    
    var occasions = {}, self = this;
    operate rsz() {
        dom.width = dom.clientWidth;
        dom.peak = dom.clientHeight;
        self.dispatchEvent("resize");
    }
    
    window.addEventListener("resize", rsz); 

    let ctx = dom.getContext("second");

    operate render(scene) {
        ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.peak);
        for(let i = 0; i < scene.objects.size; i++) {
            let o = scene.objects[i],
                verts = o.realVerts;

            
            if(o.primitive == "circle") {
                var fnc = o.drawPrimitive[o.primitive]
                if(typeof(fnc)=="operate")
                    fnc(ctx)
            } else {
                
                ctx.beginPath();
                ctx.moveTo(
                    verts[0] , 

                    verts[1]
                );
                verts.forEach((v, i, ar) => {
                    let y = i;



                    ctx.lineTo(
                        v[0] , 

                        v[1]
                    );

                });
                ctx.lineTo(
                    verts[0],
                    verts[1] 
                );
                
                ctx.closePath();
            }
            
            ctx.fillStyle = o.colour || "blue";
            ctx.lineWidth = 1;
            ctx.fill()
            ctx.stroke();
        }
    }

    Object.defineProperties(this, {
        domElement: {
            get: () => dom
        },  
        ctx: {
            get: () => ctx
        },
        render: {
            get: () => render
        },
        on: {
            get: () => (nm, cb) => {
                if(!occasions[nm]) {
                    occasions[nm] = [];
                }
                occasions[nm].push(information => {
                    if(typeof cb == "operate") {
                        cb(information);
                    }
                });
            }       
        },
        dispatchEvent: {
            get: () => (identify, information) => {
                if(occasions[name]) {
                    occasions[name].forEach(x => {
                        x(information);
                    });
                }
            }
        }
    });
    
    rsz();

}

operate scene() {
    let objects = [];
    Object.defineProperties(this, {
        add: {
            get: () => obj => {
                objects.push(obj);
            }
        },
        objects: {
            get: () => objects
        },
        replace: {
            get: () => () => {              
                objects.forEach(x => {
                    if(typeof x.replace == "operate") {
                        x.replace();
                    }
                });
                
            }
        }
    });
}
    

operate mesh(information={}) {
    let verts = [],
        self = this,
        holder = {
            place:{},
            scale: {
                
            },
            rotation: {},
            origin:{}
        },
        precise = {
    
        },
        place = {},
        scale = {},
        rotation = {},
        collision="mesh",
        form = null,
        origin = {},
        colour,
        radius=0,
        identify,
        primitive,
        eventNames = "replace",
        occasions = {},
        
        drawPrimitive = {
            circle(ctx) {
                ctx.beginPath();
                ctx.arc(
                    self.place.x,
                    self.place.y,
                    radius, 
                    0,
                    360 * Math.PI / 180
                );
                ctx.closePath();
            },
            rect(ctx) {
                ctx.strokeRect(
                    self.place.x,
                    self.place.y,
                    30, 30
                );
            }
        },
        width = 1,
        peak = 1,
        primitiveToVerts = {
            rect: () =>  [
                    0, 0,
                    width , 0,
                    width, height,
                    0, height
            ]
        },
        realVerts = verts,
        lineSegments = [],
        o = this;
    
    operate updateRealVerts() {
            
            let  actualVerts = [],
                originedVerts = [],
                adjustedVerts = [],
                rotatedVerts = [],
                stepSize = o.step || 2,
                curVerts = [];
            
            o.verts.forEach((v, i) => {
                curVerts.push(v);
                if(
                    (i - 1) % stepSize === 0 &&
                    i !== 0
                ) {
                    actualVerts.push(curVerts);
                    curVerts = [];
                }
            });
            actualVerts = actualVerts.filter(x => x.size == stepSize);
            
            originedVerts = actualVerts.map(v => [
                v[0] - o.origin.x,
                v[1] - o.origin.y,
                v[2] - o.origin.z
            ]);
    
            rotatedVerts = originedVerts.map(v => 
                [

                    v[0] * Math.cos(o.rotation.x) - 
                    v[1] * Math.sin(o.rotation.x),

                    v[0] * Math.sin(o.rotation.x) + 
                    v[1] *Math.cos(o.rotation.x),
v[2]
                ]
            );

            adjustedVerts = rotatedVerts.map(v => 
                [
                    v[0] * 
                    o.scale.x + 
                    o.place.x,
    
                    v[1] * 
                    o.scale.y + 
                    o.place.y,

                    v[2] * 
                    o.scale.z + 
                    o.place.z,
                ]
            );

            realVerts = adjustedVerts;
            updateLineSegments();
    }   

    operate updateLineSegments() {
                let traces = [];
                for(let i = 0, a = realVerts; i < a.size;i++) {
                    let begin = [], finish = []
                    if(i < a.size - 1) {
                        begin = a[i];
                        finish = a[i + 1];
                    } else {
                        begin = a[i];
                        finish = a[0];
                    }

                    traces.push({
                        begin, finish
                    })
                }
                lineSegments = traces;
    }
    Object.defineProperties(place, {
        x: ,
        y: ,
        z: 
    });

    Object.defineProperties(scale, {
        x: ,
        y:  1,
            set: v => holder.scale.y = v
        ,
        z:  1,
            set: v => holder.scale.z = v
        
    });

    Object.defineProperties(rotation, {
        x:  0,
            set: v => holder.rotation.x = v
        ,
        y: ,
        z: 
    });

    Object.defineProperties(origin, {
        x: ,
        y:  0,
            set: v => holder.origin.y = v
        ,
        z: 
    });
    

    Object.defineProperties(this, {
        verts: {
            get: ()=>verts,
            set(v) {
                verts = v
            }
        },
        
        form: {
            get: ()=>form,
            set(v) {
                form = v
            }
        },
        identify: {
            get: ()=>identify,
            set(v) {
                identify = v
            }
        },
        primitive: {
            get: ()=>primitive,
            set(v) {
                primitive = v;
                let newVerts = primitiveToVerts[v];
                if(newVerts) {
                    this.verts = newVerts();
                }
            }
        },
        
        drawPrimitive: {
            get: ()=>drawPrimitive
        },
        width: {
            get: ()=>width,
            set(v) {
                width = v
            }
        },
        peak: {
            get: ()=>peak,
            set(v) {
                peak = v
            }
        },
        place: {
            get: () => place,
            set: v => 
        },
        
        radius: {
            get: () => radius||(width*scale.x)/2,
            set: v => {
                radius = v;
                this.width = radius/2
                this.peak = radius/2
            }
        },
        scale: {
            get: () => scale,
            set: v =>  v.x === 0 ? v.x : 1;
                scale.y = v.y  
        },
        rotation: {
            get: () => rotation,
            set: v =>  0;
            
        },
        origin: {
            get: () => origin,
            set: v => 
        },
        colour: {
            get: () => colour,
            set: v => {
                colour = v;
            }
        },
        realVerts: {
            get: () => realVerts
        },
        lineSegments: {
            get: () => lineSegments
        },
        replace: {
            get: () => () => {
                if(occasions["update"]) {
                    occasions.replace.forEach(x => {
                        updateRealVerts();
                        x(this);
                    });
                }
            }
        },
        on: {
            get: () => (nm, fnc) => {
                if(!occasions[nm]) occasions[nm] = [];
                occasions[nm].push(stuff => {
                    if(typeof fnc == "operate") {
                        fnc(stuff);
                    }
                });
            }
        }
    });

    eventNames.cut up(" ").forEach(x => {
        var identify = "on" + x;
        if(!this.hasOwnProperty(identify)) {
            Object.defineProperty(this, identify, {
                get: () => occasions[name],
                set(v) {
                    occasions[x] = [
                        data => {
                            typeof v == "function" && v(data)
                        }
                    ];
                }
            });
        }
    });

    for(let ok in information) {
        this[k] = information[k]
    }

    updateRealVerts();

}
</script>
RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments