יום חמישי, דצמבר 16

גרפיקה 2D: ציור אינטראקטיבי

בהמשך לפוסט הקודם בו  התחלנו לצייר קצת במסגרת ה-subclass של View, נמשיך לצייר, לא משהו מתוחכם, אבל כבר מתחיל להראות כמו משחק משעשע: ציור אינטראקטיבי המופעל ע"י מגע, או ע"י העכבר באמולטור.
ראינו שהציור על המסך מתבצע במתודה onDraw, שהיא callback המופעל כשיש צורך לחדש את התצוגה. הפעם ניצור את הצורך הזה עם הפעלת המתודה invalidate שמבטלת את תוכן ה-view, ובכך תגרום להפעלת onDraw. אציין שניתן לעשות גם invalidate חלקי -  רק על מלבן בתוך ה-view או על drawable מסוים.


תאור פעולת התכנית
נדגים  שיתוף פעולה של invalidate ו-onDraw.
התכנית מציירת קו שמתחיל בנקודת הנגיעה על המסך ונמתח יחד עם התנועה של האצבע (או העכבר). כל נגיעה במסך מתחילה קו חדש, אך שני הקוים הקודמים נשארים. אפשר לשחק בזה ולהעביר את הזמן בכיף (אני בעצמי ביליתי יותר משעה עם כל מיני וריאציות של התרגיל הזה).

צילום מסך  לדוגמא:



הנה הקוד:


  1. public class MyViewTouchPlay extends Activity {
  2.     /** Called when the activity is first created. */
  3.     @Override
  4.     public void onCreate(Bundle savedInstanceState) {
  5.         super.onCreate(savedInstanceState);
  6.         TouchView touchView = new TouchView(this);
  7.         setContentView(touchView);
  8.     }
  9.     private class TouchView extends View{
  10.         float startX, startY;
  11.         float stopX, stopY;
  12.         float startOld1X, startOld1Y;
  13.         float stopOld1X, stopOld1Y;
  14.         float startOld2X, startOld2Y;
  15.         float stopOld2X, stopOld2Y;
  16.         Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
  17.           public TouchView(Context context) {
  18.             super(context);
  19.             paint.setColor(Color.YELLOW);
  20.            }
  21.         @Override
  22.         protected void onDraw(Canvas canvas) {
  23.             canvas.drawText("Touch the screen, Draw a line", 10, 50, paint);
  24.             canvas.drawLine(startX, startY, stopX, stopY, paint);
  25.             canvas.drawLine(startOld1X, startOld1Y, stopOld1X, stopOld1Y, paint);
  26.             canvas.drawLine(startOld2X, startOld2Y, stopOld2X, stopOld2Y, paint);
  27.         }
  28.         @Override
  29.         public boolean onTouchEvent(MotionEvent event) {
  30.             int action = event.getAction();
  31.    if (action==MotionEvent.ACTION_DOWN){
  32.                 startOld2X = startOld1X;
  33.                 startOld2Y = startOld1Y;
  34.                 startOld1X = startX;
  35.                 startOld1Y = startY;
  36.                 startX = event.getX();
  37.                 startY = event.getY();
  38.             }
  39.  
  40.          else if (action==MotionEvent.ACTION_MOVE){
  41.                 stopOld2X = stopOld1X;
  42.                 stopOld2Y = stopOld1Y;
  43.                 stopOld1X = stopX;
  44.                 stopOld1Y = stopY;
  45.                 stopX = event.getX();
  46.                 stopY = event.getY();
  47.                 invalidate();
  48.             }
  49.          
  50.             return true;
  51.         
  52.         }
  53.     }   
  54. }

הקוד קצר ופשוט. 2 אובייקטים:
  1.  subclass של   Activity, האחראי על ה-UI.
  2. ו-class פנימי שהוא subclass  של View שבונה את התצוגה.
האובייקט הראשון, כולל את onCreate שם יוצרים ומאתחלים את האובייקט השני.

האובייקט השני מכיל שתי מתודות:
  1. onDraw, שורות 22-27 - ה-callback שאחראי על הציור למסך.
  2. onTouchEvent שורות 28-52- ה-callback שמופעל כתוצאה מנגיעה על המסך.

ב-onDraw מציירים 3 קוים, בנוסף לטקסט הכותרת:
  • 2 קוים לפי הקודקודים שנשמרו משתי הפעמים הקודמות.
  • קו חדש שנקודת ההתחלה שלו היא בנקודה בה התחיל המגע על המסך (startX, startY) והקודקוד השני שלו במקום הנוכחי של האצבע.

onTouchEvent מטפלת בשני מצבים: 
  • action==MotionEvent.ACTION_DOWN
  •  action==MotionEvent.ACTION_MOVE
הראשון הוא אירוע נגיעה במסך והשני גרירה על המסך. במקרה של נגיעה, נקודת הנגיעה נשמרת כנקודת התחלה של הקו:


  1.            stopX = event.getX();
  2.            stopY = event.getY();
ו במקרה של גרירה:
  1. stopX = event.getX();
  2. stopY = event.getY();
  3. invalidate();
כאן נשמר מיקום האצבע כקודקוד השני של הקו,  ומופעלת invalidate שתגרום להפעלת onDraw וציור הקוים מחדש.


בשורות 32-35 ו- 41-44 שומרים על 2 הקוים הקודמים, וגם הם מצויירים ב-onDraw.





אין תגובות:

הוסף רשומת תגובה