page contents

WEB前端教程:足球小将

练习如何对于问题进行抽象,应用面向对象或者各种设计模式进行问题的解决

attachments-2022-11-L7i9mHzu6360b67d2c2fc.png足球小将(一)

 课程目标

通过趣味练习,来强化对于 JavaScript 的熟悉

练习如何对于问题进行抽象,应用面向对象或者各种设计模式进行问题的解决

 创建一个足球场

需求

通过 Canvas 或者 SVG 绘制一片绿色矩形,就像是我们从高空俯视绿色草坪足球场看见的一样。

有余力的同学,可以把足球场上的各种边线画上。

设计

应用工厂模式,设计一个生成足球场的类

足球场包括长度,宽度的属性,长度宽度创建时候以模拟真实单位的“米”为参数,同时以容器宽度和高度进行对应换算。

验证 在不同像素高宽的容器中生成同样长宽米的球场,看球场是否进行了对应的自适应变换

在同样像素高宽的容器中,生成不同长宽米的球场

 创建一个足球运动员

需求

通过 Canvas 或者 SVG 或者 DOM 创建一个足球运动员。

我们将足球运动员抽象为一个实心圆,不需要考虑他的方向问题。

  • 参考 (opens new window)创建球员的时候,需要将球员创建到某个球场中,球员圆形的大小默认为2米,按照和球场的大小进行对应像素的换算。

球员有很多关于足球运动能力的属性,比如速度,力量,技术,射门等等。我们先添加一个属性,叫做速度。

速度 VNum 为一个在1-99范围内的整数,随机生成。对应物理概念可以假设为:

速度值为 99 的,最高速度为 12米每秒

速度值为 1 的,最高速度为 3米每秒

假设速度值和最高速度是线性关系,我们推导出如下公式:

最高速度VMax = 3 + (VNum - 1) * ( 9 / 98 )

 让球员跑起来

需求

给球员增加一个方法,奔跑,指定一个终止点(相对于球场左上角的米的坐标),球员向那个终止点跑去。

使用上一个需求中的球员速度,以及和球场实际大小进行计算,模拟一个球员奔跑中,球员圆圈移动的动画。

为了测试方便,再给球员设置一个方法,设定球员所在位置,参数为相对于球场左上角的用米为单位的坐标,需要转换为像素

注意:球员不可能一直按着最高速度进行奔跑,球员有起步,加速到全速,到终点后降速的过程

阅读

设计

根据上面的阅读,实现球员的奔跑方法,球员有起步,逐渐加速,全速,到达终点后,再逐渐降速并继续向前再移动一小段距离

验证

  • 生成一个速度为 100 的球员,奔跑吧
  • 生成一个速度为 1 的球员,奔跑吧
  • 生成好多速度随机的球员,一起跑步比赛吧

 让球员跑得更真实

需求

我们知道,球员跑步速度不仅仅和最高速度有关系,还和体力,爆发力相关

爆发力强,则加速到最快速度会比较快,体力好,坚持在最高速度会比较久

所以给球员增加这两个属性,然后再让大家奔跑看看

设计

爆发力和体力依然用 1-99 范围内的整数来设定,假设有如下物理意义:

  • 爆发力为 99 表示能够在 1 秒就达到最高速度

  • 爆发力为 1 表示需要 4 秒才能达到最高速度

假设爆发力和需要多长时间达到最高速度是线性关系,请自行推导公式

  • 体力为 99 表示能够在最高速度上坚持 15 秒
  • 体力为 1 表示能够在最高速度上坚持 10 秒 假设体力和能够在最高速度上坚持的时间是线性关系,请自行推导公式

验证

生成不同的怪异数值球员进行比赛吧,也可以根据比赛结果适当调整各种数值的物理计算公式

 足球小将(二)

 课程目标

通过趣味练习,来强化对于 JavaScript 的熟悉

持续练习如何对于问题进行抽象,应用面向对象或者各种设计模式进行问题的解决

 创建一个足球

需求

创建一个足球,用一个圆形表示,足球大小的直径假设为 0.5 米(不太真实,但为了看清),实际显示大小按照球场像素进行对应变化。

足球不妨找一个图片做贴图

足球有一个方法是移动,参数为运动方向、初速度、加速度,先假设足球只在草地平面移动。加速度为全局常量。

验证

创建足球,尝试各种参数的搭配,观察足球在运动场上的运动轨迹。

 跑向足球

跑向静止的足球

实现运动员跑向足球并停球的行为。

随机生成足球和运动员的位置,然后运动员向足球跑去,直到运动员和足球相接后,运动员和足球停下来

跑向移动的足球

随机生成足球和运动员的位置,并让足球开始移动,接下来让运动员进行一个预判,并开始向足球可能接到的位置跑去,跑的过程中可能需要定期调整运动员奔跑的方向。

 踢出足球

简单地踢出足球

给足球运动员增加一个踢出足球的方法,参数为期望球运动的方向,期望足球初速度。

我们先简单实现踢出足球的实现,按照给定的参数,踢出足球。

实现以下踢球:

  • 球员在球场中心向球门踢出足球
  • 球员从小禁区向球场中心踢出足球
  • 球员从角球区向点球点踢出足球
  • 球员从大禁区角附近,向球门踢出足球
  • 球员从本方禁区附近向对方半场边线踢出足球

给球员增加两个属性

现在,我们稍微模拟一下真实情况,我们给球员增加两个属性:技术、力量

技术决定运动员踢球方向的准确性和力量控制的准确性,力量决定踢球的最大速度。

两个属性依然都是 1-99 的正整数。

对于力量的设定可以为:

  • 力量为 1 的静止运动员踢出静止足球的最大初速度为 5米/秒
  • 力量为 99 的静止运动员踢出静止足球的最大初速度为 50米/秒
  • 力量和静止态踢出静止足球的最大初速度为线性关系
  • 运动状态的球员可以提升或减小踢出足球的最大初速度,以球员运动方向和踢出足球方向来计算,方向完全相同,加速最大,方向完全相反,减速最大。范围为 -40% 到 40%

对于技术的设定可以为:

  • 技术对于方向及力量的控制符合正态分布
  • 技术值越低,实际踢出的方向越容易出现和期望方向角度偏离的情况
  • 技术值越高,实际踢出的方向越不容易出现和期望方向角度偏离的情况
  • 技术值越低,实际踢出的初速度越容易出现和期望初速度偏离的情况,注意实际初速度不能超过最大初速度
  • 技术值越高,实际踢出的初速度越不容易出现和期望初速度偏离的情况,注意实际初速度不能超过最大初速度
  • 技术值越低,正态分布的方差越大
  • 技术高越低,正态分布的方差越小
  • 技术值与方差大小可以为线性关系,也可以自定义

阅读

实现具体以下内容

  • 在页面中增加一个球员生成器,可以设置球员的各种属性
  • 在页面中可填写球员、球的位置
  • 在页面中可填写球员的动作及对应参数,然后有按钮进行对应动作执行

 再复杂一些

我们知道,运动员大部分时候是在运动过程中踢球,不同的角度,运动状态,会导致踢出足球的速度,角度都有偏差

静止地踢静止的球

这是我们上面做的情况,所有参数以运动员自身属性来决定

运动地踢静止的球

运动员的运动方向和球需要踢出的方向的夹角,对于最后实际踢出球的方向及初速度有一定影响,我们假设有以下影响,你也可以根据自己经验重新设定这些影响。当然我们更建议你在页面中实现参数的配置,来动态实现参数的调整,并实时进行预览

  • 运动员的运动方向和球需要踢出的方向的夹角,会对方向控制的方差产生一定影响,我们假设夹角为 a(区间为 0° 到 360°)。
  • 假设方向影响因子为 b,这个 b 会对计算概率的方差进行一个乘积的影响,即 方差 = 原方差 * b
  • 夹角 a 为 0° 时候,b = 1(参考值,可自定)
  • 夹角 a 为 180° 时候,b = 2(参考值,可自定)
  • a 与 b 可以为线性关系
  • 对力量的控制同理

静止地踢运动的球

有时候踢侧面来的球,踢出的球大概率会有一个原始方向的偏移,所以球的运动方向也会对踢出球的方向有影响,我们假设影响如下

  • 球原本运动的方向和踢出足球的方向的夹角为 a(区间为 0° 到 360°),踢出方向的正态分布概率密度函数均值 μ 会因为 a 而产生向球运动的方向进行一定量的偏移 c
  • 当 a 为 0° 或者 180° 时,踢出的期望方向不受球的运动方向影响,c 为 0
  • 当 a 为 90° 或者 270° 时,踢出的期望方向最受球的运动方向影响,c 为偏 30°对应的偏差(参考值,可自定)
  • a 与 c 可以为线性关系
  • 计算出 c 后,是否真实产生偏差,还和球员技术相关,根据球员技术,根据正态分布,计算出不会出现偏差 c 的概率,最后实际出现的偏差为 c * (1 - 不会出现偏差的概率)。所以,当球员技术很好时,c 大概率为 0,或者是个极小值,对最后方向影响最小。

运动地踢运动的球

结合上面两者,进行最复杂的踢球的实现,运动的球员踢出运动的球。

实现各种参数的可视化配置,然后不断调参,找到最模拟真实的参数配置吧。

 足球小将(三)

 课程目标

通过趣味练习,来强化对于 JavaScript 的熟悉

持续练习如何对于问题进行抽象,应用面向对象或者各种设计模式进行问题的解决

 课程描述

我们在前两个子任务中完成了运动员的运动,足球的运动,接下来我们来实现具体的足球运动的行为。

 踢球行为

停球

停球,就是将运动向自己的足球控制在自己的一定范围内。

将上一任务中的踢球封装为父类,停球继承踢球。

我们定义停球的行为,是将足球踢向一个距离自己很近的位置,甚至距离为0。比如:

  • 球员在原地停球时,需要将球停到自己脚下
  • 球员在前插奔跑中停球,需要将球停到自己奔跑方向 2 米远的地方,便于下一步射门
  • 球员在摆脱防守队员中停球,有时候需要将球停到自己当前方向反方向 1 米远的地方,便于摆脱

为了简化需求,我们将停球动作抽象为以下规则:

  • 当球员静止时,球停在原地
  • 当球员运动时,球停到 1 秒后球员在的位置

传球

传球就是将球传给另外一个运动员,依然是继承踢球的父类

最简单的传球,就是看目标运动员在哪里,然后传给他,但在实际比赛中,我们往往会把球传给目标运动员的运动方向,或者躲开防守队员,将球传到空档区域。

为了简化需求,我们将传球抽象为以下规则:

  • 对于传球目标静止的,我们将球直接传给他
  • 对于传球目标在运动中,我们需要通过计算,算好提前量,把球传到目标球员运动方向的前方,正好是目标球员跑到那个位置的时候,球也传到那个位置

带球

带球是不断地踢球的过程,每次踢一小步,让球向前滚动一小段距离,然后奔跑跟上。

我们简化需求,假设带球过程中,触球的频率是固定的,假设每秒触球一次,所以带球过程中,每次触球踢球的距离为,运动员按照当前速度 1 秒后到达的距离。

射门

射门在这其中是最好处理的,朝向球门射去即可。

为了简化射门中的参数传递,我们把射门抽象为以下几种:

  • 射向球门左上角
  • 射向球门左下角
  • 射向球门右上角
  • 射向球门右上角
  • 射向球门正上方
  • 射向球门正下方

验证 如前面的任务,创建一系列的参数可视化配置,及方法执行按钮,验证如上行为的实现和效果验证。

 提交

把你的代码放在 Github 后进行提交

 总结

依然把今天的学习用时,收获,问题进行记录


更多相关技术内容咨询欢迎前往并持续关注六星社区了解详情。

长按或扫描下方二维码,免费获取 Python公开课和大佬打包整理的几百G的学习资料,内容包含但不限于Python电子书、教程、项目接单、源码等等

attachments-2022-11-ZPEkXnhh6360b63a914cb.jpg

0 条评论

请先 登录 后评论
小柒
小柒

1478 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1478 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章