I am currently learning and having some issues in regards to an app i’m making.
The app will be for me about learning how to draw objects on the canvas and to get these ant.png’s moving around freely, wandering in a natural way like a real ant, ive tried a number of ways however due to my learning and abilities i might not be adding the code exactly where it might need to go or even correctly.
As you can see from the code below, i more than likely need help with the way i have used it and where and why ive laid it out this way.
any help or explanations as to what and why i’m going wrong is greatly appreciated.
Thank You
mark117h.
MainActivity.kt.
package com.example.antnaturalmovement
import android.graphics.Canvas
import android.graphics.Color
import android.os.Bundle
import android.view.SurfaceHolder
import android.view.SurfaceView
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
private val coroutineScope = CoroutineScope(Dispatchers.Main)
class MainActivity : AppCompatActivity() {
// Main entrance point for Ant & MainActivity Class.
private lateinit var surfaceView: SurfaceView
private lateinit var ant: Ant
private lateinit var branch: Branch
private lateinit var workerAnt: WorkerAnt
private lateinit var greenflyBitmap: Greenfly
private val drawDelay = 1500L // Delay between each draw (Adjust as needed)
//private lateinit var collisionDetection: CollisionDetection // not used yet
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Get reference to the SurfaceView from layout
surfaceView = findViewById(R.id.surfaceView)
// Initialize Ant
ant = Ant(resources)
branch = Branch(resources)
workerAnt = WorkerAnt(resources)
greenflyBitmap = Greenfly(resources)
//collisionDetection.detectCollisions() // not used yet TODO: Fix collision detection
startDrawing()
}
// Start drawing
private fun startDrawing() {
super.onStart()
coroutineScope.launch {
while (isActive) {
delay(2000L)
drawAntOnSurface(surfaceView.holder)
drawWorkerAntOnSurface(surfaceView.holder)
drawBranchOnSurface(surfaceView.holder)
drawGreenflyOnSurface(surfaceView.holder)
onStart()
}
}
}
override fun onResume() {
super.onResume()
// Start ant movement coroutine when activity resumes
startDrawing()
ant
// Start drawing on the SurfaceView when the activity resumes.
surfaceView.holder.addCallback(object : SurfaceHolder.Callback {
override fun surfaceCreated(holder: SurfaceHolder) {}
override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {}
override fun surfaceDestroyed(holder: SurfaceHolder) {
stopDrawing()
}
})
}
//Stop drawing
private fun stopDrawing() {
super.onStop()
coroutineScope.cancel()
}
override fun onPause() {
super.onPause()
// Stop ant movement coroutine when activity pauses
coroutineScope.cancel()
}
private fun drawAntOnSurface(holder: SurfaceHolder) {
coroutineScope.launch {
delay(drawDelay)
val canvas = holder.lockCanvas()
// Generate random positions for the branch and worker ant
val antX = (canvas.width * Math.random()).toFloat()
val antY = (canvas.height * Math.random()).toFloat()
// Draw the background color
canvas.drawColor(Color.WHITE) // Set background color to white / Clear the canvas
// Draw the branch bitmap at a random position on the canvas
canvas.drawBitmap(ant.getAntBitmap(), antX, antY, null)
// Unlock the canvas and post it to the SurfaceView
holder.unlockCanvasAndPost(canvas)
}
}
private fun drawBranchOnSurface(holder: SurfaceHolder) {
coroutineScope.launch {
//delay(3000L)
val canvas = holder.lockCanvas()
// Generate random positions for the branch and worker ant
val branchX = (canvas.width * Math.random()).toFloat()
val branchY = (canvas.height * Math.random()).toFloat()
// Draw the background color
canvas.drawColor(Color.WHITE) // Set background color to white / Clear the canvas
// Draw the branch bitmap at a random position on the canvas
canvas.drawBitmap(branch.getBranchBitmap(), branchX, branchY, null)
// Unlock the canvas and post it to the SurfaceView
holder.unlockCanvasAndPost(canvas)
surfaceView.invalidate()
}
}
private fun drawWorkerAntOnSurface(holder: SurfaceHolder) {
coroutineScope.launch {
delay(drawDelay)
val canvas = holder.lockCanvas()
// Generate random positions for the workerant
val waX = (canvas.width * Math.random()).toFloat()
val waY = (canvas.height * Math.random()).toFloat()
// Draw the background color
canvas.drawColor(Color.WHITE) // Set background color to white / Clear the canvas
// Draw the worker ant bitmap at a random position on the canvas
canvas.drawBitmap(workerAnt.getWorkerAntBitmap(), waX, waY, null)
// Unlock the canvas and post it to the SurfaceView
holder.unlockCanvasAndPost(canvas)
}
}
private fun drawGreenflyOnSurface(holder: SurfaceHolder) {
coroutineScope.launch {
val canvas = holder.lockCanvas()
val gfX = 125f
val gfY = 450f
//
canvas.drawColor(Color.WHITE)
canvas.drawBitmap(greenflyBitmap.getGreenflyBitmap(), gfX, gfY, null)
// Unlock the canvas and post it to the SurfaceView
holder.unlockCanvasAndPost(canvas)
}
}
} // End of MainActivity
Ant.kt.
package com.example.antnaturalmovement
import android.content.res.Resources
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlin.random.Random
// Coroutine scope for managing the coroutine lifecycle
private val coroutineScope = CoroutineScope(Dispatchers.Default)
class Ant(resources: Resources) {
// Main logic for the Ant class
private var x: Float = 0f
private var y: Float = 0f
private var screenWidth: Int = 1080
private var screenHeight: Int = 2160
private var speedX: Float = 0.05F
private var speedY: Float = 0.50F
private var ranPosA: Float = Random.nextFloat()
private var ranPosB: Float = Random.nextFloat()
private var antBitmap: Bitmap
init {
// Load the ant image from the resources
val originalAntBitmap = BitmapFactory.decodeResource(resources, R.drawable.ant)
// Scale the ant image to 150px X 150px
antBitmap = Bitmap.createScaledBitmap(originalAntBitmap, 160, 160, true)
// Initialise the screenWidth and screenHeight with the dimensions of the screen
val displayMetrics = resources.displayMetrics
screenWidth = displayMetrics.widthPixels
screenHeight = displayMetrics.heightPixels
}
// Method to start the ants movement coroutine
fun startMovement() {
coroutineScope.launch {
while (isActive) {
// Update ants position
updatePosition()
// Delay for a short duration to control the speed of movement
delay(6000) // Adjust the delay duration as needed
}
}
}
// Method to update the ants position
private fun updatePosition() {
// Update the ants position
// Generate random velocity's for X and Y directions
// val velocityX = (Math.random() / 2 - 2).toFloat() // Random float between -2 and 2
// val velocityY = (Math.random() / 2 - 2).toFloat() // Random float between -2 and 2
// Update ant's position by adding velocity's
x += speedX - speedY//velocityX //- speedX * ranPosA
y += speedY - speedX//velocityY //- speedY * ranPosB
// Boundary handling
// Ensure the ant stays within the screen boundaries
if (x < 1080 || ranPosA > 0.5) {
x = 1080f % speedX
} else if (x > screenWidth - antBitmap.width) {
x = screenWidth - antBitmap.width.toFloat()
}
// Ensure the ant stays within the screen boundaries
if (y < 2160 || ranPosB > 0.5) {
y = 2160f % speedY
} else if (y > screenHeight - antBitmap.height) {
y = screenHeight - antBitmap.height.toFloat()
}
}
// Method to stop the ants movement coroutine
fun stopMovement() {
coroutineScope.cancel()
}
// Method/Function to get the ant bitmap
fun getAntBitmap(): Bitmap {
return antBitmap
}
} // End of Ant class
activity_main.xml.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<SurfaceView
android:id="@+id/surfaceView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<TextView
android:id="@+id/tvLabel"
android:layout_width="match_parent"
android:layout_height="50dp"
android:fontFamily="@font/acme"
android:text="Ant Natural Movement"
android:textAlignment="center"
android:textColor="#100F0F"
android:textSize="24sp"
android:textStyle="bold"
tools:ignore="HardcodedText,TextSizeCheck" />
</RelativeLayout>
mark117h is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.