Использование базы данных SQLite в Libgdx

Я новичок в Libgdx, и у меня возникают проблемы с использованием базы данных в моей игре.

Я искал учебник о том, как заставить SQLite работать как с Android, так и с Desktop-приложениями с помощью Libgdx, но я не нашел простой.

В последний раз, когда я использовал базу данных в Android, я создал класс, который простирается от SQLiteOpenHelper .

Есть ли простой способ сделать то же самое с помощью Libgdx? Или, по крайней мере, может ли кто-нибудь указать мне на пошаговое руководство или что-то подобное?

РЕДАКТИРОВАТЬ

Я забыл сказать, что я ищу что-то, что позволяет мне управлять версиями, такими как SQLiteOpenHelper . Другими словами, я хочу воссоздать свою базу данных в Android при установке apk, когда я меняю версию своей БД на код.

РЕШЕНИЕ

После ответа @42n4 мне удалось подключиться к SQLite Database, используя SQLiteOpenHelper в приложении Android и JDBC на настольном приложении.

Во-первых, я создал «общий класс» для приложений для настольных компьютеров и Android:

 //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 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 для Android

 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); } [...] } } 

Наконец, я изменил основные классы приложений Android и Desktop:

 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); } } 

Обратите внимание, что:

Я сделал управление версиями, подобное тому, которое происходит в SQLiteOpenHelper используя PRAGMA user_version . Таким образом, я просто изменяю версию класса DataBase когда мне нужно его обновить.

Я не использовал все методы, которые я сделал на Result но я ставлю те, которые, по моему мнению, более важны. Это более важно.

Solutions Collecting From Web of "Использование базы данных SQLite в Libgdx"

http://marakana.com/techtv/android_bootcamp_screencast_series.html Класс 4, часть 1: Android Bootcamp – statusData, для libgdx: http://code.google.com/p/libgdx-users/wiki/SQLite

EDIT: Я должен упомянуть о двух новых курсах о играх libgdx в Udacity: https://github.com/udacity/ud405

https://github.com/udacity/ud406

Существует расширение (называемое gdx-sqlite), которое я написал, который будет выполнять большую часть требуемой работы. Последнюю сборку этого расширения можно загрузить здесь . Исходный код и чтение меня находятся по адресу: https://github.com/mrafayaleem/gdx-sqlite

В настоящее время это расширение поддерживает платформы Android и Desktop. Кроме того, нет поддержки для открытия баз данных, находящихся в папке с ресурсами приложения Android. Однако это ожидающая функция и будет добавлена ​​в ближайшее время.

Следуйте инструкциям, которые вы читаете, чтобы настроить ваши проекты для обработки баз данных. Ниже приведен пример кода:

 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"); } }