canvas实现鼠标控制方向2公里比赛游戏

代码语言:html

所属分类:游戏

代码描述:canvas实现鼠标控制方向2公里比赛游戏,纯js实现canvas游戏,无需第三方库

代码标签: 控制 方向 2公里 比赛 游戏

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">


</head>

<body style='margin:0;overflow:hidden'>
    <canvas id="c"></canvas>

    <script>
    //  HUE JUMPER - By Frank Force
    //  A 3D racing game in 2 Kilobytes!
    //
    //  Click = Start
    //  Mouse = Turn
    //  Double Click = Jump
    //
    //  The road ends at 1000...


    // draw settings
    const context = c.getContext`2d`; // canvas context
    const drawDistance = 800;         // how far ahead to draw
    const cameraDepth = 1;            // FOV of camera
    const segmentLength = 100;        // length of each road segment
    const roadWidth = 500;            // how wide is road
    const curbWidth = 150;            // with of warning track
    const dashLineWidth = 9;          // width of the dashed line
    const maxPlayerX = 2e3;           // limit player offset
    const mountainCount = 30;         // how many mountains are there
    const timeDelta = 1/60;           // inverse frame rate
    const PI = Math.PI;               // shorthand for Math.PI

    // player settings
    const height = 150;               // high of player above ground
    const maxSpeed = 300;             // limit max player speed
    const playerAccel = 1;            // player forward acceleration
    const playerBrake = -3;           // player breaking acceleration
    const turnControl = .2;           // player turning rate
    const jumpAccel = 25;             // z speed added for jump
    const springConstant = .01;       // spring players pitch
    const collisionSlow = .1;         // slow down from collisions
    const pitchLerp = .1;             // rate camera pitch changes
    const pitchSpringDamp = .9;       // dampen the pitch spring
    const elasticity = 1.2;           // bounce elasticity
    const centrifugal = .002;         // how much turns pull player
    const forwardDamp = .999;         // dampen player z speed
    const lateralDamp = .7;           // dampen player x speed
    const offRoadDamp = .98;          // more damping when off road
    const gravity = -1;               // gravity to apply in y axis
    const cameraTurnScale = 2;        // how much to rotate camera
    const worldRotateScale = .00005;  // how much to rotate world

    // level settings
    const maxTime = 20;               // time to start
    const checkPointTime = 10;        // add time at checkpoints
    const checkPointDistance = 1e5;   // how far between checkpoints
    const maxDifficultySegment = 9e3; // how far until max difficulty
    const roadEnd = 1e4;              // how far until end of road

    //////////////////////////////////////////////////////////////////
    // mouse input
    //////////////////////////////////////////////////////////////////

    mouseDown     =
    mousePressed  =
    mouseUpFrames =
    mouseX        = 0;

    onmouseup   =e=> mouseDown = 0;
    onmousedown =e=> mousePressed ? mouseDown = 1 : mousePressed = 1;
    onmousemove =e=> mouseX = e.x/window.innerWidth*2 - 1;

    //////////////////////////////////////////////////////////////////
    // math and helper functions
    //////////////////////////////////////////////////////////////////

    Clamp     =(v, a, b)  => Math.min(Math.max(v, a), b);
    ClampAngle=(a)        => (a+PI) % (2*PI) + (a+PI<0? PI : -PI);
        Lerp=(p, a, b)=> a + Clamp(p, 0, 1) * (b-a);
        R         =(a=1, b=0) => Lerp((Math.sin(++randSeed)+1)*1e5%1,a,b);
        LSHA      =(l,s=0,h=0,a=1)=>`hsl(${h+hueShift},${s}%,${l}%,${a})`;

        // simple 3d vector class
        class Vec3
        {
        constructor(x=0, y=0, z=0) {this.x = x; this.y = y; this.z = z;}

        Add=(v)=>(
        v = v < 1e5 ? new Vec3(v,v,v) : v,
            new Vec3( this.x + v.x, this.y + v.y, this.z + v.z ));

            Multiply=(v)=>(
            v = v < 1e5 ? new Vec3(v,v,v) : v,
                new Vec3( this.x * v.x, this.y * v.y, this.z * v.z ));
                }

                // draw a trapazoid shaped poly
                DrawPoly=(x1, y1, w1, x2, y2, w2, fillStyle)=>
                {
                context.beginPath(context.fillStyle = fillStyle);
                context.lineTo(x1-w1, y1|0);
                context.lineTo(x1+w1, y1|0);
                context.lineTo(x2+w2, y2|0);
                context.lineTo(x2-w2, y2|0);
                context.fill();
                }

                // draw outlined hud text
                DrawText=(text, posX)=>
                {
                // scale text so it works in tiny CodePen iframe
                const size = c.height/79;
                context.font = size+'em impact';         // set font size
                context.fillStyle = LSHA(99,0,0,.5);     // set font color
                context.fillText(text, posX, size*14);   // fill text
                context.lineWidth = size/2.5;            // line width
                context.strokeText(text, posX, size*14); // outline text

                /*
                context.font = '9em impact';         // set font size
                context.fillStyle = LSHA(99,0,0,.5); // set font color
                context.fillText(text, posX, 129);   // fill text
                context.lineWidth = 3;               // line width
                context.strokeText(text, posX, 129); // outline text
                */
                }

                //////////////////////////////////////////////////////////////////
                // build the road with procedural generation
                //////////////////////////////////////////////////////////////////

                roadGenLengthMax =                     // end of section
                roadGenLength =                        // distance left
                roadGenTaper =                         // length of taper
                roadGenFreqX =                         // X wave frequency
                roadGenFreqY =                         // Y wave frequency
                roadGenScaleX =                        // X wave amplitude
                roadGenScaleY = 0;                     // Y wave amplitude
                roadGenWidth = roadWidth;              // starting road width
                startRandSeed = randSeed = Date.now(); // set random seed
                road = [];                             // clear road

                // generate the road
                for( i = 0; i < roadEnd*2; ++i )          // build road past end
                    {
                    if (roadGenLength++ > roadGenLengthMax) // is end of section?
                    {
                    // calculate difficulty percent
                    d = Math.min(1, i/maxDifficultySegment);

                    // randomize road settings
                    roadGenWidth = roadWidth*R(1-d*.7,3-2*d);        // road width
                    roadGenFreqX = R(Lerp(d,.01,.02));               // X curves
                    roadGenFreqY = R(Lerp(d,.01,.03));               // Y bumps
                    roadGenScaleX = i>roadEnd ? 0 : R(Lerp(d,.2,.6));// X scale
                    roadGenScaleY = R(Lerp(d,1e3,2e3));              // Y scale

                    // apply taper and move back
                    roadGenTaper = R(99, 1e3)|0;                 // random taper
                    roadGenLengthMax = roadGenTaper + R(99,1e3); // random length
                    roadGenLength = 0;                           // reset length
                    i -= roadGenTaper;                           // subtract taper
                    }

                    // make a wavy road
                    x = Math.sin(i*roadGenFreqX) * roadGenScaleX;
                    y = Math.sin(i*roadGenFreqY) * roadGenScaleY;
                    road[i] = road[i]? road[i] : {x:x, y:y, w:roadGenWidth};

                    // apply taper from last section and lerp values
                    p = Clamp(roadGenLength / roadGenTaper, 0, 1);
                    road[i].x = Lerp(p, road[i].x, x);
                    road[i].y = Lerp(p, road[i].y, y);
                    road[i].w = i > roadEnd ? 0 : Lerp(p, road[i].w, roadGenWidth);

                    // calculate road pitch angle
                    road[i].a = road[i-1] ?
                    Math.atan2(road[i-1].y-road[i].y, segmentLength) : 0;
                    }

                    //////////////////////////////////////////////////////////////////
                    // init game
                    //////////////////////////////////////////////////////////////////

                    // reset everything
                    velocity = new Vec3
                    ( pitchSpring =  pitchSpringSpeed =  pitchRoad = hueShift = 0 );

                    position = new Vec3(0, height);           // set player start pos
                    nextCheckPoint = checkPointDistance;      // init next checkpoint
                    time = maxTime;                           // set the start time
                    heading = randSeed;                       // random world heading

                    //////////////////////////////////////////////////////////////////
                    // update and render frame
                    //////////////////////////////////////////////////////////////////

                    Update=()=>
                    {

                    // get player road segment
                    s = position.z / segmentLength | 0; // current road segment
                    p = position.z / segmentLength % 1; // percent along segment

                    // get lerped values between last and current road segment
                    roadX = Lerp(p, road[s].x, road[s+1].x);
                    roadY = Lerp(p, road[s].y, road[s+1].y) + height;
                    roadA = Lerp(p, road[s].a, road[s+1].a);

                    // update player velocity
                    lastVelocity = velocity.Add(0);
                    velocity.y += gravity;
                    velocity.x *= lateralDamp;
                    velocity.z = Math.max(0, time?forwardDamp*velocity.z:0);

                    // add velocity to position
                    position = position.Add(velocity);

                    // limit player x position (how far off road)
                    position.x = Clamp(position.x, -maxPlayerX, maxPlayerX);

                    // check if on ground
                    if (position.y < roadY)
                        {
                        position.y = roadY; // match y to ground plane
                        airFrame = 0;       // reset air frames

                        // get the dot product of the ground normal and the velocity
                        dp = Math.cos(roadA)*velocity.y + Math.sin(roadA)*velocity.z;

                        // bounce velocity against ground normal
                        velocity = new Vec3(0, Math.cos(roadA), Math.sin(roadA))
                        .Multiply(-elasticity * dp).Add(velocity);

                        // apply player brake and accel
                        velocity.z +=
                        mouseDown? playerBrake :
                        Lerp(velocity.z/maxSpeed, mousePressed*playerAccel, 0);

                        // check if off road
                        if (Math.abs(position.x) > road[s].w)
                        {
                        velocity.z *= offRoadDamp;                    // slow down
                        pitchSpring += Math.sin(position.z/99)**4/99; // rumble
                        }
                        }

                        // update player turning and apply centrifugal force
                        turn = Lerp(velocity.z/maxSpeed, mouseX * turnControl, 0);
                        velocity.x +=
                        velocity.z * turn -
                        velocity.z ** 2 * centrifugal * roadX;

                        // update jump
                        if (airFrame++<6 && time
                            && mouseDown && mouseUpFrames && mouseUpFrames<9)
                            {
                            velocity.y +=jumpAccel; // apply jump velocity
                            airFrame=9;            // prevent jumping again
                            }
                            mouseUpFrames=mouseDown? 0 : mouseUpFrames+1;

                            // pitch down with vertical velocity when in air
                            airPercent=(position.y-roadY) / 99;
                            pitchSpringSpeed +=Lerp(airPercent, 0, velocity.y/4e4);

                            // update player pitch spring
                            pitchSpringSpeed +=(velocity.z - lastVelocity.z)/2e3;
                            pitchSpringSpeed -=pitchSpring * springConstant;
                            pitchSpringSpeed *=pitchSpringDamp;
                            pitchSprin.........完整代码请登录后点击上方下载按钮下载查看

网友评论0