先实现完成阶段二的前两个需求,生成一个L型的模型,将容器分割成18行10列的代码。

    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>Document</title>
    8. <style type="text/css">
    9. .container{
    10. width: 200px;
    11. height: 360px;
    12. background-color: antiquewhite;
    13. position: relative;
    14. }
    15. .actvity_model{
    16. width: 20px;
    17. height: 20px;
    18. background-color: cornflowerblue;
    19. border: .3px solid rgb(148, 170, 218);
    20. box-sizing: border-box;
    21. position: absolute;
    22. }
    23. </style>
    24. </head>
    25. <body onload="init();">
    26. <!-- 背景容器 -->
    27. <div id="container" class="container">
    28. <!-- 块元素 -->
    29. </div>
    30. <script>
    31. //创建一个常量控制步长
    32. const STEP = 20;
    33. //定义常量分割容器
    34. const ROW_COUNT = 18,COL_COUNT = 10;
    35. //创建每个模型的数据源(L型)
    36. const MODELS = [
    37. {
    38. 0:{
    39. row:2,
    40. col:0
    41. },
    42. 1:{
    43. row:2,
    44. col:1
    45. },
    46. 2:{
    47. row:2,
    48. col:2
    49. },
    50. 3:{
    51. row:1,
    52. col:2
    53. }
    54. }
    55. ];
    56. //创建变量,存放当前使用的模型
    57. var currentModel = {};
    58. //入口方法
    59. function init(){
    60. createModel();
    61. onKeyDown();
    62. }
    63. //根据模型的数据创建对应的块元素
    64. function createModel(){
    65. //确定当前使用哪一个模型
    66. currentModel = MODELS[0];
    67. //生成对应数量的块元素
    68. for (var key in currentModel){
    69. var divEle = document.createElement("div");
    70. divEle.className = "actvity_model";
    71. document.querySelector("#container").appendChild(divEle);
    72. }
    73. //定位块元素的位置
    74. locationBlock();
    75. }
    76. //根据数据源定位块元素的位置
    77. function locationBlock(){
    78. //1.拿到所有的块元素
    79. var eles = document.querySelectorAll(".actvity_model");
    80. for (var i = 0;i<eles.length;i++){
    81. //单个块元素
    82. var actvityModelEle = eles[i];
    83. //2.找到每个块元素对应的数据
    84. var blockModel = currentModel[i];
    85. //3.根据每个块元素对应的数据来指定块元素的位置
    86. actvityModelEle.style.left = blockModel.col * STEP + "px";
    87. actvityModelEle.style.top = blockModel.row * STEP + "px";
    88. }
    89. }
    90. //监听用户键盘事件
    91. function onKeyDown(){
    92. document.onkeydown = function(evnet){
    93. switch(event.keyCode){
    94. case 38:
    95. console.log("上");
    96. move(0,-1);
    97. break;
    98. case 39:
    99. console.log("右");
    100. move(1,0);
    101. break;
    102. case 40:
    103. console.log("下");
    104. move(0,1);
    105. break;
    106. case 37:
    107. console.log("左");
    108. move(-1,0);
    109. break;
    110. }
    111. }
    112. }
    113. //控制块元素移动
    114. function move(x,y){
    115. var actvityModelEle = document.querySelector(".actvity_model");
    116. actvityModelEle.style.top = parseInt(actvityModelEle.style.top || 0) + y * STEP + "px";
    117. actvityModelEle.style.left = parseInt(actvityModelEle.style.left || 0) + x * STEP + "px";
    118. }
    119. </script>
    120. </body>
    121. </html>

    下面代码完成模型的移动

    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>Document</title>
    8. <style type="text/css">
    9. .container{
    10. width: 200px;
    11. height: 360px;
    12. background-color: antiquewhite;
    13. position: relative;
    14. }
    15. .actvity_model{
    16. width: 20px;
    17. height: 20px;
    18. background-color: cornflowerblue;
    19. border: .3px solid rgb(148, 170, 218);
    20. box-sizing: border-box;
    21. position: absolute;
    22. }
    23. </style>
    24. </head>
    25. <body onload="init();">
    26. <!-- 背景容器 -->
    27. <div id="container" class="container">
    28. <!-- 块元素 -->
    29. </div>
    30. <script>
    31. //创建一个常量控制步长
    32. const STEP = 20;
    33. //定义常量分割容器
    34. const ROW_COUNT = 18,COL_COUNT = 10;
    35. //创建每个模型的数据源(L型)
    36. const MODELS = [
    37. {
    38. 0:{
    39. row:2,
    40. col:0
    41. },
    42. 1:{
    43. row:2,
    44. col:1
    45. },
    46. 2:{
    47. row:2,
    48. col:2
    49. },
    50. 3:{
    51. row:1,
    52. col:2
    53. }
    54. }
    55. ];
    56. //创建变量,存放当前使用的模型
    57. var currentModel = {};
    58. //创建变量标记16宫格的位置
    59. var currentX = 0,currentY = 0;
    60. //入口方法
    61. function init(){
    62. createModel();
    63. onKeyDown();
    64. }
    65. //根据模型的数据创建对应的块元素
    66. function createModel(){
    67. //确定当前使用哪一个模型
    68. currentModel = MODELS[0];
    69. //生成对应数量的块元素
    70. for (var key in currentModel){
    71. var divEle = document.createElement("div");
    72. divEle.className = "actvity_model";
    73. document.querySelector("#container").appendChild(divEle);
    74. }
    75. //定位块元素的位置
    76. locationBlock();
    77. }
    78. //根据数据源定位块元素的位置
    79. function locationBlock(){
    80. //1.拿到所有的块元素
    81. var eles = document.querySelectorAll(".actvity_model");
    82. for (var i = 0;i<eles.length;i++){
    83. //单个块元素
    84. var actvityModelEle = eles[i];
    85. //2.找到每个块元素对应的数据
    86. var blockModel = currentModel[i];
    87. //3.根据每个块元素对应的数据来指定块元素的位置
    88. //每个块元素的位置由两个条件决定:1、16宫格所在的位置。 2、块元素在16宫格中的位置
    89. actvityModelEle.style.left = (currentX + blockModel.col) * STEP + "px";
    90. actvityModelEle.style.top = (currentY + blockModel.row) * STEP + "px";
    91. }
    92. }
    93. //监听用户键盘事件
    94. function onKeyDown(){
    95. document.onkeydown = function(evnet){
    96. switch(event.keyCode){
    97. case 38:
    98. console.log("上");
    99. move(0,-1);
    100. break;
    101. case 39:
    102. console.log("右");
    103. move(1,0);
    104. break;
    105. case 40:
    106. console.log("下");
    107. move(0,1);
    108. break;
    109. case 37:
    110. console.log("左");
    111. move(-1,0);
    112. break;
    113. }
    114. }
    115. }
    116. //控制块元素移动
    117. function move(x,y){
    118. //16宫格在动
    119. currentX += x;
    120. currentY += y;
    121. //根据16宫格来重新定位块元素
    122. locationBlock();
    123. }
    124. </script>
    125. </body>
    126. </html>

    最后,我们来实现模型的旋转,这旋转的实现基于两条算法规则。
    image.png
    image.png
    然后,我们把此算法运用到代码中,见rotate()函数

    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>Document</title>
    8. <style type="text/css">
    9. .container{
    10. width: 200px;
    11. height: 360px;
    12. background-color: antiquewhite;
    13. position: relative;
    14. }
    15. .actvity_model{
    16. width: 20px;
    17. height: 20px;
    18. background-color: cornflowerblue;
    19. border: .3px solid rgb(148, 170, 218);
    20. box-sizing: border-box;
    21. position: absolute;
    22. }
    23. </style>
    24. </head>
    25. <body onload="init();">
    26. <!-- 背景容器 -->
    27. <div id="container" class="container">
    28. <!-- 块元素 -->
    29. </div>
    30. <script>
    31. //创建一个常量控制步长
    32. const STEP = 20;
    33. //定义常量分割容器
    34. const ROW_COUNT = 18,COL_COUNT = 10;
    35. //创建每个模型的数据源(L型)
    36. const MODELS = [
    37. {
    38. 0:{
    39. row:2,
    40. col:0
    41. },
    42. 1:{
    43. row:2,
    44. col:1
    45. },
    46. 2:{
    47. row:2,
    48. col:2
    49. },
    50. 3:{
    51. row:1,
    52. col:2
    53. }
    54. }
    55. ];
    56. //创建变量,存放当前使用的模型
    57. var currentModel = {};
    58. //创建变量标记16宫格的位置
    59. var currentX = 0,currentY = 0;
    60. //入口方法
    61. function init(){
    62. createModel();
    63. onKeyDown();
    64. }
    65. //根据模型的数据创建对应的块元素
    66. function createModel(){
    67. //确定当前使用哪一个模型
    68. currentModel = MODELS[0];
    69. //生成对应数量的块元素
    70. for (var key in currentModel){
    71. var divEle = document.createElement("div");
    72. divEle.className = "actvity_model";
    73. document.querySelector("#container").appendChild(divEle);
    74. }
    75. //定位块元素的位置
    76. locationBlock();
    77. }
    78. //根据数据源定位块元素的位置
    79. function locationBlock(){
    80. //1.拿到所有的块元素
    81. var eles = document.querySelectorAll(".actvity_model");
    82. for (var i = 0;i<eles.length;i++){
    83. //单个块元素
    84. var actvityModelEle = eles[i];
    85. //2.找到每个块元素对应的数据
    86. var blockModel = currentModel[i];
    87. //3.根据每个块元素对应的数据来指定块元素的位置
    88. //每个块元素的位置由两个条件决定:1、16宫格所在的位置。 2、块元素在16宫格中的位置
    89. actvityModelEle.style.left = (currentX + blockModel.col) * STEP + "px";
    90. actvityModelEle.style.top = (currentY + blockModel.row) * STEP + "px";
    91. }
    92. }
    93. //监听用户键盘事件
    94. function onKeyDown(){
    95. document.onkeydown = function(evnet){
    96. switch(event.keyCode){
    97. case 38:
    98. console.log("上");
    99. rotate();
    100. break;
    101. case 39:
    102. console.log("右");
    103. move(1,0);
    104. break;
    105. case 40:
    106. console.log("下");
    107. move(0,1);
    108. break;
    109. case 37:
    110. console.log("左");
    111. move(-1,0);
    112. break;
    113. }
    114. }
    115. }
    116. //控制块元素移动
    117. function move(x,y){
    118. //16宫格在动
    119. currentX += x;
    120. currentY += y;
    121. //根据16宫格来重新定位块元素
    122. locationBlock();
    123. }
    124. //控制模型的旋转
    125. function rotate(){
    126. //算法
    127. //旋转后的行 == 旋转前的列
    128. //旋转后的列 == 3-旋转前的行
    129. //遍历我们当前的 模型数据源
    130. for (var key in currentModel){
    131. //块元素数据源
    132. var blockModel = currentModel[key];
    133. //实现算法
    134. var temp = blockModel.row;
    135. blockModel.row = blockModel.col;
    136. blockModel.col = 3-temp;
    137. locationBlock();
    138. }
    139. }
    140. </script>
    141. </body>
    142. </html>