2013-04-08 13 views
15

私はLibgdxで新しく、ゲームでデータベースを使用する際に問題が発生しています。LibgdxでSQLiteデータベースを使用

Libgdxを使用してAndroidとデスクトップの両方のアプリケーションでSQLiteを動作させる方法に関するチュートリアルを検索しましたが、簡単なものは見つかりませんでした。

最後にAndroidでデータベースを使用したとき、私はSQLiteOpenHelperから拡張されたクラスを作成しました。

Libgdxを使って同じことを行う簡単な方法はありますか?または、少なくとも、誰かが段階的なチュートリアルやそれに類するものを指すことができますか?私は私がSQLiteOpenHelperなどのバージョンを管理しましょう何かを探していると言うのを忘れて

EDIT

。言い換えれば、コード上でDBのバージョンを変更すると、apkのインストール時にAndroidでデータベースを再作成したいと考えています。 @42n4解答後

SOLUTION

を、私は、AndroidアプリケーションとデスクトップアプリケーションのJDBCSQLiteOpenHelperを使用してSQLiteデータベースに接続する方法を管理します。

まず、私はデスクトップとAndroidアプリケーションの両方のための "共通クラス" を作成しました:Android用

public class DatabaseDesktop extends DataBase{ 
    protected Connection db_connection; 
    protected Statement stmt; 
    protected boolean nodatabase=false; 

    public DatabaseDesktop() { 
     loadDatabase(); 
     if (isNewDatabase()){ 
      onCreate(); 
      upgradeVersion(); 
     } else if (isVersionDifferent()){ 
      onUpgrade(); 
      upgradeVersion(); 
     } 

    } 

    public void execute(String sql){ 
     try { 
      stmt.execute(sql); 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } 
    } 

    public int executeUpdate(String sql){ 
     try { 
      return stmt.executeUpdate(sql); 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } 
     return 0; 
    } 

    public Result query(String sql) { 
     try { 
      return new ResultDesktop(stmt.executeQuery(sql)); 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 

    private void loadDatabase(){ 
     File file = new File (database_name+".db"); 
     if(!file.exists()) 
      nodatabase=true; 
     try { 
      Class.forName("org.sqlite.JDBC"); 
      db_connection = DriverManager.getConnection("jdbc:sqlite:"+database_name+".db"); 
      stmt = db_connection.createStatement(); 
     } catch (ClassNotFoundException e) { 
      e.printStackTrace(); 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } 
    } 

    private void upgradeVersion() { 
     execute("PRAGMA user_version="+version); 
    } 

    private boolean isNewDatabase() { 
     return nodatabase; 
    } 

    private boolean isVersionDifferent(){ 
     Result q=query("PRAGMA user_version"); 
     if (!q.isEmpty()) 
      return (q.getInt(1)!=version); 
     else 
      return true; 
    } 

    public class ResultDesktop implements Result{ 

     ResultSet res; 
     boolean called_is_empty=false; 

     public ResultDesktop(ResultSet res) { 
      this.res = res; 
     } 

     public boolean isEmpty() { 
      try { 
       if (res.getRow()==0){ 
        called_is_empty=true; 
        return !res.next(); 
       } 
       return res.getRow()==0; 
      } catch (SQLException e) { 
       e.printStackTrace(); 
      } 
      return false; 
     } 

     public boolean moveToNext() { 
      try { 
       if (called_is_empty){ 
        called_is_empty=false; 
        return true; 
       } else 
        return res.next(); 
      } catch (SQLException e) { 
       e.printStackTrace(); 
      } 
      return false; 
     } 

     public int getColumnIndex(String name) { 
      try { 
       return res.findColumn(name); 
      } catch (SQLException e) { 
       e.printStackTrace(); 
      } 
      return 0; 
     } 

     public float getFloat(int columnIndex) { 
      try { 
       return res.getFloat(columnIndex); 
      } catch (SQLException e) { 
       e.printStackTrace(); 
      } 
      return 0; 
     } 

     [...] 

    } 

} 

そしてDatabaseAndroid:次に

//General class that needs to be implemented on Android and Desktop Applications 
public abstract class DataBase { 

    protected static String database_name="recycling_separation"; 
    protected static DataBase instance = null; 
    protected static int version=1; 

    //Runs a sql query like "create". 
    public abstract void execute(String sql); 

    //Identical to execute but returns the number of rows affected (useful for updates) 
    public abstract int executeUpdate(String sql); 

    //Runs a query and returns an Object with all the results of the query. [Result Interface is defined below] 
    public abstract Result query(String sql); 

    public void onCreate(){ 
     //Example of Highscore table code (You should change this for your own DB code creation) 
     execute("CREATE TABLE 'highscores' ('_id' INTEGER PRIMARY KEY NOT NULL , 'name' VARCHAR NOT NULL , 'score' INTEGER NOT NULL);"); 
     execute("INSERT INTO 'highscores'(name,score) values ('Cris',1234)"); 
     //Example of query to get DB data of Highscore table 
     Result q=query("SELECT * FROM 'highscores'"); 
     if (!q.isEmpty()){ 
      q.moveToNext(); 
      System.out.println("Highscore of "+q.getString(q.getColumnIndex("name"))+": "+q.getString(q.getColumnIndex("score"))); 
     } 
    } 

    public void onUpgrade(){ 
     //Example code (You should change this for your own DB code) 
     execute("DROP TABLE IF EXISTS 'highscores';"); 
     onCreate(); 
     System.out.println("DB Upgrade maded because I changed DataBase.version on code"); 
    } 

    //Interface to be implemented on both Android and Desktop Applications 
    public interface Result{ 
     public boolean isEmpty(); 
     public boolean moveToNext(); 
     public int getColumnIndex(String name); 
     public float getFloat(int columnIndex); 
     [...] 
    } 
} 

を、私はデスクトップアプリケーションのためのDatabaseDesktopクラスを作成しましたアプリケーション

public class DatabaseAndroid extends DataBase{ 
    protected SQLiteOpenHelper db_connection; 
    protected SQLiteDatabase stmt; 

    public DatabaseAndroid(Context context) { 
     db_connection = new AndroidDB(context, database_name, null, version); 
     stmt=db_connection.getWritableDatabase(); 
    } 

    public void execute(String sql){ 
     stmt.execSQL(sql); 
    } 

    public int executeUpdate(String sql){ 
     stmt.execSQL(sql); 
     SQLiteStatement tmp = stmt.compileStatement("SELECT CHANGES()"); 
     return (int) tmp.simpleQueryForLong(); 
    } 

    public Result query(String sql) { 
     ResultAndroid result=new ResultAndroid(stmt.rawQuery(sql,null)); 
     return result; 
    } 

    class AndroidDB extends SQLiteOpenHelper { 

     public AndroidDB(Context context, String name, CursorFactory factory, 
       int version) { 
      super(context, name, factory, version); 
     } 

     public void onCreate(SQLiteDatabase db) { 
      stmt=db; 
      DatabaseAndroid.this.onCreate(); 
     } 

     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
      stmt=db; 
      DatabaseAndroid.this.onUpgrade(); 
     } 

    } 

    public class ResultAndroid implements Result{ 
     Cursor cursor; 

     public ResultAndroid(Cursor cursor) { 
      this.cursor=cursor; 
     } 

     public boolean isEmpty() { 
      return cursor.getCount()==0; 
     } 

     public int getColumnIndex(String name) { 
      return cursor.getColumnIndex(name); 
     } 

     public String[] getColumnNames() { 
      return cursor.getColumnNames(); 
     } 

     public float getFloat(int columnIndex) { 
      return cursor.getFloat(columnIndex); 
     } 

     [...] 

    } 

} 

最後に、I cha

public class Main extends AndroidApplication { 

    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     initialize(new MyGame(new DatabaseAndroid(this.getBaseContext())), false); 
    } 
} 

public class Main { 

    public static void main(String[] args) { 
     new LwjglApplication(new MyGame(new DatabaseDesktop()), "Example", MyGame.SCREEN_WIDTH, MyGame.SCREEN_HEIGHT,false); 
    } 

} 

注:両方のAndroidとデスクトップアプリケーションの主要なクラスをnged

私はPRAGMA user_versionを使用してSQLiteOpenHelperで起こるもののようバージョン管理を行いました。この方法で、私はそれをアップグレードする必要があるときにDataBaseクラスのバージョンを変更するだけです。

私が作った方法はすべてResultに入れていませんでしたが、もっと重要だと思うものを入れました。もっと重要です。

答えて

3

http://marakana.com/techtv/android_bootcamp_screencast_series.html クラス4、パート1:Androidの合宿 - statusData、libgdx用:http://code.google.com/p/libgdx-users/wiki/SQLite

EDIT: 私はUdacityでlibgdxゲームについて約2の新しいコースを言及する必要があります: https://github.com/udacity/ud405

https://github.com/udacity/ud406

+0

Androidとデスクトップの両方で、私は 'StatusData'という名前のクラスを作成しますか? Androidでは、これまで使用していたように 'SQLiteOpenHelper'を使用できます。しかし、デスクトップアプリケーションはどうですか?たとえば、 'StatusData'でDBバージョンが変更されたときにデスクトップアプリケーションでDBを再作成するにはどうすればよいですか? –

+0

多分それは役立つでしょう:http://code.google.com/p/libgdx-users/wiki/SQLite – 42n4

+0

したがって、私はAndroid上で 'SQLiteOpenHelper'を使用することができますし、私は同じことをすることができます'JDBC'を使用しています。両方とも' StatusData'などのクラスに作成されます。右? –

6

私が書いた拡張機能(gdx-sqliteという)があります。これはあなたが必要とする作業のほとんどを行います。この拡張機能の最新ビルドはhereからダウンロードできます。ソースコードと読者は次の場所にあります:https://github.com/mrafayaleem/gdx-sqlite

この拡張機能は現在、Androidおよびデスクトッププラットフォームをサポートしています。また、Androidアプリのassetsフォルダにあるデータベースを開くことはできません。ただし、これは保留中の機能であり、すぐに追加されます。

データベースの処理のためにプロジェクトを設定するには、私の指示に従ってください。以下はコード例です:

package com.mrafayaleem.gdxsqlitetest; 

import com.badlogic.gdx.Gdx; 
import com.badlogic.gdx.sql.Database; 
import com.badlogic.gdx.sql.DatabaseCursor; 
import com.badlogic.gdx.sql.DatabaseFactory; 
import com.badlogic.gdx.sql.SQLiteGdxException; 

public class DatabaseTest { 

    Database dbHandler; 

    public static final String TABLE_COMMENTS = "comments"; 
    public static final String COLUMN_ID = "_id"; 
    public static final String COLUMN_COMMENT = "comment"; 

    private static final String DATABASE_NAME = "comments.db"; 
    private static final int DATABASE_VERSION = 1; 

    // Database creation sql statement 
    private static final String DATABASE_CREATE = "create table if not exists " 
      + TABLE_COMMENTS + "(" + COLUMN_ID 
      + " integer primary key autoincrement, " + COLUMN_COMMENT 
      + " text not null);"; 

    public DatabaseTest() { 
     Gdx.app.log("DatabaseTest", "creation started"); 
     dbHandler = DatabaseFactory.getNewDatabase(DATABASE_NAME, 
       DATABASE_VERSION, DATABASE_CREATE, null); 

     dbHandler.setupDatabase(); 
     try { 
      dbHandler.openOrCreateDatabase(); 
      dbHandler.execSQL(DATABASE_CREATE); 
     } catch (SQLiteGdxException e) { 
      e.printStackTrace(); 
     } 

     Gdx.app.log("DatabaseTest", "created successfully"); 

     try { 
      dbHandler 
        .execSQL("INSERT INTO comments ('comment') VALUES ('This is a test comment')"); 
     } catch (SQLiteGdxException e) { 
      e.printStackTrace(); 
     } 

     DatabaseCursor cursor = null; 

     try { 
      cursor = dbHandler.rawQuery("SELECT * FROM comments"); 
     } catch (SQLiteGdxException e) { 
      e.printStackTrace(); 
     } 
     while (cursor.next()) { 
      Gdx.app.log("FromDb", String.valueOf(cursor.getString(1))); 
     } 

     try { 
      dbHandler.closeDatabase(); 
     } catch (SQLiteGdxException e) { 
      e.printStackTrace(); 
     } 
     dbHandler = null; 
     Gdx.app.log("DatabaseTest", "dispose"); 
    } 
} 
関連する問題