When I wrote this "game" I had a lot of questions about the looping of sprites so that they would appear after a certain time, there were also problems with detecting collisions of two sprites and more, I want to highlight all these questions today in this post since On the Internet, I did not find a normal answer to my questions and had to do it myself. Fasting does not pretend to anything, I am new to the development of games for android and I write for newcomers to the industry. To whom it became interesting I ask under kat.
Formulation of the problem:
The game must be a field (scene) on which the ninja and ghosts are located. A ninja must protect his base from these ghosts by shooting at them.
An example of such a game can be viewed in the android market . Although I strongly swung, we will only have a similar idea. ')
Here is what the game will look like:
Start of development
Create a project. Run Eclipse - File - Android Project - Defens - Main.java.
Open our Main.java file and change all the code to the code below:
The code below tells our main function that we need to run not the * .xml theme file, but the class that we own is the scene itself.
setContentView(new GameView(this));
Next you need to create a GameView.java class that will serve as the main class for us to draw all the objects. Also in this class there will be our stream in which the drawing of objects in the stream will be processed to reduce the load of the game on the processor. Here's what the class will look like when nothing happens on stage:
From the comments I hope it is clear what function is doing. This class is basic for this, in it we will perform all the actions (functions) that will occur in the game, but for the beginning we need to make several more classes. Proceed to the next item - creating sprites.
Create sprites
Sprites are small pictures in 2D games that move. It can be men, ammunition or even clouds. In this game we will have three different types of sprites: Ninja ghost and projectile .
Now we will use non-animated sprites, but in the future I will insert sprites into the project, if I’m pulling to learn how to make sprites, I’ll ask you in the second lesson on creating a game for android.
Now upload these pictures to the res / drawable folder so that Eclipse can see these pictures and paste them into your project.
The following figure should visually help to understand how the player will be located on the screen. A boring picture ... Let's better create this player himself.
We need to place the sprite on the screen, how to do it? Create a class Player.java and write the following into it:
Player.java
import android.graphics.Bitmap; import android.graphics.Canvas; publicclassPlayer{ /** */ GameView gameView; // Bitmap bmp; // int x; int y; // public Player(GameView gameView, Bitmap bmp) { this.gameView = gameView; this.bmp = bmp; // this.x = 0; // this.y = gameView.getHeight() / 2; // } // public void onDraw(Canvas c) { c.drawBitmap(bmp, x, y, null); } }
Everything is very simple and clear, our player will stand still and do nothing except how to shoot at the enemy, but the shooting will be implemented in a bullet class (shell), which we will do next.
Create another class file and call it Bullet.java, this class will determine the coordinates of the flight, flight speed and other parameters of the bullet. And so, we created the file, and write the following to it:
From the comments it should be clear that the bullet performs only one action - it must fly in the direction indicated by the player.
We draw sprites on stage
In order to draw these two classes that we have created, we need to edit the code in the GameView.java class, add a few methods that will return our drawings to us. I will not write all the code completely; I will only give the code of the methods I need.
To begin with, we need to create objects of the Bullet and Player classes in order to display them on the screen, for this we create a list of bullets, so that they never end with us, and an ordinary player class object.
GameView Cap
private List<Bullet> ball = new ArrayList<Bullet>(); private Player player; Bitmap players;
Next, we need to assign pictures to our classes, find the GameView constructor and insert two lines at the very end:
GameView.java - GameView Designer
players= BitmapFactory.decodeResource(getResources(), R.drawable.player2); player= new Player(this, guns);
And in the onDraw method (Canvas c); make these sprites visible. We pass through the entire collection of our items generated in the list.
And in order for the bullets to start flying out when you click on the screen, you need to create the createSprites () method; which will return our sprite.
Well, in the end we create another method - onTouch (); which will actually catch all the touches on the screen and direct the bullet to the point where the screen was tapped.
If you want to do so that pressing would not be processed once, i.e. 1 click - 1 bullet, and 1 click - and until you release it will shoot, you need to delete if (e.getAction () == MotionEvent.ACTION_DOWN) {} and leave only ball.add (createSprite (R.drawable.bullet)); .
Everything, we start our game and we try to shoot. It should go like this:
The enemies
In order for us not to be bored playing, you need to create enemies. To do this, we will have to create another class that will be called Enemy.java and which will be able to display and direct our enemy to our base. The class is pretty simple so look at the code below:
And so what happens in this class? I tell you: we have declared vital variables for our enemy, height, width and coordinates. To place them on the stage, I used the Random () class so that when they appear on the scene, they appear at all at one point, and at different points and at different coordinates. The speed is also random in our country, so that each enemy goes at a different speed, our speed starts from 0 and ends at 10, 10 - the maximum speed of which the enemy can reach. They will move from the right to the left, so that they are not immediately visible on the stage, I threw them at 900 pixels for the screen visibility. So until they reach it will be possible to prepare in full for the attack.
Next, we need to display the enemy on the scene, for this in the GameView.java class we do the following:
Create a list of enemies so that they never end and create a bitmap that will contain a sprite:
GameView Cap
private List<Enemy> enemy = new ArrayList<Enemy>(); Bitmap enemies;
Next, create a new stream to set the speed of the appearance of enemies on the screen:
GameView Cap
private Thread thred = new Thread(this);
And implement the Runuble class, here’s what the initialization of the GameView class should look like:
And of course, we need to declare these methods in onDraw (); That means we write the following in it:
OnDraw () method in gameview
Iterator<Enemy> i = enemy.iterator(); while(i.hasNext()) { Enemy e = i.next(); if(ex >= 1000 || ex <= 1000) { e.onDraw(canvas); } else { i.remove(); } }
Again we go through the collection of enemies with the help of an iterator and check - if the enemy has gone beyond the limit of 1000 pixels - delete it, because if we do not remove our memory, it will harden and the phone will hang, but we do not need such problems. The whole game is ready for launch.
We start our game and what will we see? Here's what:
But what do I see? Oh no!!! Bullets don't kill our ghosts. What should we do? And I will tell you what to do, we need to create a method that will form a rectangle around each sprite - and will compare them on collisions. The next topic will be about this.
Collision detection
And so, we have a sprite, we have a scene, we all even move beautifully, but what is the use of all this when we have nothing on the scene except going to these sprites here?
With this function, I dug in full, even somehow it turned out that I was hysterical and went for a walk along the street)) The most difficult method, although it looks quite harmless ...
Okay, let's create this method and do not talk much ... Somewhere at the end of the GameView class, create the testCollision () method and write the following code:
And so, what happens with us in this method? We create one iterator and run a loop to view the entire collection of sprites, and say that every next bullet sprite will be the first.
Next, create another iterator with another list of sprites and again redefine and say that each next enemy sprite will be the first. And we create a branch operator - if () which actually checks our sprites for collisions. In it, I used a mathematical function module (abs) which returns me an absolute integer from two rectangles.
Inside the ifa, a comparison is made between two rectangles Module from (Bullet on coordinate X minus coordinate of enemy on coordinate X is less than or equal to the width of the bullet plus width of the enemy / 2 (divide by two to find the center of the rectangle)) and (Module from (Bullet on coordinate Y minus coordinate enemy Y coordinate is less than or equal to the width of the bullet plus the width of the enemy / 2 (divide by two to find the center of the rectangle)));
And at the end of all, if the bullet did reach the enemy, we remove him from the scene with the ends.
Well, in order for this function to work, we write it to the run () method that is in the GameThread class, below our onDraw () drawing method.
Here is what we get after launching the application: