创建一个图形化应用程序来解决骑马过程中的问题

这是有关创建交互式应用程序以解决处理p5.j​​s中 的马进程问题的 教程

第一部分


创建一匹马-矩形rect()。 马用灰色圆圈表示。

rect(bx, by, boxSize, boxSize); fill(50); //  ellipse(bx+50,by+50,20,20); //  

让马在它经过的所有细胞上绘画,这就是这里的样子。

接下来,在释放mouseRealised()按钮时,将马匹吸引到笼子的中央。

添加storXstorY变量, 这些变量将存储光标所在的单元格的坐标。 如果按下左键,并且光标在马的上方,那么我们将当前单元格的坐标保存在变量storXstorY中

  void mouseClick() { if (mouseX >= x && mouseX <= x+100 && mouseY >= y && mouseY <= y+100) { if (overBox && mousePressed && (mouseButton == LEFT)) { storX=x; //  x storY=y; //  y } } } 


释放按钮时,坐标storX和storY将被加载到knightX和knightY骑士的坐标中。
  knightX=storX; knightY=storY; 

如果对于按下的按钮状态存在标准的mousePressed布尔变量,则对于按下的按钮状态不存在这样的变量-自己创建:
  boolean bool_mouseReleased; // ... void mouseReleased() { bool_mouseReleased=true; locked = false; knightX=storX; knightY=storY; } 

现在,如果未按下鼠标按钮(即bool_mouseReleased = true ),则使用坐标storX和storY绘制单元格
 if((bool_mouseReleased ) && (x==storX && y==storY )){ modColor=200; } 


将马拉到笼子的中心
 //  bool_mouseReleased; storX; storY; boolean bool_mouseReleased; float storX; float storY; float knightX; float knightY; // size of canvas 600*600 int edgeOfCanvas=600; int knightSize = 100; boolean overKnight = false; boolean locked = false; float xOffset = 0.0; float yOffset = 0.0; int unit = 100; // -> width / unit; int unitSize=100; int count; Module[] mods; void setup() { size(600, 600); knightX = 0; knightY = 0; rectMode(CORNER); stroke(100); int wideCount = edgeOfCanvas / unit; int highCount = edgeOfCanvas / unit; count = wideCount * highCount; mods = new Module[count]; int index = 0; for (int y = 0; y < highCount; y++) { for (int x = 0; x < wideCount; x++) { mods[index++] = new Module(x*unit, y*unit); } } } void draw() { background(0); for (Module mod : mods) { mod.mouseClick(); mod.update(); } // // // // // Test if the cursor is over the box fill(200); if (mouseX > knightX && mouseX < knightX+knightSize && mouseY > knightY && mouseY < knightY+knightSize) { overKnight = true; } else { overKnight = false; } fill(200); rect(0,0,100,100); rect(knightX, knightY, knightSize, knightSize); fill(50); ellipse(knightX+50,knightY+50,20,20); } class Module { int x; int y; int modColor=0; // Contructor Module(int xT, int yT){ x = xT; y = yT; } void mouseClick() { if ((mouseX >= x && mouseX <= x+100 && mouseY >= y && mouseY <= y+100)&& (overKnight && mousePressed && (mouseButton == LEFT))) { storX=x; storY=y; } if( (bool_mouseReleased ) && (x==storX && y==storY ) ){ modColor=200; } } void update() { fill(modColor); rect(x, y, unitSize, unitSize); } } void mousePressed() { if(overKnight) { locked = true; } else { locked = false; } xOffset = mouseX-knightX; yOffset = mouseY-knightY; } void mouseDragged() { if(locked) { bool_mouseReleased=false; knightX = mouseX-xOffset; knightY = mouseY-yOffset; } } void mouseReleased() { bool_mouseReleased=true; locked = false; knightX=storX; knightY=storY; } 


在这里检查

第二部分


添加一个取消按钮。
这里是一个说明按钮操作的示例。

首先,创建IntList列表,其中包含马所经过的单元格坐标; 在左下角绘制按钮本身:

 // list IntList listOfCoordinatesX; IntList listOfCoordinatesY; //button int buttonX=25, buttonY=525; int buttonSize = 50; boolean boolButton = false; 

初始化清单
 listOfCoordinatesX = new IntList(); listOfCoordinatesY = new IntList(); listOfCoordinatesX.append(0); listOfCoordinatesY.append(0); 

在下一步的最后(释放鼠标按钮时),我们将单元格坐标添加到列表/堆栈中:
  if(overKnight){ knightX=storX; knightY=storY; listOfCoordinatesX.append(int(knightX)); listOfCoordinatesY.append(int(knightY)); } 

让我们创建一个布尔函数overButton() ,如果鼠标光标在按钮上方,则返回true;而按钮Update()函数将更新变量
boolButton
  void buttonUpdate() { if ( overButton(buttonX, buttonY, buttonSize, buttonSize) ) { boolButton = true; } else { boolButton = false; } } boolean overButton(int x, int y, int width, int height) { if (mouseX >= x && mouseX <= x+width && mouseY >= y && mouseY <= y+height) { return true; } else { return false; } } 

变量和列表显示在控制台的主程序循环中:
  println(boolButton); println(listOfCoordinatesX); println(listOfCoordinatesY); 


整个程序
 // list IntList listOfCoordinatesX; IntList listOfCoordinatesY; //button int buttonX=25, buttonY=525; int buttonSize = 50; boolean boolButton = false; //mouse boolean bool_mouseReleased; // jump to rect center on button release float storX; float storY; float knightX; float knightY; // size of canvas int edgeOfCanvas=500; int knightSize = 100; boolean overKnight = false; boolean locked = false; float xOffset = 0.0; float yOffset = 0.0; int unit = 100; // -> width / unit; int unitSize=100; int count; Module[] mods; void setup() { size(500, 600); stroke(100); knightX = 0; knightY = 0; rectMode(CORNER); listOfCoordinatesX = new IntList(); listOfCoordinatesY = new IntList(); listOfCoordinatesX.append(0); listOfCoordinatesY.append(0); int wideCount = edgeOfCanvas / unit; int highCount = edgeOfCanvas / unit; count = wideCount * highCount; mods = new Module[count]; int index = 0; for (int y = 0; y < highCount; y++) { for (int x = 0; x < wideCount; x++) { mods[index++] = new Module(x*unit, y*unit); } } } void draw() { background(0); buttonUpdate(); for (Module mod : mods) { mod.mouseClick(); mod.update(); } // // // // // // // Test if the cursor is over the box fill(200); if (mouseX > knightX && mouseX < knightX+knightSize && mouseY > knightY && mouseY < knightY+knightSize) { overKnight = true; } else { overKnight = false; } fill(200); rect(0,0,100,100); rect(knightX, knightY, knightSize, knightSize); fill(50); ellipse(knightX+50,knightY+50,20,20); // draw button rect(buttonX,buttonY,buttonSize,buttonSize); if(boolButton && mousePressed) { fill(200); rect(buttonX,buttonY,buttonSize,buttonSize); } println(); println(storX); println(storY); println(boolButton); println(listOfCoordinatesX); println(listOfCoordinatesY); } class Module { int x; int y; int modColor=0; // Contructor Module(int xT, int yT){ x = xT; y = yT; } void mouseClick() { if (mouseX >= x && mouseX <= x+100 && mouseY >= y && mouseY <= y+100) { if (overKnight && mousePressed && (mouseButton == LEFT)) { storX=x; storY=y; // if(bool_mouseReleased ) {modColor=200;} } } if((bool_mouseReleased ) && (x==storX && y==storY )){ modColor=200; } } void update() { fill(modColor); rect(x, y, unitSize, unitSize); } } void mousePressed() { if(overKnight) { locked = true; } else { locked = false; } xOffset = mouseX-knightX; yOffset = mouseY-knightY; } void mouseDragged() { if(locked) { bool_mouseReleased=false; knightX = mouseX-xOffset; knightY = mouseY-yOffset; } } void mouseReleased() { bool_mouseReleased=true; locked = false; if(overKnight){ knightX=storX; knightY=storY; listOfCoordinatesX.append(int(knightX)); listOfCoordinatesY.append(int(knightY)); } } // button void buttonUpdate() { if ( overButton(buttonX, buttonY, buttonSize, buttonSize) ) { boolButton = true; } else { boolButton = false; } } boolean overButton(int x, int y, int width, int height) { if (mouseX >= x && mouseX <= x+width && mouseY >= y && mouseY <= y+height) { return true; } else { return false; } } 


在这里检查

第三部分


单击取消按钮时,添加跳到上一个单元格的功能。
mousePressed()函数中, 我们检查是否已按下取消按钮。 如果按下该按钮,则如果坐标列表中有多个元素,则从坐标列表(堆栈顶部)中删除最后一个元素:
 if(boolButton && listOfCoordinatesX.size()>1) { listOfCoordinatesX.pop(); listOfCoordinatesY.pop(); } 

当您单击Module类的mouseClick()方法中的取消按钮时,我们将坐标列表的元素(堆栈顶部)保存到storXstorY变量中:
 if(boolButton && mousePressed) { storX= listOfCoordinatesX.get(listOfCoordinatesX.size()-1); storY= listOfCoordinatesY.get(listOfCoordinatesY.size()-1); } 

松开“取消”按钮时,我们返回到上一个坐标,并向该单元格返回原始(黑色)颜色:
 if(boolButton && bool_mouseReleased){ if(x==storX && y==storY ) { modColor=0; } } 

mouseReleased()函数中, 我们将马放置在字段的相应单元格中。
 if(boolButton) { knightX=storX; knightY=storY; } 


完整代码
 // list IntList listOfCoordinatesX; IntList listOfCoordinatesY; //button int buttonX=25, buttonY=525; int buttonSize = 50; boolean boolButton = false; //mouse boolean bool_mouseReleased; // jump to rect center on button release float storX; float storY; float knightX; float knightY; // size of canvas int edgeOfCanvas=500; int knightSize = 100; boolean overKnight = false; boolean locked = false; float xOffset = 0.0; float yOffset = 0.0; int unit = 100; // -> width / unit; int unitSize=100; int count; Module[] mods; void setup() { size(500, 600); stroke(100); knightX = 0; knightY = 0; rectMode(CORNER); listOfCoordinatesX = new IntList(); listOfCoordinatesY = new IntList(); listOfCoordinatesX.append(0); listOfCoordinatesY.append(0); int wideCount = edgeOfCanvas / unit; int highCount = edgeOfCanvas / unit; count = wideCount * highCount; mods = new Module[count]; int index = 0; for (int y = 0; y < highCount; y++) { for (int x = 0; x < wideCount; x++) { mods[index++] = new Module(x*unit, y*unit); } } } void draw() { background(0); buttonUpdate(); for (Module mod : mods) { mod.mouseClick(); mod.update(); } // // // // // // // Test if the cursor is over the box fill(200); if (mouseX > knightX && mouseX < knightX+knightSize && mouseY > knightY && mouseY < knightY+knightSize) { overKnight = true; } else { overKnight = false; } fill(200); rect(0,0,100,100); rect(knightX, knightY, knightSize, knightSize); fill(50); ellipse(knightX+50,knightY+50,20,20); // draw button rect(buttonX,buttonY,buttonSize,buttonSize); if(boolButton && mousePressed) { fill(200); rect(buttonX,buttonY,buttonSize,buttonSize); } /* println(); println(storX); println(storY); println(boolButton); println(listOfCoordinatesX); println(listOfCoordinatesY); */ } class Module { int x; int y; int modColor=0; // Contructor Module(int xT, int yT){ x = xT; y = yT; } void mouseClick() { if (mouseX >= x && mouseX <= x+100 && mouseY >= y && mouseY <= y+100) { if (overKnight && mousePressed && (mouseButton == LEFT)) { storX=x; storY=y; // if(bool_mouseReleased ) {modColor=200;} } } if((bool_mouseReleased ) && (x==storX && y==storY )){ modColor=200; } if(boolButton && mousePressed){ storX= listOfCoordinatesX.get(listOfCoordinatesX.size()-1); storY= listOfCoordinatesY.get(listOfCoordinatesY.size()-1); } if(boolButton && bool_mouseReleased){ if(x==storX && y==storY ){ modColor=0; } } } void update() { fill(modColor); rect(x, y, unitSize, unitSize); } } void mousePressed() { if(overKnight) { locked = true; // listOfCoordinatesX.append(int(knightX)); // listOfCoordinatesY.append(int(knightY)); } else { locked = false; } xOffset = mouseX-knightX; yOffset = mouseY-knightY; if(boolButton && listOfCoordinatesX.size()>1){ listOfCoordinatesX.pop(); listOfCoordinatesY.pop(); } } void mouseDragged() { if(locked) { bool_mouseReleased=false; knightX = mouseX-xOffset; knightY = mouseY-yOffset; } } void mouseReleased() { bool_mouseReleased=true; locked = false; if(overKnight){ knightX=storX; knightY=storY; listOfCoordinatesX.append(int(knightX)); listOfCoordinatesY.append(int(knightY)); } if(boolButton){ knightX=storX; knightY=storY; } } // button void buttonUpdate() { if ( overButton(buttonX, buttonY, buttonSize, buttonSize) ) { boolButton = true; } else { boolButton = false; } } boolean overButton(int x, int y, int width, int height) { if (mouseX >= x && mouseX <= x+width && mouseY >= y && mouseY <= y+height) { return true; } else { return false; } } 


现在,使用处理语言的程序可以正常运行,而p5.js上程序中的撤消功能将无法正常运行。
此处检查p5.js上的程序

用int []数组替换主程序中的InList列表。 您可以使用append()函数元素动态添加到数组以及列表中
  listOfCoordinatesX = append(listOfCoordinatesX,0); 

您无法从数组中使用pop()检索元素。 为此,有一个函数可以将数组的长度减少一个short() 。 要确定数组的长度,请使用length而不是size()
整个程序
  // list int[] listOfCoordinatesX; int[] listOfCoordinatesY; //button int buttonX=25, buttonY=525; int buttonSize = 50; boolean boolButton = false; //mouse boolean bool_mouseReleased; // jump to rect center on button release float storX; float storY; float knightX; float knightY; // size of canvas int edgeOfCanvas=500; int knightSize = 100; boolean overKnight = false; boolean locked = false; float xOffset = 0.0; float yOffset = 0.0; int unit = 100; // -> width / unit; int unitSize=100; int count; Module[] mods; void setup() { size(500, 600); stroke(100); //   listOfCoordinatesX = new int[0]; //    listOfCoordinatesY = new int[0]; //   (0,0) listOfCoordinatesX = append(listOfCoordinatesX,0); listOfCoordinatesY = append(listOfCoordinatesY,0); knightX = 0; knightY = 0; rectMode(CORNER); int wideCount = edgeOfCanvas / unit; int highCount = edgeOfCanvas / unit; count = wideCount * highCount; mods = new Module[count]; int index = 0; for (int y = 0; y < highCount; y++) { for (int x = 0; x < wideCount; x++) { mods[index++] = new Module(x*unit, y*unit); } } } void draw() { background(0); buttonUpdate(); for (Module mod : mods) { mod.mouseClick(); mod.update(); } // // // // // // // Test if the cursor is over the box fill(200); if (mouseX > knightX && mouseX < knightX+knightSize && mouseY > knightY && mouseY < knightY+knightSize) { overKnight = true; } else { overKnight = false; } fill(200); rect(0,0,100,100); rect(knightX, knightY, knightSize, knightSize); fill(50); ellipse(knightX+50,knightY+50,20,20); // draw button rect(buttonX,buttonY,buttonSize,buttonSize); if(boolButton && mousePressed) { fill(200); rect(buttonX,buttonY,buttonSize,buttonSize); } // println(); // println(storX); // println(storY); // println(boolButton); // println(listOfCoordinatesX); // println(listOfCoordinatesY); } class Module { int x; int y; int modColor=0; // Contructor Module(int xT, int yT){ x = xT; y = yT; } void mouseClick() { if (mouseX >= x && mouseX <= x+100 && mouseY >= y && mouseY <= y+100) { if (overKnight && mousePressed && (mouseButton == LEFT)) { storX=x; storY=y; // if(bool_mouseReleased ) {modColor=200;} } } if((bool_mouseReleased ) && (x==storX && y==storY )){ modColor=200; } if(boolButton && mousePressed){ storX= listOfCoordinatesX[listOfCoordinatesX.length-1]; storY= listOfCoordinatesY[listOfCoordinatesY.length-1]; } if(boolButton && bool_mouseReleased){ if(x==storX && y==storY ){ modColor=0; } } } void update() { fill(modColor); rect(x, y, unitSize, unitSize); } } void mousePressed() { if(overKnight) { locked = true; } else { locked = false; } xOffset = mouseX-knightX; yOffset = mouseY-knightY; if(boolButton && listOfCoordinatesX.length>1){ // listOfCoordinatesX.pop(); // listOfCoordinatesY.pop(); listOfCoordinatesX=shorten(listOfCoordinatesX); listOfCoordinatesY=shorten(listOfCoordinatesY); } } void mouseDragged() { if(locked) { bool_mouseReleased=false; knightX = mouseX-xOffset; knightY = mouseY-yOffset; } } void mouseReleased() { bool_mouseReleased=true; locked = false; if(overKnight){ knightX=storX; knightY=storY; listOfCoordinatesX=append(listOfCoordinatesX,int(knightX)); listOfCoordinatesY=append(listOfCoordinatesY,int(knightY)); } if(boolButton){ knightX=storX; knightY=storY; } } // button void buttonUpdate() { if ( overButton(buttonX, buttonY, buttonSize, buttonSize) ) { boolButton = true; } else { boolButton = false; } } boolean overButton(int x, int y, int width, int height) { if (mouseX >= x && mouseX <= x+width && mouseY >= y && mouseY <= y+height) { return true; } else { return false; } } 


该程序可以作为js脚本添加到html页面。 要运行脚本,您必须使用processing.js
在此查看此页面。
这里是一样的,只是带有马的形象。
在这里,马只能带着字母G行走其余的动作均被禁止。

链接到github,并提供本文中提供的程序的文本。

Source: https://habr.com/ru/post/zh-CN444512/


All Articles