2024年Web前端最新【基于Html+CSS+JS的canvas赛车小游戏(效果+源码,面试官常问的问题以及巧妙的回答

总结

三套“算法宝典”

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

28天读完349页,这份阿里面试通关手册,助我闯进字节跳动

算法刷题LeetCode中文版(为例)

人与人存在很大的不同,我们都拥有各自的目标,在一线城市漂泊的我偶尔也会羡慕在老家踏踏实实开开心心养老的人,但是我深刻知道自己想要的是一年比一年有进步。

最后,我想说的是,无论你现在什么年龄,位于什么城市,拥有什么背景或学历,跟你比较的人永远都是你自己,所以明年的你看看与今年的你是否有差距,不想做咸鱼的人,只能用尽全力去跳跃。祝愿,明年的你会更好!

由于篇幅有限,下篇的面试技术攻克篇只能够展示出部分的面试题,详细完整版以及答案解析,有需要的可以关注

-webkit-box-pack: center;

-webkit-justify-content: center;

-ms-flex-pack: center;

justify-content: center;

min-height: 100vh;

}

canvas {

border-radius: .4em;

margin:20px auto;

}

var $ = {

canvas: null,

ctx: null,

canvas2: null,

ctx2: null,

colors: {

sky: “#D4F5FE”,

mountains: “#83CACE”,

ground: “#8FC04C”,

groundDark: “#73B043”,

road: “#606a7c”,

roadLine: “#FFF”,

hud: “#FFF”

},

settings: {

fps: 60,

skySize: 120,

ground: {

size: 350,

min: 4,

max: 120

},

road: {

min: 76,

max: 700,

}

},

state: {

bgpos: 0,

offset: 0,

startDark: true,

curve: 0,

currentCurve: 0,

turn: 1,

speed: 27,

xpos: 0,

section: 50,

car: {

maxSpeed: 50,

friction: 0.4,

acc: 0.85,

deAcc: 0.5

},

keypress: {

up: false,

left: false,

right: false,

down: false

}

},

storage: {

bg: null

}

};

$.canvas = document.getElementsByTagName(‘canvas’)[0];

$.ctx = $.canvas.getContext(‘2d’);

$.canvas2 = document.createElement(‘canvas’);

$.canvas2.width = $.canvas.width;

$.canvas2.height = $.canvas.height;

$.ctx2 = $.canvas2.getContext(‘2d’);

window.addEventListener(“keydown”, keyDown, false);

window.addEventListener(“keyup”, keyUp, false);

drawBg();

draw();

function draw() {

setTimeout(function() {

calcMovement();

//if($.state.speed > 0) {

. s t a t e . b g p o s + = ( .state.bgpos += ( .state.bgpos+=(.state.currentCurve * 0.02) * ($.state.speed * 0.2);

$.state.bgpos = $.state.bgpos % $.canvas.width;

. c t x . p u t I m a g e D a t a ( .ctx.putImageData( .ctx.putImageData(.storage.bg, $.state.bgpos, 5);

. c t x . p u t I m a g e D a t a ( .ctx.putImageData( .ctx.putImageData(.storage.bg, $.state.bgpos > 0 ? $.state.bgpos - $.canvas.width : $.state.bgpos + $.canvas.width, 5);

//}

$.state.offset += $.state.speed * 0.05;

if($.state.offset > $.settings.ground.min) {

$.state.offset = $.settings.ground.min - $.state.offset;

. s t a t e . s t a r t D a r k = ! .state.startDark = ! .state.startDark=!.state.startDark;

}

drawGround($.ctx, $.state.offset, $.colors.ground, $.colors.groundDark, $.canvas.width);

drawRoad($.settings.road.min + 6, $.settings.road.max + 36, 10, $.colors.roadLine);

drawGround($.ctx2, $.state.offset, $.colors.roadLine, $.colors.road, $.canvas.width);

drawRoad($.settings.road.min, $.settings.road.max, 10, $.colors.road);

drawRoad(3, 24, 0, . c t x . c r e a t e P a t t e r n ( .ctx.createPattern( .ctx.createPattern(.canvas2, ‘repeat’));

drawCar();

drawHUD($.ctx, 630, 340, $.colors.hud);

requestAnimationFrame(draw);

}, 1000 / $.settings.fps);

}

function drawHUD(ctx, centerX, centerY, color) {

var radius = 50, tigs = [0, 90, 135, 180, 225, 270, 315],

angle = 90;

ctx.beginPath();

ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);

ctx.lineWidth = 7;

ctx.fillStyle = ‘rgba(0, 0, 0, 0.4)’;

ctx.fill();

ctx.strokeStyle = color;

ctx.stroke();

for (var i = 0; i < tigs.length; i++) {

drawTig(ctx, centerX, centerY, radius, tigs[i], 7);

}

// draw pointer

angle = map($.state.speed, 0, $.state.car.maxSpeed, 90, 360);

drawPointer(ctx, color, 50, centerX, centerY, angle);

}

function drawPointer(ctx, color, radius, centerX, centerY, angle) {

var point = getCirclePoint(centerX, centerY, radius - 20, angle),

point2 = getCirclePoint(centerX, centerY, 2, angle + 90),

point3 = getCirclePoint(centerX, centerY, 2, angle - 90);

ctx.beginPath();

ctx.strokeStyle = “#FF9166”;

ctx.lineCap = ‘round’;

ctx.lineWidth = 4;

ctx.moveTo(point2.x, point2.y);

ctx.lineTo(point.x, point.y);

ctx.lineTo(point3.x, point3.y);

ctx.stroke();

ctx.beginPath();

ctx.arc(centerX, centerY, 9, 0, 2 * Math.PI, false);

ctx.fillStyle = color;

ctx.fill();

}

function drawTig(ctx, x, y, radius, angle, size) {

var startPoint = getCirclePoint(x, y, radius - 4, angle),

endPoint = getCirclePoint(x, y, radius - size, angle)

ctx.beginPath();

ctx.lineCap = ‘round’;

ctx.moveTo(startPoint.x, startPoint.y);

ctx.lineTo(endPoint.x, endPoint.y);

ctx.stroke();

}

function getCirclePoint(x, y, radius, angle) {

var radian = (angle / 180) * Math.PI;

return {

x: x + radius * Math.cos(radian),

y: y + radius * Math.sin(radian)

}

}

function calcMovement() {

var move = $.state.speed * 0.01,

newCurve = 0;

if($.state.keypress.up) {

$.state.speed += . s t a t e . c a r . a c c − ( .state.car.acc - ( .state.car.acc(.state.speed * 0.015);

} else if ($.state.speed > 0) {

$.state.speed -= $.state.car.friction;

}

if($.state.keypress.down && $.state.speed > 0) {

$.state.speed -= 1;

}

// Left and right

. s t a t e . x p o s − = ( .state.xpos -= ( .state.xpos=(.state.currentCurve * $.state.speed) * 0.005;

if($.state.speed) {

if($.state.keypress.left) {

. s t a t e . x p o s + = ( M a t h . a b s ( .state.xpos += (Math.abs( .state.xpos+=(Math.abs(.state.turn) + 7 + ($.state.speed > . s t a t e . c a r . m a x S p e e d / 4 ? ( .state.car.maxSpeed / 4 ? ( .state.car.maxSpeed/4?(.state.car.maxSpeed - ($.state.speed / 2)) : $.state.speed)) * 0.2;

$.state.turn -= 1;

}

if($.state.keypress.right) {

. s t a t e . x p o s − = ( M a t h . a b s ( .state.xpos -= (Math.abs( .state.xpos=(Math.abs(.state.turn) + 7 + ($.state.speed > . s t a t e . c a r . m a x S p e e d / 4 ? ( .state.car.maxSpeed / 4 ? ( .state.car.maxSpeed/4?(.state.car.maxSpeed - ($.state.speed / 2)) : $.state.speed)) * 0.2;

$.state.turn += 1;

}

if(KaTeX parse error: Expected 'EOF', got '&' at position 19: …ate.turn !== 0 &̲& !.state.keypress.left && !$.state.keypress.right) {

$.state.turn += $.state.turn > 0 ? -0.25 : 0.25;

}

}

. s t a t e . t u r n = c l a m p ( .state.turn = clamp( .state.turn=clamp(.state.turn, -5, 5);

. s t a t e . s p e e d = c l a m p ( .state.speed = clamp( .state.speed=clamp(.state.speed, 0, $.state.car.maxSpeed);

// section

$.state.section -= $.state.speed;

if($.state.section < 0) {

$.state.section = randomRange(1000, 9000);

newCurve = randomRange(-50, 50);

if(Math.abs($.state.curve - newCurve) < 20) {

newCurve = randomRange(-50, 50);

}

$.state.curve = newCurve;

}

if($.state.currentCurve < KaTeX parse error: Expected 'EOF', got '&' at position 14: .state.curve &̲& move < Math.a….state.currentCurve - $.state.curve)) {

$.state.currentCurve += move;

} else if($.state.currentCurve > KaTeX parse error: Expected 'EOF', got '&' at position 14: .state.curve &̲& move < Math.a….state.currentCurve - $.state.curve)) {

$.state.currentCurve -= move;

}

if(Math.abs($.state.xpos) > 550) {

$.state.speed *= 0.96;

}

. s t a t e . x p o s = c l a m p ( .state.xpos = clamp( .state.xpos=clamp(.state.xpos, -650, 650);

}

function keyUp(e) {

move(e, false);

}

function keyDown(e) {

move(e, true);

}

function move(e, isKeyDown) {

if(e.keyCode >= 37 && e.keyCode <= 40) {

e.preventDefault();

}

if(e.keyCode === 37) {

$.state.keypress.left = isKeyDown;

}

if(e.keyCode === 38) {

$.state.keypress.up = isKeyDown;

}

if(e.keyCode === 39) {

$.state.keypress.right = isKeyDown;

}

if(e.keyCode === 40) {

$.state.keypress.down = isKeyDown;

}

}

function randomRange(min, max) {

return min + Math.random() * (max - min);

}

function norm(value, min, max) {

return (value - min) / (max - min);

}

function lerp(norm, min, max) {

return (max - min) * norm + min;

}

function map(value, sourceMin, sourceMax, destMin, destMax) {

return lerp(norm(value, sourceMin, sourceMax), destMin, destMax);

}

function clamp(value, min, max) {

return Math.min(Math.max(value, min), max);

}

function drawBg() {

$.ctx.fillStyle = $.colors.sky;

$.ctx.fillRect(0, 0, $.canvas.width, $.settings.skySize);

drawMountain(0, 60, 200);

drawMountain(280, 40, 200);

drawMountain(400, 80, 200);

drawMountain(550, 60, 200);

$.storage.bg = $.ctx.getImageData(0, 0, $.canvas.width, $.canvas.height);

}

function drawMountain(pos, height, width) {

$.ctx.fillStyle = $.colors.mountains;

$.ctx.strokeStyle = $.colors.mountains;

$.ctx.lineJoin = “round”;

$.ctx.lineWidth = 20;

$.ctx.beginPath();

$.ctx.moveTo(pos, $.settings.skySize);

$.ctx.lineTo(pos + (width / 2), $.settings.skySize - height);

$.ctx.lineTo(pos + width, $.settings.skySize);

$.ctx.closePath();

$.ctx.stroke();

$.ctx.fill();

}

JavaScript

  • js的基本类型有哪些?引用类型有哪些?null和undefined的区别。

  • 如何判断一个变量是Array类型?如何判断一个变量是Number类型?(都不止一种)

  • Object是引用类型嘛?引用类型和基本类型有什么区别?哪个是存在堆哪一个是存在栈上面的?

  • JS常见的dom操作api

  • 解释一下事件冒泡和事件捕获

  • 事件委托(手写例子),事件冒泡和捕获,如何阻止冒泡?如何组织默认事件?

  • 对闭包的理解?什么时候构成闭包?闭包的实现方法?闭包的优缺点?

  • this有哪些使用场景?跟C,Java中的this有什么区别?如何改变this的值?

  • call,apply,bind

  • 显示原型和隐式原型,手绘原型链,原型链是什么?为什么要有原型链

  • 创建对象的多种方式

  • 实现继承的多种方式和优缺点

  • new 一个对象具体做了什么

  • 手写Ajax,XMLHttpRequest

  • 变量提升

  • 举例说明一个匿名函数的典型用例

  • 指出JS的宿主对象和原生对象的区别,为什么扩展JS内置对象不是好的做法?有哪些内置对象和内置函数?

  • attribute和property的区别

  • document load和document DOMContentLoaded两个事件的区别

  • JS代码调试

  • 开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

  • 8
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值