当前位置:   article > 正文

使用Android完成案例教学

使用Android完成案例教学

目录

题目:完成在Android平台下2个玩家分别利用2个手机连接在同一局域网下通过滑动摇杆分别使红飞机和黄飞机移动的开发。(全代码解析)


题目:完成在Android平台下2个玩家分别利用2个手机连接在同一局域网下通过滑动摇杆分别使红飞机和黄飞机移动的开发。(全代码解析)

用一个真机运行,连接此电脑 的模拟机进行利用2个手机连接在同一局域网下通过滑动摇杆分别使红飞机和黄飞机移动的开发

运行结果: 

模拟机:

真机:

DrawThread.java代码:
  1. package com.example.client.thread;
  2. import com.example.clinet.view.GameView;
  3. import android.annotation.SuppressLint;
  4. import android.graphics.Canvas;
  5. import android.view.SurfaceHolder;
  6. public class DrawThread extends Thread
  7. {
  8. private int SLEEP_SPAN =50;//睡眠的毫秒数
  9. private SurfaceHolder surfaceHolder;
  10. private GameView view;
  11. private boolean flag = true;
  12. public DrawThread(SurfaceHolder surfaceHolder, GameView view) {//构造器
  13. this.surfaceHolder = surfaceHolder;
  14. this.view = view;
  15. }
  16. public void setFlag(boolean flag) {//设置循环标记位
  17. this.flag = flag;
  18. }
  19. @SuppressLint("WrongCall")
  20. public void run()
  21. {
  22. Canvas c;
  23. while(flag)
  24. {
  25. c = null;
  26. try
  27. {// 锁定整个画布,在内存要求比较高的情况下,建议参数不要为null
  28. c = this.surfaceHolder.lockCanvas(null);
  29. synchronized (this.surfaceHolder)
  30. {
  31. this.view.onDraw(c);
  32. }
  33. } finally
  34. {
  35. if (c != null)
  36. {
  37. //更新屏幕显示内容
  38. this.surfaceHolder.unlockCanvasAndPost(c);
  39. }
  40. }
  41. try
  42. {
  43. Thread.sleep(SLEEP_SPAN);//睡眠指定毫秒数
  44. }
  45. catch(Exception e)
  46. {
  47. e.printStackTrace();
  48. }
  49. }
  50. }
  51. }

KeyThread.java代码:
  1. package com.example.client.thread;
  2. import com.example.client.MainActivity;
  3. import com.example.util.GameData;
  4. public class KeyThread extends Thread
  5. {
  6. int SPAN_SLEEP=10;
  7. MainActivity father;
  8. boolean flag=true;
  9. public KeyThread(MainActivity father)
  10. {
  11. this.father=father;
  12. }
  13. public void run()
  14. {
  15. while(flag)
  16. {
  17. try
  18. {
  19. if(GameData.state==2)
  20. {
  21. father.nt.dout.writeUTF("<#KEY#>"+father.KeyDispX+"|"+father.KeyDispY);
  22. }
  23. Thread.sleep(SPAN_SLEEP);
  24. }
  25. catch(Exception e)
  26. {
  27. e.printStackTrace();
  28. }
  29. }
  30. }
  31. }
更改自己电脑上的IP地址,win+R输入cmd,然后输入ipconfig命令获取此电脑的IP地址,NetworkThread.java代码如下:
  1. package com.example.client.thread;
  2. import android.util.Log;
  3. import java.io.DataInputStream;
  4. import java.io.DataOutputStream;
  5. import java.net.Socket;
  6. import com.example.client.MainActivity;
  7. import com.example.util.GameData;
  8. public class NetworkThread extends Thread{
  9. MainActivity activity;
  10. Socket sc;
  11. DataInputStream din;
  12. DataOutputStream dout;
  13. public boolean flag=true;
  14. public NetworkThread(MainActivity activity)
  15. {
  16. this.activity=activity;
  17. }
  18. public void run()
  19. {
  20. try
  21. {//与服务端建立连接 ,参数分别是要连接的服务端IP地址和要连接的服务端对应的监听端口
  22. Log.i("测试", "run: 开始连接");
  23. sc=new Socket("192.168.43.252",9999);
  24. din=new DataInputStream(sc.getInputStream());
  25. dout=new DataOutputStream(sc.getOutputStream());
  26. dout.writeUTF("<#CONNECT#>");
  27. Log.i("测试", "run: 完成连接");
  28. }
  29. catch(Exception e)
  30. {
  31. Log.e("测试", "run: 执行失败",e );
  32. e.printStackTrace();
  33. return;
  34. }
  35. while(flag)
  36. {
  37. try
  38. {
  39. String msg=din.readUTF();
  40. if(msg.startsWith("<#OK#>"))
  41. {
  42. System.out.println("Connect ok...");
  43. GameData.state=1;
  44. }
  45. else if(msg.startsWith("<#BEGIN#>"))
  46. {
  47. GameData.state=2;
  48. this.activity.kt.start();
  49. }
  50. else if(msg.startsWith("<#FULL#>"))
  51. {
  52. System.out.println("Full...");
  53. break;
  54. }
  55. else if(msg.startsWith("<#GAME_DATA#>"))
  56. {
  57. String nr=msg.substring(13);
  58. String[] strA=nr.split("\\|");
  59. int temprx=Integer.parseInt(strA[0]);
  60. int tempry=Integer.parseInt(strA[1]);
  61. int tempgx=Integer.parseInt(strA[2]);
  62. int tempgy=Integer.parseInt(strA[3]);
  63. synchronized(this.activity.gd.lock)
  64. {
  65. this.activity.gd.rx=temprx;
  66. this.activity.gd.ry=tempry;
  67. this.activity.gd.gx=tempgx;
  68. this.activity.gd.gy=tempgy;
  69. }
  70. }
  71. }catch(Exception e)
  72. {
  73. e.printStackTrace();
  74. }
  75. }
  76. try
  77. {
  78. din.close();
  79. dout.close();
  80. sc.close();
  81. }catch(Exception e)
  82. {
  83. e.printStackTrace();
  84. }
  85. }
  86. }

MainActivity.Java代码:
  1. package com.example.client;
  2. import com.example.client.thread.KeyThread;
  3. import com.example.client.thread.NetworkThread;
  4. import com.example.clinet.view.GameView;
  5. import com.example.util.GameData;
  6. import android.os.Bundle;
  7. import android.view.Menu;
  8. import android.view.MenuItem;
  9. import android.app.Activity;
  10. import android.graphics.Bitmap;
  11. import android.graphics.BitmapFactory;
  12. public class MainActivity extends Activity {
  13. public int KeyDispX=0;//方向x
  14. public int KeyDispY=0;//方向y
  15. public Bitmap planer;
  16. public Bitmap planeg;
  17. public GameData gd=new GameData();
  18. public KeyThread kt=new KeyThread(this);
  19. public NetworkThread nt;
  20. GameView gv;
  21. @Override
  22. protected void onCreate(Bundle savedInstanceState) {
  23. super.onCreate(savedInstanceState);
  24. setContentView(R.layout.main);
  25. planer=BitmapFactory.decodeResource(getResources(), R.drawable.red);//红飞机
  26. planeg=BitmapFactory.decodeResource(getResources(), R.drawable.yellow);//黄飞机
  27. gv=(GameView)this.findViewById(R.id.mf1);
  28. }
  29. @Override
  30. public boolean onCreateOptionsMenu(Menu menu)
  31. {
  32. //调用Activity的getMenuInflater()得到一个MenuInflater,
  33. //使用inflate方法来把布局文件中的定义的菜单 加载给 第二个参数所对应的menu对象
  34. getMenuInflater().inflate(R.menu.activity_main, menu);
  35. return true;
  36. }
  37. @Override
  38. public boolean onOptionsItemSelected(MenuItem item) {
  39. if(item.getItemId()==R.id.menu_connect)
  40. {
  41. if(this.nt==null)
  42. {
  43. this.nt=new NetworkThread(MainActivity.this);
  44. this.nt.start();
  45. }
  46. }
  47. return true;
  48. }
  49. }
ServerAgentThread.java代码如下:
  1. package com.example.util;
  2. import java.io.*;
  3. import java.net.*;
  4. import java.util.*;
  5. public class ServerAgentThread extends Thread
  6. {
  7. //�ͻ��˼�����
  8. static int count=0;
  9. //�ͻ����б�
  10. static List<ServerAgentThread> ulist=new ArrayList<ServerAgentThread>();
  11. //ȫ������
  12. static int rx=150;
  13. static int ry=750;
  14. static int gx=460;
  15. static int gy=750;
  16. //��������
  17. static Queue<Action> aq=new LinkedList<Action>();
  18. //����������
  19. static Object lock=new Object();
  20. Socket sc;
  21. DataInputStream din;
  22. DataOutputStream dout;
  23. int redOrYellow;
  24. boolean flag=true;
  25. public static void broadcastState()
  26. {
  27. for(ServerAgentThread sa:ulist)
  28. {
  29. try
  30. {
  31. sa.dout.writeUTF("<#GAME_DATA#>"+rx+"|"+ry+"|"+gx+"|"+gy);
  32. }
  33. catch(Exception e)
  34. {
  35. e.printStackTrace();
  36. }
  37. }
  38. }
  39. public ServerAgentThread(Socket sc)
  40. {
  41. this.sc=sc;
  42. try
  43. {
  44. din=new DataInputStream(sc.getInputStream());
  45. dout=new DataOutputStream(sc.getOutputStream());
  46. }
  47. catch(Exception e)
  48. {
  49. e.printStackTrace();
  50. }
  51. }
  52. public void run()
  53. {
  54. while(flag)
  55. {
  56. try
  57. {
  58. String msg=din.readUTF();
  59. if(msg.startsWith("<#CONNECT#>"))
  60. {
  61. if(count==0)
  62. {
  63. dout.writeUTF("<#OK#>");
  64. redOrYellow=0;
  65. ulist.add(this);
  66. count++;
  67. System.out.println("==red connect...");
  68. // for(ServerAgentThread sa:ulist)
  69. // {
  70. // sa.dout.writeUTF("<#BEGIN#>");
  71. // }
  72. }
  73. else if(count==1)
  74. {
  75. dout.writeUTF("<#OK#>");
  76. redOrYellow=1;
  77. ulist.add(this);
  78. count++;
  79. System.out.println("==yellow connect...");
  80. for(ServerAgentThread sa:ulist)
  81. {
  82. sa.dout.writeUTF("<#BEGIN#>");
  83. }
  84. }
  85. else
  86. {
  87. dout.writeUTF("<#FULL#>");
  88. break;
  89. }
  90. }
  91. else if(msg.startsWith("<#KEY#>"))
  92. {
  93. String iStr=msg.substring(7);
  94. String[] str=iStr.split("\\|");
  95. synchronized(lock)
  96. {//���¶����������
  97. aq.offer(new Action(this.redOrYellow,Integer.parseInt(str[0]),Integer.parseInt(str[1])));
  98. }
  99. }
  100. }
  101. catch(Exception e)
  102. {
  103. e.printStackTrace();
  104. }
  105. }
  106. try
  107. {
  108. din.close();
  109. dout.close();
  110. sc.close();
  111. }
  112. catch(Exception e)
  113. {
  114. e.printStackTrace();
  115. }
  116. }
  117. }
Joystick.java代码:
  1. package com.example.util;
  2. import com.example.client.MainActivity;
  3. import com.example.client.R;
  4. import com.example.clinet.view.GameView;
  5. import static com.example.util.Constant.*;
  6. import android.graphics.BitmapFactory;
  7. import android.graphics.Canvas;
  8. public class Joystick
  9. {
  10. public MainActivity activity;
  11. public GameView view;
  12. public int length;
  13. public float x;
  14. public float y;
  15. public Joystick( GameView view,MainActivity activity,float x,float y)
  16. {
  17. this.view=view;
  18. this.activity=activity;
  19. this.x=x;
  20. this.y=y;
  21. }
  22. public void drawJoystick(Canvas canvas)
  23. {
  24. canvas.drawBitmap(BitmapFactory.decodeResource(this.activity.getResources(),R.drawable.yaogan1),
  25. JK_Start_x,JK_Start_y, null);
  26. canvas.drawBitmap(BitmapFactory.decodeResource(this.activity.getResources(),R.drawable.yaogan2),
  27. x,y,null);
  28. }
  29. public boolean change(float x,float y)
  30. {
  31. length=getLength(this.view.pCenter.x,this.view.pCenter.y, x,y);
  32. if(length>radio)
  33. {//如果手指触点不在大环范围内
  34. return false;
  35. }
  36. else if(length<radio)
  37. { //如果手指在摇杆活动范围内,则摇杆处于手指触摸位置
  38. this.view.mJoystick.x=x;
  39. this.view.mJoystick.y=y;
  40. }
  41. else
  42. {//设置摇杆位置,使其处于手指触摸方向的 摇杆活动范围边缘
  43. float angle=getRadian(this.view.pCenter.x,this.view.pCenter.y, x, y);
  44. this.view.mJoystick.x=(int)(this.view.pCenter.x+radio* Math.cos(angle));
  45. this.view.mJoystick.y=(int)(this.view.pCenter.y+radio*Math.sin(angle));
  46. }
  47. //方向
  48. this.activity.KeyDispX=(int) (x-this.view.pCenter.x);//x偏移量
  49. this.activity.KeyDispY=(int) (y-this.view.pCenter.y);//y偏移量
  50. return true;
  51. }
  52. }

 Action.java代码:

  1. package com.example.util;
  2. public class Action
  3. {
  4. int redOrYellow;//0-red 1-green
  5. float keyX;
  6. float keyY;
  7. int span=20;//�ƶ�����
  8. public Action(int redOrYellow,float keyX,float keyY)
  9. {
  10. this.redOrYellow=redOrYellow;
  11. this.keyX=keyX;
  12. this.keyY=keyY;
  13. }
  14. public void doAction()
  15. {
  16. float xx=0;
  17. float yy=0;
  18. if(Math.sqrt(keyX*keyX+keyY*keyY)!=0)
  19. {//ת��Ϊ��λ����ֵ
  20. xx= (float) (keyX/Math.sqrt(keyX*keyX+keyY*keyY));
  21. yy=(float) (keyY/Math.sqrt(keyX*keyX+keyY*keyY));
  22. }
  23. if(redOrYellow==0)
  24. {//��
  25. if(ServerAgentThread.ry+yy*span>=0&&ServerAgentThread.ry+yy*span<=1100)
  26. {//���÷ɻ��ƶ���Χ
  27. ServerAgentThread.ry+=yy*span;
  28. }
  29. if(ServerAgentThread.rx+xx*span>=0&&ServerAgentThread.rx+xx*span<=600)
  30. {
  31. ServerAgentThread.rx+=xx*span;
  32. }
  33. }
  34. else
  35. {//��
  36. if(ServerAgentThread.gy+yy*span>=0&&ServerAgentThread.gy+yy*span<=1100)
  37. {//���÷ɻ��ƶ���Χ
  38. ServerAgentThread.gy+=yy*span;
  39. }
  40. if(ServerAgentThread.gx+xx*span>=0&&ServerAgentThread.gx+xx*span<=600)
  41. {
  42. ServerAgentThread.gx+=xx*span;
  43. }
  44. }
  45. }
  46. }
ActionThread.java代码:
  1. package com.example.util;
  2. public class ActionThread extends Thread
  3. {
  4. static final int SLEEP=5;
  5. boolean flag=true;
  6. public void run()
  7. {
  8. while(flag)
  9. {
  10. Action a=null;
  11. synchronized(ServerAgentThread.lock)
  12. {
  13. //��ȡ���Ƴ�����Ԫ��
  14. a=ServerAgentThread.aq.poll();
  15. }
  16. if(a!=null)
  17. {
  18. a.doAction();
  19. ServerAgentThread.broadcastState();
  20. }
  21. else
  22. {
  23. try
  24. {
  25. Thread.sleep(SLEEP);
  26. }
  27. catch(Exception e)
  28. {
  29. e.printStackTrace();
  30. }
  31. }
  32. }
  33. }
  34. }
Constant.java代码:
  1. package com.example.util;
  2. public class Constant {
  3. public static final int radio=80;//半径
  4. public static final int JK_Start_x=30;//摇杆大环起点x
  5. public static final int JK_Start_y=830;//摇杆大环起点y
  6. public static final int xJoystick=100;//摇杆小环x
  7. public static final int yJoystick=900;//摇杆小环y
  8. //获取水平线夹角弧度
  9. public static float getRadian (float x1,float y1,float x2,float y2)
  10. {
  11. float lenA=x2-x1;
  12. float lenB=y2-y1;
  13. float lenC=(float) Math.sqrt(lenA*lenA+lenB*lenB);
  14. float angle=(float)Math.acos(lenA/lenC);
  15. angle=angle*(y2<y1?-1:1);
  16. return angle;
  17. }
  18. //获取长度
  19. public static int getLength(float centerX,float centerY,float x,float y)
  20. {
  21. int result=(int)Math.sqrt(Math.pow(x-centerX, 2)+Math.pow(y-centerY, 2));
  22. return result;
  23. }
  24. }

GameData.java代码;
  1. package com.example.util;
  2. public class GameData {
  3. public static int state=0;//0--未连接 1---成功连接 2--游戏开始
  4. public Object lock=new Object();
  5. public int rx=150;
  6. public int ry=750;
  7. public int gx=460;
  8. public int gy=750;
  9. }
启动ServerThread.java代码:
  1. package com.example.util;
  2. import java.net.*;
  3. public class ServerThread extends Thread
  4. {
  5. boolean flag=false;
  6. ServerSocket ss;
  7. public void run()
  8. {
  9. try
  10. {
  11. ss=new ServerSocket(9999);
  12. System.out.println("Server Listening on 9999...");
  13. flag=true;
  14. new ActionThread().start();
  15. }
  16. catch(Exception e)
  17. {
  18. e.printStackTrace();
  19. }
  20. while(flag)
  21. {
  22. try
  23. {
  24. Socket sc=ss.accept();
  25. System.out.println(sc.getInetAddress()+" connect...");
  26. new ServerAgentThread(sc).start();
  27. }
  28. catch(Exception e)
  29. {
  30. e.printStackTrace();
  31. }
  32. }
  33. }
  34. public static void main(String args[])
  35. {
  36. new ServerThread().start();
  37. }
  38. }

 main.xml代码如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="vertical" >
  6. <com.example.clinet.view.GameView
  7. android:id="@+id/mf1"
  8. android:layout_width="fill_parent"
  9. android:layout_height="wrap_content"
  10. />
  11. </LinearLayout>

 今天就分享到这里,感谢预览~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/414193
推荐阅读
相关标签
  

闽ICP备14008679号