我是Libgdx的新手,在使用游戏数据库时遇到麻烦。
我搜索了有关如何使用Libgdx使SQLite在Android和桌面应用程序上运行的教程,但没有找到一个简单的教程。
我上一次在Android中使用数据库时,创建了一个从扩展的类SQLiteOpenHelper。
SQLiteOpenHelper
有没有一种简单的方法可以使用Libgdx做到这一点?或者至少,有人可以指出我的逐步教程或类似内容吗?
编辑
我忘了说我正在寻找可以让我管理诸如的版本的东西SQLiteOpenHelper。换句话说,当我更改代码数据库的版本时,我想在apk安装中的Android中重新创建数据库。
解
按照@42n4答案,我设法SQLiteOpenHelper在Android应用程序和JDBC桌面应用程序上使用SQLite数据库进行连接。
@42n4
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为桌面应用程序创建了一个类:
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应用程序
DatabaseAndroid
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和桌面应用程序的主要类:
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在需要升级时更改类的版本。
PRAGMA user_version
DataBase
我并没有把我做的所有方法都放在上面,Result而是我认为更重要的方法也更重要。
Result
编辑:我应该提到有关Udacity的libgdx游戏的两门新课程:https : //github.com/udacity/ud405
https://github.com/udacity/ud406