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 }
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 }