Also in einem Spiel, das ich mache, versuche ich über eine ArrayList vom Typ Troop und ArrayList des Typs Tower über einen Sockel, mit beiden Klasse Troop zu senden und Tower mit einem gepufferten Image. Das Spiel läuft mit 60 fps und sendet jedes Mal die beiden ArrayLists zwischen Server und Client in der updateConnection() -Methode. Als ich die Troop-Klasse und die Server- und Client-Klassen herausholte, bin ich erfolgreich in der Lage, die ArrayLists zu senden, aber ich bekomme eine Fehlermeldung, dass Troop nicht sterilisierbar ist, wenn es im Spiel läuft. Im Folgenden enthalten ich die Truppe Klasse, die beiden Klassen der Server- und Client-Klassen, die den Test zum Senden und Empfangen, und die Methode updateConnection() in der Klasse Spiel liefen:Problem mit Klasse nicht im Spiel Serilizable, aber funktioniert gut, wenn isoliert
public class Server{
private ObjectOutputStream output;
private ObjectInputStream input;
private ServerSocket server;
private Socket connection;
JTextArea t;
JFrame f;
//constructor
public Server(){
f = new JFrame();
f.getContentPane().setPreferredSize(new Dimension(300, 300));
f.pack();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocationRelativeTo(null);
t = new JTextArea();
f.add(t, BorderLayout.CENTER);
f.setVisible(true);
try{
server = new ServerSocket(8790, 10); //8798 is a dummy port for testing, this can be changed. The 100 is the maximum people waiting to connect.
try{
//Trying to connect and have conversation
waitForConnection();
setupStreams();
}catch(EOFException eofException){
//t.append("Connection was terminated");
}
} catch (IOException ioException){
ioException.printStackTrace();
}
}
//wait for connection, then display connection information
private void waitForConnection() throws IOException{
t.append(" Waiting for someone to connect...");
connection = server.accept();
t.append(" Now connected to " + connection.getInetAddress().getHostName());
}
//get stream to send and receive data
private void setupStreams() throws IOException{
output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream());
t.append(" Streams are now setup ");
f.setVisible(false);
f.dispose();
}
// input.readObject();
public void closeConnection(){
//t.append(" Closing Connections... ");
try{
output.close(); //Closes the output path to the client
input.close(); //Closes the input path to the server, from the client.
connection.close(); //Closes the connection between you can the client
}catch(IOException ioException){
ioException.printStackTrace();
}
}
public ObjectOutputStream getOutput(){
return output;
}
public ObjectInputStream getInput(){
return input;
}
public void sendObjects(Object obj){
try {
output.writeObject(obj);
output.flush();
output.reset();
} catch (IOException e) {
e.printStackTrace();
}
}
public Object receiveObjects(){
try{
return input.readObject();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
return null;
}
}
}
.
public class Client extends JFrame{
private static final long serialVersionUID = 1L;
private ObjectOutputStream output;
private ObjectInputStream input;
private String serverIP;
private Socket connection;
JTextArea t;
JFrame f;
//constructor
public Client(String host){
serverIP = host;
f = new JFrame();
f.getContentPane().setPreferredSize(new Dimension(300, 300));
f.pack();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocationRelativeTo(null);
t = new JTextArea();
f.add(t, BorderLayout.CENTER);
f.setVisible(true);
try{
connectToServer();
setupStreams();
}catch(EOFException eofException){
//t.append("Connection was terminated");
}catch(IOException ioException){
ioException.printStackTrace();
}
}
public Client(){
serverIP = "127.0.0.1";
f = new JFrame();
f.getContentPane().setPreferredSize(new Dimension(300, 300));
f.pack();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocationRelativeTo(null);
t = new JTextArea();
f.add(t, BorderLayout.CENTER);
f.setVisible(true);
try{
connectToServer();
setupStreams();
}catch(EOFException eofException){
//t.append("Connection was terminated");
}catch(IOException ioException){
ioException.printStackTrace();
}
}
//connect to server
private void connectToServer() throws IOException{
t.append("Attempting connection...");
connection = new Socket(InetAddress.getByName(serverIP), 8790);
t.append("Connection Established! Connected to: " + connection.getInetAddress().getHostName());
}
//set up streams
private void setupStreams() throws IOException{
output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream());
t.append(" The streams are now set up!");
f.setVisible(false);
f.dispose();
}
//Close connection
public void closeConnection(){
//t.append(" Closing the connection!");
try{
output.close();
input.close();
connection.close();
}catch(IOException ioException){
ioException.printStackTrace();
}
}
public ObjectOutputStream getOutput(){
return output;
}
public ObjectInputStream getInput(){
return input;
}
public void sendObjects(Object obj){
try {
output.writeObject(obj);
output.flush();
output.reset();
} catch (IOException e) {
e.printStackTrace();
}
}
public Object receiveObjects(){
try{
return input.readObject();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
return null;
}
}
}
.
public class Troop implements Serializable{
private int x;
private int y;
private int health;
private int movSpeed;
private int movSpeedx;
private int movSpeedy;
private int cost;
private long deployCoolDown;
private int level;
private transient BufferedImage image;
private int size = 16;
private Handler handler;
/**
*
* @param x
* @param y
* @param level
* @param health
* @param movSpeed
* @param movSpeedx
* @param movSpeedy
* @param cost
* @param deployCoolDown
* @param image
*
*/
public Troop(int x, int y, int level, int health, int movSpeed, int movSpeedx, int movSpeedy, int cost, long deployCoolDown, BufferedImage image, Handler handler){
this.x = x;
this.y = y;
this.level = level;
this.health = health;
this.movSpeed = movSpeed;
this.movSpeedx = -movSpeed;
this.movSpeedy = movSpeedy;
this.cost = cost;
this.deployCoolDown = deployCoolDown;
this.image = image;
this.handler = handler;
}
public void update(){
Move();
if(health <= 0){
handler.getTroops().remove(this);
}
}
public void checkX(){
int z = 0;
int tempMovSpeed = movSpeed;
if(tempMovSpeed> 0){ //moving down
int ty = (int) (y + tempMovSpeed + size + size/2)/Tile.TILE_WIDTH;
if(!collisionWithTile((int) (x)/Tile.TILE_HEIGHT,ty) &&
!collisionWithTile((int) (x + size)/Tile.TILE_HEIGHT,ty) &&
!collisionWithTile((int) (x + size/2)/Tile.TILE_HEIGHT,ty)){
z = 1;
}else{
//System.out.println("collision moving down");
}
}
tempMovSpeed = -movSpeed;
if(tempMovSpeed < 0){ // up
int ty = (int) (y + tempMovSpeed - size/2)/Tile.TILE_WIDTH;
if(!collisionWithTile((int) (x)/Tile.TILE_HEIGHT,ty) &&
!collisionWithTile((int) (x + size)/Tile.TILE_HEIGHT,ty) &&
!collisionWithTile((int) (x + size/2)/Tile.TILE_HEIGHT,ty)){
if(z == 1){
z = 3;
}
else{
z = 2;
}
}else{
//System.out.println("collision moving up");
}
}
//System.out.println(z);
if(z == 0){
//System.out.println("dead end?");
}
else if(z == 1){
movSpeedy = movSpeed;
}
else if(z == 2){
movSpeedy = -movSpeed;
}
else if(z == 3){
Random r = new Random();
int q = r.nextInt(2);
if(q == 0){
movSpeedy = movSpeed;
}
else{
movSpeedy = -movSpeed;
}
}
}
public void checkY(){
int z = 0;
int tempMovSpeed = movSpeed;
int tx = (int) (x + tempMovSpeed + size + size/2)/Tile.TILE_WIDTH;
if(!collisionWithTile(tx, (int) (y)/Tile.TILE_HEIGHT) &&
!collisionWithTile(tx, (int) (y + size)/Tile.TILE_HEIGHT) &&
!collisionWithTile(tx, (int) (y + size/2)/Tile.TILE_HEIGHT)){
z = 1;
}
tempMovSpeed = -movSpeed;
tx = (int) (x + tempMovSpeed - size/2)/Tile.TILE_WIDTH;
if(!collisionWithTile(tx, (int) (y)/Tile.TILE_HEIGHT) &&
!collisionWithTile(tx, (int) (y + size)/Tile.TILE_HEIGHT) &&
!collisionWithTile(tx, (int) (y + size/2)/Tile.TILE_HEIGHT)){
if(z != 1){
z = 2;
}
else{
z = 3;
}
}
if(z == 0){
//System.out.println("dead end");
}
else if(z == 1){
movSpeedx = movSpeed;
}
else if(z == 2){
movSpeedx = -movSpeed;
}
else{
Random r = new Random();
int q = r.nextInt(1);
if(q == 0){
movSpeedx = movSpeed;
}
else{
movSpeedx = -movSpeed;
}
}
}
protected boolean collisionWithTile(int x, int y){
return !handler.getWorlds().get(handler.getGame().getLevel()).getTile(x, y).isPath();
}
public void render(Graphics g){
g.setColor(Color.GREEN);
g.fillRect(x, y, size, size);
}
public void Move(){
if(movSpeedx > 0){ //moving right
int tx = (int) (x + movSpeedx + size + size/2)/Tile.TILE_WIDTH;
if(!collisionWithTile(tx, (int) (y)/Tile.TILE_HEIGHT) &&
!collisionWithTile(tx, (int) (y + size)/Tile.TILE_HEIGHT) &&
!collisionWithTile(tx, (int) (y + size/2)/Tile.TILE_HEIGHT)){
x += movSpeedx;
}else{
x = tx * Tile.TILE_WIDTH - 3 * size /2;
checkX();
movSpeedx = 0;
}
}
else if(movSpeedx < 0){ // left
int tx = (int) (x + movSpeedx - size/2)/Tile.TILE_WIDTH;
if(!collisionWithTile(tx, (int) (y)/Tile.TILE_HEIGHT) &&
!collisionWithTile(tx, (int) (y + size)/Tile.TILE_HEIGHT) &&
!collisionWithTile(tx, (int) (y + size/2)/Tile.TILE_HEIGHT)){
x += movSpeedx;
}else{
x = tx * Tile.TILE_WIDTH + Tile.TILE_WIDTH + size/2;
checkX();
movSpeedx = 0;
}
}
if(movSpeedy > 0){ //moving down
int ty = (int) (y + movSpeedy + size + size/2)/Tile.TILE_WIDTH;
if(!collisionWithTile((int) (x)/Tile.TILE_HEIGHT, ty) &&
!collisionWithTile((int) (x + size)/Tile.TILE_HEIGHT, ty) &&
!collisionWithTile((int) (x + size/2)/Tile.TILE_HEIGHT, ty)){
y += movSpeedy;
}else{
//System.out.println("collision");
y = ty * Tile.TILE_WIDTH - 3 * size /2;
movSpeedy = 0;
checkY();
}
}
else if(movSpeedy < 0){ // up
int ty = (int) (y + movSpeedy - size/2)/Tile.TILE_WIDTH;
if(!collisionWithTile((int) (x)/Tile.TILE_HEIGHT, ty) &&
!collisionWithTile((int) (x + size)/Tile.TILE_HEIGHT, ty) &&
!collisionWithTile((int) (x + size/2)/Tile.TILE_HEIGHT, ty)){
y += movSpeedy;
}else{
y = ty * Tile.TILE_WIDTH + Tile.TILE_WIDTH + size/2;
movSpeedy = 0;
checkY();
}
}
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getSize(){
return size;
}
public int getMovSpeed() {
return movSpeed;
}
public void setMovSpeed(int movSpeed) {
this.movSpeed = movSpeed;
}
public int getHealth() {
return health;
}
public void changeHealth(int health) {
this.health += health;
}
public int getCost() {
return cost;
}
public void setCost(int cost) {
this.cost = cost;
}
public long getDeployCoolDown() {
return deployCoolDown;
}
public void setDeployCoolDown(int deployCoolDown) {
this.deployCoolDown = deployCoolDown;
}
private void writeObject(ObjectOutputStream out)throws IOException{
out.defaultWriteObject();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{
in.defaultReadObject();
}
}
Das Verfahren von Game (das 60-mal pro Sekunde aufgerufen wird):
private void updateConnection(){
if(isClientActive()){
if(player.getType() == 0){
client.sendObjects(towers);
System.out.println("sent towers: " + towers.size());
}else{
client.sendObjects(troops);
System.out.println("sent troops: " + troops.size());
}
ArrayList<Object> obj = (ArrayList<Object>)client.receiveObjects();
System.out.println("obj: " +obj.size());
if(obj != null && obj.size() > 0){
if (obj.get(0) instanceof Troop) {
mendTroops(obj);
}else if(obj.get(0) instanceof Troop){
mendTowers(obj);
}
}
}else if(isServerActive()){
if(player.getType() == 0){
server.sendObjects(towers);
System.out.println("sent towers: " + towers.size());
}else{
server.sendObjects(troops);
System.out.println("sent troops: " + troops.size());
}
ArrayList<Object> obj = (ArrayList<Object>)server.receiveObjects();
System.out.println("obj: " +obj.size());
if(obj != null && obj.size() > 0){
if (obj.get(0) instanceof Troop) {
mendTroops(obj);
}else if(obj.get(0) instanceof Troop){
mendTowers(obj);
}
}
}
}
Hier sind die beiden wichtigsten Methoden, die ich den Server, Client zu testen, rufen, und Truppen Klassen:
Hierpublic static void main(String[] args){
Server s = new Server();
ArrayList<Troop> troopsArray = new ArrayList<Troop>();
troopsArray.add(new Goblin(1,1,1));
troopsArray.add(new Goblin(2,2,2));
s.sendObject(troopsArray);
}
public static void main(String[] args){
Client c = new Client();
while(true){
ArrayList<Troop> troop2 = (ArrayList<Troop>)c.receiveObjects();
JOptionPane.showMessageDialog(null, troop2.get(1).getX());
}
}
ist der angeforderte Code Handler:
public class Handler implements Serializable{
private Game game;
private transient Player player;
private transient ArrayList<Tower> towers;
private transient ArrayList<Troop> troops;
private transient Screen screen;
private transient Frame frame;
private transient Menu menu;
private ArrayList<Worlds> worlds;
public Handler(Game game, Player player, ArrayList<Tower> towers, ArrayList<Troop> troops, Screen screen, Frame frame, Menu menu, ArrayList<Worlds> worlds){
this.game = game;
this.player = player;
this.towers = towers;
this.troops = troops;
this.screen = screen;
this.frame = frame;
this.menu = menu;
this.worlds = worlds;
}
public Server getServer(){
return game.getServer();
}
public Client getClient(){
return game.getClient();
}
public ArrayList<Worlds> getWorlds() {
return worlds;
}
public Game getGame() {
return game;
}
public Player getPlayer() {
return player;
}
public ArrayList<Tower> getTowers() {
return towers;
}
public ArrayList<Troop> getTroops() {
return troops;
}
public Screen getScreen() {
return screen;
}
public Frame getFrame() {
return frame;
}
public Menu getMenu() {
return menu;
}
public boolean towerCollisionWithTile(int x, int y){
return worlds.get(game.getLevel()).getTile(x, y).isTowerNotPlaceable();
}
}
Weltklasse:
public class Worlds implements Serializable{
private int width = 40;
private int height = 20; //in tiles
private int spawnX, spawnY;
private int[][] tiles;
public Worlds(String path){
loadWorld(path);
}
public Tile getTile(int x, int y){
if(x < 0 || y < 0 || x >= width || y >= height)
return Tile.grassTile;
Tile t = Tile.tiles[tiles[x][y]];
if(t == null)
return Tile.grassTile;
return t;
}
public void render(Graphics g){
for(int y = 0; y < height; y++){
for(int x = 0; x < width; x++){
getTile(x, y).render(g, (int) (x * Tile.TILE_WIDTH),
(int) (y* Tile.TILE_HEIGHT));
}
}
}
private void loadWorld(String path){
String file = Utils.loadFileAsString(path);
String [] tokens = file.split("\\s");
tiles = new int[width][height];
for(int y = 0; y < height; y++){
for(int x = 0; x < width; x++){
tiles[x][y] = Utils.parseInt(tokens[(x + y * width)]);
}
}
}
}
Sorry, wenn ich zu viel Code geschrieben, aber ich würde lieber ein wenig zu viel, als nicht genug haben. Wenn es erforderlich ist, kann ich den Inhalt der Konsole für die Fehler veröffentlichen. Ich schätze die Hilfe.
Ich bin nicht sicher, was "Handler" ist, aber sind Sie sicher, dass serialisieren-fähig ist und seine Eigenschaften? Wenn ein Objekt serialisiert wird, muss es zusammen mit einer seiner Eigenschaften serialisiert werden können. – CConard96
Das könnte das Problem sein, ich werde versuchen, das alles jetzt zu beheben. – Dak31
Ich ging und machte alle Klassen implementieren serializable, aber ohne Erfolg – Dak31