Erstellen einer grafischen Anwendung zur Lösung des Pferdefortschritts

Dies ist ein Tutorial zum Erstellen einer interaktiven Anwendung zur Lösung des Fortschrittsproblems des Pferdes in der Verarbeitung und in p5.js.

Teil I.


Erstellen Sie ein Pferd - Rechteck rect (). Das Pferd ist durch einen grauen Kreis gekennzeichnet.

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

Lassen Sie das Pferd alle Zellen übermalen, durch die es geht, so ist es hier .

Lassen Sie das Pferd als Nächstes von der Mitte des Käfigs angezogen werden, wenn Sie die mouseRealised () -Taste loslassen .

Fügen Sie die Variablen storX und storY hinzu , in denen die Koordinaten der Zelle gespeichert werden, auf der sich der Cursor befindet. Wenn die linke Taste gedrückt wird und sich der Cursor über dem Pferd befindet, speichern Sie die Koordinaten des aktuellen Zellenmods in den Variablen storX und storY :

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


Wenn Sie die Taste loslassen, werden die Koordinaten storX und storY in die Koordinaten der Ritter KnightX und KnightY geladen.
  knightX=storX; knightY=storY; 

Wenn es eine standardmäßige moolPressed-Boolesche Variable für den Status der gedrückten Taste gibt, existiert eine solche Variable für den Status der gedrückten Taste nicht - erstellen Sie sie selbst:
  boolean bool_mouseReleased; // ... void mouseReleased() { bool_mouseReleased=true; locked = false; knightX=storX; knightY=storY; } 

Wenn nun die Maustaste nicht gedrückt wird (d. H. Bool_mouseReleased = true ), übermalen Sie die Zelle mit den Koordinaten storX und storY
 if((bool_mouseReleased ) && (x==storX && y==storY )){ modColor=200; } 


Zeichne ein Pferd in die Mitte des Käfigs
 //  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; } 


Überprüfen Sie hier

Teil II


Fügen Sie eine Abbrechen-Schaltfläche hinzu.
Ein Beispiel für die Bedienung von Tasten finden Sie hier .

Erstellen Sie zunächst IntList- Listen mit Zellkoordinaten, an denen das Pferd vorbeigegangen ist. Zeichnen Sie den Knopf selbst in der unteren linken Ecke:

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

Listen initialisieren
 listOfCoordinatesX = new IntList(); listOfCoordinatesY = new IntList(); listOfCoordinatesX.append(0); listOfCoordinatesY.append(0); 

Am Ende des nächsten Zuges (beim Loslassen der Maustaste) fügen wir die Zellkoordinaten zur Liste / zum Stapel hinzu:
  if(overKnight){ knightX=storX; knightY=storY; listOfCoordinatesX.append(int(knightX)); listOfCoordinatesY.append(int(knightY)); } 

Erstellen wir eine boolesche Funktion overButton () , die true zurückgibt, wenn sich der Mauszeiger über der Schaltfläche befindet, und die Funktion buttonUpdate () , die die Variable aktualisiert
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; } } 

Die Variablen und Listen werden in der Konsole in der Hauptprogrammschleife angezeigt:
  println(boolButton); println(listOfCoordinatesX); println(listOfCoordinatesY); 


Ganzes Programm
 // 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; } } 


Überprüfen Sie hier

Teil III


Fügen Sie die Funktion zum Springen zur vorherigen Zelle hinzu, wenn Sie auf die Schaltfläche Abbrechen klicken.
In der Funktion mousePressed () prüfen wir , ob die Abbrechen-Taste gedrückt wurde. Wenn die Schaltfläche gedrückt wird, löschen Sie die letzten Elemente aus den Koordinatenlisten (oben auf den Stapeln), wenn die Liste mehr als ein Element enthält:
 if(boolButton && listOfCoordinatesX.size()>1) { listOfCoordinatesX.pop(); listOfCoordinatesY.pop(); } 

Wenn Sie in der mouseClick () -Methode der Module- Klasse auf die Schaltfläche Abbrechen klicken, speichern wir die Elemente der Koordinatenlisten (oben auf den Stapeln) in den Variablen storX und storY :
 if(boolButton && mousePressed) { storX= listOfCoordinatesX.get(listOfCoordinatesX.size()-1); storY= listOfCoordinatesY.get(listOfCoordinatesY.size()-1); } 

Wenn Sie die Abbrechen-Schaltfläche loslassen, kehren wir zur vorherigen Koordinate zurück und kehren zur ursprünglichen (schwarzen) Farbe in die Zelle zurück:
 if(boolButton && bool_mouseReleased){ if(x==storX && y==storY ) { modColor=0; } } 

In der Funktion mouseReleased () platzieren wir unser Pferd in der entsprechenden Zelle des Feldes.
 if(boolButton) { knightX=storX; knightY=storY; } 


Vollständiger Code
 // 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; } } 


Jetzt funktioniert das Programm in der Verarbeitungssprache korrekt, und die Rückgängig-Funktion im Programm auf p5.js funktioniert nicht richtig.
Überprüfen Sie das Programm auf p5.js hier

Ersetzen Sie die InList-Listen im Hauptprogramm durch int [] -Arrays. Mit der Funktion append () können Sie dem Array sowie der Liste dynamisch ein Element hinzufügen
  listOfCoordinatesX = append(listOfCoordinatesX,0); 

Sie können ein Element mit pop () nicht aus einem Array abrufen. Zu diesem Zweck gibt es eine Funktion, mit der die Länge des Arrays um ein Shorten () reduziert werden kann. Verwenden Sie anstelle von size () die Länge, um die Länge des Arrays zu bestimmen
Ganzes Programm
  // 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; } } 


Dieses Programm kann als js-Skript zu einer HTML-Seite hinzugefügt werden. Um das Skript auszuführen, müssen Sie process.js verwenden
Sehen Sie sich diese Seite hier an .
Und hier ist das gleiche, aber mit dem Bild eines Pferdes.
Und hier kann das Pferd nur mit dem Buchstaben G laufen . Der Rest der Bewegungen ist verboten.

Link zu Github mit den Texten der im Artikel vorgestellten Programme.

Source: https://habr.com/ru/post/de444512/


All Articles