Games that are designed to be played by a single player commonly have levels. Each level can present increasingly difficult tasks. In my balloon popping game, each level will cause the balloons to rise faster, making it harder to catch them. During initial development, each level will only have 3 balloons. But I'll be able to change that easily once the app is closer to being complete.
[Presenter] - So far, I've created the basic visual appearance of my application. And implemented animations that allow balloon objects to rise, from the bottom to the top of the screen. Now, I want to add some gaming logic. Games that are designed to be played by a single player, commonly have levels. Each level can present increasingly difficult tasks. In my balloon popping game, each level will cause the balloons to rise faster, making it harder to pop them. My balloon class is already capable of adjusting its pace, as it rises to the top of the screen.
The releaseBalloon method takes a duration argument, and that's what determines the length of the animation. That value is being determined right now statically, when the releaseBalloon method is called, a literal value of 3,000 milliseconds is being passed in, creating a three second animation. I'm going to make that a variable value. I'll start by adding some new fields to the main activity class. I'll use this template, psf, and that expands to public static final, and I'll create an integer that I'll name MIN_ANIMATION_DELAY, and I'll set it to a value of 500, for 500 milliseconds.
Now I'm going to need three more integer fields, the second one will be MAX_ANIMATION_DELAY, and it'll have a value of 1500. Next I have a constant named MIN_ANIMATION_DURATION, and its value will be a thousand, and then I'll have a MAX_ANIMATION_DURATION, and its value will be 8,000. So I'm setting up these constants to define certain limits to the animations. The delay will be the amount of time between balloon launches, and the duration will be the length of each balloon's animation.
So the slowest animation will be eight seconds, and the fastest will be one second. I also need an integer that won't be static. I'll make that private to this class, and I'll name it mLevel. And this is how I'll track the levels. When the activity first starts up, mLevel will default automatically to zero. Now I'll create a new method that I'll call startLevel. Whenever this method is called, first I'll increment mLevel by one.
And then I'm going to use an AsyncTask, to actually start the level. I'll go get the AsyncTask code in a moment, but the name of the class will be BallonLauncher. So I'll declare instance of that class, and I'll name it launcher, and I'll instantiate it. And then, because it's going to be an instance of the Async class type, I'll start it up by calling its execute method. And I'll pass in the current level. Now I need to go get the code for the AsyncTask.
This will take quite a bit of code, so I've defined it in a gist that I previously created. I'll go to my browser, and I'll go to thisgit io URL. Git.io/v6 then uppercase BWS. And that expands to this gist, and I'll select and copy all of the code, and return to Android Studio, and I'll paste it right here, after my startLevel method. After I paste all that code in, I'll need to add a couple of imports.
I'll add an import for the AsyncTask class, and one for the Random class, and also one for the Date class. Make sure to choose Date from Java.util. I'll scan for any other errors, and it looks like all this code is in tact. So now lets take a look at what it's doing. When I instantiate BalloonLauncher, I'm passing in an Integer named mLevel. That's passed in as the first type of the generics in AsyncTask, and it's defined in the doInBackground method as one of the perams.
That'll be passed in as a single argument. It'll be known initially as params, and then I'll save that as the current level within the method. Then I'm going to do a bit of math, and calculate the delay. The delay is affected by the level. But it can't be lower than the minimum, or greater than the maximum delay. Right now, I'm only launching three balloons per level. Later on, I'll increase that number. The next step is to determine the exposition of the balloon. I'm doing that by randomizing the value by making sure I don't exceed the screen width minus 200 pixels.
That'll make sure that each balloon is on the screen. Then I call the publishProgress method of AsyncTask. That's how I'm going to call something that's on the UI thread. Remember this is running in a background thread right now. And then I increment balloonsLaunched, to keep track of the number of balloons that have actually been launched. Next, I implement the delay. And I'm going to use Thread.sleep for that purpose. And then I cycle through the loop, and launch the next balloon. So each level will launch three balloons right now.
When I call publishProgress, that results in calling onProgressUpdate. doinBackground is running in a background thread, but onProgressUpdate is running on the UI thread. And so from here, I can save the position that I calculated in the background thread, and then I can call my launchBalloon method, which I also copied and pasted. I'm passing in the xPosition. And so now, I create my balloon just as I did previously. I choose a color.
I increment to the next color, so I'm cycling through the colors again, and then I set the x and y positions of the balloon, and I add the balloon object to the screen. Finally, I calculate the duration, respecting the minimum and maximum durations that I set up above. And then I release the balloon, passing in the screen height, and the duration. Now with this code in place, I no longer need my touch handler code. So I'll go back to the top of the main activity, and I'll locate the setOnTouchListener method, and I will delete that.
Because now I'm launching balloons as part of a level instead of on touch events. Finally, I need to call the startLevel method, and I'll do that from my go button. I'll go down here, find my go button, I'll add an onClick attribute, and I'll set that as goButtoClickHandler. I'll use an intention action, and I'll create the event handler in my MainActivity class, and then I'll call startLevel.
And I'm ready to test my code. Now each time I click the play game button, I get a level. Each level consists of three balloons. The first three balloons take eight seconds to go from the bottom of the screen to the top. The next set of balloons go a little bit faster. And I can keep on clicking this button right now, and increase the speed for each new set of balloons. And you'll see that as I continually click, the balloons get faster and faster and faster, until finally they hit the minimum duration of one second each.
I've now successfully defined my levels, and I'm ready to go to the next step of implementing my game logic.
- Working with Java vs. C++
- Creating a new Android project
- Defining the visuals: background, menus, and animation
- Defining and managing levels
- Displaying scores
- Managing limited gaming resources
- Completing the game logic
- Adding audio effects