本文介绍cocos2d-android实现的Android植物大战僵尸,最后附源码

内容介绍:

一.游戏最原始的开发框架。

主要会介绍

a)  SurfaceView+SurfaceHolder.CalllBack+Thread

b)  Canvas+Paint

c)  业务处理

二.Cocos2d-android游戏引擎

a)  什么是游戏引擎

b)  为什么选择Cocos2d

c)  Cocos2d架构

d)  Cocos2d基础

i.  如何使用Cocos2d

1.  CCDirector

ii. 图形引擎Graphic

1.  CCNode

2.  CCScene

3.  CCLayer

4.  CCSprite

5.  CCLable

6.  CCMenu

7.  CCAction

iii.  声音引擎CocosDenshion

iv. Tiled工具使用

v.  粒子系统

游戏开发一般流程

三.植物大战僵尸

a)  大体功能

i.  连接服务器失败处理方式。(弹出对话框,引擎线程和UI线程交互)

ii. 根据等级选择植物,白天或黑夜进入游戏界面

iii.         可以种植向日葵收集阳光

iv. 可以种植植物攻击僵尸

v.  僵尸可以吃掉植物和向日葵

b)  架构

i.  MVC

c)  五个界面

i.  登陆界面LoginScene

ii. Home界面HomeScene

iii.         帮助界面HelpPop

iv. 选择界面SelectScene

v.  游戏界面GameScene

游戏开发框架原理

在Activity当中加载一个View,该View继承了SurfaceView并实现了SurfaceHolder.CallBack和Runnable接口。之后在线程中实现界面的不断刷新,在每次刷新当中通过SurfaceHolder取得Canvas对象,整个界面由Canvas绘制。

基础点:

①游戏开发框架 原理

SurfaceView+SurfaceHolder.CallBack和Runnable

②SurfaceHolder sfh = null;

sfh = this.getHolder();//拿到SurfaceView的控制者,SurfaceView在SurfaceHolder内,但是两者不直接打交道,而是通过lockCanvas和unlockCanvasAndPost。

sfh.addCallback(this);

③Canvas画布

canvas = sfh.lockCanvas();//拿到画布

draw…

sfh.unlockCanvasAndPost(canvas);

canvas.save();//保存之前的画布,继续往下绘制

canvas.restore();//还原到上一次画布保存的状态

介绍:

Canvas():创建一个空的画布,可以使用setBitmap()方法来设置绘制的具体画布;

Canvas(Bitmap bitmap):以bitmap对象创建一个画布,则将内容都绘制在bitmap上,bitmap不得为null;

Canvas(GL gl):在绘制3D效果时使用,与OpenGL有关;

drawColor:设置画布的背景色;

setBitmap:设置具体的画布;

clipRect:设置显示区域,即设置裁剪区;

isOpaque:检测是否支持透明;

rotate:旋转画布;

canvas.drawRect(RectF,Paint)方法用于画矩形,第一个参数为图形显示区域;第二个参数为画笔。

canvas.drawRoundRect(RectF, float, float,Paint) 方法用于画圆角矩形,第一个参数为图形显示区域,第二个参数和第三个参数分别是水平圆角半径和垂直圆角半径。

canvas.drawLine(startX, startY, stopX, stopY,paint):前四个参数的类型均为float,最后一个参数类型为Paint。表示用画笔paint从点(startX,startY)到点(stopX,stopY)画一条直线;

canvas.drawArc(oval, startAngle, sweepAngle,useCenter, paint):第一个参数oval为RectF类型,即圆弧显示区域,startAngle和sweepAngle均为float类型,分别表示圆弧起始角度和圆弧度数,3点钟方向为0度,useCenter设置是否显示圆心,boolean类型,paint为画笔;

canvas.drawCircle(float,float, float, Paint)方法用于画圆,前两个参数代表圆心坐标,第三个参数为圆半径,第四个参数是画笔;

④Paint画笔。在自定义绘图当中,可以通过其来改变该View的颜色,字体大小,样式,透明度等。

paint.setAntiAlias(true);//设置抗锯齿

⑤动手练习

publicvoid drawAndroid() {

//将画笔的颜色设置为绿色

paint.setColor(Color.GREEN);

//绘制两根天线

canvas.drawLine(113, 103, 100, 80, paint);

canvas.drawLine(190, 100, 205, 80, paint);

//绘制一个半圆,Android的小脑袋

RectF oval = new RectF(90, 90, 220, 200);

canvas.drawArc(oval, 0, -180, true, paint);

//绘制身体

canvas.drawRect(90, 150, 220, 315, paint);

//绘制左手

canvas.drawRect(50, 150, 80, 245, paint);

//绘制右手

canvas.drawRect(230, 150, 260, 245, paint);

//绘制左脚

canvas.drawRect(110, 320, 140, 400, paint);

//绘制右脚

canvas.drawRect(170, 320, 200, 400, paint);

//绘制两个小圆,眼睛

canvas.drawCircle(125, 120, 8, paint);

canvas.drawCircle(180, 120, 8, paint);

}

Cocos2d-android游戏引擎

游戏引擎是指一些已编写好的可编辑游戏系统或者一些交互式实时图像应用程序的核心组件。这些系统为游戏设计者提供各种编写游戏所需的各种工具,其目的在于让游戏设计者能容易和快速地做出游戏程式而不用由零开始。

Cocos2d-x

Cocos2d-iphone

Cocos2d-android

Cocos2d-html

本质区别:开发的语言不一样

共同点:api名字基本一致

1.概述

起源于iphone,后经翻译出现了java版

LGame 微云---

我们为什么要使用cocos2d

1.一款开源的,跨平台,轻量级的2D游戏引擎。

2.性能良好

3.广泛的社区支持

4.拥护很多成功案例。比如捕鱼达人,三国塔防等

5.使用MIT授权协议。可以自由使用,修改源码,不需要像GPL一样公开源码,可以商用

2.架构

帧率:每秒钟屏幕刷新的次数

1.图形引擎Cocos2D Graphic

View的层次

各个知识点介绍:

A)CCApplication,初始化程序,获取屏幕方向,系统语言等,不会直接操作

B)CCDirector,导演类,负责管理和切换场景。还负责初始化openGL各项参数。

CCDirector引擎的控制者,控制场景的切换,游戏引擎属性的设置

i.  单例模式,sharedDirector()取得对象

ii. attachInView()连接OpenGL的SurfaceView

iii.    setDeviceOrientation()设置横屏竖屏

iv. setDisplayFPS(true)显示fps帧率

v.  setAnimationInterval(1.0f/ 60)设置帧率,每秒刷新60次

vi. setScreenSize(480, 320)设置屏幕分辨率,高于设置的分辨率时,引擎会自动适配

vii.    runWithScene()运行场景

viii.   replaceScene()替换场景

ix. resume()进入运行状态

x.  pause()暂停

xi. end()结束

C)CCNode,引擎中最重要的元素,所有可以被绘制的东西都是派生于此。它可以包含其它CCNode,可以执行定时器操作,可以执行CCAtion。

D)CCScene,场景类,例如游戏的闪屏,主菜单,游戏主界面等。

E)CCLayer,图层类。

每个图层都有自己的触发事件,该事件只能对其拥有的元素有效,而图层之上的元素所包含的元素,是不受其事件管理的

查找第一个精灵位置与touch点位置相交的精灵。

//判断是否点中

if(CGRect.containsPoint(sprite.getBoundingBox(), point)){

CCNode有一个辅助属性叫做boundingBox,它返回精灵的边界矩形。

调用CCNode的一个辅助函数,convertTouchToNodeSpace。这个方法做了以下三件事:

1        计算touch视图(也就是屏幕)的touch点位置(使用locaitonInView方法)

2        转换touch坐标点为OpenGL坐标点(使用convertToGL方法

3        转换OpenGL坐标系为指定结点的坐标系(使用convertToNodeSpace方法)

注意:在实现事件处理的时候,①事件event的原点为屏幕的左上角②游戏中的position为屏幕的左下角.故在事件处理的时候一定要先将event点转化为游戏中的点,通过

convertToNodeSpace转化.

比如点击地图

CGPointpoint= tiledMap.convertTouchToNodeSpace(event);

点击当前Layer层的元素

CGPoint point = this.convertTouchToNodeSpace(event);

转化点后,开始判断是否点中了该元素

if(CGRect.containsPoint(sprite.getBoundingBox(),point)){

满足条件,则说明点中了

F)CCSprite,精灵类。

①锚点:设置在屏幕上显示的位置,原点为自身左下角为准,锚点的值乘以被设置锚点的元素宽或高,为移动的距离

a)setRelativeAnchorPoint和setAnchorPoint区别:当不设置setAnchorPoint只设置setRelativeAnchorPoint(false)时锚点为(0,0),如果设置setAnchorPoint,setRelativeAnchorPoint无效

b)和旋转动作的关系:旋转动作时以锚点(0.5,0.5)为中心点,向左向上为正方向,故锚点的原点(0,0)在精灵的左下角。而位置锚点向下向右为正方向。一个是设置为旋转的中心点,另一个是设置位置

c)通常设置位置时,建议锚点全部以左下点为准,即设置锚点为(0,0),用position改变坐标

d)加载Scene或Layer时的锚点,虽然默认他们的锚点是(0.5,0.5),但是被加载的时候用不上锚点。之所以Scene有锚点是因为Scene是CCNode的子类

②坐标

③镜像setFilpX(true)

④透明度setOpacity()0-255之间,值越小越透明,反之越不透明

⑤addChild添加子元素,三个参数

G)CCAction,动作类。

①移动CCMoveByCCMoveTo

//加载图片资源

CCSprite s =CCSprite.spriteWithSpriteFrameName("nu.png");

s.setAnchorPoint(0,0);//设置锚点

s.setPosition(300,150);//设置坐标

//创建一个移动动作①动作执行所需时间②x或y方向的位移

CCMoveBy move =CCMoveBy.actionWithDuration(1, ccp(100,80));

CCMoveBy moveBack =move.reverse();//reverse返回一个反方向的动作

CCSequence seq =CCSequence.actions(move, moveBack);//按顺序执行相应动作

CCRepeatForever rf = CCRepeatForever.action(seq);//永远重复执行该动作

s.runAction(rf);//运行动作

②缩放CCScaleBy, 除了整体缩放外,还可以xy方向缩放不同的值

放大缩小

float mapWidth= tiledMap.getContentSize().width;

CCScaleTo zoomin = CCScaleTo.actionWithDuration(1,480/mapWidth);

CCDelayTime delay = CCDelayTime.actionWithDuration(0.3f);//该动作停留指定时间

CCScaleTo st = CCScaleTo.actionWithDuration(1,1);

CCDelayTimedelay2 = CCDelayTime.actionWithDuration(1);

CCInstantAction call = CCCallFunc.actionWithTarget(this, "mapScaleCallback");

tiledMap.runAction(CCSequence.actions(zoomin,delay,st,delay2,call));

③旋转CCRotateBy,正反旋转

不断旋转精灵实现

xii.    代码:

//第一个参数为经历时间,第二个参数为要旋转的角度

CCRotateBy by =CCRotateBy.actionWithDuration(2, 360);

//设置该动作不断循环

CCRepeatForever seq =CCRepeatForever.action(by);

xiii.   注意点:以锚点为中心点来旋转。如要以中心点旋转,则应设置锚点(0.5,0.5),如果锚点为(0,0),则以左下点为中心点旋转

④可见性CCHideCCShow

⑤弹跳CCJumpByCCJumpTo。三个参数的含义a)时间b)目标点c)回落高度d)跳动次数

⑥贝塞尔曲线运动

CCBezierConfig bezier = new CCBezierConfig();

bezier.controlPoint_1 =ccp(10, 10); 起点

bezier.controlPoint_2 =ccp(50, 100); 控制点,制高点

bezier.endPosition =ccp(100, 20); 结束位置

CCBezierBy b = CCBezierBy.action(2,bezier);

⑦闪烁

⑧播放序列帧

CCAnimation加载

如果要停止播放,可以采用stopAction

⑨渐快CCEaseIn。让动作渐快执行,两个参数a)被控制的动作b)加速度,如果为1就匀速了

⑩渐慢CCEaseOut

11.先渐快后渐慢

12.特效,先缓冲再加速CCEaseBlackIn

13.正弦曲线速度变化CCEaseSineInCCEaseSineOut CCEaseSineInOut

14.CCTintTo颜色渐变动作

CCLabellabel label= CCLabel.labelWithString("那些年,我们在传智播客学习的日子", font, 20);

label.setAnchorPoint(ccp(0.5,0.5));

label.setPosition(150,150);

label.setColor(ccc3(255,228, 0));

CCTintTo tint = CCTintTo.actionWithDuration(0.6,285, 182, 0);

CCTintTo back = CCTintTo.actionWithDuration(0.6,255, 230, 0);

CCSequence seq = CCSequence.actions(tint,back);

label.runAction(CCRepeatForever.actionWithAction(seq));

a)CCSequence:按顺序执行动画

b)CCCallFunc:执行指定函数的动作,回调动作

c)CCDelayTime:逗留指定时间的动作

d)CCSpawn:同时执行要被执行的动作

注意:By在执行重复性动画的时候用,To在一次性动画的时候调用,换句话说:To执行完了就结束释放掉了,如果要执行该动画必须重新run该动作,而By是可以还原回到原位置,然后继续循环执行动作。

By传入的CGPoint为x或者y方向的位移差

To传入的CGPoint为目标坐标,该坐标是以屏幕左下角为原点的

I)CCMenu菜单

CClayer的子类

代码:

//初始化

CCMenu menu = CCMenu.menu();

menu.setPosition(0,0);

//加载图片

CCSpritenight=CCSprite.spriteWithSpriteFrameName("item.png");

//添加菜单item

CCMenuItem item =CCMenuItemSprite.item(night,night,this, menuCall);

item.setAnchorPoint(0,0);

item.setPosition(20,160);

//添加item到菜单

menu.addChild(item, TagNight,TagNight);

//添加菜单到界面

this.addChild(menu,TagMenu,TagMenu);

注意:CCMenu默认锚点(0.5,0.5),默认Position为屏幕的中点

J)CCLabel文本 与CCLabelAtlas

//①文本内容;②字体;③文本字体大小

CCLabel label = CCLabel.makeLabel(name,Const.textFont, fontsize);

//①要显示的字符位置;②图片资源;③单个资源的宽;④单个资源的高;⑤起始字符

CCLabelAtlas atlas = CCLabelAtlas.label("12","seedpackets.png", 57, 80,'1');

K)schedule()定时器

X)附加

①帧动画:编辑工具有Zwoptex,TexturePacker

②瓦块地图TiledMap:编辑工具Tiled

③粒子系统:编辑工具PracticalDesigner

2.声音引擎CocosDenshion

a)SoundEngine.sharedEngine().playSound(CCDirector.theApp,  R.raw.bg, ture);最后一个参数是setLooping(true),ture表示要循环播放资源,反之false则只播放一遍

b)对外提供了设置音量,媒体音量,是否要静音,暂停,继续播放,释放内存功能等常用功能

物理引擎

a)  Box2d

b)  Chipmunk

网络库

a)  libCurl

脚本库Lua

Lua 是一个小巧的脚本语言。是巴西里约热内卢天主教大学(PontificalCatholic University of Rio de Janeiro)里的一个研究小组,由RobertoIerusalimschy、WaldemarCeles 和Luiz Henrique de Figueiredo所组成并于1993年开发。 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。Lua由标准C编写而成,几乎在所有操作系统和平台上都可以编译,运行。Lua并没有提供强大的库,这是由它的定位决定的。所以Lua不适合作为开发独立应用程序的语言。Lua有一个同时进行的JIT项目,提供在特定平台上的即时编译功能。

3.补充

①坐标:

a)  屏幕坐标系:以屏幕的左上角为原点,向右,向下为正方向

b)   GL坐标系:以屏幕的左下角为原点,向右,向上为正方向

注意:在CCLayer的触摸事件处理中,注意两个坐标系的转换

②游戏速度

针对塔防游戏,有时候需要加快游戏速度。可以通过

CCScheduler.sharedScheduler().setTimeScale(ts);

来设置,ts>1表示加速,ts<1表示减速,设置为0则游戏处于静止状态

③使用Handle

④锚点与Position锚点

①CCNode默认锚点(0.5,0.5)

②锚点的原点是相对自身CCNode的左下角,不是屏幕的左下角

正方向为右或者上

③能够改变自身CCNode的锚点值(x,y)

X方向的位移:x*CCNode.w

Y方向的位移:y*CCNode.h

④当x或者y为正值,移动的方向为左边,或者下边

当x或者y为负值,移动的方向为右边,或者上边

什么地方用到锚点

改变自身CCNode坐标,在执行某些动作的时候会用到

位置Position

①默认(0,0)为屏幕的左下角或者父CCNode的左下角

②正方向为屏幕的右边或者上边

一般锚点都设置为(0,0)

只改变Position来调整坐标

===========================================

⑤粒子系统

CCParticleSystem  ps= CCParticleSystemPoint.particleWithFile("demo.plist");

加载plist文件,添加到当前层就偶了

3.瓦片地图TiledMap

1.编辑工具:Tiled

2.输出文件为tmx格式

3.关键字

a)图层Layer

b)对象Object

c)瓦片Tile

4.工具的使用流程

a)创建new一个地图,可以设置:

①地图方向:是否成45°角,成45°角能有一个倾斜视角

②地图大小:单位块的个数

③块大小:单位像素

b)在地图中选择新图块来创建瓦片,瓦片的数量根据需求自定义

c)在地图上根据需求创建Object对象:在图层区域右键添加

d)添加图块属性

5.cocos2d-android提供了CCTMXTiledMap专门用来解析地图文件

a)  其中CCTMXObjectGroup专门用来储存Object对象

CCTMXObjectGroup group =tiledMap.objectGroupNamed("road");

tiledMap.touchMove(event,tiledMap);地图就能滑动起来

//地图上人物行走①实现匀速②添加动作结束后调用相应函数提示③执行动作

float duration =CGPoint.ccpDistance() / 30;

CCMoveTo moveto =CCMoveTo.actionWithDuration(duration,);

CCCallFunc call =CCCallFunc.actionWithTarget(this,"WalkCallback");

CCSequence move = CCSequence.actions(moveto,call);

this.runAction(move);

//播放序列帧①加载array②添加动作③执行

CCAnimation animation =CCAnimation.animation("walk", 0.1f,array);

CCAnimate animate =CCAnimate.action(animation);

CCRepeatForever repeat =CCRepeatForever.action(animate);

this.runAction(repeat);

6.注意

a)  地图编辑好后可选保存参数:zlib或gzip压缩。部分引擎可能只支持一种压缩格式解析,如果引擎不支持可考虑换另一种压缩格式保存地图文件

b)  瓦片引入的图片路径:有时候需要去编辑tmx文件,修改图片路径

c)  Object绘制按先后循序插入对象

i.  生成的对象x,y以左下角点为准

CGSize mapSize = tiledMap.getContentSize();

CGSizewinSize = CCDirector.sharedDirector().winSize();

finalint N = event.getHistorySize() - 1;

if (N < 0)

return;

CGPointtouchLocation = CGPoint.make(event.getX(), event.getY());

CGPointprevLocation = CGPoint.make(event.getHistoricalX(N),event.getHistoricalY(N));

touchLocation  = CCDirector.sharedDirector().convertToGL(touchLocation);

prevLocation   = CCDirector.sharedDirector().convertToGL(prevLocation);

if (prevLocation.x != 0 &&prevLocation.y != 0) {

if (mapSize.width *tiledMap.getScale()/2 >= tiledMap.getPosition().x &&winSize.width-mapSize.width * tiledMap.getScale()/2 <= tiledMap.getPosition().x) {

CGPoint mp = tiledMap.getPosition();

mp.x += touchLocation.x-prevLocation.x;

tiledMap.setPosition(mp);

}

if (mapSize.height *tiledMap.getScale()/2 >= tiledMap.getPosition().y &&winSize.height-mapSize.height * tiledMap.getScale()/2 <= tiledMap.getPosition().y) {

CGPoint mp = tiledMap.getPosition();

mp.y += touchLocation.y-prevLocation.y;

tiledMap.setPosition(mp);

}

}

CGPointmpoint = tiledMap.getPosition();

if (mapSize.width *tiledMap.getScale()/2 < tiledMap.getPosition().x) {

mpoint.x = mapSize.width *tiledMap.getScale()/2;

}

if (winSize.width-mapSize.width * tiledMap.getScale()/2> tiledMap.getPosition().x) {

mpoint.x = winSize.width-mapSize.width *tiledMap.getScale()/2;

}

if (mapSize.height *tiledMap.getScale()/2 < tiledMap.getPosition().y) {

mpoint.y = mapSize.height * tiledMap.getScale()/2;

}

if (winSize.height-mapSize.height *tiledMap.getScale()/2 > tiledMap.getPosition().y) {

mpoint.y = winSize.height-mapSize.height *tiledMap.getScale()/2;

}

tiledMap.setPosition(mpoint);

4.游戏应用——植物vs僵尸

4.1概述

1.游戏类型

a)        RPG=Role-playing Game:角色扮演游戏

b)       ACT=Action Game:动作游戏

c)        AVG=Adventure Game:冒险游戏

d)       SLG=Simulation Game:策略游戏

e)        RTS=Real-Time Strategy Game:即时战略游戏

f)        FTG=Fighting Game:格斗游戏

g)       STG= Shooting Game:射击类游戏

h)       FPS=First Personal Shooting Game:第一人称视角射击游戏

i)         PZL=Puzzle Game:益智类游戏

j)         RCG=Racing Game:竞速游戏[也有称作为RAC的

k)       CAG=Card Game:卡片游戏

......了解游戏类型是为了在交流的过程中,当别人提到一种类型如rpg游戏,你能立刻知道他说的是角色扮演类型游戏

2.游戏中的对象

a)        植物

i.         ID

ii.       名称

iii.     建造价格

iv.      类型(攻击类型和增益类型)

v.        CD时间

vi.      伤害值

vii.    金币值

viii.  生命值

b)       僵尸

i.         ID

ii.       名称

iii.     血量

iv.      行走速度

v.        伤害值

vi.      CD时间

4.2工程配置

1.开发工具eclipse

2.引入jar:cocos2d-android.jar

3.UTF-8编码

4.4基础功能

2.欢迎界面

a)  加载背景

b)  等待效果

c)  获取累计天数业务

d)  右上角显示当前版本号PackageManagerPackageInfo

e)  如果连接失败,自动弹出一个layer提示2.主界面

a)  加载背景

b)  底部栏

c)  菜单

d)  帮助pop

<style name="init_game" parent="@android:style/Theme.Dialog">

<item name="android:windowFrame">@null</item>

<item name="android:windowIsFloating">true</item>

<item name="android:windowIsTranslucent">false</item>

<item name="android:windowNoTitle">true</item>

<item name="android:windowBackground">@drawable/out</item>

<item name="android:backgroundDimEnabled">false</item>

</style>

/**

* @param context

* @return返回一般的对话框

*/

publicstatic Dialog getDialog(Context context, float f){

Dialog d = new Dialog(context,R.style.init_game);

d.requestWindowFeature(Window.FEATURE_NO_TITLE);

Window window =d.getWindow();

WindowManager.LayoutParamslp=window.getAttributes();

lp.dimAmount=f;

window.setAttributes(lp);

window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);

window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,

WindowManager.LayoutParams.FLAG_FULLSCREEN);

return d;

}

//彻底退出应用

android.os.Process.killProcess(android.os.Process.myPid());

Intent intent = new Intent();

intent.setClass(context,A.class);

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

context.startActivity(intent);

context.finish();

==========================================================================================

效果图

==========================================================================================

完整源码

http://download.csdn.net/detail/codehxy/9708531

Android植物大战僵尸附源码相关推荐

  1. 【安卓游戏开发】植物大战僵尸 cocos2d-android 源码

    TUNMPVZ 植物大战僵尸安卓版 cocos2d-Android 植物大战僵尸 学院课程设计<android游戏开发>的期末作业项目. 应该是不会继续更新了,有兴趣的可以继续拓展. 项目 ...

  2. Android 小项目之--数据存储【Files】(附源码)

    继上篇数据存储,现在我们来讲讲另外一种数据存储,Files.本篇讲述步骤如下: 1.温故而知新,复习四种数据存储的区别. 2.什么是 Files 数据存储. 3.什么是 Properties ? 4. ...

  3. Android根据音量大小绘制心电图(附源码)

    前提:很久没有更新了,今天就为大家带来一个画布和SurfaceView的使用吧.(附源码资源) 需求:录制音频时有时候为了增加与用户的体验,我们需要增加与用户的交互,于是就有了录音动画.如下图 ) 分 ...

  4. android studio增加一个界面,Android Studio在同一个窗口中打开多个Project【附效果图附源码...

    Android Studio在同一个窗口中打开多个Project[附效果图附源码 Android Studio在同一个窗口中打开多个Project[附效果图附源码]

  5. java实现高德地图app,Android 高德地图入门demo,最新高德地图实现方法,附源码及apk...

    [实例简介] Android 高德地图入门demo,最新高德地图实现方法,附源码及apk [实例截图] [核心代码] GaoDeDemo ├── GaoDeDemo │   ├── app │   │ ...

  6. [附源码]计算机毕业设计Python+uniapp基于Android 工厂考勤系统4h291(程序+源码+LW+远程部署)

    [附源码]计算机毕业设计Python+uniapp基于Android 工厂考勤系统4h291(程序+源码+LW+远程部署) 该项目含有源码.文档.程序.数据库.配套开发软件.软件安装教程 项目运行环境 ...

  7. Android富文本编辑器附源码

    Android富文本编辑器附源码 1,源码分析 本软件是Android端创建富文本数据,向服务器发送;安卓端创建数据可以是文字,图片,语音,文件,还可以录音,可以拍照.录音完毕保存的时候应该提交给服务 ...

  8. Android使用GridView实现俄罗斯方块(附源码)(三)

    GitHub地址: https://github.com/weijifen/AndroidTetris 移动方向 移动方向包括左移,右移和下移. 移动方块实际是对position向量做改变,改变之后使 ...

  9. [附源码]计算机毕业设计Python+uniapp基于Android的自来水收费系统3e359(程序+源码+LW+远程部署)

    [附源码]计算机毕业设计Python+uniapp基于Android的自来水收费系统3e359(程序+源码+LW+远程部署) 该项目含有源码.文档.程序.数据库.配套开发软件.软件安装教程 项目运行环 ...

最新文章

  1. Dockerfile的详解
  2. 前端趋势榜:上周最有意思、又实用的 10 大 Web 项目 - 210924
  3. java的轻量锁,jvm第7节-锁(偏向锁,轻量锁,自旋锁)
  4. Jenkins中切换devtoolset
  5. 大二c语言期末考试题库及详解答案,大学C语言期末考试练习题(带详解答案)...
  6. python是什么?python该怎么学?一招告诉你!!
  7. [Codeforces Round #254 div1] C.DZY Loves Colors 【线段树】
  8. hdu 5748(LIS) Bellovin
  9. CommonJS模块的循环加载
  10. 学习面试题Day09
  11. 2021华为软挑-成渝复赛复盘
  12. curl模拟登陆 php实例,php 使用curl模拟登录人人(校内)网的简单实例
  13. 嵩天python_跟着北京理工大学嵩天老师学习Python
  14. 基于IDS模型设计的ICS
  15. GitLab之docker注册Runner
  16. linux 运行有道词典,Ubuntu中使用有道词典
  17. java代码为word中添加水印图片。
  18. [附源码]计算机毕业设计JAVAst音乐网站
  19. 启动Tomcat6.x时manager does not exist or is not a readable directory
  20. excel表格添加文字太长了,需要换行?

热门文章

  1. asp.net模糊查询
  2. 基本软件项目管理考试题目
  3. MySQL8.0Clone插件
  4. c盘是不是越大越好_Windows系统磁盘分区,C盘划分多大最合适?不是越大越好!...
  5. 什么是mysql 中级工程师的理解
  6. java极光推送如何设置别名_Android 极光推送设置别名
  7. JAVA钓鱼游戏_5个小时写一个扑克牌游戏——金钩钓鱼
  8. ios高德地图提醒打开定位功能
  9. [转]Flex 处理bmp图片as
  10. redis清空所有数据 php