Create Android Game Using Kotlin - Tutorial Kart

Transcription

Create Android Game using KotlinAndroid Game DevelopmentThere are many ways and many frameworks out there for Android Game development. But, this Kotlin AndroidTutorial helps you to get started with Android Game Development from scratch with well detailed steps.Game StoryAny game that you would like to develop should have a story and script. You have to decide about the playersin the game, the strategies, how you level up in the game, and what are the objects that are going to be used.When you are ready with an fully scripted idea, you are good to start for taking it to application developmentmode. Small changes to the script during the development may not cost you much time, but if there are majorchanges to the game plan or such, it may eat up your development time. And this could be checked to someextent by modularizing your code.In this tutorial, our game story is as follows.There is a grenade trying to blast you. The player has to avoid it. A simple hero-villain story to get started.What game development techniques we shall learn in this tutorialFor any android application development, we need some techniques. For example, if you are creating aContacts application, you should be having an idea of how to get the list of contacts and how to present it to theuser : these are the techniques or capabilities that the developer should be aware of.Similarly for this android game, we shall learn following techniques to realize our game.PlayGround : Use of SurfaceView and SurfaceHolder.CallbackSprites on Playground : In Gaming terminology, Sprite is a 2D bitmap image drawn on to the Canvas of SurfaceViewSprite Movement : Redrawing the image of sprite at a different positionSprite Position : Tracking the touch of the Android user, to update the position of sprite(s)Example – Android Game DevelopmentFollowing is a step-by-step guide to develop an Android Game in Kotlin programming language. Or if you like toget to the code and go through it yourself, you may find the zipped fileat les/blob/master/ExampleGame.zip.Step 1: Create an Android Application for the GameOpen Android Studio and create a new Application with Kotlin support.Lets name our application with “ExampleGame” and Click on Next.

Select API version. For this project, we have selected Android 5.0 as minimum supported Android version.Click on Next.

Select “Empty Activity” and Click on Next.

Name your Main Activity file and layout file. Uncheck “Backwards Compatibility(AppCompat)” and click onFinish. Our Android Application is created.

Step 2: Add SurfaceView and SurfaceHolder.CallbackSurfaceView by default does not help us much. So, we shall create a class that extends SurfaceView andimplements SurfaceHolder.Callback.

Right Click on the package “com.tutorialkart.examplegame” and follow the actions.Give name as “GameView” and select “Class” for Kind.GameView.ktclass GameView {}Change the primary constructor or GameView to GameView(context: Context, attributes: AttributeSet) andextend with SurfaceView(context, attributes), SurfaceHolder.Callback.You should override some of the functions of SurfaveHolder.Callback as shown in the below program.Also, in order to update the position of our players and draw them on the Canvas of SurfaceView, we need tocreate a function update() and override draw(Canvas: canvas) function of android.view.SurfaceViewclass GameView(context: Context, attributes: AttributeSet) : SurfaceView(context, attributes), Surfacoverride fun surfaceDestroyed(p0: SurfaceHolder?) {TODO("not implemented") //To change body of created functions use File Settings File Temp}override fun surfaceCreated(p0: SurfaceHolder?) {TODO("not implemented") //To change body of created functions use File Settings File Temp}override fun surfaceChanged(p0: SurfaceHolder?, p1: Int, p2: Int, p3: Int) {TODO("not implemented") //To change body of created functions use File Settings File Temp}/*** Function to update the positions of player and game objects*/fun update() {}/*** Everything that has to be drawn on Canvas*/override fun draw(canvas: Canvas) {super.draw(canvas)}}Step 3: Include GameView in activity main.xml

We shall use the GameView in activity main.xml.activity main.xml ?xml version "1.0" encoding "utf-8"? RelativeLayout xmlns:android tools "http://schemas.android.com/tools"android:layout width "match parent"android:layout height "match parent"tools:context "com.tutorialkart.examplegame.MainActivity" t width "match parent"android:layout height "match parent" / /RelativeLayout And in the AndroidManifest.xml, lets set the theme as Theme.NoTitleBar.Fullscreen, for the MainActivity.AndroidManifest.xml ?xml version "1.0" encoding "utf-8"? manifest xmlns:android e "com.tutorialkart.examplegame" applicationandroid:allowBackup "true"android:icon "@mipmap/ic launcher"android:label "@string/app name"android:roundIcon "@mipmap/ic launcher round"android:supportsRtl "true"android:theme "@style/AppTheme" activity android:name ".MainActivity"android:theme "@android:style/Theme.NoTitleBar.Fullscreen" intent-filter action android:name "android.intent.action.MAIN" / category android:name "android.intent.category.LAUNCHER" / /intent-filter /activity /application /manifest Step 4: FullScreen Activity.Make your Activity get rid of the notification bar and title bar.MainActivity.kt

package w.WindowManagerandroid.util.DisplayMetricsclass MainActivity : Activity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// remove notification arams.FLAG FULLSCREEN, ivity main)}}Step 5: Create Game ThreadNext thing we need to do is, creating a thread which calls GameView for : updating the state of the game anddrawing the game objects on to Canvas. GameView runs on UI Thread and it could go through different stagesof life cycle. We do not want this to mess up with the smoothness of our game, which is why we are using adedicated thread.We shall create a Kotlin Class named, “GameThread”. The process of creating this Kotlin Class is same as thatof GameView Class.GameThread.ktpackage com.tutorialkart.examplegameimport android.graphics.Canvasimport android.view.SurfaceHolder/*** Created by arjun on 26/12/17.*/class GameThread(private val surfaceHolder: SurfaceHolder, private val gameView: GameView) : Thread()private var running: Boolean falseprivate val targetFPS 50 // frames per second, the rate at which you would like to refresh thefun setRunning(isRunning: Boolean) {this.running isRunning}override fun run() {var startTime: Longvar timeMillis: Longvar waitTime: Longval targetTime (1000 / targetFPS).toLong()while (running) {startTime System.nanoTime()canvas null

canvas nulltry {// locking the canvas allows us to draw on to itcanvas eHolder) )}} catch (e: Exception) {e.printStackTrace()} finally {if (canvas ! null) {try {surfaceHolder.unlockCanvasAndPost(canvas)} catch (e: Exception) {e.printStackTrace()}}}timeMillis (System.nanoTime() - startTime) / 1000000waitTime targetTime - timeMillistry {sleep(waitTime)} catch (e: Exception) {e.printStackTrace()}}}companion object {private var canvas: Canvas? null}}The important things to note here is the following four lines of code, in the try block.canvas eHolder) )}We locked the Canvas, so that it allows us to draw on it.Using synchronized(surfaceHolder) means, we are not letting any other threads do any modifications to surfaceHolder(where Canvas is).Then we update the game state and draw the canvas with the new state of sprites.Once we are done updating the canvas, unlock it in the finally block.surfaceHolder.unlockCanvasAndPost(canvas)The rest of the code is trying to update the canvas at the frequency set by targetFPS.

And finally where we are going to start this GameThread ? Ofcourse from GameView.GameView.ktpackage iewandroid.view.SurfaceHolder/*** GameView is our playground.*/class GameView(context: Context, attributes: AttributeSet) : SurfaceView(context, attributes), Surfacprivate val thread: GameThreadinit {// add callbackholder.addCallback(this)// instantiate the game threadthread GameThread(holder, this)}override fun surfaceCreated(surfaceHolder: SurfaceHolder) {// start the game de fun surfaceChanged(surfaceHolder: SurfaceHolder, i: Int, i1: Int, i2: Int) {}override fun surfaceDestroyed(surfaceHolder: SurfaceHolder) {var retry truewhile (retry) {try {thread.setRunning(false)thread.join()} catch (e: Exception) {e.printStackTrace()}retry false}}/*** Function to update the positions of player and game objects*/fun update() {}/**

* Everything that has to be drawn on Canvas*/override fun draw(canvas: Canvas) {super.draw(canvas)}}Try giving it a run on an Android Phone. If all you are seeing is a black screen! Good. We have successfullylearned to use create a SurfaceView. And we have prepared our playground. Now its time to introduce someplayers on to the field.Step 6: Introducing Sprites.Now, we shall introduce a sprite that moves on the Canvas. And keeping the idea that our game should bemaintainable, when it becomes huge with code, we shall try to abstract a game object with a Class. We shalluse the class to hold bitmap image, its position and state through the game. We shall take a Grenade as aSprite.Grenade.kt

package com.tutorialkart.examplegameimport android.content.res.Resourcesimport android.graphics.Bitmapimport android.graphics.Canvas/*** Grenade Class.* It could be considered as System. System is playing against you in the game.* Grenade is the opponent.*/class Grenade(var image: Bitmap) {var x: Int 0var y: Int 0var w: Int 0var h: Int 0private var xVelocity 20private var yVelocity 20private val screenWidth ivate val screenHeight nit {w image.widthh image.heightx screenWidth/2y screenHeight/2}/*** Draws the object on to the canvas.*/fun draw(canvas: Canvas) {canvas.drawBitmap(image, x.toFloat(), y.toFloat(), null)}/*** update properties for the game object*/fun update() {// val randomNum ThreadLocalRandom.current().nextInt(1, 5)if (x screenWidth - image.width x image.width) {xVelocity xVelocity * -1}if (y screenHeight - image.height y image.height) {yVelocity yVelocity * -1}x (xVelocity)y (yVelocity)}}Take away from this class is that, we have two functions namely update() and draw(). We shall instantiateGrenade when Surface is created, and call Grenade.update() from GameView.update() and Grenade.draw()from GameView.draw().

This is kind of our scaling dimension. We can add as many types of sprites as per the game plan (script), andinstantiate the sprites in GameView.surfaceCreated(), update the sprites’ state in GameView.update() and drawthe sprite on to Canvas in GameView.draw().GameView.ktpackage w.SurfaceHolder/*** GameView is our playground.*/class GameView(context: Context, attributes: AttributeSet) : SurfaceView(context, attributes), Surfacprivate val thread: GameThreadprivate var grenade: Grenade? nullinit {// add callbackholder.addCallback(this)// instantiate the game threadthread GameThread(holder, this)}override fun surfaceCreated(surfaceHolder: SurfaceHolder) {// game objectsgrenade Grenade(BitmapFactory.decodeResource(resources, R.drawable.grenade))// start the game de fun surfaceChanged(surfaceHolder: SurfaceHolder, i: Int, i1: Int, i2: Int) {}override fun surfaceDestroyed(surfaceHolder: SurfaceHolder) {var retry truewhile (retry) {try {thread.setRunning(false)thread.join()} catch (e: Exception) {e.printStackTrace()}retry false}}/**

/*** Function to update the positions of sprites*/fun update() {grenade!!.update()}/*** Everything that has to be drawn on Canvas*/override fun draw(canvas: Canvas) {super.draw(canvas)grenade!!.draw(canvas)}}Add the following image file to res/drawableOutputWhen run the application in an Android device, the result would look like below.Step 7: Introducing another Sprite – Our next and ofcourse the most importantGame Object.For the player, we shall use a circle kind of image and make it track the touch on the screen. And likeGrenade.kt, we are going to have update() and draw() functions.

Player.ktpackage com.tutorialkart.examplegameimport android.content.res.Resourcesimport android.graphics.Bitmapimport android.graphics.Canvas/*** Player Class.*/class Player(private val image: Bitmap) {private var x: Int 0private var y: Int 0private val w: Intprivate val h: Intprivate val screenWidth ivate val screenHeight nit {w image.widthh image.heightx screenWidth/2y screenHeight - 200}/*** Draws the object on to the canvas.*/fun draw(canvas: Canvas) {canvas.drawBitmap(image, x.toFloat(), y.toFloat(), null)}/*** update properties for the game object* when the player touches the screen, position the player bitmap there*/fun updateTouch(touch x: Int, touch y: Int) {x touch x - w / 2y touch y - h / 2}}Now we have to make use of Player in our GameView, just as we did for Grenade.kt. But we are going to learnone more thing in this step. That is, how to track user touch input. And we shall make our Player track thetouch.To track touch input, we shall override onTouchEvent(event: MotionEvent) method in GameView Class. And withthe introduction of Player.kt to GameView. Following is the updated GameView.kt file.GameView.ktpackage com.tutorialkart.examplegameimport android.content.Context

iew.SurfaceHolder/*** GameView is our playground.*/class GameView(context: Context, attributes: AttributeSet) : SurfaceView(context, attributes), Surfacprivate val thread: GameThreadprivate var grenade: Grenade? nullprivate var player: Player? nullprivate var touched: Boolean falseprivate var touched x: Int 0private var touched y: Int 0init {// add callbackholder.addCallback(this)// instantiate the game threadthread GameThread(holder, this)}override fun surfaceCreated(surfaceHolder: SurfaceHolder) {// game objectsgrenade Grenade(BitmapFactory.decodeResource(resources, R.drawable.grenade))// start the game de fun surfaceChanged(surfaceHolder: SurfaceHolder, i: Int, i1: Int, i2: Int) {}override fun surfaceDestroyed(surfaceHolder: SurfaceHolder) {var retry truewhile (retry) {try {thread.setRunning(false)thread.join()} catch (e: Exception) {e.printStackTrace()}retry false}}/*** Function to update the positions of sprites*/fun update() {grenade!!.update()if(touched) {

if(touched) {player!!.update(touched x, touched y)}}/*** Everything that has to be drawn on Canvas*/override fun draw(canvas: Canvas) draw(canvas)}override fun onTouchEvent(event: MotionEvent): Boolean {// when ever there is a touch on the screen,// we can get the position of touch// which we may use it for tracking some of the game objectstouched x event.x.toInt()touched y event.y.toInt()val action event.actionwhen (action) {MotionEvent.ACTION DOWN - touched trueMotionEvent.ACTION MOVE - touched trueMotionEvent.ACTION UP - touched falseMotionEvent.ACTION CANCEL - touched falseMotionEvent.ACTION OUTSIDE - touched false}return true}}Run the application and you will observe that the circle (Player bitmap), shall track your touch.ConclusionIn this Kotlin Android Tutorial, we have built a Game in Android using Kotlin.There are many other techniques that we could learn to use in Android Game Development. In our subsequentKotlin Android Tutorials, we shall learn some of them and make our Game awesome, or you may use them tomake your Game Script come to life. Happy coding Android.Getting Started with Android Kotlin Android Tutorial Create Android Application with Kotlin Support Walk Through Android Studio Convert Java Files to Kotlin Files Kotlin vs Java Use Java 8 in Android

Add External Jar to Android DependenciesAndroid TextView Android TextView Android TextView - Basic Example Android TextView - Create programmatically Android TextView - OnClickListener Android TextView - Justify Text Android TextView - Italic Android TextView - BoldAndroid Button Android - New Button programmatically Android Button - OnClickListener Android Button - Disable All Caps Android Button - Custom Background Android Button - Change background programaticallyAndroid Toast Android Toast - ExampleAndroid EditText Android EditText - Create programmatically Android EditText - On Text Change - Listener Android TextInputLayout - Floating Label in EditText Android EditText - Keyboard with only Numbers Android EditText - Show/Hide PasswordAndroid ImageView Android ImageView - OnClickListenerAndroid Radio Buttons Android RadioGroup - RadioButtons Create programmaticallyAndroid SeekBar Android SeekBar - Example Android SeekBar Set Custom RangeAndroid Intent Android - Start Another Activity Android - Open URL in Browser Activity

Android AlertDialog Android AlertDialog - ExampleAndroid W ebView Android WebView - ExampleAndroid ProgressBar Kotlin Android - Inderterminate ProgressBarAndroid Snackbar Android Snackbar - Example Android Snackbar - Set Action Android Snackbar - Change Text Color, Background ColorAndroid ListView Android ListView Example Android Refresh ListViewAndroid Device Parameters Android Get Screen Width and Height ProgramaticallyAndroid Canvas Draw Rect / Oval to Canvas Android Draw Circle Border Android Draw SVG to CanvasAndroid Programming - Other Android - Access View Programmatically using findViewById Android runOnUiThreadAndroid Game Development Android Game Development Detect Collisions between two Sprites (Bitmaps)Android Text To Speech Android Text To Speech - Kotlin ExampleFix Errors Android - Minimum supported Gradle version Android - All support libraries must use the exact same version specificationExample Applications Android - Login Form

Android - Login Form Android - Color Picker Kotlin Android Game DevelopmentKotlin - Java Kotlin TutorialUseful Resources How to Learn Programming

Android Game Development There are many ways and many frameworks out there for Android Game development. But, this Kotlin Android Tutorial helps you to get started with Android Game Development from scratch with well detailed steps. Game Story Any game that you would like to develop should have a story and script. You have to decide about the .