Let's craft a simple, workable code lab based on the course content, specifically focusing on 2D graphics, as it's foundational and aligns with the course's early objectives.
Code Lab: Drawing Basic Shapes on Android
Objective:
Learn to use Canvas and Paint to draw basic 2D shapes (rectangle, circle) on an Android View. Prerequisites:
Basic understanding of Android Studio and creating layouts (XML or Compose). Familiarity with Kotlin programming language. Steps:
Create a new Kotlin class (e.g., MyDrawingView) that extends View. Override the onDraw(canvas: Canvas) method. This is where the drawing magic happens. Inside onDraw, create a Paint object. Configure its properties: color = Color.BLUE (or any color you like) style = Paint.Style.FILL (to fill the shape) You can also set stroke width, style, etc., for outlines. Use canvas.drawRect(left, top, right, bottom, paint) Provide coordinates for the rectangle's corners. Example: canvas.drawRect(100f, 100f, 300f, 200f, paint) Use canvas.drawCircle(centerX, centerY, radius, paint) Provide the center coordinates and radius. Example: canvas.drawCircle(200f, 400f, 80f, paint) Add the View to your Layout In your activity's layout file, add <com.yourpackage.MyDrawingView ... /> Set its width and height appropriately. Complete Code (Kotlin):
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.view.View
class MyDrawingView(context: Context) : View(context) {
private val paint = Paint().apply {
color = Color.BLUE
style = Paint.Style.FILL
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
// Draw rectangle
canvas.drawRect(100f, 100f, 300f, 200f, paint)
// Draw circle
canvas.drawCircle(200f, 400f, 80f, paint)
}
}
Explanation:
This code lab introduces the core concepts of 2D drawing in Android. It's simplified for beginners, focusing on drawing basic shapes. Further exploration could involve: Handling touch events for interactive drawing. Drawing more complex shapes (paths, arcs). Using transformations (translate, rotate, scale). Remember, this is a basic starting point. The course outline covers more advanced topics like 3D graphics, animations, and utilizing hardware acceleration, which would require more elaborate code labs.
Let's evolve the basic 2D drawing code into a rudimentary "Floating Balloons" game.
Conceptual Evolution
Represent balloons as circles drawn on the Canvas. Assign random starting positions and sizes. Optionally, add colors and/or simple animations (e.g., slight vertical movement). Detect touch events on the View. Check if the touch coordinates intersect with any balloon. If a balloon is touched, "pop" it (remove from the list of balloons). Keep track of the number of balloons popped. End the game when 10 balloons are popped. Display the time taken to pop all balloons. Code Evolution (Illustrative)
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.os.SystemClock
import android.view.MotionEvent
import android.view.View
import kotlin.random.Random
class BalloonGameView(context: Context) : View(context) {
private val paint = Paint().apply {
color = Color.BLUE
style = Paint.Style.FILL
}
private val balloons = mutableListOf<Balloon>()
private var balloonsPopped = 0
private var startTime: Long = 0
init {
// Initialize balloons with random positions and sizes
for (i in 1..10) {
balloons.add(Balloon(
Random.nextInt(width),
Random.nextInt(height),
Random.nextInt(50, 100) // Random radius between 50 and 100
))
}
startTime = SystemClock.uptimeMillis()
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
for (balloon in balloons) {
canvas.drawCircle(balloon.x.toFloat(), balloon.y.toFloat(), balloon.radius.toFloat(), paint)
}
}
override fun onTouchEvent(event: MotionEvent): Boolean {
if (event.action == MotionEvent.ACTION_DOWN) {
val touchX = event.x
val touchY = event.y
for (balloon in balloons) {
if (isTouchInsideBalloon(touchX, touchY, balloon)) {
balloons.remove(balloon)
balloonsPopped++
if (balloonsPopped == 10) {
val endTime = SystemClock.uptimeMillis()
val timeTaken = (endTime - startTime) / 1000.0 // Time in seconds
// Display timeTaken (you'll need to implement this part)
}
invalidate() // Redraw the view
break
}
}
}
return true
}
private fun isTouchInsideBalloon(touchX: Float, touchY: Float, balloon: Balloon): Boolean {
val distance = Math.sqrt(
Math.pow((touchX - balloon.x).toDouble(), 2.0) +
Math.pow((touchY - balloon.y).toDouble(), 2.0)
)
return distance <= balloon.radius
}
data class Balloon(val x: Int, val y: Int, val radius: Int)
}
Caveats:
This code is a simplified illustration. A real game would likely involve: More sophisticated balloon behavior (movement, maybe even floating away!). Proper game state management and UI updates. Sound effects and visual feedback. Difficulty adjustments and scoring. The course outline touches on advanced graphics concepts (3D, animations) that could further enhance this game.