"Back from scratch "......
Originally, Lao Yan had decided to end the writing of this series of articles, but unexpectedly received an invitation from Yan, hoping to compile and publish these articles. Although publishing is very troublesome, however, having the opportunity to write your own text is an exciting thing, so I decided to give it a try. As Yan said, there is a little bit of content in the series from scratch, and Lao Yan can just sort out the previous notes and add something that he wanted to write but didn't write. The content to be added includes files and networks, integration of gae, parsing XML, box2d physical engine, HGE particle system, Lua script, scoreloop ranking, AdMob ads, and how to publish applications to the Android Market. Most of the content has notes, but it takes a lot of time to sort it out. Because there is still new engine development work, and it cannot be dispersed too much energy, I hope it can be completed as soon as possible.
Next Let's enter a new chapter.
In the game, file operations are basically the access to resources (images, sounds, etc.) and access records. We will explain them in two parts. First, resources. Generally, when the game is relatively small, we can directly place the resource files in the corresponding directory of RES and read them through the resources class. For files outside the image, such as audio and map data, we can create a raw directory under the res directory to access the file by using the resource ID. However, if a game is large and has many resources, it will be divided into many directories for management. At this time, relying on the resource ID generated by Android is insufficient. In this case, we can use the Assets Directory to directly store the directory structure in the assets and access it through the file name. For larger games, resource files containing dozens or even hundreds of MB are all packaged with the main program (stored in the Assets Directory) it seems a bit BT to let everyone download data from the App Store. Therefore, such large games generally choose to separately issue data packets or download data from the network when the app starts.
Using the resource methods in the res directory, I think you have mastered the previous chapter. Next let's learn how to access the resource files in assets and sdcard respectively.
Operations on the Assets Directory must use special APIs, which are determined by the features of the assets. The Assets Directory is packaged in the APK file, so it is not a real file system, but a compressed package. In the following example, we put player1.png in the assets/graphics directory, put the audio sample. Mid in the assets/audio directory, display the image in the program, and play the audio.
First, let's take a look at the code for displaying the image:
Bitmap BMP =Null;
Public VoidStart (surfaceholder ){
Try{
BMP = bitmapfactory.Decodestream(Main.Getinstance(). Getassets (). Open ("graphics/player1.png "));
}Catch(Exception e ){
//TodoAuto-generated Catch Block
E. printstacktrace ();
}
}
First, we declare a bitmap object BMP in scenestartmenu. Then initialize BMP in the Start function. Although the Code here only has one line (except the try/catch structure), it involves a lot of knowledge.
First, we use bitmapfactory, and the reader is certainly familiar with it. We always use it to obtain BMP objects. But this time, we didn't use decoderesource, but another function, decodestream. Stream is a mechanism for processing byte data, such as network, file, and keyboard input. Stream provides an encapsulation of data, making it easier for users to read and write data. In this example, we want to obtain image data from the file without resource ID, so we need to use stream.
The following question is how to obtain stream. As mentioned above, a file in the Assets Directory requires a special API. This is assetmanager, which must be used to access the assets file. Two of the most important methods in assetmanager are often used: open and openfd. The former obtains an inputstream, which is the input stream. We can use this input stream to obtain the file content (outputstream corresponds to inputstream and can modify the file content ). The latter gets a description of the file, which will be used for playing music in the next step.
The new question comes again. How can we obtain assetmanager? First, you can obtain the activity instance through the static method of main, and then call the getasset method to obtain the assetmanager instance. After completing the above steps, we can use decodestream to build a bitmap instance. The bitmap is displayed in update.
@ Override
Public VoidUpdate (canvas c ){
//TodoAuto-generated method stub
C. drawargb (255, 0, 0, 0 );
C. drawtext ("scenestartmenu", gameview.Width/2, gameview.Height/2, paint );
If(BMP! =Null){
C. drawbitmap (BMP, 0, 0, paint );
}
}
Let's run the program to see the effect:
After loading image files from the Assets Directory, let's learn how to load resources from sdcard.
First, save the image file to the graphics directory in sdcard. If you haven't added the ADB path to the system path, you need to manually enter the platform-tools directory under the SDK directory and execute the ADB command.
After creating the directory, we can push the file to the sdcard of the simulator through commands or ddms.
After learning above, we know that we can create bitmap instances through stream. sdcard is a common file system. Therefore, the fileinputstream class in the Java. Io package can complete this work, which is very simple. See the Code:
BMP = bitmapfactory.Decodestream(NewFileinputstream ("/sdcard/graphics/player1.png "));
Note that the file path must be correct. to access the file in sdcard, use "/sdcard/" as the root directory. Of course, bitmapfactory also has a simpler decodefile method. You can try it yourself.
Next, let's complete the second part of this chapter and play an audio file stored in the Assets Directory.
You must remember the method we mentioned in the previous chapter for playing music and sound effects. Take music as an example. We played a MIDI audio file stored on the sdcard. This time, we copied the audio file to the Assets Directory. Do you still remember how we obtained the audio file in the previous chapter?
MP. Setdatasource (PATH );
Yes, we use the file path. Can we use the file path in assets as the parameter of setdatasource? It seems that people often ask such questions. But the old man can say for sure, no. Remember that assets is a compressed package, not a common file system, so we must also use assetmanager. Based on the Image Display experience, the reader may soon think of creating an inputstream for mediaplayer. In fact, this is what we do on many systems. But it is strange that android does not have such a function, which is really confusing. So we have laid a foreshadowing -- another important function openfd in assetmanager.
When we look at the mediaplayer documentation (you can still remember the method for viewing the documentation), we will find that setdatasource has a form that uses the filedescriptor file descriptor as the parameter, this is exactly what we need. Like the image display method, we can use openfd to obtain a descriptor for the audio file.
Assetfiledescriptor AFD = Main.Getinstance(). Getassets (). openfd ("audio/sample. Mid ");
But careful readers will find that this file descriptor is not a filedescriptor and has an asset prefix. In addition, it is not a subclass of filedescriptor, so it cannot be used directly as a parameter of setdatasource. But this is not a problem. We can use the getfiledescriptor of assetfiledescripter to obtain the filedescriptor we need.
Next, let's modify playbgm in util and replace path with filedescriptor as the parameter:
Public Static VoidPlaybgm (filedescriptor FD,LongOffset,LongLength,BooleanLooping ){
If(MP=Null){
MP=NewMediaplayer ();
}
MP. Reset ();
Try{
MP. Setdatasource (FD, offset, length );
MP. Prepare ();
}Catch(Illegalargumentexception e ){
//TodoAuto-generated Catch Block
E. printstacktrace ();
}Catch(Illegalstateexception e ){
//TodoAuto-generated Catch Block
E. printstacktrace ();
}Catch(Ioexception e ){
//TodoAuto-generated Catch Block
E. printstacktrace ();
}
MP. Setlooping (looping );
MP. Start ();
}
In this way, you can use playbgm To Play files in the Assets Directory.
Util.Playbgm(AFD. getfiledescriptor (), AFD. getstartoffset (), AFD. getlength (),False);
Of course, you can also use other methods, such as path/assets/path/file. EXT is used as the path parameter, but the path value is checked inside the function. If it starts with/assets, assetmanager is used to obtain the file description. The modified playbgm is as follows:
Public Static VoidPlaybgm (string path,BooleanLooping ){
If(MP=Null){
MP=NewMediaplayer ();
}
MP. Reset ();
Try{
If(Path. indexof ("/assets/") = 0 ){
Assetfiledescriptor AFD = Main.Getinstance(). Getassets (). openfd (path. substring (8 ));
MP. Setdatasource (AFD. getfiledescriptor (), AFD. getstartoffset (), AFD. getlength ());
}Else{
MP. Setdatasource (PATH );
}
MP. Prepare ();
}Catch(Illegalargumentexception e ){
//TodoAuto-generated Catch Block
E. printstacktrace ();
}Catch(Illegalstateexception e ){
//TodoAuto-generated Catch Block
E. printstacktrace ();
}Catch(Ioexception e ){
//TodoAuto-generated Catch Block
E. printstacktrace ();
}
MP. Setlooping (looping );
MP. Start ();
}
In this way, we can use
Util.Playbgm("/Assets/Audio/sample. Mid ",False);
The audio file has been played. But remember that assetmanager is still used in playbgm.
The method for playing audio files in sdcard has been discussed in the previous chapter.
Here we will introduce how to read resources. In this chapter, we have learned how to load resources from the Assets Directory and sdcard. We will introduce how to load resources from the network in the following sections.