首页 > 其他分享 >使用Android完成案例教学

使用Android完成案例教学

时间:2024-04-06 14:00:16浏览次数:20  
标签:int float 教学 案例 example import Android com public

目录

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


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

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

 

运行结果: 

模拟机:

真机:

 

DrawThread.java代码:
package com.example.client.thread;

import com.example.clinet.view.GameView;

import android.annotation.SuppressLint;
import android.graphics.Canvas;
import android.view.SurfaceHolder;

public class DrawThread extends Thread
{
    private int SLEEP_SPAN =50;//睡眠的毫秒数
    private SurfaceHolder surfaceHolder;
    private GameView view;
    private boolean flag = true;
    public DrawThread(SurfaceHolder surfaceHolder, GameView view) {//构造器
        this.surfaceHolder = surfaceHolder;
        this.view = view;
    }
    public void setFlag(boolean flag) {//设置循环标记位
        this.flag = flag;
    }
    @SuppressLint("WrongCall")
    public void run()
    {
        Canvas c;
        while(flag)
        {
            c = null;
            try
            {// 锁定整个画布,在内存要求比较高的情况下,建议参数不要为null
                c = this.surfaceHolder.lockCanvas(null);
                synchronized (this.surfaceHolder)
                {
                    this.view.onDraw(c);
                }
            } finally
            {
                if (c != null)
                {
                    //更新屏幕显示内容
                    this.surfaceHolder.unlockCanvasAndPost(c);
                }
            }
            try
            {
                Thread.sleep(SLEEP_SPAN);//睡眠指定毫秒数
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
        }
    }
}

 

KeyThread.java代码:
package com.example.client.thread;

import com.example.client.MainActivity;
import com.example.util.GameData;


public class KeyThread extends Thread
{
	int SPAN_SLEEP=10;
	MainActivity father;
	boolean flag=true;

	public KeyThread(MainActivity father)
	{
		this.father=father;
	}

	public void run()
	{
		while(flag)
		{

			try
			{
				if(GameData.state==2)
				{
					father.nt.dout.writeUTF("<#KEY#>"+father.KeyDispX+"|"+father.KeyDispY);
				}
				Thread.sleep(SPAN_SLEEP);

			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
		}
	}
}
更改自己电脑上的IP地址,win+R输入cmd,然后输入ipconfig命令获取此电脑的IP地址,NetworkThread.java代码如下:
package com.example.client.thread;

import android.util.Log;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import com.example.client.MainActivity;
import com.example.util.GameData;

public class NetworkThread extends Thread{
	MainActivity activity;
	Socket sc;
	DataInputStream din;
	DataOutputStream dout;
	public boolean flag=true;
	public NetworkThread(MainActivity activity)
	{
		this.activity=activity;
	}
	public void run()
	{
		try
		{//与服务端建立连接 ,参数分别是要连接的服务端IP地址和要连接的服务端对应的监听端口
			Log.i("测试", "run: 开始连接");
			sc=new Socket("192.168.43.252",9999);
			din=new DataInputStream(sc.getInputStream());
			dout=new DataOutputStream(sc.getOutputStream());
			dout.writeUTF("<#CONNECT#>");
			Log.i("测试", "run: 完成连接");
		}
		catch(Exception e)
		{
			Log.e("测试", "run: 执行失败",e );
			e.printStackTrace();
			return;
		}
		while(flag)
		{
			try
			{
				String msg=din.readUTF();
				if(msg.startsWith("<#OK#>"))
				{
					System.out.println("Connect ok...");
					GameData.state=1;
				}
				else if(msg.startsWith("<#BEGIN#>"))
				{
					GameData.state=2;
					this.activity.kt.start();
				}
				else if(msg.startsWith("<#FULL#>"))
				{
					System.out.println("Full...");
					break;
				}
				else if(msg.startsWith("<#GAME_DATA#>"))
				{
					String nr=msg.substring(13);
					String[] strA=nr.split("\\|");
					int temprx=Integer.parseInt(strA[0]);
					int tempry=Integer.parseInt(strA[1]);
					int tempgx=Integer.parseInt(strA[2]);
					int tempgy=Integer.parseInt(strA[3]);
					synchronized(this.activity.gd.lock)
					{
						this.activity.gd.rx=temprx;
						this.activity.gd.ry=tempry;
						this.activity.gd.gx=tempgx;
						this.activity.gd.gy=tempgy;
					}
				}
			}catch(Exception e)
			{
				e.printStackTrace();
			}
		}

		try
		{
			din.close();
			dout.close();
			sc.close();
		}catch(Exception e)
		{
			e.printStackTrace();
		}
	}
}

 

MainActivity.Java代码:
package com.example.client;

import com.example.client.thread.KeyThread;
import com.example.client.thread.NetworkThread;
import com.example.clinet.view.GameView;
import com.example.util.GameData;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

public class MainActivity extends Activity {
	public int KeyDispX=0;//方向x
	public int KeyDispY=0;//方向y

	public Bitmap planer;
	public Bitmap planeg;
	public GameData gd=new GameData();
	public KeyThread kt=new KeyThread(this);
	public 	NetworkThread nt;
	GameView gv;



	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		planer=BitmapFactory.decodeResource(getResources(), R.drawable.red);//红飞机
		planeg=BitmapFactory.decodeResource(getResources(), R.drawable.yellow);//黄飞机

		gv=(GameView)this.findViewById(R.id.mf1);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu)
	{
		//调用Activity的getMenuInflater()得到一个MenuInflater,
		//使用inflate方法来把布局文件中的定义的菜单 加载给 第二个参数所对应的menu对象

		getMenuInflater().inflate(R.menu.activity_main, menu);
		return true;
	}
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		if(item.getItemId()==R.id.menu_connect)
		{
			if(this.nt==null)
			{
				this.nt=new NetworkThread(MainActivity.this);
				this.nt.start();
			}


		}
		return true;
	}
}
ServerAgentThread.java代码如下:
package com.example.util;

import java.io.*;
import java.net.*;
import java.util.*;

public class ServerAgentThread extends Thread
{
	//�ͻ��˼�����
	static int count=0;
	//�ͻ����б�
	static List<ServerAgentThread> ulist=new ArrayList<ServerAgentThread>();
	//ȫ������
	static int rx=150;
	static int ry=750;
	static int gx=460;
	static int gy=750;
	//��������
	static Queue<Action> aq=new LinkedList<Action>();
	//����������
	static Object lock=new Object();
	
	Socket sc;
	DataInputStream din;
	DataOutputStream dout;
	int redOrYellow;
	boolean flag=true;
	
	public static void broadcastState()
	{
		for(ServerAgentThread sa:ulist)
		{
			try
			{
				sa.dout.writeUTF("<#GAME_DATA#>"+rx+"|"+ry+"|"+gx+"|"+gy);
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
		}
	}
	
	public ServerAgentThread(Socket sc)
	{
		this.sc=sc;
		try
		{
			din=new DataInputStream(sc.getInputStream());
			dout=new DataOutputStream(sc.getOutputStream());
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	
	public void run()
	{
		while(flag)
		{
			try
			{
				String msg=din.readUTF();
				if(msg.startsWith("<#CONNECT#>"))
				{
					if(count==0)
					{
						dout.writeUTF("<#OK#>");
						redOrYellow=0;
						ulist.add(this);
						count++;
						System.out.println("==red connect...");
//						for(ServerAgentThread sa:ulist)
//						{
//							sa.dout.writeUTF("<#BEGIN#>");
//						}
					}
					else if(count==1)
					{
						dout.writeUTF("<#OK#>");
						redOrYellow=1;
						ulist.add(this);
						count++;
						System.out.println("==yellow connect...");
						
						for(ServerAgentThread sa:ulist)
						{
							sa.dout.writeUTF("<#BEGIN#>");
						}
					}
					else
					{
						dout.writeUTF("<#FULL#>");
						break;
					}
				}
				else if(msg.startsWith("<#KEY#>"))
				{
					String iStr=msg.substring(7);
					String[] str=iStr.split("\\|");
					synchronized(lock)
					{//���¶����������
						aq.offer(new Action(this.redOrYellow,Integer.parseInt(str[0]),Integer.parseInt(str[1])));
					}
				}
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
		}
		try
		{
			din.close();
			dout.close();
			sc.close();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
}
Joystick.java代码:
package com.example.util;

import com.example.client.MainActivity;
import com.example.client.R;
import com.example.clinet.view.GameView;

import static com.example.util.Constant.*;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;

public class Joystick
{
	public MainActivity activity;
	public GameView view;
	public int length;
	public float x;
	public float y;
	public Joystick( GameView view,MainActivity activity,float x,float y)
	{
		this.view=view;
		this.activity=activity;
		this.x=x;
		this.y=y;
	}

	public void drawJoystick(Canvas canvas)
	{
		canvas.drawBitmap(BitmapFactory.decodeResource(this.activity.getResources(),R.drawable.yaogan1),
				JK_Start_x,JK_Start_y, null);
		canvas.drawBitmap(BitmapFactory.decodeResource(this.activity.getResources(),R.drawable.yaogan2),
				x,y,null);
	}


	public boolean change(float x,float y)
	{
		length=getLength(this.view.pCenter.x,this.view.pCenter.y, x,y);
		if(length>radio)
		{//如果手指触点不在大环范围内
			return false;
		}
		else if(length<radio)
		{ //如果手指在摇杆活动范围内,则摇杆处于手指触摸位置
			this.view.mJoystick.x=x;
			this.view.mJoystick.y=y;
		}
		else
		{//设置摇杆位置,使其处于手指触摸方向的 摇杆活动范围边缘
			float angle=getRadian(this.view.pCenter.x,this.view.pCenter.y, x, y);
			this.view.mJoystick.x=(int)(this.view.pCenter.x+radio* Math.cos(angle));
			this.view.mJoystick.y=(int)(this.view.pCenter.y+radio*Math.sin(angle));
		}
		//方向
		this.activity.KeyDispX=(int) (x-this.view.pCenter.x);//x偏移量
		this.activity.KeyDispY=(int) (y-this.view.pCenter.y);//y偏移量
		return true;
	}
}

 Action.java代码:

package com.example.util;

public class Action 
{
	int redOrYellow;//0-red 1-green	
	float keyX;
	float keyY;
	int span=20;//�ƶ�����
	
	public Action(int redOrYellow,float keyX,float keyY)
	{
		this.redOrYellow=redOrYellow;
		this.keyX=keyX;
		this.keyY=keyY;
	}
	
	public void doAction()
	{		
		float xx=0;
		float yy=0;
		if(Math.sqrt(keyX*keyX+keyY*keyY)!=0)
		{//ת��Ϊ��λ����ֵ
			xx= (float) (keyX/Math.sqrt(keyX*keyX+keyY*keyY));
			yy=(float) (keyY/Math.sqrt(keyX*keyX+keyY*keyY));
		}
		if(redOrYellow==0)
		{//��
			if(ServerAgentThread.ry+yy*span>=0&&ServerAgentThread.ry+yy*span<=1100)
			{//���÷ɻ��ƶ���Χ
				ServerAgentThread.ry+=yy*span;
			}			
			if(ServerAgentThread.rx+xx*span>=0&&ServerAgentThread.rx+xx*span<=600)
			{
				ServerAgentThread.rx+=xx*span;
			}
		}
		else
		{//��
			if(ServerAgentThread.gy+yy*span>=0&&ServerAgentThread.gy+yy*span<=1100)
			{//���÷ɻ��ƶ���Χ
				ServerAgentThread.gy+=yy*span;
			}		
			if(ServerAgentThread.gx+xx*span>=0&&ServerAgentThread.gx+xx*span<=600)
			{
				ServerAgentThread.gx+=xx*span;
			}
		}
		
	}
}
ActionThread.java代码:
package com.example.util;

public class ActionThread extends Thread
{
	static final int SLEEP=5;
	boolean flag=true;
		
	public void run()
	{
		while(flag)
		{
			Action a=null;
			
			synchronized(ServerAgentThread.lock)
			{
				//��ȡ���Ƴ�����Ԫ��
				a=ServerAgentThread.aq.poll();
			}
			if(a!=null)
			{
				a.doAction();
				ServerAgentThread.broadcastState();	
			}
			else
			{
				try
				{
					Thread.sleep(SLEEP);
				}
				catch(Exception e)
				{
					e.printStackTrace();
				}
			}
		}
	}
}
Constant.java代码:
package com.example.util;

public class Constant {

	public static final int radio=80;//半径
	public static final int JK_Start_x=30;//摇杆大环起点x
	public static final int JK_Start_y=830;//摇杆大环起点y
	public static final int  xJoystick=100;//摇杆小环x
	public static final int  yJoystick=900;//摇杆小环y


	//获取水平线夹角弧度
	public static float getRadian (float x1,float y1,float x2,float y2)
	{
		float lenA=x2-x1;
		float lenB=y2-y1;
		float lenC=(float) Math.sqrt(lenA*lenA+lenB*lenB);
		float angle=(float)Math.acos(lenA/lenC);
		angle=angle*(y2<y1?-1:1);
		return angle;
	}

	//获取长度
	public static int getLength(float centerX,float centerY,float x,float y)
	{
		int result=(int)Math.sqrt(Math.pow(x-centerX, 2)+Math.pow(y-centerY, 2));
		return result;
	}
}

 

GameData.java代码;
package com.example.util;

public class GameData {
	public static int state=0;//0--未连接  1---成功连接  2--游戏开始

	public Object lock=new Object();

	public int rx=150;
	public int ry=750;
	public int gx=460;
	public int gy=750;
}
启动ServerThread.java代码:
package com.example.util;
import java.net.*;

public class ServerThread extends Thread
{
	boolean flag=false;
	ServerSocket ss;
	
	public void run()
	{
		try
		{
			ss=new ServerSocket(9999);
			System.out.println("Server Listening on 9999...");
			flag=true;
			new ActionThread().start();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		
		while(flag)
		{
			try
			{
				Socket sc=ss.accept();
				System.out.println(sc.getInetAddress()+" connect...");
				new ServerAgentThread(sc).start();
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String args[])
	{
		new ServerThread().start();
	}
}

 

 main.xml代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <com.example.clinet.view.GameView
        android:id="@+id/mf1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        />

</LinearLayout>

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

标签:int,float,教学,案例,example,import,Android,com,public
From: https://blog.csdn.net/m0_73490019/article/details/137426821

相关文章

  • 最高院诉讼时效案例汇总
    近期诸多案件牵涉诉讼时效问题,现统一学习、汇总:1.合同对付款条件/期限有约定的,节点到期前当事人是否积极主张权利对是否超过诉讼时效无影响(不超过20年的情况下)(2011)民再申字第60号  儋州春江南华糖业有限公司与中国人民银行儋州市支行、中国建设银行股份有限公司儋州支行等买......
  • 【外推SEO案例】搜索留痕排名代发反的链接怎么查看
    【外推SEO案例】搜索留痕排名代发反的链接怎么查看搜索留痕外链怎么发更有效果?高质量SEO外链制作教学,附带【2000+搜索留痕外链资源】分享哦!#SEO外链#搜索留痕优化#百度SEO#搜索引擎优化#百度排名#搜索留痕推广#SEO技术#搜索留痕运营经典的搜索排名为什么一直那么高?我......
  • 1Android开始,让工程跑起来
    1、怎么让项目能运行?修改Setting使用国内源在KotlinDSL(.kts 文件)中,配置Maven仓库的方式与GroovyDSL略有不同。在KotlinDSL中应该这样写:1repositories{2maven{url=uri("https://maven.aliyun.com/repository/public/")}3} ......
  • Android NDK之使用 arm-v7a 汇编实现两数之和
    AndroidNDK之使用arm-v7a汇编实现两数之和关键词:NDKarmv7aWebRTCarm汇编CMake最近适配对讲程序,在webrtc的库编译的过程中,发现其为arm的平台定制了汇编程序以优化平方根倒数算法速度,上次写汇编还是8086的,借此机会初步尝试下android上arm汇编具体jni工程建立就不介绍了,An......
  • Vue2和3中的插槽区别及其简单案例
    vue中的插槽是什么,官方解释是:Vue实现了一套内容分发的API,这套API的设计灵感源自WebComponents规范草案,将<slot>元素作为承载分发内容的出口......vue2插槽和vue3插槽基本概念是一致的,也是匿名插槽、具名插槽、作用域插槽三种,只是基础语法有一些区别。下面让我们温习......
  • Android 14.0 添加自定义服务,并生成jar给第三方app调用
    1.概述在14.0系统ROM产品定制化开发中,由于需要新增加自定义的功能,所以要增加自定义服务,而app上层通过调用自定义服务,来调用相应的功能,所以系统需要先生成jar,然后生成jar给上层app调用,接下来就来分析实现的步骤,然后来实现相关的功能从而来实现所需要的功能2.关于添加系统......
  • 【Java后端开发】教程及案例
    Java后端开发是软件开发中的一个重要领域,它涉及到服务器端的程序设计、数据库交互、API开发、安全性处理等多个方面。以下是关于Java后端开发的教程和案例的详细介绍:###Java后端开发基础####1.Java基础知识-掌握Java基础语法、面向对象编程、集合框架、异常处理等。-......
  • Docker内Chrome中文乱码的解决方案以及部署360奇安信失败案例
    Docker内Chrome中文乱码的解决方案以及部署360奇安信失败案例背景搞了一个清明假期,把chrome安装上去了可以实现简单的的版本确认然后想着搞一下国产化的浏览器突然发现国产化的浏览器的坑是无与伦比的深.记录一下过程.下载https://www.qianxin.com/ctp/gmbrowser.......
  • koa、koa-router、nunjucks 综合案例
     constKoa=require('koa');constrouter=require('koa-router')();constnunjucks=require('nunjucks');constapp=newKoa();//配置Nunjucksnunjucks.configure(__dirname+'/views',{autoescape:true,//是......
  • Android 连接数据库
    1.添加新用户。   2.在libs中导入mysql的jar包。 3.修改AndroidManifest.xml,代码如下。1<?xmlversion="1.0"encoding="utf-8"?>2<manifestxmlns:android="http://schemas.android.com/apk/res/android"3xmlns:tools=&......