当前位置:  编程技术>移动开发
本页文章导读:
    ▪libGDX开发课程(三)-中文显示与        libGDX开发教程(三)--中文显示与… 本文使用的libgdx是0.98版本,可能和最新版有一些不同地方。全文内容仅供参考。 Libgdx虽然是由美国人MarioZechner(即BadlogicGames)写的开源引擎,由于Libgdx底.........
    ▪ 移栽u-boot到gec210        移植u-boot到gec210第一步:在顶层Makefile 中添加板级目标 gec210_config : unconfig @$(MKCONFIG) $(@:_config=) arm s5pc11x gec210 samsung s5pc110 @echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/smdkc110/config.mk 第二步.........
    ▪ androi之Service+Broadcast+Timer+ui【经过绑定服务、自定义回调接口判断网络连接】       androi之Service+Broadcast+Timer+ui【通过绑定服务、自定义回调接口判断网络连接】      最近项目要定时从服务器获取某些信息,通过研究来总结一下下【我以定时判断网络状态为例来阐述】    .........

[1]libGDX开发课程(三)-中文显示与
    来源: 互联网  发布时间: 2014-02-18
libGDX开发教程(三)--中文显示与…
本文使用的libgdx是0.98版本,可能和最新版有一些不同地方。全文内容仅供参考。

Libgdx虽然是由美国人MarioZechner(即BadlogicGames)写的开源引擎,由于Libgdx底层是用OpenGL实现的,所以Libgdx是可以支持中文的,在libgdx中的汉字都是通过贴图的方式显示,使用BitmapFont和SpriteBatch组合来完成文字的绘制,构造BitmapFont时需要一个描述文字构成的fnt文件,和一个提供文字图片的png文件。因此显示中文,归根结底就是读取一个包含中文信息的.fnt文件和相应的.png文件并展示出来的问题。

Libgdx游戏引擎(1群):187378034
Libgdx游戏引擎(2群):148848483
Libgdx游戏引擎(3群): 79168470
Libgdx国内交流论坛 :www.libgdx.net

1.Hiero工具的使用

如何得到一个“.fnt”和“相应的.png”的文件呢?作者(MarioZechner)给我们提供了一个非常好用的s工具:Hiero。

下载地址:https://code.google.com/p/libgdx/downloads/list



下载结束后,双击hiero.jar文件开,打开后,我们可以看到Hiero的一些基本功能,相比来说作者做的还是比较简单易懂的。从界面上知道,它包括很多选项,像可以制作特效、改变背景颜色、设置内间距等等,右侧还有作提供给我们的做好的字体效果点击Add按钮就可以添加。这里土豆做了一张图片,将它的功能简单的标注了下,这就不详细介绍了.

如下图:



编辑好你要写的文字后,点File—Saveas BMFontFiles,生成两个文件(如下图),将它们拷贝到asserts文件夹。

  
注意:如果你要使用的字,只能是.fnt文件里面存在的文字,否则是显示不出来的.比如,我文件里面有“奋斗小土豆”几个字,那么我可以在程序输出的时候写出这几个字,但是我要是想输出“杜甫很忙”这4个字,因为编辑文件里面没有这几个字,那么就显示不出来。

PS:为什么要加载fnt文件?.fnt文件是做什么用的呢?
答:由于Libgdx底层是用OpenGL实现的,所以Libgdx是可以支持中文的。但是libgdx中的汉字都是通过贴图的方式显示的,我们用记事本打开Potato.fnt文件,里面显示的部分内容(如下图),同时对照.png图片来参考下,可以发现可以很明显看出,libgdx的文字绘制是根据fnt文件获取对应文字的在png中的坐标位置,然后截取图片的相应部分进行绘制。


2.BitmapFont类

API介绍:呈现位图字体,包括2个文件:一个图像文件textureregion,包含符号在anglecodebmfont文本格式,描述了每个字形是图像文件。文本是使用一个SpriteBatch画。

功能用途:渲染静态文本,同时可以设置文字颜色,文字大小等。

使用方法:我们可以手动设置文字大小和颜色以及旋转,这里使用函数设置是可以的,在Hiero里面也是可以设置的,同学们可以自行选择哪种方法设置,new()里面的false是管理翻转的,如下图:



下面我们简单的介绍下用代码来实现一下,我们就画出“奋斗小土豆丶”这几个字,我们依旧使用之前的HelloWorld项目,修改代码如下:


package com.potato;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;

public class HelloWorld implements ApplicationListener {

   public SpriteBatch batch;
  BitmapFont font;

   @Override
   public void create() {
      font = new BitmapFont(Gdx.files.internal("data/Potato.fnt"),
             Gdx.files.internal("data/Potato.png"), false);
      font.setColor(0.5f, 0.4f, 0.6f, 1);// 设置颜色
      font.setScale(1.0f);// 字体比例大小
      batch = new SpriteBatch();
   }

   @Override
   public void dispose() {

   }

   @Override
   public void render() {
      Gdx.gl.glClearColor(1, 1, 1, 1);
      Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
      batch.begin();
      font.draw(batch, "奋斗小土豆丶", 200, 160);
      batch.end();
   }

   @Override
   public void resize(int width, int height) {
   }

   @Override
   public void pause() {
   }

   @Override
   public void resume() {
   }
}

输出效果图:

     


(1)文字单行显示

文字单行显示很简单,font.draw()就可以,下面我介绍下font中持有的draw方法,解释下里面的参数是做什么用的。
方法:draw(SpriteBatch spriteBatch,,java.lang.CharSequence str, float x, float y, int start, int end) 

第一个参数是SpriteBatch类的对象,这里不多解释了。

第二个参数是字符串,也你要输出的中文字符,例如刚才我们写的“奋斗小土豆丶”这个就是第二个对应的字符。

第三个和第四个参数(即float x,float y),它们是绘制字中文字符的起点坐标,遵循普通坐标系(左下角起点)。

第五个参数和第六个参数,是设置从第几个字符开始输出,到第几个字符结束,比如我们要输出“小土豆”这3个字就将start改为2,end改为5,这里面第一个字符默认编码是0而不是1,请牢记。

下面给大家用代码演示,代码如下:

package com.potato;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;

public class HelloWorld implements ApplicationListener {

   public SpriteBatch batch;
  BitmapFont font;

   @Override
   public void create() {
      font = new BitmapFont(Gdx.files.internal("data/Potato.fnt"),
             Gdx.files.internal("data/Potato.png"), false);
      //font.setColor(0.5f,0.4f,0.6f,1);//设置颜色
      //
      //font.setScale(1.0f);//字体比例大小
      batch = new SpriteBatch();
   }

   @Override
   public void dispose() {

   }

   @Override
   public void render() {
      Gdx.gl.glClearColor(1, 1, 1, 1);
      Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
      batch.begin();
      font.draw(batch, "奋斗小土豆丶", 200, 160, 2, 5);
      batch.end();
   }

   @Override
   public void resize(int width, int height) {
   }

   @Override
   public void pause() {
   }

   @Override
   public void resume() {
   }
}

效果图:



(2)文字换行显示

文字进入可以写出了,但是有的同学的文字比较多,一行根本写不完。BitmapFont类中有一个drawMultiLine()方法帮我们解决了多行显示的问题,我们只需要在中文字符中加入换行符(\n)即可,而且它还是自动识别的,非常简单。

方法:drawMultiLine(SpriteBatch spriteBatch, java.lang.CharSequence str, float x, float y, float alignmentWidth,BitmapFont.HAlignment alignment)

这里面前几个参数我都详细介绍了,最后面2个 “float alignmentWidth,BitmapFont.HAlignment alignment” 是指文字的对齐方式,有LEFT、RIGHT、CENTER几种方式。其中,LEFT的绘制原点是左上角、RIGHT的绘制原点是由上角、CENTER的绘制原点是每行文字中心,向两边展开。

float alignmentWidth,,对LEFT不起作用,只对RIGHT和CENTER起作用,对RIGHT来说就相当于把绘制原点平移alignmentWidth的宽度,对CENTER来说相当于平移绘制原点平移alignmentWidth/2的宽度。

下面给大家用代码演示,代码如下:

package com.potato;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;

public class HelloWorld implements ApplicationListener {

   public SpriteBatch batch;
  BitmapFont font;

   @Override
   public void create() {
      font = new BitmapFont(Gdx.files.internal("data/Potato.fnt"),
             Gdx.files.internal("data/Potato.png"), false);
      //font.setColor(0.5f,0.4f,0.6f,1);//设置颜色
      //
      //font.setScale(1.0f);//字体比例大小
      batch = new SpriteBatch();
   }

   @Override
   public void dispose() {

   }

   @Override
   public void render() {
      Gdx.gl.glClearColor(1, 1, 1, 1);
      Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
      batch.begin();
      font.draw(batch, "------奋斗小土豆丶", 200, 160);
      font.drawMultiLine(batch, "爱情来得快,去的也快,\n只有猪肉卷是永恒的",
             Gdx.graphics.getWidth() / 5, 0.8f * Gdx.graphics.getHeight());
      batch.end();
   }

   @Override
   public void resize(int width, int height) {
   }

   @Override
   public void pause() {
   }

   @Override
   public void resume() {
   }
}


效果图:

    

写在最后,有关于中文显示的基本方法今天就介绍到这里了,下一篇是也是关于libgdx框架中文显示的博文,我会介绍下《TTF字库的使用》。如果大家有什么问题可以加我QQ:316344618,一起讨论下。。PS:今天写的比较仓促,有很多准备不充分的地方,希望大家能多给予指点,帮助修改完善。
                                                                                                                                                                                                                                                           ------------奋斗小土豆丶
                                                                                                                             2013年 4 月 10 日

    
[2] 移栽u-boot到gec210
    来源: 互联网  发布时间: 2014-02-18
移植u-boot到gec210
第一步:在顶层Makefile 中添加板级目标

gec210_config :	unconfig
	@$(MKCONFIG) $(@:_config=) arm s5pc11x gec210 samsung s5pc110
	@echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/smdkc110/config.mk

第二步:按照u-boot的模版要求,增加相应的板级目录,并添加对应的代码:
  •     增加board/samsung/gec210目录(将smdkc110复制并改名成gec210)
  •     将gec210目录中的文件进行改名:smdkc110.c -->  gec210.c
  •     将Makefile中的smdkc110改成gec210
  • 第三步:添加板级配置.h文件     就将 include/configs/smdkv210single.h 复制生成 gec210.h
    第四步:添加cpu初始化代码
    如果需要,增加相应的CPU初始化代码(由于当前gec210使用的是s5pc11x,已存在,则忽略)
    第五步:修改Makefile 指定交叉工具链:
    145行
    CROSS_COMPILE = /usr/local/arm/arm-2009q3/bin/arm-none-linux-gnueabi-
    
    第六步:编译
    make
    cp u-boot   /tftpboot


    总结
    1、拿到一块新板子,先确认其CPU架构
    2、核实u-boot中对该CPU的支持(查看cpu目录及board目录)
    3、核实Makefile中与其对应的目标(如果有就加载,没有就添加)
    4、新增该板子的外设功能,在board目录的对应c程序中增加(需要考虑效率跟加载时间,尽量保存简洁)
    5、加载正确的板级配置 (make xxx_config)
    6、编译uboot
    ---------------------------------------------------------------------分割线-------------------------------------------------------------------------------------------
    以上全部是个人观点,如有错误请指正


        
    [3] androi之Service+Broadcast+Timer+ui【经过绑定服务、自定义回调接口判断网络连接】
        来源: 互联网  发布时间: 2014-02-18
    androi之Service+Broadcast+Timer+ui【通过绑定服务、自定义回调接口判断网络连接】

          最近项目要定时从服务器获取某些信息,通过研究来总结一下下【我以定时判断网络状态为例来阐述】

         原理:

        我们定义一个Service,在该Service中设置一个定时器Timer,通过TimerTask的策略来检查当前应用的网络连接状态,关键是在该Service需要自定义一个回调接口用于向我们的Activity来回调发送网络状态,然后通过Bind来绑定当前的Service,在绑定成功之后得到回调信息

      代码:

    Service类

      

    package com.example.androidtimerdemo;
    
    import java.util.Timer;
    import java.util.TimerTask;
    
    import android.app.Service;
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.net.ConnectivityManager;
    import android.net.NetworkInfo;
    import android.net.NetworkInfo.State;
    import android.os.Binder;
    import android.os.IBinder;
    import android.util.Log;
    import android.widget.Toast;
    
    public class NetService extends Service
    {
    
    	@Override
    	public IBinder onBind(Intent intent)
    	{
    		// TODO Auto-generated method stub
    		return netBind;
    	}
    
    	//上下文
    	Context context;
    	
    	//网络连接状态
    	boolean isConntect = true;
        
    	//定时器
    	Timer timer = new Timer();
    
    	@Override
    	public void onCreate()
    	{
    		// 注册广播   检查网络状态
    		IntentFilter filter = new IntentFilter();
    		filter.addAction( ConnectivityManager.CONNECTIVITY_ACTION );
    		registerReceiver( receiver, filter );
    		Log.i( "tag", "service**"+Thread.currentThread().getId() );
    		super.onCreate();
    	}
    
    	//网络检查广播接受者
    	private BroadcastReceiver receiver = new BroadcastReceiver()
    	{
    
    		@Override
    		public void onReceive(Context context, Intent intent)
    		{
    			String action = intent.getAction();
    			// 启动定时任务
    			if (action.equals( ConnectivityManager.CONNECTIVITY_ACTION ))
    			{
    				//立即启动,每隔5秒执行一次Task
    				Log.i( "tag", "receiver**"+Thread.currentThread().getId() );
    				timer.schedule( new NetTask( context ), 0, 5*1000 );
    			}
    		}
    	};
    
    	//具体的TimerTask实现类
    	class NetTask extends TimerTask
    	{
    
    		public NetTask(Context context1)
    		{
    			context = context1;
    		}
    
    
    		@Override
    		public void run()
    		{
    			
    			try
    			{
    				Thread.sleep( 20*1000 );
    			}
    			catch (InterruptedException e)
    			{
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    			
    			if (isConnectNet())
    			{
    				isConntect = true;
    			}
    			else
    			{
    				isConntect = false;
    			}
    			Log.i( "tag", "run**"+Thread.currentThread().getId() );
    			if (onGetConnectState != null)
    			{
    				onGetConnectState.GetState( isConntect ); // 通知网络状态改变
    			}
    		}
    
    	}
    
    	// 网络状态改变之后,通过此接口的实例通知当前网络的状态,此接口在Activity中注入实例对象
    	public interface GetConnectState
    	{
    		public void GetState(boolean isConnected); 
    	}
    
    	private GetConnectState onGetConnectState;
    
    
    	public void setOnGetConnectState(GetConnectState onGetConnectState)
    	{
    		this.onGetConnectState = onGetConnectState;
    	}
    
    
    	/**
    	 * 判断是否连通网络
    	 * @return
    	 */
    	private boolean isConnectNet()
    	{
    		ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService( Context.CONNECTIVITY_SERVICE );
    		NetworkInfo Mobile = connectivityManager.getNetworkInfo( ConnectivityManager.TYPE_MOBILE );
    
    		NetworkInfo Wifi = connectivityManager.getNetworkInfo( ConnectivityManager.TYPE_WIFI );
    		if (Mobile.getState().equals( State.DISCONNECTED ) && Wifi.getState().equals( State.DISCONNECTED ))
    		{
    			return false;
    		}
    		return true;
    	}
    
    	
    	 //定义一个Bind类
    	private NetBind netBind = new NetBind();
    	class NetBind extends Binder
    	{
    		public NetService getNetService()
    		{
    			return NetService.this;
    		}
    	}
    
    
    	//销毁广播、停止定时轮询
    	@Override
    	public void onDestroy()
    	{
    		// TODO Auto-generated method stub
    		super.onDestroy();
    		timer.cancel();
    		unregisterReceiver( receiver );
    	}
    
    }
    

    Activity:

     

    package com.example.androidtimerdemo;
    
    import java.util.Timer;
    import java.util.TimerTask;
    
    import com.example.androidtimerdemo.MybindService.MyBind;
    import com.example.androidtimerdemo.NetService.GetConnectState;
    import com.example.androidtimerdemo.NetService.NetBind;
    
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.IBinder;
    import android.os.Message;
    import android.app.Activity;
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.util.Log;
    import android.view.Menu;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.TextView;
    import android.widget.Toast;
    
    public class MainActivity extends Activity implements OnClickListener
    {
    
    	TextView textView;
    
    	TextView textView2;
    
    	Button button1, button2;
    
    	Activity activity;
    
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState)
    	{
    		super.onCreate( savedInstanceState );
    		setContentView( R.layout.activity_main );
    		activity = this;
    		initView();
    	}
    
    
    	private void initView()
    	{
    		textView = (TextView) findViewById( R.id.textView1 );
    		textView2 = (TextView) findViewById( R.id.textView2 );
    		button1 = (Button) findViewById( R.id.button1 );
    		button2 = (Button) findViewById( R.id.button2 );
    		button1.setOnClickListener( this );
    		button2.setOnClickListener( this );
    
    	}
    
    	boolean is;
    
    
    	@Override
    	public void onClick(View v)
    	{
    		switch (v.getId())
    		{
    			case R.id.button1:
    				// 绑定服务
    				Log.i( "tag", "click**" + Thread.currentThread().getId() );
    				Intent intent = new Intent( activity, NetService.class );
    				boolean isTrue = bindService( intent, conn, Context.BIND_AUTO_CREATE );
    				is = isTrue;
    				break;
    			case R.id.button2:
    				unBind();
    			default:
    				break;
    		}
    	}
    
    
    	private void unBind()
    	{
    		if (conn != null)
    		{
    			unbindService( conn );
    		}
    	}
    
    	private boolean conncetState = true;
    
    	private ServiceConnection conn = new ServiceConnection()
    	{
    
    		@Override
    		public void onServiceDisconnected(ComponentName name)
    		{
    			// TODO Auto-generated method stub
    
    		}
    
    
    		@Override
    		public void onServiceConnected(ComponentName name, IBinder service)
    		{
    
    			NetBind bind = (NetBind) service;
    			NetService netService = bind.getNetService();
                //此处回调
    			netService.setOnGetConnectState( new GetConnectState()
    			{
    
    				@Override
    				public void GetState(boolean isConnected)
    				{
    					// TODO Auto-generated method stub
    					if (conncetState != isConnected)
    					{
    						conncetState = isConnected;
    					}
    					Message msg = handler.obtainMessage();
    					if (conncetState)
    					{
    						msg.what = 1;
    					}
    					else
    					{
    						msg.what = 2;
    					}
    					handler.sendMessage( msg );
    				}
    			} );
    
    		}
    	};
    
    	Handler handler = new Handler()
    	{
    		public void handleMessage(Message msg)
    		{
    			switch (msg.what)
    			{
    				case 1:
    					Toast.makeText( activity, "connect", 2000 ).show();
    					break;
    				case 2:
    					Toast.makeText( activity, "not", 2000 ).show();
    				default:
    					break;
    			}
    		};
    	};
    
    }
    

    PS:记得加网络权限哦




        
    最新技术文章:
    ▪Android开发之登录验证实例教程
    ▪Android开发之注册登录方法示例
    ▪Android获取手机SIM卡运营商信息的方法
    ▪Android实现将已发送的短信写入短信数据库的...
    ▪Android发送短信功能代码
    ▪Android根据电话号码获得联系人头像实例代码
    ▪Android中GPS定位的用法实例
    ▪Android实现退出时关闭所有Activity的方法
    ▪Android实现文件的分割和组装
    ▪Android录音应用实例教程
    ▪Android双击返回键退出程序的实现方法
    ▪Android实现侦听电池状态显示、电量及充电动...
    ▪Android获取当前已连接的wifi信号强度的方法
    ▪Android实现动态显示或隐藏密码输入框的内容
    ▪根据USER-AGENT判断手机类型并跳转到相应的app...
    ▪Android Touch事件分发过程详解
    ▪Android中实现为TextView添加多个可点击的文本
    ▪Android程序设计之AIDL实例详解
    ▪Android显式启动与隐式启动Activity的区别介绍
    ▪Android按钮单击事件的四种常用写法总结
    ▪Android消息处理机制Looper和Handler详解
    ▪Android实现Back功能代码片段总结
    ▪Android实用的代码片段 常用代码总结
    ▪Android实现弹出键盘的方法
    ▪Android中通过view方式获取当前Activity的屏幕截...
    ▪Android提高之自定义Menu(TabMenu)实现方法
    ▪Android提高之多方向抽屉实现方法
    ▪Android提高之MediaPlayer播放网络音频的实现方法...
    ▪Android提高之MediaPlayer播放网络视频的实现方法...
    ▪Android提高之手游转电视游戏的模拟操控
     


    站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3