byte包
Calss Byte
1 package Byte; 2 import java.io.*; 3 public class Byte implements Serializable{ 4 public static byte[] int2Byte(int []intValue){ 5 int length=intValue.length; 6 byte[] b=new byte[length*4]; 7 for(int i=0;i<length;i++){ 8 for(int j=0;j<4;j++){ 9 b[i*4+j]=(byte)(intValue[i]>>8*(3-j) & 0xFF); 10 } 11 } 12 return b; 13 } 14 public static int[] byte2Int(byte[] b){ 15 int len=b.length/4; 16 int []intValue=new int[len]; 17 for(int j=0;j<len;j++){ 18 for(int i=0;i<4;i++){ 19 intValue[j] +=(b[j*4+i] & 0xFF)<<(8*(3-i)); 20 } 21 } 22 return intValue; 23 } 24 public static Object ByteToObject(byte[] bytes){ 25 Object obj = null; 26 try { 27 ByteArrayInputStream bi = new ByteArrayInputStream(bytes); 28 ObjectInputStream oi = new ObjectInputStream(bi); 29 30 obj = (Object) oi.readObject(); 31 32 bi.close(); 33 oi.close(); 34 } 35 catch(Exception e) { 36 e.printStackTrace(); 37 } 38 return obj; 39 } 40 public static byte[] ObjectToByte(Object obj) 41 { 42 byte[] bytes=null; 43 try { 44 //object to bytearray 45 ByteArrayOutputStream bo = new ByteArrayOutputStream(); 46 ObjectOutputStream oo = new ObjectOutputStream(bo); 47 oo.writeObject(obj); 48 bytes = bo.toByteArray(); 49 bo.close(); 50 oo.close(); 51 } 52 catch(Exception e) { 53 e.printStackTrace(); 54 } 55 return(bytes); 56 } 57 }
Client 包
class Window
1 package Client; 2 import javax.swing.*; 3 import java.awt.*; 4 import java.awt.event.*; 5 import java.io.DataInputStream; 6 import java.io.DataOutputStream; 7 import java.io.IOException; 8 import java.net.DatagramPacket; 9 import java.net.InetAddress; 10 import java.net.InetSocketAddress; 11 import java.net.MulticastSocket; 12 import java.net.Socket; 13 14 import Byte.Byte; 15 /** 16 * @author 荣钦 17 * 18 */ 19 public class Window extends JFrame implements KeyListener, Runnable { 20 /** 21 * 22 */ 23 private static final long serialVersionUID = -7379543475187728667L; 24 private Container cn; 25 private JLabel sc,bestsc; 26 mainFrame mainframe; 27 JLabel statue = new JLabel(); 28 JButton [][]piece = new JButton[4][4]; 29 // String InetAddr = "192.168.0.101"; 30 String InetAddr = "127.0.0.1"; 31 // String InetAddr = "10.22.149.112"; 32 Socket socket=null; 33 DataInputStream in=null; 34 DataOutputStream out=null; 35 int port=5858; //组播的端口 36 InetAddress group=null; //组播组的地址 37 MulticastSocket Msocket=null; //多点广播套接字 38 Thread Receive; 39 Window(){ 40 int length=376,width=679; 41 double dw=360/9; 42 /* 43 * 9:16 44 * 1:4:4:4:4:1 45 * 7:8:1 46 */ 47 this.setSize(length, width); 48 this.setLocationRelativeTo(null); //让窗体居中显示 49 this.setLayout(null); 50 addKeyListener(this); 51 cn=getContentPane(); 52 53 statue.setBounds((int)(dw*4),(int)(dw*10),(int)(dw*3),+(int)dw); 54 cn.add(statue); 55 sc = new JLabel(); 56 bestsc = new JLabel(); 57 bestsc.setBounds((int)(6*dw), (int)dw,(int)(4*dw),(int)(1*dw)); 58 cn.add(bestsc); 59 sc.setBounds((int)(6*dw), (int)(2*dw),(int)(4*dw),(int)(1*dw)); 60 cn.add(sc); 61 mainframe = new mainFrame(); 62 mainframe.setBackground(new Color(153,204,255)); 63 mainframe.setBounds((int)(dw/2), (int)(15*dw/2),(int)(8*dw),(int)(8*dw)); 64 cn.add(mainframe); 65 this.validate(); 66 init(); 67 this.setVisible(true); 68 this.requestFocus();//添加button 后Frame 失去焦点 69 int i,j; 70 for(i=0;i<4;i++){ 71 for(j=0;j<4;j++){ 72 piece[i][j] = new JButton(); 73 piece[i][j].setSize(70,70); 74 piece[i][j].setEnabled(false); 75 piece[i][j].setLocation(5,5); 76 } 77 } 78 mainframe.show(piece); 79 Receive=new Thread(this); 80 socket=new Socket(); 81 try { 82 if(socket.isConnected()){} //请求和服务器建立套接字连接: 83 else{ 84 InetAddress address=InetAddress.getByName(InetAddr); 85 InetSocketAddress socketAddress=new InetSocketAddress(address,4331); 86 socket.connect(socketAddress); 87 in =new DataInputStream(socket.getInputStream()); 88 out = new DataOutputStream(socket.getOutputStream()); 89 System.out.println("identity:"+in.read()); 90 if(!(Receive.isAlive())) 91 Receive=new Thread(this); 92 Receive.start(); 93 } 94 group=InetAddress.getByName("239.255.8.0");//设置广播组的地址为239.255.8.0 95 Msocket=new MulticastSocket(port); //多点广播套接字将在port端口广播 96 Msocket.joinGroup(group); //加入group 97 } 98 catch (IOException ee) { 99 System.out.println(ee); 100 socket=new Socket(); 101 } 102 103 } 104 /* 105 * 初始化 106 */ 107 void init(){ 108 statue.setText(""); 109 statue.setVisible(false); 110 this.requestFocus();//添加button 后Frame 失去焦点 111 } 112 113 114 /* 115 * 按键事件 116 * (non-Javadoc) 117 * @see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent) 118 */ 119 public void keyTyped(KeyEvent arg0) { 120 } 121 public void keyReleased(KeyEvent arg0) { 122 } 123 public void keyPressed(KeyEvent arg0) { 124 125 switch(arg0.getKeyCode()){ 126 case KeyEvent.VK_LEFT: 127 case KeyEvent.VK_A:{ 128 slip(0); 129 break; 130 } 131 case KeyEvent.VK_RIGHT: 132 case KeyEvent.VK_D:{ 133 slip(1); 134 break; 135 } 136 case KeyEvent.VK_UP: 137 case KeyEvent.VK_W:{ 138 slip(2); 139 break; 140 } 141 case KeyEvent.VK_DOWN: 142 case KeyEvent.VK_S:{ 143 slip(3); 144 break; 145 } 146 } 147 } 148 void slip(int control){ 149 try { 150 out.write(control); 151 } catch (IOException e) { 152 e.printStackTrace(); 153 } 154 } 155 public void run() { 156 int[] pieces = null; 157 int i,j; 158 while(true) { 159 byte data[]=new byte[80]; 160 DatagramPacket packet=null; 161 packet=new DatagramPacket(data,data.length,group,port); //待接收的数据包,即数据存于字节数组data中) 162 try { Msocket.receive(packet); 163 data=packet.getData(); 164 } 165 catch(Exception e) {} 166 pieces = Byte.byte2Int(data); 167 for(i=0;i<4;i++) 168 for(j=0;j<4;j++){ 169 pieceSet(piece[i][j],pieces[3+i*4+j]); 170 } 171 mainframe.show(piece); 172 if(pieces[0]==-1){ 173 statue.setText("Game Over"); 174 statue.setVisible(true); 175 } 176 else if(pieces[0]==1){ 177 statue.setText("Win"); 178 statue.setVisible(true); 179 } 180 else { 181 statue.setVisible(false); 182 } 183 sc.setFont(new Font("Arial",Font.BOLD,15)); 184 sc.setText("Score:"+pieces[1]); 185 bestsc.setText("Best:"+pieces[2]); 186 bestsc.setFont(new Font("Arial",Font.BOLD,15)); 187 } 188 } 189 void pieceSet(JButton p,int level){ 190 int value=1; 191 int colorValue=256/10*(10-level); 192 p.setBackground(new Color(255,colorValue,colorValue)); 193 if (level==0){ 194 p.setText(""); 195 return; 196 } 197 int i; 198 for(i=0;i<level;i++){ 199 value=value*2; 200 } 201 p.setFont(new Font("Arial",Font.BOLD,20)); 202 p.setText(""+value); 203 } 204 public static void main(String args[]){ 205 new Window(); 206 } 207 }
Server 包
class Server
1 package Server; 2 import java.awt.event.ActionEvent; 3 import java.awt.event.ActionListener; 4 import java.io.DataInputStream; 5 import java.io.DataOutputStream; 6 import java.io.IOException; 7 import java.net.DatagramPacket; 8 import java.net.InetAddress; 9 import java.net.MulticastSocket; 10 import java.net.ServerSocket; 11 import java.net.Socket; 12 13 import javax.swing.SwingUtilities; 14 import javax.swing.Timer; 15 16 import Byte.Byte; 17 18 public class Server implements ActionListener, Runnable{ 19 private int [][]piece; 20 private int score; 21 private int bestscore; 22 private int statue; 23 private int[] controls; 24 Timer time; 25 Thread client; 26 27 int port=5858; 28 InetAddress group=null; //组播组的地址 29 MulticastSocket Msocket=null; //多点广播套接字 30 public Server(){ 31 client = new Thread(this); 32 time = new Timer(500,this); 33 init(); 34 client.start(); 35 } 36 public static void main(String args[]){ 37 new Server(); 38 } 39 public void init(){ 40 piece = new int[4][4]; 41 for(int i=0;i<4;i++) 42 for(int j=0;j<4;j++){ 43 piece[i][j]=0; 44 } 45 controls = new int[4]; 46 for(int i=0;i<4;i++) 47 controls[i]=0; 48 score=0; 49 statue=0; 50 addNewPiece(); 51 addNewPiece(); 52 SwingUtilities.invokeLater( 53 new Runnable(){//实例化更新组件的线程 unnable run 54 public void run() { 55 broadcast(); 56 } 57 } 58 ); 59 60 time.start(); 61 } 62 @Override 63 public void actionPerformed(ActionEvent arg0) { 64 int control = handle(-1); 65 if(control!=-1){ 66 Run2048(control); 67 SwingUtilities.invokeLater( 68 new Runnable(){//实例化更新组件的线程 unnable run 69 public void run() { 70 addNewPiece(); 71 } 72 } 73 ); 74 } 75 SwingUtilities.invokeLater( 76 new Runnable(){//实例化更新组件的线程 unnable run 77 public void run() { 78 broadcast(); 79 } 80 } 81 ); 82 } 83 void Run2048(int mindex){ 84 switch(mindex){ 85 case 0:{ 86 SwingUtilities.invokeLater( 87 new Runnable(){//实例化更新组件的线程 unnable run 88 public void run() { 89 leftgo(0); 90 } 91 } 92 ); 93 SwingUtilities.invokeLater( 94 new Runnable(){//实例化更新组件的线程 unnable run 95 public void run() { 96 leftgo(1); 97 } 98 } 99 ); 100 SwingUtilities.invokeLater( 101 new Runnable(){//实例化更新组件的线程 unnable run 102 public void run() { 103 leftgo(2); 104 } 105 } 106 ); 107 SwingUtilities.invokeLater( 108 new Runnable(){//实例化更新组件的线程 unnable run 109 public void run() { 110 leftgo(3); 111 } 112 } 113 ); 114 break; 115 } 116 case 1:{ 117 SwingUtilities.invokeLater( 118 new Runnable(){//实例化更新组件的线程 unnable run 119 public void run() { 120 rihetgo(0); 121 } 122 } 123 ); 124 SwingUtilities.invokeLater( 125 new Runnable(){//实例化更新组件的线程 unnable run 126 public void run() { 127 rihetgo(1); 128 } 129 } 130 ); 131 SwingUtilities.invokeLater( 132 new Runnable(){//实例化更新组件的线程 unnable run 133 public void run() { 134 rihetgo(2); 135 } 136 } 137 ); 138 SwingUtilities.invokeLater( 139 new Runnable(){//实例化更新组件的线程 unnable run 140 public void run() { 141 rihetgo(3); 142 } 143 } 144 ); 145 break; 146 } 147 case 2:{ 148 SwingUtilities.invokeLater( 149 new Runnable(){//实例化更新组件的线程 unnable run 150 public void run() { 151 upgo(0); 152 } 153 } 154 ); 155 SwingUtilities.invokeLater( 156 new Runnable(){//实例化更新组件的线程 unnable run 157 public void run() { 158 upgo(1); 159 } 160 } 161 ); 162 SwingUtilities.invokeLater( 163 new Runnable(){//实例化更新组件的线程 unnable run 164 public void run() { 165 upgo(2); 166 } 167 } 168 ); 169 SwingUtilities.invokeLater( 170 new Runnable(){//实例化更新组件的线程 unnable run 171 public void run() { 172 upgo(3); 173 } 174 } 175 ); 176 break; 177 } 178 case 3:{ 179 SwingUtilities.invokeLater( 180 new Runnable(){//实例化更新组件的线程 unnable run 181 public void run() { 182 downgo(0); 183 } 184 } 185 ); 186 SwingUtilities.invokeLater( 187 new Runnable(){//实例化更新组件的线程 unnable run 188 public void run() { 189 downgo(1); 190 } 191 } 192 ); 193 SwingUtilities.invokeLater( 194 new Runnable(){//实例化更新组件的线程 unnable run 195 public void run() { 196 downgo(2); 197 } 198 } 199 ); 200 SwingUtilities.invokeLater( 201 new Runnable(){//实例化更新组件的线程 unnable run 202 public void run() { 203 downgo(3); 204 } 205 } 206 ); 207 break; 208 } 209 } 210 } 211 void leftgo(int i){ 212 int k;//当前的下标 213 int p;//遍历用 214 int q=i;//第几条 215 int m;//末端的下标 216 int n;//消除位置 217 k=0; 218 m=3; 219 n=k; 220 while(k<=m){ 221 while(piece[q][k]==0){ 222 for(p=k;p<m;p++) 223 piece[q][p]=piece[q][p+1]; 224 piece[q][m]=0; 225 m--; 226 if(m<k) 227 return; 228 } 229 230 if(k>n){ 231 if(piece[q][k]==piece[q][k-1]){ 232 setCreateScore(++piece[q][k-1]); 233 piece[q][k]=0; 234 n=k; 235 k--; 236 } 237 } 238 k++; 239 } 240 } 241 void rihetgo(int i){ 242 int k;//当前的下标 243 int p;//遍历用 244 int q=i;//第几条 245 int m;//末端的下标 246 int n;//消除位置 247 k=3; 248 m=0; 249 n=k; 250 while(k>=m){ 251 while(piece[q][k]==0){ 252 for(p=k;p>0;p--) 253 piece[q][p]=piece[q][p-1]; 254 piece[q][m]=0; 255 m++; 256 if(m>k) 257 return; 258 } 259 if(k<n){ 260 if(piece[q][k]==piece[q][k+1]){ 261 setCreateScore(++piece[q][k+1]); 262 piece[q][k]=0; 263 n=k; 264 k++; 265 } 266 } 267 k--; 268 } 269 } 270 void upgo(int i){ 271 int k;//当前的下标 272 int p;//遍历用 273 int q=i;//第几条 274 int m;//末端的下标 275 int n;//消除位置 276 k=0; 277 m=3; 278 n=k; 279 while(k<=m){ 280 while(piece[k][q]==0){ 281 for(p=k;p<m;p++) 282 piece[p][q]=piece[p+1][q]; 283 piece[m][q]=0; 284 m--; 285 if(m<k) 286 return; 287 } 288 if(k>n){ 289 if(piece[k][q]==piece[k-1][q]){ 290 setCreateScore(++piece[k-1][q]); 291 piece[k][q]=0; 292 n=k; 293 k--; 294 } 295 } 296 k++; 297 } 298 } 299 void downgo(int i){ 300 int k;//当前的下标 301 int p;//遍历用 302 int q=i;//第几条 303 int m;//末端的下标 304 int n;//消除位置 305 k=3; 306 m=0; 307 n=k; 308 while(k>=m){ 309 while(piece[k][q]==0){ 310 for(p=k;p>0;p--) 311 piece[p][q]=piece[p-1][q]; 312 piece[m][q]=0; 313 m++; 314 if(m>k) 315 return; 316 } 317 if(k<n){ 318 if(piece[k][q]==piece[k+1][q]){ 319 setCreateScore(++piece[k+1][q]); 320 piece[k][q]=0; 321 n=k; 322 k++; 323 } 324 } 325 k--; 326 } 327 } 328 synchronized void setCreateScore(int level){ 329 int i; 330 int levelValue=1; 331 for(i=0;i<level;i++) 332 levelValue=levelValue*2; 333 score+=levelValue; 334 if(levelValue>1023){ 335 statue=1; 336 } 337 if(score>bestscore) 338 bestscore=score; 339 } 340 void addNewPiece(){ 341 int p; 342 for(p=0;p<16;p++){ 343 if(piece[p/4][p%4]==0){ 344 while(true){ 345 int i=(int)(Math.random()*4); 346 int j=(int)(Math.random()*4); 347 if(piece[i][j]==0){ 348 piece[i][j]++; 349 return; 350 } 351 } 352 } 353 } 354 statue=-1; 355 } 356 /* 357 * (non-Javadoc) 358 * @see java.lang.Runnable#run() 359 * 监听连接客户端 360 */ 361 @Override 362 public void run() { 363 ServerSocket server=null; 364 Socket socket=null; 365 while(true) { 366 try{ 367 server=new ServerSocket(4331); 368 } 369 catch(IOException e1) { 370 System.out.println("正在监听"); //ServerSocket对象不能重复创建 371 } 372 try{ 373 System.out.println(" 等待客户呼叫"); 374 socket=server.accept(); 375 System.out.println("客户的地址:"+socket.getInetAddress()); 376 } 377 catch (IOException e) { 378 System.out.println("正在等待客户"); 379 } 380 if(socket!=null) { 381 if(ServerThread.clientnum<ServerThread.maxclientnum) 382 new ServerThread(socket,this).start(); //为每个客户启动一个专门的线程 383 else System.out.println("超出最大客户端数量"); 384 } 385 } 386 } 387 /* 388 * 数据广播 389 */ 390 void broadcast(){ 391 try { 392 group=InetAddress.getByName("239.255.8.0");//设置广播组的地址为 393 Msocket=new MulticastSocket(port); //多点广播套接字将在port端口广播 394 Msocket.setTimeToLive(1); //多点广播套接字发送数据报范围为本地网络 395 Msocket.joinGroup(group); //加入group后,socket发送的数据报被group中的成员接收到 396 } catch (Exception e) { 397 } 398 DatagramPacket packet=null; //待广播的数据包 399 int []dataInt = new int[20]; 400 dataInt[0]=statue; 401 dataInt[1]=score; 402 dataInt[2]=bestscore; 403 int i,j; 404 for(i=0;i<4;i++){ 405 for(j=0;j<4;j++){ 406 dataInt[3+i*4+j]=piece[i][j]; 407 } 408 } 409 byte []data = Byte.int2Byte(dataInt); 410 packet=new DatagramPacket(data,data.length,group,port); 411 try { 412 Msocket.send(packet); 413 } catch (IOException e) { 414 e.printStackTrace(); 415 } 416 if(statue!=0){ 417 time.stop(); 418 try { 419 new Thread().sleep(2*1000); 420 } catch (InterruptedException e) { 421 // TODO Auto-generated catch block 422 e.printStackTrace(); 423 } 424 init(); 425 time.start(); 426 } 427 } 428 /* 429 * 数据处理 430 */ 431 public synchronized int handle(int control){ 432 switch (control){ 433 case -1: 434 int i,mindex=0; 435 for(i=0;i<4;i++) 436 if(controls[mindex]<controls[i]) 437 mindex=i; 438 if(controls[mindex]==0) 439 mindex =-1; 440 for(i=0;i<4;i++) 441 controls[i]=0; 442 return mindex; 443 default: 444 controls[control]++; 445 return -1; 446 } 447 } 448 } 449 class ServerThread extends Thread{ 450 Server server; 451 Socket socket; 452 DataOutputStream out=null; 453 DataInputStream in=null; 454 /* 455 * 客户端信息 456 */ 457 int identity=0; 458 static int clientnum=0; 459 final static int maxclientnum=10; 460 private static int clientn=0;//用来设置id 461 462 public ServerThread(Socket socket,Server server) { 463 this.socket=socket; 464 this.server=server; 465 try { 466 out=new DataOutputStream(socket.getOutputStream()); 467 in=new DataInputStream(socket.getInputStream()); 468 } 469 catch (IOException e){} 470 try { 471 out.write(identity); 472 } catch (IOException e) { 473 e.printStackTrace(); 474 } 475 catch(Exception e) { 476 System.out.println("Error: "+ e); 477 } 478 /* 479 * 给每一个客户端分配ID 480 * 统计当前已经连接的客户端数量 481 */ 482 clientn++; 483 identity=clientn; 484 clientnum++; 485 System.out.println("新连接客户端:客户端"+identity); 486 } 487 /* 488 * (non-Javadoc) 489 * @see java.lang.Thread#run() 490 * 接受数据 491 */ 492 public void run(){ 493 while(true) { 494 try{ 495 int r=in.read(); //堵塞状态,除非读取到信息 496 // 统计数据 497 server.handle(r); 498 } 499 catch (IOException e) { 500 clientnum--; 501 System.out.println("客户离开"); 502 return; 503 } 504 } 505 } 506 }