问题描述:

I've been looking through this code for over 2 days and still can't find any errors in the code as to why it crashes on Android. It works perfectly fine on desktop.

Android Target: 4.0.3

Android Phone used: HTC Desire C

Logcat:


04-07 16:42:35.785: E/AndroidRuntime(24197): FATAL EXCEPTION: GLThread 2955

04-07 16:42:35.785: E/AndroidRuntime(24197): java.lang.ClassCastException: com.badlogic.gdx.math.Vector2 cannot be cast to java.lang.String

04-07 16:42:35.785: E/AndroidRuntime(24197): at com.survivegameandroidtest.survive.Player.readPlayer(Player.java:191)

04-07 16:42:35.785: E/AndroidRuntime(24197): at com.survivegameandroidtest.survive.MainMenu.loadPlayer(MainMenu.java:278)

04-07 16:42:35.785: E/AndroidRuntime(24197): at com.survivegameandroidtest.survive.MainMenu.show(MainMenu.java:127)

04-07 16:42:35.785: E/AndroidRuntime(24197): at com.badlogic.gdx.Game.setScreen(Game.java:62)

04-07 16:42:35.785: E/AndroidRuntime(24197): at com.survivegameandroidtest.survive.GameHub.create(GameHub.java:12)

04-07 16:42:35.785: E/AndroidRuntime(24197): at com.badlogic.gdx.backends.android.AndroidGraphics.onSurfaceChanged(AndroidGraphics.java:334)

04-07 16:42:35.785: E/AndroidRuntime(24197): at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1463)

04-07 16:42:35.785: E/AndroidRuntime(24197): at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1224)


Like I said, this works fine on desktop, but crashes on Android.

Player class

package com.survivegameandroidtest.survive;

import java.io.ByteArrayInputStream;

import java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.io.OutputStream;

import java.io.Serializable;

import com.badlogic.gdx.Gdx;

import com.badlogic.gdx.Input.Keys;

import com.badlogic.gdx.files.FileHandle;

import com.badlogic.gdx.graphics.Texture;

import com.badlogic.gdx.graphics.g2d.Animation;

import com.badlogic.gdx.graphics.g2d.SpriteBatch;

import com.badlogic.gdx.graphics.g2d.TextureRegion;

import com.badlogic.gdx.math.Rectangle;

import com.badlogic.gdx.math.Vector2;

public class Player implements Serializable{

private static final long serialVersionUID = 1L;

SpriteBatch batch;

static Vector2 position = new Vector2(1,1);

Vector2 size;

Vector2 boundSize;

Vector2 boundOffset;

Texture texture;

Rectangle bounds;

String direction = "";

StringCheese cheese;

EnemyCheddarling enemy;

int health = 0, damage;

boolean alive;

private static final int col = 4, row = 4;

Animation animation;

TextureRegion[] frames;

TextureRegion currentFrame;

float stateTime;

int speed = 0;

static String name = "";

public Player(Texture texture, Vector2 position, Vector2 size, Vector2 boundSize, Vector2 boundOffset) {

this.texture = texture;

Player.position = position;

this.size = size;

this.boundOffset = boundOffset;

TextureRegion[][] tmp = TextureRegion.split(texture, texture.getWidth() / col, texture.getHeight() / row);

frames = new TextureRegion[col * row];

int index = 0;

for(int i = 0; i < row; i++) {

for(int j = 0; j < col; j++) {

frames[index++] = tmp[i][j];

}

}

animation = new Animation(1f, frames);

stateTime = 0f;

currentFrame = animation.getKeyFrame(0);

this.boundSize = boundSize;

bounds = new Rectangle(position.x + boundOffset.x, position.y + boundOffset.y, boundSize.x, boundSize.y);

health = 100;

damage = 20;

alive = true;

name = "SET YO NAME FOOL";

}

public void update() {

bounds.set(position.x + boundOffset.x, position.y + boundOffset.y, boundSize.x, boundSize.y);

if(health <= 0) {

alive = false;

}

stateTime += Gdx.graphics.getDeltaTime()*8;

if(stateTime > col) {

stateTime = 0;

}

//WASD MOVE METHOD

if(Gdx.input.isKeyPressed(Keys.W)) {

position.y += 2f;

currentFrame = animation.getKeyFrame(12 + stateTime);

direction = "up";

speed = 2;

}

if(Gdx.input.isKeyPressed(Keys.A)) {

position.x -= 2f;

currentFrame = animation.getKeyFrame(4 + stateTime);

direction = "left";

speed = 2;

}

if(Gdx.input.isKeyPressed(Keys.S)) {

position.y -= 2f;

currentFrame = animation.getKeyFrame(0 + stateTime);

direction = "down";

speed = 2;

}

if(Gdx.input.isKeyPressed(Keys.D)) {

position.x += 2f;

currentFrame = animation.getKeyFrame(8 + stateTime);

direction = "right";

speed = 2;

}

//ACCELEROMETER MOVE METHOD

if(Gdx.input.getAccelerometerX() != 1 || Gdx.input.getAccelerometerX() != 0 || Gdx.input.getAccelerometerX() != -1 || Gdx.input.getAccelerometerY() != 1 || Gdx.input.getAccelerometerY() != 0 || Gdx.input.getAccelerometerY() != -1) {

for(int rotation = 2; rotation < 5; rotation++) {

if(Gdx.input.getAccelerometerX() <= -rotation) { //DOWN

position.y += rotation;

currentFrame = animation.getKeyFrame(12 + stateTime);

direction = "down";

speed = rotation;

}

if(Gdx.input.getAccelerometerX() >= rotation) { //UP

position.y -= rotation;

currentFrame = animation.getKeyFrame(0 + stateTime);

direction = "up";

speed = rotation;

}

if(Gdx.input.getAccelerometerY() <= -rotation) { //LEFT

position.x -= rotation;

currentFrame = animation.getKeyFrame(4 + stateTime);

direction = "left";

speed = rotation;

}

if(Gdx.input.getAccelerometerY() >= rotation) { //RIGHT

position.x += rotation;

currentFrame = animation.getKeyFrame(8 + stateTime);

direction = "right";

speed = rotation;

}

}

}

}

public void draw(SpriteBatch batch) {

batch.draw(currentFrame, position.x, position.y, size.x, size.y);

}

public void collision() {

if(direction == "up") {

position.y += speed;

}

if(direction == "down") {

position.y -= speed;

}

if(direction == "left") {

position.y -= speed;

}

if(direction == "right") {

position.y += speed;

}

}

public static void savePlayer(Player playerName) throws IOException{

FileHandle file = Gdx.files.local("player.dat");

OutputStream out = null;

try{

file.writeBytes(serialize(name), false);

}catch(Exception ex){

System.out.println(ex.toString());

}finally{

if(out != null) try{out.close();} catch(Exception ex){}

}

try {

System.out.println("Saving Player" + " " + deserialize(file.readBytes()));

} catch (ClassNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

public static String readPlayer() throws IOException, ClassNotFoundException{

String playerName = "";

FileHandle file = Gdx.files.local("player.dat");

playerName = (String) deserialize(file.readBytes());

System.out.println("Reading Player");

return playerName;

}

private static byte[] serialize(Object obj) throws IOException {

ByteArrayOutputStream b = new ByteArrayOutputStream();

ObjectOutputStream o = new ObjectOutputStream(b);

o.writeObject(obj);

return b.toByteArray();

}

public static Object deserialize(byte[] bytes) throws IOException, ClassNotFoundException {

ByteArrayInputStream b = new ByteArrayInputStream(bytes);

ObjectInputStream o = new ObjectInputStream(b);

return o.readObject();

}

//GETTERS AND SETTERS

public SpriteBatch getBatch() {

return batch;

}

public String getName() {

return name;

}

public void setName(String object) {

Player.name = object;

}

public Vector2 getBoundOffset() {

return boundOffset;

}

public void setBoundOffset(Vector2 boundOffset) {

this.boundOffset = boundOffset;

}

public int getHealth() {

return health;

}

public void setHealth(int health) {

this.health = health;

}

public int getDamage() {

return damage;

}

public void setDamage(int damage) {

this.damage = damage;

}

public boolean isAlive() {

return alive;

}

public void setAlive(boolean alive) {

this.alive = alive;

}

public String getDirection() {

return direction;

}

public void setDirection(String direction) {

this.direction = direction;

}

public StringCheese getCheese() {

return cheese;

}

public void setCheese(StringCheese cheese) {

this.cheese = cheese;

}

public Rectangle getBounds() {

return bounds;

}

public void setBounds(Rectangle bounds) {

this.bounds = bounds;

}

public Vector2 getSize() {

return size;

}

public void setSize(Vector2 size) {

this.size = size;

}

public Vector2 getBoundSize() {

return boundSize;

}

public void setBoundSize(Vector2 boundSize) {

this.boundSize = boundSize;

}

public Texture getTexture() {

return texture;

}

public void setTexture(Texture texture) {

this.texture = texture;

}

public Animation getAnimation() {

return animation;

}

public void setAnimation(Animation animation) {

this.animation = animation;

}

public TextureRegion[] getFrames() {

return frames;

}

public void setFrames(TextureRegion[] frames) {

this.frames = frames;

}

public TextureRegion getCurrentFrame() {

return currentFrame;

}

public void setCurrentFrame(TextureRegion currentFrame) {

this.currentFrame = currentFrame;

}

public float getStateTime() {

return stateTime;

}

public void setStateTime(float stateTime) {

this.stateTime = stateTime;

}

public static int getCol() {

return col;

}

public static int getRow() {

return row;

}

public void setBatch(SpriteBatch batch) {

this.batch = batch;

}

public Vector2 getPosition() {

return position;

}

public void setPosition(Vector2 position) {

Player.position = position;

}

}


In savePlayer(), I try to serialize the String variable 'name'.

System.out.println("Saving Player" + " " + deserialize(file.readBytes()));

^ This line of code prints out "Saving Player Hosif Yimms" in the console, and none of the methods return a Vector2.


ANSWER: Used a FileHandle method to save the players name, as deserialize return an Object, not String.

网友答案:

Why are you using Object serialization for strings anyway? Just get a reader/writer for your FileHandle. Chase

public static void savePlayerName(Player player) {
    FileHandle file = Gdx.files.local("playername.dat");
    file.writeString(player.getName(), false);
}

public static String readPlayerName() {
    FileHandle file = Gdx.files.local("playername.dat");
    String name = file.readString();
    return name;
}
相关阅读:
Top