إنشاء تطبيق رسومية لحل مشكلة مسار الحصان

هذا هو برنامج تعليمي حول إنشاء تطبيق تفاعلي لحل مشكلة تقدم الحصان في المعالجة و p5.js

الجزء الأول


إنشاء حصان - مستطيل مستطيل (). يرمز الحصان من قبل دائرة رمادية.

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

دع الحصان يرسم على كل الخلايا التي يمر من خلالها ، هكذا هو الحال هنا .

بعد ذلك ، دع الحصان ينجذب إلى وسط القفص عند إطلاق زر mouseRealised () .

أضف متغيرات storX و storY التي ستقوم بتخزين إحداثيات الخلية التي يقع عليها المؤشر. إذا تم الضغط على الزر الأيسر وكان المؤشر أعلى الحصان ، فاحفظ إحداثيات وزارة الدفاع الحالية الخلية في المتغيرات storX و 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 } } } 


عند تحرير الزر ، يتم تحميل إحداثيات storX و storY في إحداثيات knightX و knightY knights.
  knightX=storX; knightY=storY; 

إذا كان هناك متغير منطقي قياسي mousePressed لحالة الزر المضغوط ، فلا يوجد مثل هذا المتغير لحالة الزر المضغوط - قم بإنشائه بنفسك:
  boolean bool_mouseReleased; // ... void mouseReleased() { bool_mouseReleased=true; locked = false; knightX=storX; knightY=storY; } 

الآن ، إذا لم يتم الضغط على زر الماوس (أي bool_mouseReleased = صواب ) ، قم بالطلاء على الخلية باستخدام الإحداثيات 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 () ، والتي تعود بشكل صحيح إذا كان مؤشر الماوس أعلى الزر و buttonUpdate () ، والذي يقوم بتحديث المتغير
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(); } 

عند النقر فوق زر "إلغاء" في طريقة mouseClick () لفئة الوحدة النمطية ، فإننا نحفظ عناصر قوائم الإحداثيات (قمم الرصات) في متغيرات storX و storY :
 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 هنا

استبدل قوائم InList في البرنامج الرئيسي بمصفوفات int []. يمكنك إضافة عنصر ديناميكي إلى المصفوفة ، وكذلك إلى القائمة ، باستخدام وظيفة append ()
  listOfCoordinatesX = append(listOfCoordinatesX,0); 

لا يمكنك استرداد عنصر به pop () من صفيف. للقيام بذلك ، هناك دالة لتقليل طول الصفيف بواسطة تقصير واحد () . لتحديد طول الصفيف ، بدلاً من 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. أما بقية الحركات فهي محظورة.

رابط إلى جيثب بنصوص البرامج المقدمة في المقال.

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


All Articles