因此,我在Java中有一个大学项目,正在制作一个应该在服务器上运行的轰炸机游戏。我遇到了问题,因为某些计时器正在创建新线程,这些线程在尝试发送对象Map时会更改对象Map。
我试图在计时器和输出流的代码块上使用syncnize(Map),但是没有用
我还有一个问题,我想将我的类Image_library保留为临时类,因为它不需要通过流发送,但是当我在其中将ArrayLists标记为此类时,它们只是被视为null。 / p>
以下是一些代码:
public class GameHandler extends Thread{
private ArrayList<Client> Players = new ArrayList<Client>();
private ArrayList<Bomber> Characters = new ArrayList<Bomber>();
public GameLogic L;
transient private Image_library lib;
private Map m;
private ArrayList<Integer> actions = new ArrayList<Integer>();
GameHandler(Client x1,Client x2) {
x1.AddToGame(this);
x2.AddToGame(this);
Players.add(x1);
Players.add(x2);
}
@Override
public void run() {
boolean init=true;
for(int i=0;i<Players.size();i++) {
Create_New_Socket(Players.get(i));
}
Timer tt = new Timer();
tt.schedule(new Player_Info_Querry(),200);
while(true) {
if(!init){
}
else {
int i;
for(i=0;i<Players.size();i++)
if(Players.get(i).GetBomber()==null)
break;
if(i==Players.size()) {
init=false;
tt.cancel();
try {
init_game();
for(i=0;i<Players.size();i++) {
Players.get(i).dos.writeUTF("game_start");
}
Timer tt2 = new Timer();
tt2.schedule(new Update_Task(),100);
} catch (SlickException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
private class Player_Info_Querry extends TimerTask{
@Override
public void run() {
for(int i=0;i<Players.size();i++) {
if(Players.get(i).GetBomber()!=null)
continue;
try {
Players.get(i).Request_Client_Player();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
private class Update_Task extends TimerTask{
@Override
public void run() {
// TODO Auto-generated method stub
try {
while(actions.size()!=0) {
L.action(actions.get(0));
actions.remove(0);
}
lib.Run_Changes();
} catch (SlickException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
for(int i=0;i<Players.size();i++)
try {
Players.get(i).Send_Map(m);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Timer tt2 = new Timer();
tt2.schedule(new Update_Task(),100);
}
}
private void Create_New_Socket(Client x){
try {
x.objectsocket = new Socket(x.datasocket.getInetaddress(),x.outputsocket);
System.out.println("SOCKET CREATED " + x.objectsocket);
x.oos = new ObjectOutputStream(x.objectsocket.getOutputStream());
x.ois = new ObjectInputStream(x.objectsocket.getInputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// obtaining input and out streams
}
private void init_game() throws SlickException {
lib = new Image_library();
Layout_Logic map_gen = new Layout_Logic(lib);
m = map_gen.Generate_Standard_Map();
L=new GameLogic(lib,m);
Characters = new ArrayList<Bomber>();
for(int i=0;i<Players.size();i++){
Characters.add(Players.get(i).GetBomber());
}
L.Place_Characters(Characters);
}
public void Buffer_Input(int key){
actions.add(key);
}
}
package GameLogic;
import java.io.Serializable;
import java.util.ArrayList;
import org.newdawn.slick.SlickException;
public class Image_library implements Serializable{
/**
*
*/
private static final long serialVersionUID = -8459759623730666317L;
private ArrayList<Element> flagged = new ArrayList<Element>();
private ArrayList<String> flagged_images = new ArrayList<String>();
public Map m;
public void flag_For_Change(Element x,String img){
flagged.add(x);
flagged_images.add(img);
}
public void Run_Changes() throws SlickException {
while(flagged.size()!=0 && flagged_images.size()!=0) {
flagged.get(0).Set_Image(flagged_images.get(0));
flagged.remove(0);
flagged_images.remove(0);
}
}
}
package GameLogic;
import org.newdawn.slick.SlickException;
import java.util.Timer;
import java.util.TimerTask;
public class Bomber extends Element{
/**
*
*/
private static final long serialVersionUID = -9085303141098935687L;
transient protected boolean bomb_cd;
transient protected boolean Walking_cd;
static private int cooldown = 500; //milliseconds
static private int bomb_cooldown=1000;
static protected int move_res = 5;
protected int progression_count=move_res;
protected int direction; //0-down 1-left 2-up 3-right
static protected String StopDown="StopDown";
static protected String Down1="Down1";
static protected String Down2="Down2";
static protected String StopUp="StopUp";
static protected String Up1="Up1";
static protected String Up2="Up2";
static protected String StopLeft="StopLeft";
static protected String Left1="Left1";
static protected String Left2="Left2";
static protected String StopRight="StopRight";
static protected String Right1="Right1";
static protected String Right2="Right2";
protected int upkey,downkey,rightkey,leftkey,actionkey;
private int player;
public Bomber(int x,int y,Image_library lib,Map m,int c1,int c2,int k1,int k2,int k3,int k4,int k5,int p) throws SlickException{
Coordinate tmp = new Coordinate(x,y);
Coord=tmp;
Solid=true;
this.lib=lib;
this.m=m;
img=StopDown;
upkey=k1;
downkey=k2;
leftkey=k3;
rightkey=k4;
actionkey=k5;
player=p;
img = StopDown;
bomb_cd=false;
Walking_cd=false;
//direction=0;
GUI_Scale=64;
}
public void MoveUp() {
Coord.MoveUp();
direction=2;
Start_Walking();
}
public void MoveRight() {
Coord.MoveRight();
direction=3;
Start_Walking();
}
public void MoveLeft() {
Coord.MoveLeft();
direction=1;
Start_Walking();
}
public void MoveDown() {
Coord.MoveDown();
direction=0;
Start_Walking();
}
private void Start_Walking(){
Walking_cd=true;
Timer tt = new Timer();
tt.schedule(new Walking(this),cooldown/move_res);
progression_count=0;
}
public void Used_Bomb(){
bomb_cd=true;
Timer tt = new Timer();
tt.schedule(new Bomb_Cd(),bomb_cooldown);
}
public boolean Can_Use_Bomb(){
return !bomb_cd;
}
public boolean Can_Walk() {
return !Walking_cd;
}
public boolean Death_Check(){
return m.Has_Explosion(Coord.getX(),Coord.getY());
}
private class Bomb_Cd extends TimerTask{
public void run(){
synchronized(m) {
bomb_cd=false;
}
}
}
private class Walking extends TimerTask{
transient private boolean feet=false;
private Bomber person;
Walking (Bomber person){
this.person=person;
bomb_cd=true;
}
public void run(){
progression_count++;
if(feet) {
if(direction==0)
lib.flag_For_Change(person,Down1);
if(direction==1)
lib.flag_For_Change(person,Left1);
if(direction==2)
lib.flag_For_Change(person,Up1);
if(direction==3)
lib.flag_For_Change(person,Right1);
}
else {
if(direction==0)
lib.flag_For_Change(person,Down2);
if(direction==1)
lib.flag_For_Change(person,Left2);
if(direction==2)
lib.flag_For_Change(person,Up2);
if(direction==3)
lib.flag_For_Change(person,Right2);
}
feet=!feet;
if(progression_count==move_res){
Walking_cd=false;
if(direction==0)
lib.flag_For_Change(person,StopDown);
if(direction==1)
lib.flag_For_Change(person,StopLeft);
if(direction==2)
lib.flag_For_Change(person,StopUp);
if(direction==3)
lib.flag_For_Change(person,StopRight);
bomb_cd=false;
this.cancel();
}
}
}
}