游戏来源于 Mdn学习网站

该例子用于对象的理解非常有效(建议看完上面网站的内容在开始练习)

  1. 弹球
  2. body {
  3. margin: 0;
  4. overflow: hidden;
  5. font-family: "PingFangSC-Regular", "微软雅黑", sans-serif;
  6. height: 100%;
  7. }
  8. h1 {
  9. font-size: 2rem;
  10. letter-spacing: \-1px;
  11. position: absolute;
  12. margin: 0;
  13. top: \-4px;
  14. right: 5px;
  15. color: transparent;
  16. text-shadow: 0 0 4px white;
  17. }
  18. p {
  19. position: absolute;
  20. margin: 0;
  21. top: 35px;
  22. right: 5px;
  23. color: #aaa;
  24. }
  25. 弹球
  26. //弹球的个数
  27. const BALLS\_COUNT \= 25;
  28. //弹球的半径范围
  29. const BALL\_SIZE\_MIN \= 10;
  30. const BALL\_SIZE\_MAX \= 20;
  31. // 弹球的速度
  32. const BALL\_SPEED\_MAX \= 7;
  33. // 设定画布
  34. var canvas \= document.querySelector("canvas");
  35. var pcount \= document.querySelector("p");
  36. var ctx \= canvas.getContext("2d");
  37. //获取屏幕的宽高 并设置为画布的宽高
  38. var width \= (canvas.width \= window.innerWidth);
  39. var height \= (canvas.height \= window.innerHeight);
  40. // 生成随机数的函数
  41. function random(min, max) {
  42. return Math.floor(Math.random() \* (max \- min)) + min;
  43. }
  44. // 生成随机颜色的函数
  45. function randomColor() {
  46. return (
  47. "rgb(" + random(0, 255) + ", " + random(0, 255) + ", " +random(0, 255) + ")");
  48. }
  49. //定义形状
  50. function Shape(x, y, velX, velY, exists) {
  51. this.x \= x;
  52. this.y \= y;
  53. this.velX \= velX;
  54. this.velY \= velY;
  55. this.exists \= exists;
  56. }
  57. // 创建弹球对象
  58. function Ball(x, y, velX, velY, color, size, exists) {
  59. Shape.call(this, x, y, velX, velY, exists);
  60. this.color \= color;
  61. this.size \= size;
  62. }
  63. Ball.prototype \= Object.create(Shape.prototype);
  64. Ball.prototype.constructor \= Ball;
  65. // 定义绘制球的函数
  66. Ball.prototype.draw \= function() {
  67. ctx.beginPath();
  68. ctx.fillStyle \= this.color;
  69. ctx.arc(this.x, this.y, this.size, 0, 2 \* Math.PI);
  70. ctx.fill();
  71. };
  72. //更新跳球的位置
  73. Ball.prototype.update \= function() {
  74. //到达右边,反弹
  75. if (this.x + this.size \>= width) {
  76. this.velX \= \-this.velX;
  77. }
  78. //到达左边,反弹
  79. if (this.x \- this.size <= 0) {
  80. this.velX \= \-this.velX;
  81. }
  82. //到达底部,反弹
  83. if (this.y + this.size \>= height) {
  84. this.velY \= \-this.velY;
  85. }
  86. //到达顶部 反弹
  87. if (this.y \- this.size <= 0) {
  88. this.velY \= \-this.velY;
  89. }
  90. this.x += this.velX;
  91. this.y += this.velY;
  92. };
  93. //弹球的碰撞处理
  94. Ball.prototype.collisionDetect \= function() {
  95. for (var j \= 0; j < balls.length; j++) {
  96. //是不是弹球本身
  97. if (balls\[j\] \=== this) continue;
  98. var dx \= this.x \- balls\[j\].x;
  99. var dy \= this.y \- balls\[j\].y;
  100. var distance \= Math.sqrt(dx \* dx + dy \* dy);
  101. //碰撞改变两个球的颜色
  102. if (distance < this.size + balls\[j\].size) {
  103. this.color \= balls\[j\].color \= randomColor();
  104. }
  105. }
  106. };
  107. //定义一个小吃货
  108. function EvilCircle(x, y, exists) {
  109. Shape.call(this, x, y, 20, 20, exists);
  110. this.color \= "white";
  111. this.size \= 10;
  112. }
  113. EvilCircle.prototype \= Object.create(Shape.prototype);
  114. EvilCircle.prototype.constructor \= EvilCircle;
  115. // 定义绘制小吃货的函数
  116. EvilCircle.prototype.draw \= function() {
  117. ctx.beginPath();
  118. ctx.strokeStyle \= this.color;
  119. ctx.arc(this.x, this.y, this.size, 0, 2 \* Math.PI);
  120. ctx.stroke();
  121. };
  122. // 检查小吃货是否碰壁
  123. EvilCircle.prototype.checkBounds \= function() {
  124. if (this.x + this.size \>= width) {
  125. this.velX \= \-this.velX;
  126. }
  127. if (this.x \- this.size <= 0) {
  128. this.x \= this.size;
  129. }
  130. if (this.y + this.size \>= height) {
  131. this.y \= height \- this.size;
  132. }
  133. if (this.y \- this.size <= 0) {
  134. this.y \= this.size;
  135. }
  136. };
  137. // 定义小吃货移动函数
  138. EvilCircle.prototype.setControls \= function() {
  139. window.onkeydown \= e \=> {
  140. if (e.key \=== "a") {
  141. this.x \-= this.velX;
  142. } else if (e.key \=== "d") {
  143. this.x += this.velX;
  144. } else if (e.key \=== "w") {
  145. this.y \-= this.velY;
  146. } else if (e.key \=== "s") {
  147. this.y += this.velY;
  148. }
  149. //上下左右移动
  150. if (e.key \=== "ArrowLeft") {
  151. this.x \-= this.velX;
  152. } else if (e.key \=== "ArrowRight") {
  153. this.x += this.velX;
  154. } else if (e.key \=== "ArrowUp") {
  155. this.y \-= this.velY;
  156. } else if (e.key \=== "ArrowDown") {
  157. this.y += this.velY;
  158. }
  159. };
  160. };
  161. //小吃货碰撞到了弹球
  162. EvilCircle.prototype.collisionDetect \= function() {
  163. for (var j \= 0; j < balls.length; j++) {
  164. //弹球没被吃
  165. if (balls\[j\].exists) {
  166. var dx \= this.x \- balls\[j\].x;
  167. var dy \= this.y \- balls\[j\].y;
  168. var distance \= Math.sqrt(dx \* dx + dy \* dy);
  169. if (distance < this.size + balls\[j\].size) {
  170. //标记弹球被吃
  171. balls\[j\].exists \= false;
  172. }
  173. }
  174. }
  175. };
  176. //激活小吃货
  177. EvilCircle.prototype.run \= function() {
  178. this.draw();
  179. this.checkBounds();
  180. this.collisionDetect();
  181. };
  182. //创建吃货
  183. var evilCircle \= new EvilCircle(20, 20, true);
  184. evilCircle.setControls();
  185. // 定义一个数组来保存所有的球
  186. var balls \= \[\];
  187. pcount.textContent \= "还剩" + BALLS\_COUNT + "个球";
  188. for (let i \= 0; i < BALLS\_COUNT; i++) {
  189. var size \= random(BALL\_SIZE\_MIN, BALL\_SIZE\_MAX);
  190. var ball \= new Ball(
  191. // 为避免绘制错误,球至少离画布边缘球本身一倍宽度的距离
  192. random(0 + size, width \- size),
  193. random(0 + size, height \- size),
  194. random(\-BALL\_SPEED\_MAX, BALL\_SPEED\_MAX),
  195. random(\-BALL\_SPEED\_MAX, BALL\_SPEED\_MAX),
  196. randomColor(),
  197. size,
  198. true
  199. );
  200. balls.push(ball);
  201. }
  202. // 定义一个循环来不停地播放
  203. function loop() {
  204. background("rgb(0, 0, 0)");
  205. for (var i \= 0; i < balls.length; i++) {
  206. if (!balls\[i\].exists) {
  207. continue;
  208. }
  209. balls\[i\].draw();
  210. balls\[i\].update();
  211. balls\[i\].collisionDetect();
  212. }
  213. evilCircle.run();
  214. var newballs \= balls.filter(balls \=> balls.exists);
  215. pcount.textContent \= "还剩" + newballs.length + "个球";
  216. requestAnimationFrame(loop);
  217. }
  218. function background(color) {
  219. ctx.fillStyle \= color;
  220. ctx.fillRect(0, 0, width, height);
  221. ctx.beginPath();
  222. }
  223. loop();

js 学习四 对象应用 吃货游戏的更多相关文章

  1. js学习日记-对象字面量

    一.对象字面量语法 var person={ name:'小王', age:18, _pri:233 } 成员名称的单引号不是必须的 最后一个成员结尾不要用逗号,不然在某些浏览器中会抛出错误 成员名相 ...

  2. JS学习四(BOM DOM)

    BOM                Screen对象 console.log(window.width);//屏幕宽度 console.log(window.height);//屏幕高度 conso ...

  3. js学习--浏览器对象计时器setInterval()与setTimeout()的使用与区别

    一.setInterval()与setTimeout()的定义: 二.setInterval()与setTimeout()的使用:    1.setInterval()与clearInterval() ...

  4. Hibernate基础学习(四)—对象-关系映射(上)

    一.映射对象标识符      Java语言按内存地址来识别或区分同一个类的不同对象,而关系数据库按主键值来识别或区分同一个表的不同记录.Hibernate使用对象标识符(OID)来建立内存中的对象和数 ...

  5. spring学习 四 对象的创建

    spring中,有三种创建对象的方式 (1)构造创建 (2)实例工厂构造 (3)静态工厂构造 一  构造器创建 在构造器创建对象时,有无参构造和有参构造 两种 (1)在spring中,默认的是无参构造 ...

  6. JS 学习(四)对象

    对象 在JS中,对象是数据(变量),拥有属性和方法. JS中所有事物都是对象:字符串.数字.数组.日期等. 对象是拥有属性和方法的特殊数据类型. 属性是与对象相关的值. 方法是能够在对象上执行的动作. ...

  7. Node.js学习笔记(四): 全局对象

    在浏览器 JavaScript 中,通常 window 是全局对象, 而 Node.js 中的全局对象是 global,所有全局变量(除了 global 本身以外)都是 global 对象的属性. 这 ...

  8. web前端学习(四)JavaScript学习笔记部分(6)-- js内置对象

    1.JS内置对象-什么是对象 1.1.什么是对象: JavaScript中的所有事物都是对象:字符串.数值.数组.函数 每个对象带有属性和方法 JavaScript允许自定义对象 1.2.自定义对象: ...

  9. JavaScript学习12 JS中定义对象的几种方式

    JavaScript学习12 JS中定义对象的几种方式 JavaScript中没有类的概念,只有对象. 在JavaScript中定义对象可以采用以下几种方式: 1.基于已有对象扩充其属性和方法 2.工 ...

随机推荐

  1. php设计模式-注册树模式

    php注册树模式 1.什么是注册树模式? 注册树模式通过将对象实例注册到全局对象树上,需要的时候将对象从全局对象树上取下来,就像小时候买糖葫芦一样,卖糖葫芦的将糖葫芦插在一个大的杆子上,人们买的时候就 ...

  2. shell笔记-----常用命令积累

    set -x # 执行指令前,先输出指令#set -o xtrace  # 与set -x效果一样 set -e 在"set -e"之后出现的代码,一旦出现了返回值非零,整个脚本就 ...

  3. 【剑指offer37】二叉树的序列化

    序列化过程很简单,如果是采用先序序列,那么对先序遍历做出改变即可: 层序遍历建立二叉树,如: 1 2        3 4   #     5   6 输入第一行:将要输入的节点的个数N,如上面的为7 ...

  4. JAVA初级面试题,附个人理解答案

    一,面向对象的特征:1.抽象 包括数据抽象跟行为抽象,将对象共同的特征取出形成一个类2.继承 被继承类为基类/超类,继承类为子类/派生类3.封装 多次使用道德数据或方法,封装成类,方便多次重复调用4. ...

  5. idea 编译 brooklin

    gradle 项目导入 idea 之后,各种报错,run 不起来 手动加入各种依赖 配置启动类 指定 log4j.properties

  6. 阶段3 2.Spring_02.程序间耦合_6 工厂模式解耦

    使用类加载器去加载文件 定义getBean的方法 运行测试方法报错. 在工厂类里面打印输出BeanPath 删除dao的实现类 没有dao的实现类.再次运行程序.编译不报错.运行时报错 以上就是工厂模 ...

  7. 【工具】rinetd 使用教程(linux 下的端口转发工具 )

    日期:2019-07-30 20:00:36 更新: 作者:Bay0net 介绍:使用 rinetd 来转发某端口的流量. 0x01. 安装 官网 RINETD 安装方法很简单,一条语句就 OK 了. ...

  8. Java学习之==>泛型

    一.什么是泛型 泛型,即“参数化类型”,在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型.也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类.接口 ...

  9. XMLHttpRequest 对象相关

    XMLHttpRequest 对象用于在后台与服务器交换数据. 后台 package com.java1234.web; import java.io.IOException; import java ...

  10. APP Store上架QA&注意事项

    一. App Store上架费用,要多少钱. 这个因产品而异,一般是6000-10000元人民币. 二. App Store上架周期,要多久过. 这个因产品而异,正常的话一周内,如果产品老是出问题,被 ...