大家好,又见面了,我是你们的朋友全栈君。
一、游戏开发基础
1.快速进入android游戏开发
自学、demo、问题、百度&Google
2.游戏简单概括
View Canvas Paint 刷新
3.游戏开发常用三种视图
View ——>SurfaceView 2D——> GLSurfaceView 3D
4.View游戏框架
a.绘图函数onDraw
绘制图形、图片等函数都在画布类中。
b.设置全屏主要操作:隐去状态栏部分、隐去标题栏部分。
c。按键监听 onKeyDown、onKeyUp
触屏监听 onTouchEvent
setFocusable(true)焦点生效
重新绘制画布 invalidate() 和 postInvalidate()
触屏监听动作:按下、抬起、移动、屏幕压力、多点触屏等。
setFocusableInTouchMode(true)
5.SurfaceView游戏框架
a。implements SurfaceHolder.Callback 控制SurfaceView的大小、格式等
b。通过SurfaceViewHolder的lockCanvas()函数获取Canvas对象,加锁
c。unlockCanvasAndPost函数用于解锁画布和提交
d。刷新画布
第一种 每次绘图之前,绘制一个等同于屏幕大小的图形覆盖画布上。
canvas.drawRect(0,0,this.getWidth(),this.getHeigt(),paint);
第二种 每次绘图之前,在画布上填充一种颜色
canvas.drawColor(Color.BLACK);
第三种 每次绘图之前,指定RGB来填充画布
canvas.drawRGB(0,0,0);
第四种 每次绘图之前,绘制一张等同于屏幕大小的图片覆盖在画布上。
6.SurfaceView视图添加线程
固定时间刷新画布比如倒计时、动态花草、流水、怪物、钱币等。
设计一个线程不停去重绘画布,实时更新游戏元素状态。
public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback,Runnable{
private SurfaceHolder sfh;
private Paint paint;
private int textX =10,textY = 10;
private Thread thread;
private boolean flag;
private Canvas canvas;
private int screenW,screenH;
public MySurfaceView(Context context) {
super(context);
sfh = this.getHolder();
sfh.addCallback(this);
paint = new Paint();
paint.setColor(Color.WHITE);
setFocusable(true);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO 视图创建,响应此函数
screenW = this.getWidth();
screenH = this.getHeight();
flag = true;
thread = new Thread(this);
thread.start();
}
/**
* 游戏绘图
*/
public void myDraw(){
try {
canvas = sfh.lockCanvas();
if (canvas!= null) {
//利用绘制矩形的方式刷屏
// canvas.drawRect(0,0,this.getWidth(),this.getHeight(), paint);
//利用RGB的方式刷屏
canvas.drawRGB(0, 0, 0);
canvas.drawText("Game", textX, textY, paint);
}
} catch (Exception e) {
// TODO: handle exception
}finally {
if (canvas!= null) {
sfh.unlockCanvasAndPost(canvas);
}
}
}
/**
* 游戏逻辑
*/
private void logic(){
}
@Override
public boolean onTouchEvent(android.view.MotionEvent event) {
textX = (int) event.getX();
textY = (int) event.getY();
return true;
}
@Override
public boolean onKeyDown(int keyCode, android.view.KeyEvent event) {
return super.onKeyDown(keyCode, event);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
flag = false;
}
@Override
public void run() {
while(flag){
long start = System.currentTimeMillis();
myDraw();
logic();
long end = System.currentTimeMillis();
try {
if (end - start <50) {
Thread.sleep(50-(end-start));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
1).线程标识位 便于消亡线程,防止重复创建线程
2).获取视图的宽和高 this.getWidth和this.getHeight
3).绘图函数try一下
4).提交画布必须放在finally中
5).刷帧时间尽可能保持一致
6.View与SurfaceView的区别
a。SurfaceView不会出现因主UI线程阻塞影响按键触屏等问题。
b。SurfaceView视图有双缓冲机制
c。棋牌类游戏适合View,动态类游戏适合SurfaceView
7.Bitmap位图的渲染与操作
BitmapFactory.decodeResource()通过资源文件生成一张位图
canvas.save()保存当前画布状态
canvas.restore()回复上次保存的画布状态
8.游戏开发中常用png图片,支持透明度。
9.剪切区域 由画布进行设置
第一种 矩形可视区域canvas.clipRect()
path.addCircle(30,30.30,Direction.CCW);canvas.clipRect(path);利用path设置可视区域
设置剪切区域前需要保存画布的状态。
第二种 利用Regin对画布设置可视区域
10. 动画
角色的移动,爆炸的效果,过场的特效等。
Animation的每种动画都是对画布操作
Animation.AnimationListener
第一种 系统动画特效
AlphaAnimation、ScaleAnimation、TranslateAnimation、RotateAnimation
第二种 自定义动画
a 在游戏逻辑处理中调整x和y轴坐标
b 利用帧动画
c 剪切图动画 最常用
动态物体的动作帧全部放在一张图片中,通过设置可视区域完成。
11.游戏适屏
利用视图和屏幕宽高获取x和y坐标
当想要用按下人物一直动的效果时,View的onKeyDown和onKeyUp一起用
设置private boolean isUP,isDown,isLeft,isRight
分别在onKeyDown函数中设置isUP,isDown,isLeft,isRight为true
和在onKeyUp函数中设置isUP,isDown,isLeft,isRight为false
12。碰撞检测
a、矩形碰撞,利用两个矩形之间的位置进行判断,如果一个矩形的像素在另外一个矩形之中,或者之上,就可以认为这两个矩形发生了碰撞。
b。圆形碰撞,利用两圆的圆心距进行判定,当两圆的圆心距小于两圆半径之和时,判定发生了碰撞。
c。像素碰撞,以上两种方式碰撞不精确。但不推荐使用。
首先遍历算出一张位图所有的像素点坐标,然后与另外一张位图上的所有点坐标进行对比,一旦有一个像素点坐标相同,
d。多矩形碰撞 多个矩形碰撞区域
e。Region碰撞
判断一个点是否在矩形区域内。使用Region类中的contains函数
13.游戏音乐与音效
播放游戏背景音乐MediaPlayer 游戏音效类 SoundPool
a。MediaPlayer
prepare()、start()、pause()、stop()
setLooping()、seekTo()、getDuration()、getCurrentPosition()
b。AudioManager音乐管理类,音量大小等
setStreamVolume()、getStreamVolume()、getStreamMaxVolume()
c。MediaPlayer.OnCompletionListerner 监听音乐是否播放完毕
SoundPool类 只能播放小的文件
MediaPlayer优缺点
1)缺点:资源占用较高,延迟时间较长,不支持多个音频同时播放等。
快速连续播放声音,会有明显的1-3s的延迟。可通过seetTo()解决。
2)优点:支持大音乐文件播放,不需要加载准备时间。
SoundPool优缺点
1)缺点:短音频文件。最大1M空间。不要轻易使用pause和stop方法,容易造成程序莫名终止。音频格式最好用OGG格式。一般不在构造中调用播放函数进行播放,需要加载时间。
2)优点:支持多个音乐文件同时播放。
13.游戏数据存储
FileInputStream/FileOutputStream 适合游戏的保存和使用,
SharedPreference适合保存配置信息
SQLite也适合保存游戏
ContentProvider不适合保存游戏
二、游戏开发实战演练
1.准备项目资源文件
2.划分游戏状态。
三、游戏开发提高
1.360°平滑游戏导航摇杆
首先在屏幕上绘制两个大小不一的圆形,让小圆中心点围绕大圆做圆周运动。
用户触点位置分为两种情况
第一种:触点位置在大圆内或者大圆上,小圆的中心点直接跟随玩家触点即可。
第二种:触点位置在大圆外,小圆中心在大圆的圆周上,但小圆所在大圆上的角度,应该等同于用户触点位置相对于大圆的角度。
实际使用中,需要通过摇杆控制游戏主角的移动,首先将整个360°分成4或8等分
2.多触点实现图片缩放
3.触屏手势识别
根据玩家接触屏幕时间的长短、在屏幕上滑动的距离、按下抬起的时间等包装,就是触屏事件监听
GestureDetector.OnGestureListener监听手势
6个主要抽象函数
onDown onSingleTapUp onFling onScroll onShowPress onLongPress
View.onTouchListener 触屏监听器接口
绑定触屏监听器如下
public boolean onTouch(View view, MotionEvent event){
return GestureDetector.onTouchEvent(event) ; }
4.加速度传感器 又称重力传感器
其他传感器:陀螺仪传感器、光传感器、恒定磁场传感器、方向传感器、压力传感器
接近传感器、温度传感器等。
SensorManager 传感器管理类
SensorManager sm = (SensorManager)MainActivity;
instance.getSystemService (Service.SENSOR_SERVICE);
Sensor传感器类
Sensor sensor = SensorManager.getDefaultSensor(int type);
SensorEventListener 传感器监听接口,监听当前传感器的属性及状态。
手机朝向x、y、z
z>0手机屏幕朝上,z<0手机屏幕朝下
当手机是纵向屏幕,
x>0当前手机左翻,x<0当前手机右翻;y>0当前手机下翻y<0上番
当手机是横向屏幕
x>0当前手机下翻,x<0当前手机上翻;y>0当前手机右翻y<0左番
5.9patch工具
6.代码实现截屏功能
原理:通过手动创建一张位图,通过此位图得到一个Canvas实例,利用得到的画布进行绘制, 绘制的图形都保存在最初创建的位图上。最后只要利用游戏主画布绘制这张位图即可。
7.效率检视工具 TraceView
8.游戏视图与系统组件共同显示
9.蓝牙对战游戏
BluetoothAdapter蓝牙适配器类, 对蓝牙是否可见是否可用进行监听
BluetoothDevice 蓝牙设备类 ,
BluetoothSocket蓝牙连接类 ,用于发送和接收报文数据
10.网络游戏开发基础
角色扮演游戏(Role-playing game),简称为RPG
ACT(Action Game):动作类游戏
FPS是第一人称射击类游戏的简称(游戏专有名词)。FPS(First-Person Shooter Game)
格斗游戏(Fight Technology Game,简称为FTG)
模拟游戏(Simulation Game),简称为SIM或SLG
RAC(Race Game):竞速类游戏
冒险游戏(Adventure Game),简称为AVG
SIM(模拟经营类):SIM (Simulation)
SPT(体育类):Sports little game
即时战略(RTS,Real-Time Strategy)
模拟养成游戏(Education Simulation)
CAG卡片类游戏
PUZ儿童益智类游戏,需要通关的那种
a。Socket协议
Socket协议属于长连接,下次交互数据不需要再次连接,一直维持交互状态。适用于通信类游戏,如 ARPG、RPG类游戏。
InputStream is = Socket.getInputStream();
OutputStream os = Socket.getOutputStream();
b、http协议
http协议属于短连接,客户端正常连接到服务器后,数据交互完就断开。
11.本地化与国际化
values-en-rUS等
四、Box2D物理引擎
游戏引擎是指一些已编写好的可编辑电脑游戏系统或者一些交互式实时图像应用程序的核心组件。这些系统为游戏设计者提供各种编写游戏所需的各种工具,其目的在于让游戏设计者能容易和快速地做出游戏程式而不用由零开始。
Box2D用于2D游戏的物理引擎。Java平台的称为JBox2D。
Android游戏中常见游戏引擎有Rokon、AndEngine、libgdx等。
1.创建矩形物体
Box2D中存在两种2D图形,圆形和多边形。创建物体都应该设质量、摩擦力、恢复力三个基本属性。Box2D属于工厂模式,创建物体都是由工厂World生成的,不是new出来的。
分为三步创建:首先创建物体皮肤,其次创建物体刚体,最后创建物体。
质量density:当物体质量设置为0时,物体视为静态物体,没有外力不会发生运动的物体。
摩擦力friction:取值通常设置0~1之间,0没有摩擦,1最强摩擦。
恢复力restitution:取值通常设置0~1之间,0物体没有恢复力,1物体有最大恢复力。
弧度-角度:body.getAngle()/180*Math.PI;
角度-弧度:body.getAngle()/Math.PI*180
遍历body
World.getBodyCount() world.getBodyList()
2.设置Body坐标与给Body施加力
setXForm(Vec2 position,float angle)
applyForce(Vec2 force,Vec2 point)
3.Body碰撞监听、筛选与Body传感器
碰撞监听器接口 ContactListener
add 发生碰撞,有新的接触点时响应的函数;
persist ,当已存在的接触点扔存在响应的函数。
remove ,当存在的接触点被删除时响应的函数。
result, 每次时间步监听,如仍有触点存在则被响应。
Body碰撞筛选 FilterData类 ContactFilter监听器
shouldColide
Body传感器
Body传感器就是Body皮肤的一个属性,属性名为isSensor,默认值false。
body.getShapeList().m_isSensor = true;
作用:一个Body传感器属性为true,不会与其他Body产生碰撞效果,但可以监听到碰撞。
4.关节 Joint
关节主要作用是限制和约束Body之间的位置、距离、速度、运动轨迹等。
1.距离关节 DistanceJoint 限制两个Body的质心距离永远保持不变
2,旋转关节 RevoluteJoint 一个Body围绕另一个Body旋转。还需要一个力驱动Body
RevoluteJointDef实例作为力驱动旋转
3.齿轮关节 GearJoint 两个Body进行齿轮咬合运动。
4.滑轮关节 PulleyJoint 两个Body绑定滑轮关节,沿着一个世界锚点进行滑轮运动。
5。移动关节 PrismaticJoint起两个作用,一个是让物体沿着世界锚点进行移动,另一个是让绑定在移动关节上的两个Body进行相同的动作。
6.鼠标关节 MouseJoint 利用鼠标提供力的作用,拖拽Body,Body朝向鼠标点击的位置进行移动,效果如同在Body与鼠标之间绑定了一个橡皮筋。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/133636.html原文链接:https://javaforall.cn