Processing là một trong những thư viện mạnh mẽ nhất hiện nay để tạo các hình ảnh đồ họa, cả 2D và 3D. Đây là thư viện mã nguồn mở, dựa trên Java, và có nhiều chức năng đa dạng, phục vụ việc vẽ và đổ màu với code thật dễ dàng.

Sử dụng thư viện Processing trong các ứng dụng Android của mình, bạn có thể tạo đồ họa và hình ảnh động hiệu suất cao, mà không cần quan tâm tới OpenGL hoặc Canvas của Android.

Vì vậy, bạn không phải bận tâm đến các tác vụ cấp thấp như quản lý threads, tạo ra các vòng lặp render, hoặc tỉ lệ khung hình trên giây.

1. Thiết lập Project

Processing đi cùng với môi trường phát triển tích hợp riêng của nó, có thể được sử dụng để tạo các ứng dụng Android. Tuy nhiên, nếu bạn là một nhà phát triển ứng dụng Android, tôi chắc chắn bạn muốn sử dụng Studio Android thay thế.

Hãy tải xuống Android Mode phiên bản mới nhất.

Bên trong file ZIP bạn đã download, bạn sẽ tìm thấy một file tên là processing-core.zip. Giải nén nó ra và đổi tên thành processing-core.jar.

Cuối cùng, thêm file JAR vào project trong folder app/libs.

OK ngon. Chúng ta hãy bắt đầu với Processing.

2. Tạo một Canvas

Hầu như tất cả các chức năng cốt lõi của Processing đều có sẵn thông qua lớp PApplet, nó lưu trữ một Canvas mà bạn có thể vẽ. Kế thừa từ class này, bạn có thể dễ dàng truy cập vào tất cả các phương pháp nó cung cấp.

val myCanvas = object: PApplet() {
    // More code here
}

Để định cấu hình canvas, bạn phải override phương thức settings () của nó. Bên trong phương thức, bạn có thể chỉ định hai cấu hình quan trọng: kích thước mong muốn của canvas và nó có sử dụng công cụ vẽ 2D hay 3D hay không.

Bây giờ, chúng ta hãy tạo ra một Canvas lớn bằng màn hình của thiết bị và sử dụng công cụ render 2D mặc định. Để làm như vậy, bạn có thể gọi phương thức fullScreen ().

override fun settings() {
    fullScreen()
}

Phương thức settings () là một phương thức đặc biệt, chỉ cần đến khi bạn không sử dụng IDE của Processing.

Nếu bạn muốn khởi tạo bất kỳ biến nào, hoặc thay đổi bất kỳ tham số liên quan đến bản vẽ nào, chẳng hạn như màu nền của canvas, hoặc số khung hiển thị mỗi giây, bạn nên sử dụng phương thức setup ().
Ví dụ : code sau cho bạn thấy cách sử dụng phương thức background () để thay đổi màu nền của canvas thành màu đỏ:

override fun setup() {
    background(Color.parseColor("#FF8A80")) // Material Red A100
}

3. Hiển thị Canvas

Bởi vì canvas vẫn không phải là một thành phần của Activity nào, bạn sẽ không thể nhìn thấy nó khi chạy ứng dụng. Để hiển thị Canvas, trước tiên bạn phải tạo một vùng chứa cho nó, bên trong layout XML của Activity.
LinearLayout hoặc FrameLayout đều có thể là vùng chứa.

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/canvas_container">
     
</FrameLayout>

Không thể thêm một đối tượng PApplet trực tiếp vào vùng chứa mà bạn đã tạo.
Bạn phải đặt nó bên trong một PFragment trước tiên, và sau đó gọi phương thức setView () của đối tượng PFragment, để liên kết nó với vùng chứa.
Đoạn code dưới đây chỉ cho bạn cách thực hiện:

// Place canvas inside fragment
val myFragment = PFragment(myCanvas)
 
// Display fragment
myFragment.setView(canvas_container, this)

Tại thời điểm này, nếu bạn chạy ứng dụng, bạn sẽ có thể thấy một canvas trống bao phủ toàn bộ màn hình của thiết bị.

4. Vẽ một hình Shapes đơn giản

Bây giờ, bạn có thể nhìn thấy canvas, chúng ta hãy bắt đầu vẽ.
Để vẽ bên trong canvas, bạn phải override phương thức draw() của PApplet mà bạn đã tạo ra trước đó.

override fun draw() {
    // More code here
}

Processing theo mặc định, gọi phương thức draw() 60 lần mỗi giây, miễn là canvas được hiển thị. Điều đó có nghĩa là bạn có thể dễ dàng tạo ra cả đồ họa và hình ảnh động với nó.

Processing có rất nhiều phương thức được đặt tên theo trực giác, cho phép bạn vẽ các hình học cơ bản như điểm, đường kẻ, hình eclipse và hình chữ nhật.

Ví dụ, phương thức rect() vẽ một hình chữ nhật, và phương thức ellipse() vẽ một hình elip.
Cả hai phương pháp rect() và ellipse() đềucần các tham số như : tọa độ X và Y của hình dạng, chiều rộng và chiều cao của nó.

Đoạn code sau cho bạn thấy làm thế nào để vẽ một hình chữ nhật và một hình elip:

rect(100f, 100f, 500f, 300f) // Top-left corner is at (100,100)
ellipse(350f, 650f, 500f, 400f) // Center is at (350,650)

Nhiều phương pháp được override, cho phép bạn sửa đổi một chút các hình dạng cơ bản.
Ví dụ: bằng cách truyền tham số thứ năm cho phương thức rect(), độ bo tròn của góc, bạn có thể vẽ một hình được bo tròn 4 góc.

rect(100f, 900f, 500f, 300f, 100f) // Corner radius of 100 pixels

Nếu bạn chạy ứng dụng, bạn sẽ thấy một số hình ảnh như sau:

Nếu bạn muốn thay đổi màu đường viền của hình shape, bạn có thể gọi phương thức stroke() và truyền tham số vào là màu sắc mong muốn.
Tương tự, nếu bạn muốn đổ màu vào các hình dạng với một màu sắc cụ thể, bạn có thể gọi phương thức fill().

Cả hai phương thức nên được gọi trước khi bạn thực sự vẽ hình dạng.

Đoạn code sau vẽ một tam giác màu xanh nước biển với một đường viền màu xanh lá cây:

stroke(Color.GREEN)
fill(Color.BLUE)
triangle(100f, 1600f, 300f, 1300f, 500f, 1600f)

Nếu bạn chạy ứng dụng, bạn sẽ có thể thấy tam giác màu xanh, nhưng bạn cũng sẽ nhận thấy rằng mọi hình dạng khác cũng đã chuyển sang màu xanh.

Hãy nhớ rằng phương thức draw() được gọi là lặp đi lặp lại. Điều đó có nghĩa là bất kỳ tham số cấu hình nào bạn thay đổi trong chu kỳ vẽ sẽ có ảnh hưởng đến các chu kỳ vẽ tiếp theo.
Vì vậy, để đảm bảo rằng tất cả các hình dạng của bạn được vẽ bằng đúng màu sắc, bạn nên luôn xác định rõ màu sắc của mỗi hình vẽ mà bạn vẽ ngay trước khi vẽ nó.

Ví dụ, bằng cách thêm code sau vào đoạn đầu của phương thức draw(), bạn có thể làm cho các hình dạng khác trở lại màu trắng.

// Set the fill and stroke to white and black
// before drawing the rectangles and ellipses
stroke(Color.BLACK)
fill(Color.WHITE)

Lúc này, Canvas sẽ như sau:

5. Xử lí Touch Event

Với Processing, việc xử lý các sự kiện chạm tay rất dễ dàng. Bạn không cần bất kỳ trình xử lý sự kiện nào. Tất cả bạn cần làm là kiểm tra xem một biến boolean tên mousePressed khi người dùng chạm vào màn hình hay không.

Khi bạn đã xác nhận rằng người dùng đang chạm vào màn hình, bạn có thể sử dụng các biến mouseX và mouseY để xác định tọa độ X và Y của lần chạm.

Ví dụ : đoạn code sau sẽ vẽ ra một hình chữ nhật mới bất cứ nơi nào người dùng chạm vào canvas.

// Check if user is touching the canvas
if(mousePressed) {
    // Specify fill and stroke colors
    stroke(Color.RED)
    fill(Color.YELLOW)
     
    // Draw rectangle
    rect(mouseX.toFloat(), mouseY.toFloat(), 100f, 100f)
}

Nếu bạn chạy ứng dụng và vuốt ngón tay của mình qua màn hình, bạn sẽ thấy rất nhiều hình chữ nhật màu vàng được vẽ ra.

Mẹo nhỏ : nếu tại bất kỳ điểm nào bạn muốn xóa trên Canvas, bạn chỉ cần gọi lại phương thức background() 😄

background(Color.parseColor("#FF8A80")) // Material Red A100