android3d案例
① Android核心技术与实例详解的前 言
Android是Google于2007年11月推出的一款开放的嵌入式操作系统平台,由于其完全开源的特性,Android正以空前的速度吸引着大批开发者的加入。为了帮助众多的软件开发人员尽快地掌握Android平台的相关知识,尽快地步入实际项目的开发中来,作者根据多年项目开发经验编写了此书。
本书既介绍了Android应用程序基本框架,也对Android平台的各种控件进行了讲解,还通过三个真实案例向读者介绍了Android应用程序完整的开发步骤。通过本书读者可以尽快地掌握在Android平台下进行开发的相关知识。
本书特点
1.内容饱满,由浅入深
本书内容既包括Android平台下开发的基础知识,也有项目编程的实用技巧,还提供了多个真实案例供读者学习。本书在知识的层次上由浅入深,使读者可以从Android的门外汉平稳、快速地步入Android开发的殿堂。
2.结构清晰、语言简洁
本书中所有案例都是按照笔者的实际开发过程进行介绍的,同时也是按照真实项目的开发流程进行的,结构清晰,语言简洁,便于实际练习。为了帮助读者更好地理解相关知识点,全书穿插了很多实用技巧及温馨提示。
3.实用超值的光盘
为了帮助读者更好地掌握与实践Android平台下应用程序的开发,本书附赠DVD光盘一张,其中包括案例的多媒体视频、电子教案(PPT)和实例源代码等。
4.实际商业案例
本书最后的三个案例都有实际商业价值,如果进行开发,价格要数万元,笔者将其完整地展现给了读者。
本书内容导读
本书共分三篇,第一篇介绍了在Android平台下进行应用程序开发的基本知识,主要对Android应用程序框架及用户界面的开发进行了介绍。章 名 主 要 内 容
第1章 Android开发起步 简要说明Android平台的来历及其特性,同时介绍了在Android平台下开发用户界面的基本知识
第2章 Android应用程序的构成 对Android平台下的应用程序构成进行了介绍,同时还介绍了应用程序基本组件(如Activity等)的相关知识
第3章 Android布局管理器 初步介绍Android平台下用户界面的开发,主要对布局管理器(如线性布局等的用法)进行了介绍
第4章 Android常用基本控件 介绍了Android平台用户界面中基本控件(如按钮和文本框等)的特性及其用法
第5章 Android常用高级控件 继续上一章的内容,对Android平台用户界面中的高级控件的相关知识和用法进行了介绍
第6章 菜单与对话框 介绍了Android平台选项菜单、上下文菜单和子菜单等的相关知识,同时还将各种对话框的用法进行了详细的介绍
第7章 Android事件处理模型 对Android平台下用户界面开发中常用到的事件处理模型进行了介绍
第二篇介绍如何在Android平台下进行高级应用程序的开发,包括游戏和基于OpenGL ES的3D应用程序的开发,以及与针对手机特性和网络服务程序的开发。
章 名 主 要 内 容
第8章 游戏与3D应用程序开发 向读者介绍了在Android平台下进行游戏开发的相关知识,同时还对Android平台下3D应用程序的开发进行了初步介绍
第9章 消息广播与服务 对Android平台下基于Intent的消息广播机制进行了介绍,同时通过一个比较大的案例说明Service组件的用法
第10章 网络与数据处理 简要介绍了在Android平台下进行网络编程的相关知识,同时还对Android平台下的SQLite等数据处理机制进行了介绍
第11章 手机通信功能开发 通过实例对Android平台下基于手机通信功能(如打电话、发短信和E-mail)的开发进行了介绍
第12章 手机特有Feature开发 介绍了如何基于Android平台对手机的特性进行开发,如改变壁纸、控制手机振动和音量等
第13章 桌面组件与多媒体数据采集 简单介绍了如何在Android平台下开发包括快捷方式和实时文件夹等在内的桌面组件的流程,以及如何在程序中对多媒体数据(如音频和图像)等进行采集的步骤
第14章 传感器应用的开发 对Android平台下传感器的相关知识进行了简单介绍,并通过案例来讲解开发基于传感器的应用程序的步骤
第15章 Google服务 介绍了在应用程序中与Google提供的如Google Map等网络服务进行混搭的开发步骤
第三篇以三个比较大的案例来说明Android平台下大型应用的开发流程,通过这三个案例的讲解,读者对Android开发将会有更深层次的理解。
章 名 主 要 内 容
第16章 Android游戏开发实践——快乐数独 介绍了手机游戏《快乐数独》的开发,通过该案例向读者介绍了在Android平台下进行游戏开发的相关知识和基本流程,并对游戏开发中的编程技巧进行了介绍
第17章 Android地图搜索应用——美食天下 介绍了地图搜索应用《美食天下》的开发,该应用包括Web端和Android手机端,通过该案例向读者介绍了在Android平台下开发大型应用的基本步骤
第18章 Android社交分享平台——口袋微博 介绍了社交分享平台《口袋微博》的开发,该平台包括Web端和Android手机端,通过该案例向读者介绍了基于客户端/服务器模式的网络应用程序开发的基本步骤
本书面向的读者
本书的内容十分详细,几乎涵盖了Android相关的所有技术,并向读者介绍了真实项目的开发流程,主要面向以下读者。
Android初学者:本书详细介绍了Android的基础知识及各种控件,并对Android平台下3D程序的开发进行了介绍,Android初学者通过本书可以快速、全面地掌握Android平台相关知识,快速地步入Android开发人员的行列。
有一定java基础且希望学习Android开发的读者:Android平台下的开发基于Java语言,有一定Java基础的读者通过阅读本书的前半部分便可快速地掌握Android的各种组件及基础控件,然后通过三个真实案例的学习迅速地掌握Android平台下的应用程序开发。
在职的开发人员:本书中的案例都是作者精心挑选的,其中涉及的相关知识均是作者多年来积累的编程经验及心得体会。具有一定开发经验的在职开发人员可以通过本书进一步巩固Android的基础知识,并迅速成为高级的Android开发人员。
本书作者
吴亚峰,毕业于北京邮电大学,后留学澳大利亚卧龙岗大学取得硕士学位。1998年开始从事Java的开发,有十多年的Java开发与培训经验。主要的研究方向为手机游戏、Java EE、搜索引擎,现为手机游戏、Java EE独立软件开发工程师,同时兼任Sun授权Java培训中心认证教师。为数十家着名企业培训了上千名软件开发人员,曾编写过《Java SE 6.0编程指南》、《30天学通Java Web项目案例开发》、《Java程序员职场全攻略:从小工到专家》、《Android 2.0游戏开发实战宝典》等畅销技术书籍。2008年开始关注Android平台下的应用开发,并开发出一系列优秀的Android应用程序。
索依娜,毕业于燕山大学,从业于计算机软件领域9年,在软件开发和计算机教学方面有着丰富的经验。工作期间曾参与省级科研项目2项、市级科研项目1项、发表论文多篇;同时为多个厂矿,企事业单位设计、开发了信息管理系统;从2008年开始关注Android平台下应用的开发,参与开发了多款手机娱乐应用。
另外,昊燃、方振宇、陈冠佐、傅奎、陈勤、梁洋洋、毕梦飞、陈庆、柴相花、陈非凡、陈华、陈嵩、承卓也参与了本书的编写。在此表示感谢!
本书在编写过程中得到了唐山百纳科技有限公司Java培训中心的大力支持,同时 于庭龙、魏鹏飞、王海峰及作者的家人为本书的编写提供了很多帮助,在此表示衷心感谢!
由于编者的水平和学识有限,且书中涉及的知识较多,难免有疏漏之处,敬请广大读者朋友批评指正。
编者
② Android 3D游戏开发技术详解与典型案例的本书作者
吴亚峰,本科毕业于北京邮电大学,后留学澳大利亚卧龙岗大学取得硕士学位,1998年开始从事Java应用的开发,有10多年的Java开发与培训经验。主要的研究方向为Open GL ES、手机游戏、Java EE、搜索引擎,同时为手机游戏、Java EE独立软件开发工程师,并兼任百纳科技Java培训中心首席培训师。从2000年来为数十家着名企业培养了上千名软件开发人员,曾编写过《Java SE6.0编程指南》、《Java程序员职场全攻略——从小工到专家》、《Android2.0游戏开发实战宝典》、《Android核心技术与实例详解》等多本畅销技术书籍。2008年初开始关注Android平台下的应用开发,并开发出一系列优秀的Android应用程序与游戏。
苏亚光,哈尔滨理工大学硕士,有软件领域8年的从业经历,在软件开发和计算机教学方面有着丰富的经验。早期主要从事底层软件的设计与开发工作,现主要从事ARM平台下嵌入式程序的设计、开发等方面的工作。同时,在SOA领域也做了很多有益的工作。
另外,昊燃、方振宇、陈冠佐、傅奎、陈勤、梁洋洋、毕梦飞、陈庆、柴相花、陈非凡、陈华、陈嵩、承卓也参与了本书的编写。在此表示感谢!
致谢
本书在编写过程中得到了唐山百纳科技有限公司Java培训中心的大力支持,同时孙佳佳、李光正、蒋召志、郑安、田永宏、李建宝、王海峰及作者的家人为本书的编写提供了很多帮助,在此表示衷心的感谢!
由于编者的水平和学识有限,且书中涉及的知识较多,难免有疏漏之处,敬请广大读者朋友批评指正,并多多提出宝贵意见。
编者
③ 求助,怎么用android实现控件的3D立体旋转效果
实现水平滑动,所以可在手势抬起的时候进行判断并处理,是滑动显得流畅,代码如下:
packagecom.example.rotation3dview;
importandroid.content.Context;
importandroid.graphics.Camera;
importandroid.graphics.Canvas;
importandroid.graphics.Matrix;
importandroid.util.AttributeSet;
importandroid.view.MotionEvent;
importandroid.view.VelocityTracker;
importandroid.view.View;
importandroid.view.ViewDebug.HierarchyTraceType;
importandroid.view.ViewGroup;
importandroid.widget.ImageView;
importandroid.widget.Scroller;
{
privateintmCurScreen=1;
//滑动的速度
privatestaticfinalintSNAP_VELOCITY=500;
;
privateintmWidth;
privateScrollermScroller;
privateCameramCamera;
privateMatrixmMatrix;
//旋转的角度,可以进行修改来观察效果
privatefloatangle=90;
publicRote3DView(Contextcontext,AttributeSetattrs){
super(context,attrs);
mScroller=newScroller(context);
mCamera=newCamera();
mMatrix=newMatrix();
initScreens();
}
publicvoidinitScreens(){
ViewGroup.LayoutParamsp=newViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
for(inti=0;i<3;i++){
this.addView(newImageView(this.getContext()),i,p);
}
((ImageView)this.getChildAt(0)).setImageResource(R.drawable.page1);
((ImageView)this.getChildAt(1)).setImageResource(R.drawable.page2);
((ImageView)this.getChildAt(2)).setImageResource(R.drawable.page3);
}
@Override
protectedvoidonLayout(booleanchanged,intl,intt,intr,intb){
intchildLeft=0;
finalintchildCount=getChildCount();
for(inti=0;i<childCount;i++){
finalViewchildView=getChildAt(i);
if(childView.getVisibility()!=View.GONE){
finalintchildWidth=childView.getMeasuredWidth();
childView.layout(childLeft,0,childLeft+childWidth,childView.getMeasuredHeight());
childLeft+=childWidth;
}
}
}
@Override
protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){
super.onMeasure(widthMeasureSpec,heightMeasureSpec);
finalintwidth=MeasureSpec.getSize(widthMeasureSpec);
finalintwidthMode=MeasureSpec.getMode(widthMeasureSpec);
if(widthMode!=MeasureSpec.EXACTLY){
thrownewIllegalStateException("仅支持精确尺寸");
}
finalintheightMode=MeasureSpec.getMode(heightMeasureSpec);
if(heightMode!=MeasureSpec.EXACTLY){
thrownewIllegalStateException("仅支持精确尺寸");
}
finalintcount=getChildCount();
for(inti=0;i<count;i++){
getChildAt(i).measure(widthMeasureSpec,heightMeasureSpec);
}
scrollTo(mCurScreen*width,0);
}
privatefloatmDownX;
@Override
publicbooleanonTouchEvent(MotionEventevent){
if(mVelocityTracker==null){
mVelocityTracker=VelocityTracker.obtain();
}
//将当前的触摸事件传递给VelocityTracker对象
mVelocityTracker.addMovement(event);
floatx=event.getX();
switch(event.getAction()){
caseMotionEvent.ACTION_DOWN:
if(!mScroller.isFinished()){
mScroller.abortAnimation();
}
mDownX=x;
break;
caseMotionEvent.ACTION_MOVE:
intdisX=(int)(mDownX-x);
mDownX=x;
scrollBy(disX,0);
break;
caseMotionEvent.ACTION_UP:
=mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000);
intvelocityX=(int)velocityTracker.getXVelocity();
if(velocityX>SNAP_VELOCITY&&mCurScreen>0){
snapToScreen(mCurScreen-1);
}elseif(velocityX<-SNAP_VELOCITY&&mCurScreen<getChildCount()-1){
snapToScreen(mCurScreen+1);
}else{
snapToDestination();
}
if(mVelocityTracker!=null){
mVelocityTracker.recycle();
mVelocityTracker=null;
}
break;
}
returntrue;
}
@Override
publicvoidcomputeScroll(){
if(mScroller.computeScrollOffset()){
scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
postInvalidate();
}
}
publicvoidsnapToDestination(){
setMWidth();
finalintdestScreen=(getScrollX()+mWidth/2)/mWidth;
snapToScreen(destScreen);
}
publicvoidsnapToScreen(intwhichScreen){
whichScreen=Math.max(0,Math.min(whichScreen,getChildCount()-1));
setMWidth();
intscrollX=getScrollX();
intstartWidth=whichScreen*mWidth;
if(scrollX!=startWidth){
intdelta=0;
intstartX=0;
if(whichScreen>mCurScreen){
setPre();
delta=startWidth-scrollX;
startX=mWidth-startWidth+scrollX;
}elseif(whichScreen<mCurScreen){
setNext();
delta=-scrollX;
startX=scrollX+mWidth;
}else{
startX=scrollX;
delta=startWidth-scrollX;
}
mScroller.startScroll(startX,0,delta,0,Math.abs(delta)*2);
invalidate();
}
}
privatevoidsetNext(){
intcount=this.getChildCount();
Viewview=getChildAt(count-1);
removeViewAt(count-1);
addView(view,0);
}
privatevoidsetPre(){
intcount=this.getChildCount();
Viewview=getChildAt(0);
removeViewAt(0);
addView(view,count-1);
}
privatevoidsetMWidth(){
if(mWidth==0){
mWidth=getWidth();
}
}
}
实现立体效果,添加如下代码:
/*
*当进行View滑动时,会导致当前的View无效,该函数的作用是对View进行重新绘制调用drawScreen函数
*/
@Override
protectedvoiddispatchDraw(Canvascanvas){
finallongdrawingTime=getDrawingTime();
finalintcount=getChildCount();
for(inti=0;i<count;i++){
drawScreen(canvas,i,drawingTime);
}
}
publicvoiddrawScreen(Canvascanvas,intscreen,longdrawingTime){
//得到当前子View的宽度
finalintwidth=getWidth();
finalintscrollWidth=screen*width;
finalintscrollX=this.getScrollX();
//偏移量不足的时
if(scrollWidth>scrollX+width||scrollWidth+width<scrollX){
return;
}
finalViewchild=getChildAt(screen);
finalintfaceIndex=screen;
finalfloatcurrentDegree=getScrollX()*(angle/getMeasuredWidth());
finalfloatfaceDegree=currentDegree-faceIndex*angle;
if(faceDegree>90||faceDegree<-90){
return;
}
finalfloatcenterX=(scrollWidth<scrollX)?scrollWidth+width
:scrollWidth;
finalfloatcenterY=getHeight()/2;
finalCameracamera=mCamera;
finalMatrixmatrix=mMatrix;
canvas.save();
camera.save();
camera.rotateY(-faceDegree);
camera.getMatrix(matrix);
camera.restore();
matrix.preTranslate(-centerX,-centerY);
matrix.postTranslate(centerX,centerY);
canvas.concat(matrix);
drawChild(canvas,child,drawingTime);
canvas.restore();
}
④ 求《Android 3D游戏开发技术详解与典型案例》书中源代码,万分感谢!!
请问有电子版的?邮箱 [email protected] 多谢!
⑤ android 3d画廊(转)
public class GalleryActivity2extends AppCompatActivity {
private LayoutInflatermLayoutInflater;
private ViewPagermVp;
private int[]mImg =new int[]{R.mipmap.pic4, R.mipmap.pic5, R.mipmap.pic6, R.mipmap.pic4, R.mipmap.pic5};
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gallery);
mLayoutInflater = LayoutInflater.from(this);
mVp = (ViewPager) findViewById(R.id.vp_gallery_vp);
mVp.setAdapter(new MyAdapter());
mVp.setOffscreenPageLimit(mImg.length);//设置预加载数量
mVp.setPageMargin(-150);//控制两幅图之间的间距
mVp.setPageTransformer(true, new ZoomOutPageTransformer());
//viewPager左右两边滑动无效的处理
findViewById(R.id.ll_gallery_outer).setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return mVp.dispatchTouchEvent(motionEvent);
}
});
}
class MyAdapterextends PagerAdapter {
@Override
public int getCount() {
return mImg.length;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public ObjectinstantiateItem(ViewGroup container, final int position) {
View view =mLayoutInflater.inflate(R.layout.item_img, container, false);
ImageView img = view.findViewById(R.id.img_item_img);
//img.setImageResource(R.mipmap.sea);
img.setImageResource(mImg[position]);
img.setScaleType(ImageView.ScaleType.CENTER_CROP);
img.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(GalleryActivity2.this, "" +position, Toast.LENGTH_SHORT).show();
}
});
container.addView(view);
return view;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}
//设置切换动画
public class ViewPager.PageTransformer {
//自由控制缩放比例
private static final float MAX_SCALE =1f;
private static final float MIN_SCALE =0.6f;//0.85f
@Override
public void transformPage(View page, float position) {
if (position <=1) {
float scaleFactor =MIN_SCALE + (1 - Math.abs(position)) * (MAX_SCALE -MIN_SCALE);
page.setScaleX(scaleFactor);
if (position >0) {
page.setTranslationX(-scaleFactor *2);
}else if (position <0) {
page.setTranslationX(scaleFactor *2);
}
page.setScaleY(scaleFactor);
}else {
page.setScaleX(MIN_SCALE);
page.setScaleY(MIN_SCALE);
}
}
}
activity_gallery.xml
android:id="@+id/ll_gallery_outer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:orientation="vertical">
android:id="@+id/vp_gallery_vp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="50dp"
android:clipChildren="false" />
item_img.xml
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
android:id="@+id/img_item_img"
android:layout_width="200dp"
android:scaleType="centerCrop"
android:layout_height="100dp"
android:src="@mipmap/pic4" />
⑥ Android OpenGLES2.0(十六)——3D模型贴图及光照处理(obj+mtl)
在Android OpenGLES2.0(十四)——Obj格式3D模型加载中实现了Obj格式的3D模型的加载,加载的是一个没有贴图,没有光照处理的帽子,为了呈现出立体效果,“手动”加了光照,拥有贴图的纹理及光照又该怎么加载呢?
本篇博客例子中加载的是一个卡通形象皮卡丘,资源是在网上随便找的一个。加载出来如图所示:
obj内容格式如下:
mtl文件内容格式如下:
关于Obj的内容格式,在上篇博客中已经做了总结,本篇博客中使用的obj,可以看到f后面的不再跟的是4个数字,而是 f 2/58/58 3/59/59 17/60/60 这种样子的三组数,每一组都表示为顶点坐标索引/贴图坐标点索引/顶点法线索引,三个顶点组成一个三角形。而头部的 mtllib pikachu.mtl 则指明使用的材质库。
而mtl格式文件中,主要数据类型为:
模型加载和之前的模型加载大同小异,不同的是,这次我们需要将模型的贴图坐标、顶点法线也一起加载,并传入到shader中。其他参数,有的自然也要取到。
模型加载以obj文件为入口,解析obj文件,从中获取到mtl文件相对路径,然后解析mtl文件。将材质库拆分为诸多的单一材质。obj对象的 加载,根据具使用材质不同来分解为多个3D模型。具体加载过程如下:
顶点着色器
片元着色器
完成了以上准备工作,就可以调用 readMultiObj 方法,将obj文件读成一个或多个带有各项参数的3D模型类,然后将每一个3D模型的参数传入shader中,进而进行渲染:
⑦ 求《Android 3D游戏开发技术详解与典型案例》书中源代码,万分感谢!!
游戏开发引擎本身就是一个成熟的固有框架,这东西哪里都有啊,去专业论坛找吧,除非你从零开始写代码
⑧ 《Android3D游戏开发技术宝典OpenGLES2.0》pdf下载在线阅读,求百度网盘云资源
《Android 3D游戏开发技术宝典》(吴亚峰)电子书网盘下载免费在线阅读
资源链接:
链接:https://pan..com/s/1A5S0LK7aslncrVbBQAJ5Rg
书名:Android 3D游戏开发技术宝典
作者:吴亚峰
出版年份:2012-5
页数:749
内容简介:
《Android 3D游戏开发技术宝典:OpenGL ES 2.0》内容简介:随着智能手机移动嵌入式平台硬件性能的不断提升,3D游戏应用也逐渐普及开来。《Android 3D游戏开发技术宝典:OpenGL ES 2.0》结合作者多年从事3D游戏应用开发的宝贵经验,全面介绍了与Android平台相关的必知必会的基础知识及大型完整3D案例,讲解上由浅入深,循序渐进,起点低、终点高,既适合初学者学习,也适合有一定基础的读者进一步提升之用。另外,由于OpenGL ES2.0的着色语言通用于各种移动嵌入式平台,因此,《Android 3D游戏开发技术宝典:OpenGL ES 2.0》中与着色器开发相关的60%左右的内容还可供iPhone、Windows Mobile、MeeGoo等平台的开发人员参考。全书共22章,其中第1章与第2章为Android平台相关的一些基础知识;第3章~第10章介绍了基于OpenGL ES2.0进行3D应用开发的一些必知必会的基本知识;第11章~第15章介绍了一些高级特效的实现方法;第16章~第17章介绍了3D游戏开发中相关的一些物理、碰撞检测知识以及常用的3D物理引擎JBullet:第19章介绍了3种人机交互的高级技术;第20章~第22章给出了3个完整的大型3D游戏案例,总代码量接近6万行。同时为了便于读者的学习,《Android 3D游戏开发技术宝典:OpenGL ES 2.0》附赠的光盘中包含了书中所有案例的完整源代码,同时给出了最后3个完整大型3D游戏案例的讲解视频,最大限度地帮助读者快速掌握相应的开发技术。