Android游戏开发基础part9--游戏数据存储

来源:互联网 发布:oppor11plus数据流量 编辑:程序博客网 时间:2024/06/06 10:07

Android游戏开发基础part9--游戏数据存储

在Android中,对于数据的存储,提供了4种保存方式:

1.SharedPreference

此方式适用于简单的数据的保存,文如其名,属于配置性质的保存,不适合数据比较大的情况,默认存放在手机内存里。

2.FileInputStream/FileOutputStream

此方式比较适合游戏的保存和使用,流文件存储可以保存较大的数据,而且通过此方式不仅能把数据存储在手机内存中,也能将数据保存到手机的SDcard

3.SQLite

此方式也适合游戏的保存和使用,不仅可以保存较大的数据,而且可以将自己的数据存放在文件系统或者数据库当中,如SQLite数据库,也能将数据保存到SDcard中。

4.ContentProvider

此方式不推荐用于游戏保存,虽然次方式能存储较大的数据,还支持多个程序之间的数据进行交换,但由于游戏中基本就不可能访问外部应用的数据。

1.SharedPreference

SharedPreference实例是通过Context对象得到的:

Context.getSharedPreference(String name, int mode)

作用:利用Context对象获取一个SharedPreference实例

第一个参数:生成保存记录的文件名

第二个参数:操作模式

操作模式:

·Context.MODE_PRIVATE:新内容覆盖原内容。

·Context.MODE_APPEND:新内容追加到原内容后。

·Context.MODE_WORLD_READABLE:允许其他应用程序读取。

·Context.MODE_WORLD_WRITEABLE:允许其他应用程序写入,会覆盖原数据。

常用函数:

·getFloat(String key, float defValue)

·getInt(String key, int defValue)

·getLong(String key, long defValue)

·getString(String key, String defValue)

·getBoolean(String key, Boolean defValue)

对存储文件的数据进行存入操作时,首先需要利用SharedPreference实例得到一个编辑对象:SharedPreferences.Editor edit();

得到一个编辑对象后就可以对SharedPreference中的数据进行操作。

·SharedPreferences.Editor.putFloat(arg0, arg1)

·SharedPreferences.Editor.putFInt(arg0, arg1)

·SharedPreferences.Editor.putLong(arg0, arg1)

·SharedPreferences.Editor.putString(arg0, arg1)

·SharedPreferences.Editor.putBoolean(arg0, arg1)

以上方法的作用是对存储的数据进行操作(写入、保存),其中的第一个参数是需要保存数据的Key值索引,第二个参数是需要保存的数据。

数据要真正写入到SharedPreferences生成的存储文件中,还需要提交:

SharedPreference.Editor.commit();

创建实例:SharedPreferenceProject

==>MySurfaceView.java

package com.spfp;import android.content.Context;import android.content.SharedPreferences;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Paint.Style;import android.view.KeyEvent;import android.view.MotionEvent;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.SurfaceHolder.Callback;/** *  * @author Himi * */public class MySurfaceView extends SurfaceView implements Callback, Runnable {private SurfaceHolder sfh;private Paint paint;private Thread th;private boolean flag;private Canvas canvas;private int screenW, screenH;//记录当前圆形所在九宫格的位置下标private int creentTileIndex;//声明一个SharedPreferences对象private SharedPreferences sp;/** * SurfaceView初始化函数 */public MySurfaceView(Context context) {super(context);sfh = this.getHolder();sfh.addCallback(this);paint = new Paint();paint.setColor(Color.BLACK);paint.setAntiAlias(true);setFocusable(true);//通过Context获取SharedPreference实例sp = context.getSharedPreferences("SaveName", Context.MODE_PRIVATE);//每次程序运行时获取圆形的下标int tempIndex = sp.getInt("CirCleIndex", -1);//判定如果返回-1 说明没有找到,就不对当前记录圆形的变量进行赋值if (tempIndex != -1) {creentTileIndex = tempIndex;}}/** * SurfaceView视图创建,响应此函数 */@Overridepublic void surfaceCreated(SurfaceHolder holder) {screenW = this.getWidth();screenH = this.getHeight();flag = true;//实例线程th = new Thread(this);//启动线程th.start();}/** * 游戏绘图 */public void myDraw() {try {canvas = sfh.lockCanvas();if (canvas != null) {canvas.drawColor(Color.WHITE);paint.setColor(Color.BLACK);paint.setStyle(Style.STROKE);//绘制九宫格(将屏幕九等份)//得到每个方格的宽高int tileW = screenW / 3;int tileH = screenH / 3;for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {canvas.drawRect(i * tileW, j * tileH, (i + 1) * tileW, (j + 1) * tileH, paint);}}//根据得到的圆形下标位置进行绘制相应的方格中paint.setStyle(Style.FILL);canvas.drawCircle(creentTileIndex % 3 * tileW + tileW / 2, creentTileIndex / 3 * tileH + tileH / 2, 30, paint);//操作说明canvas.drawText("上键:保存游戏", 0, 20, paint);canvas.drawText("下键:读取游戏", 110, 20, paint);canvas.drawText("左右键:移动圆形", 215, 20, paint);}} catch (Exception e) {// TODO: handle exception} finally {if (canvas != null)sfh.unlockCanvasAndPost(canvas);}}/** * 触屏事件监听 */@Overridepublic boolean onTouchEvent(MotionEvent event) {return true;}/** * 按键事件监听 */@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {//上键保存游戏状态if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {sp.edit().putInt("CirCleIndex", creentTileIndex).commit();//下键读取游戏状态} else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {int tempIndex = sp.getInt("CirCleIndex", -1);if (tempIndex != -1) {creentTileIndex = tempIndex;}//圆形的移动} else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {if (creentTileIndex > 0) {creentTileIndex -= 1;}} else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {if (creentTileIndex < 8) {creentTileIndex += 1;}}return super.onKeyDown(keyCode, event);}/** * 游戏逻辑 */private void logic() {}@Overridepublic void run() {while (flag) {long start = System.currentTimeMillis();myDraw();logic();long end = System.currentTimeMillis();try {if (end - start < 50) {Thread.sleep(50 - (end - start));}} catch (InterruptedException e) {e.printStackTrace();}}}/** * SurfaceView视图状态发生改变,响应此函数 */@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}/** * SurfaceView视图消亡时,响应此函数 */@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {flag = false;}}


2.流文件存储 FileInputStream/FileOutputStream

创建实例:修改SharedPreference项目中“读取”与“保存的操作” StreamProject

代码:MySurfaceView.java

package com.stp;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Paint.Style;import android.os.Environment;import android.util.Log;import android.view.KeyEvent;import android.view.MotionEvent;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.SurfaceHolder.Callback;/** *  * @author Himi * */public class MySurfaceView extends SurfaceView implements Callback, Runnable {private SurfaceHolder sfh;private Paint paint;private Thread th;private boolean flag;private Canvas canvas;private int screenW, screenH;//记录当前圆形所在九宫格的位置下标private int creentTileIndex;/** * SurfaceView初始化函数 */public MySurfaceView(Context context) {super(context);sfh = this.getHolder();sfh.addCallback(this);paint = new Paint();paint.setColor(Color.BLACK);paint.setAntiAlias(true);setFocusable(true);}/** * SurfaceView视图创建,响应此函数 */@Overridepublic void surfaceCreated(SurfaceHolder holder) {screenW = this.getWidth();screenH = this.getHeight();flag = true;//实例线程th = new Thread(this);//启动线程th.start();}/** * 游戏绘图 */public void myDraw() {try {canvas = sfh.lockCanvas();if (canvas != null) {canvas.drawColor(Color.WHITE);paint.setColor(Color.BLACK);paint.setStyle(Style.STROKE);//绘制九宫格(将屏幕九等份)//得到每个方格的宽高int tileW = screenW / 3;int tileH = screenH / 3;for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {canvas.drawRect(i * tileW, j * tileH, (i + 1) * tileW, (j + 1) * tileH, paint);}}//根据得到的圆形下标位置进行绘制相应的方格中paint.setStyle(Style.FILL);canvas.drawCircle(creentTileIndex % 3 * tileW + tileW / 2, creentTileIndex / 3 * tileH + tileH / 2, 30, paint);//操作说明canvas.drawText("上键:保存游戏", 0, 20, paint);canvas.drawText("下键:读取游戏", 110, 20, paint);canvas.drawText("左右键:移动圆形", 215, 20, paint);}} catch (Exception e) {// TODO: handle exception} finally {if (canvas != null)sfh.unlockCanvasAndPost(canvas);}}/** * 触屏事件监听 */@Overridepublic boolean onTouchEvent(MotionEvent event) {return true;}/** * 按键事件监听 */@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {//用到的读出、写入流FileOutputStream fos = null;FileInputStream fis = null;DataOutputStream dos = null;DataInputStream dis = null;//上键保存游戏状态if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {try {// 从SDcard中写入数据// 试探终端是否有sdcard! 并且探测SDCard是否处于被移除的状态if (Environment.getExternalStorageState() != null && !Environment.getExternalStorageState().equals("removed")) {Log.v("Himi", "写入,有SD卡");File path = new File("/sdcard/himi");// 创建目录  File f = new File("/sdcard/himi/save.himi");// 创建文件  if (!path.exists()) {// 目录存在返回true  path.mkdirs();// 创建一个目录  }if (!f.exists()) {// 文件存在返回true  f.createNewFile();// 创建一个文件  }fos = new FileOutputStream(f);// 将数据存入sd卡中  } else {//默认系统路径//利用Activity实例打开流文件得到一个写入流fos = MainActivity.instance.openFileOutput("save.himi", Context.MODE_PRIVATE);}//将写入流封装在数据写入流中dos = new DataOutputStream(fos);//写入一个int类型(将圆形所在格子的下标写入流文件中)dos.writeInt(creentTileIndex);} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {//即使保存时发生异常,也要关闭流try {if (fos != null)fos.close();if (dos != null)dos.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}//下键读取游戏状态} else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {boolean isHaveSDCard = false;// 从SDcard中读取数据// 试探终端是否有sdcard! 并且探测SDCard是否处于被移除的状态if (Environment.getExternalStorageState() != null && !Environment.getExternalStorageState().equals("removed")) { Log.v("Himi", "读取,有SD卡");isHaveSDCard = true;}try {if (isHaveSDCard) {File path = new File("/sdcard/himi");// 创建目录  File f = new File("/sdcard/himi/save.himi");// 创建文件  if (!path.exists()) {// 目录存在返回truereturn false;} else {if (!f.exists()) {// 文件存在返回true  return false;}}fis = new FileInputStream(f);// 将数据存入sd卡中  } else {if (MainActivity.instance.openFileInput("save.himi") != null) {//利用Activity实例打开流文件得到一个读入流fis = MainActivity.instance.openFileInput("save.himi");}}//将读入流封装在数据读入流中dis = new DataInputStream(fis);//读出一个Int类型赋值与圆形所在格子的下标creentTileIndex = dis.readInt();} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {//即使读取时发生异常,也要关闭流try {if (fis != null)fis.close();if (dis != null)dis.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}} else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {if (creentTileIndex > 0) {creentTileIndex -= 1;}} else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {if (creentTileIndex < 8) {creentTileIndex += 1;}}return super.onKeyDown(keyCode, event);}/** * 游戏逻辑 */private void logic() {}@Overridepublic void run() {while (flag) {long start = System.currentTimeMillis();myDraw();logic();long end = System.currentTimeMillis();try {if (end - start < 50) {Thread.sleep(50 - (end - start));}} catch (InterruptedException e) {e.printStackTrace();}}}/** * SurfaceView视图状态发生改变,响应此函数 */@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}/** * SurfaceView视图消亡时,响应此函数 */@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {flag = false;}}


将流文件保存在SDcard中的步骤:

(1)声明写入权限:

<uses-permission android:name="android.premission.WRITE_EXTERNAL_STORAGE"/>

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.stp" android:versionCode="1" android:versionName="1.0"><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><application android:icon="@drawable/icon" android:label="@string/app_name"><activity android:name=".MainActivity" android:label="@string/app_name"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>


(2)创建目录和存储文件

1.首先需要创建路径:/sdcard/wwj

//声明一个路径

File path = new File("/sdcard/wwj");

if(!path.exists()){

path.mkdirs();

}

2.然后创建存储文件:/sdcard/wwj/save.wwj

//声明一个路径

File f = new File("/sdcard/wwj/save.wwj");

if(!f.exist()){//文件存在就返回true

f.createNewFile();//创建一个文件

}

(3)通过加载指定路径的存储文件获取输入输出流

·输入流:FileInputStream fis = new FileInputStream(File file);

·输出流:FileOutputSteam fos = new FileOutputSteam(File file);

原创粉丝点击