Android游戏入门 SurfaceView应用----手指发动小球
来源:互联网 发布:淘宝规则关于假货 编辑:程序博客网 时间:2024/06/05 20:40
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import
android.os.Bundle;
import
android.app.Activity;
import
android.view.Window;
import
android.view.WindowManager;
public
class
MainActivity
extends
Activity {
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
//全屏设置
requestWindowFeature(Window.FEATURE_NO_TITLE);
this
.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
//将画布放进去
GameView gameView =
new
GameView(
this
);
setContentView(gameView);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import
android.graphics.Canvas;
import
android.graphics.Color;
import
android.graphics.Paint;
/**
* 小球实例
* @author ZHF
*
*/
public
class
Ball {
int
x, y;
//小球的实时位置
int
startX, startY;
//小球的初始位置
float
vX, vY;
//小球的速度
int
r;
//小球的半径
double
startTimeX;
//开始时间
double
startTimeY;
//开始时间
BallThread ballThread;
//小球移动线程
Paint paint =
new
Paint();
//画笔
public
Ball(
int
x,
int
y,
float
vX,
float
vY,
int
r) {
this
.x = x;
this
.y = y;
this
.startX = x;
this
.startY = y;
this
.vX = vX;
this
.vY = vY;
this
.r = r;
//为每个小球实例化一个独立的线程,在抬手时开启线程
ballThread =
new
BallThread(
this
);
paint.setColor(Color.RED);
//小球为红色实心
}
/**绘画方法**/
public
void
drawSelf(Canvas canvas) {
canvas.drawCircle(x, y, r, paint);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import
android.graphics.Canvas;
import
android.graphics.Color;
import
android.graphics.Paint;
/**
* 障碍物
*
* @author ZHF
*
*/
public
class
Obstruction {
int
x, y;
int
hWeight;
//宽度和高度一样
Paint paint =
new
Paint();
public
Obstruction(
int
x,
int
y,
int
hWeight) {
this
.x = x;
this
.y = y;
this
.hWeight = hWeight;
paint.setColor(Color.GREEN);
//设置画笔颜色
}
public
void
drawSelf(Canvas canvas) {
canvas.drawRect(x - hWeight, y - hWeight, x + hWeight, y + hWeight, paint);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/**
* 小球移动和碰撞检测线程
* @author ZHF
*
*/
public
class
BallThread
extends
Thread {
boolean
flag;
//标记线程是否开启
Ball ball;
//小球
double
currentTime;
//当前时间
public
BallThread(Ball ball) {
flag =
true
;
this
.ball = ball;
}
@Override
public
void
run() {
while
(flag) {
//调试:碰撞检测开始时间
long
startTime = System.currentTimeMillis();
//计算出小球移动的时间片:将每次刷新分成若干时间小片段,用于计算每次时间小片段小球移动的距离
currentTime = System.nanoTime();
double
timeSpanX = (currentTime - ball.startTimeX) /
1000
/
1000
/
1000
;
double
timeSpanY = (currentTime - ball.startTimeY) /
1000
/
1000
/
1000
;
int
xBackup = ball.x;
//保存小球的碰撞前的位置
int
yBackup = ball.y;
ball.x = (
int
) (ball.startX + ball.vX * timeSpanX);
//小球移动的距离
ball.y = (
int
) (ball.startY + ball.vY * timeSpanY);
//边界碰撞检测
if
((ball.vX >
0
&& (ball.x + ball.r) >=
479
) || (ball.vX <
0
&& (ball.x - ball.r) <=
0
)) {
ball.x = xBackup;
ball.vX =
0
- ball.vX;
//速度反向
ball.startTimeX = System.nanoTime();
//重新记录开始时间
ball.startX = ball.x;
//重新记录开始位置
}
if
((ball.vY >
0
&& (ball.y + ball.r) >=
799
) || (ball.vY <
0
&& (ball.y - ball.r) <=
0
)) {
ball.y = yBackup;
ball.vY =
0
- ball.vY;
//速度反向
ball.startTimeY = System.nanoTime();
//重新记录开始时间
ball.startY = ball.y;
//重新记录开始位置
}
//障碍物碰撞检测
for
(
int
i =
0
; i < GameView.obstructList.size(); i++) {
Obstruction o = GameView.obstructList.get(i);
if
(Math.abs(ball.x - o.x) < (ball.r + o.hWeight) && Math.abs(ball.y - o.y) < (ball.r + o.hWeight)){
if
(Math.abs(xBackup - o.x) >= (ball.r + o.hWeight)) {
ball.x = xBackup;
ball.vX =
0
- ball.vX;
ball.startTimeX = System.nanoTime();
ball.startX = ball.x;
}
if
(Math.abs(yBackup - o.y) >= (ball.r + o.hWeight)) {
ball.y = yBackup;
ball.vY =
0
- ball.vY;
ball.startTimeY = System.nanoTime();
ball.startY = ball.y;
}
break
;
//跳出循环
}
}
//调试:碰撞检测结束时间 实验证明碰撞加测基本不耗时间
long
endTime = System.currentTimeMillis();
System.out.println(endTime +
"----"
+ startTime +
"= "
+(endTime - startTime));
try
{
Thread.sleep(
10
);
}
catch
(Exception e) {
e.printStackTrace();
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import
android.graphics.Canvas;
import
android.util.Log;
import
android.view.SurfaceHolder;
/**
* 绘画主界面线程
* @author ZHF
*
*/
public
class
DrawThread
extends
Thread {
boolean
flag;
//标记线程是否开启
GameView gameView;
SurfaceHolder holder;
Canvas canvas;
public
DrawThread(GameView gameView) {
flag =
true
;
this
.gameView = gameView;
holder = gameView.getHolder();
//获取画布锁
}
@Override
public
void
run() {
while
(flag) {
//获取当前绘画开始时间
long
startTime = System.currentTimeMillis();
synchronized
(holder) {
canvas = holder.lockCanvas();
//获取当前被锁住的画布
if
(canvas !=
null
) {
gameView.draw(canvas);
//对画布进行操作
holder.unlockCanvasAndPost(canvas);
//释放画布
}
}
long
endTime = System.currentTimeMillis();
int
diffTime = (
int
) (endTime - startTime);
Log.d(
"DrawTime"
, diffTime+
""
);
while
(diffTime <=
2
) {
diffTime = (
int
) (System.currentTimeMillis() - startTime);
Thread.yield();
//将线程的所有权交给另一个线程
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import
java.util.ArrayList;
import
java.util.Random;
import
android.content.Context;
import
android.graphics.Canvas;
import
android.graphics.Color;
import
android.graphics.Paint;
import
android.view.MotionEvent;
import
android.view.SurfaceHolder;
import
android.view.SurfaceView;
/**
* 游戏主界面
* @author ZHF
*
*/
public
class
GameView
extends
SurfaceView
implements
SurfaceHolder.Callback {
SurfaceHolder holder;
DrawThread drawThread;
//绘画线程
Ball[] ballArray =
new
Ball[
5
];
//装小球的数组
int
ballPointer =
0
;
//当前指向数组中第几个球
static
ArrayList<Obstruction> obstructList =
new
ArrayList<Obstruction>();
//装障碍物的集合
int
xDown, yDown;
//记录手指按下时的坐标
public
GameView(Context context) {
super
(context);
holder = getHolder();
//获取画布锁
holder.addCallback(
this
);
//添加回调
//初始化障碍物
Random random =
new
Random();
for
(
int
i =
0
; i <
3
; i++) {
Obstruction o =
new
Obstruction(random.nextInt(
380
) +
50
, random.nextInt(
700
) +
50
,
50
);
obstructList.add(o);
//将创出的障碍物对象添加到集合中去
}
}
@Override
public
void
surfaceCreated(SurfaceHolder holder) {
drawThread =
new
DrawThread(
this
);
drawThread.start();
//开启绘画线程
}
@Override
public
void
surfaceChanged(SurfaceHolder holder,
int
format,
int
width,
int
height) {
//画布发生变化,eg:转屏操作,处理画布操作
}
@Override
public
void
surfaceDestroyed(SurfaceHolder holder) {
//销毁画布操作
drawThread.flag =
false
;
//停掉线程
drawThread =
null
;
//GC会及时发现并处理掉该对象
}
public
void
draw(Canvas canvas) {
canvas.drawColor(Color.BLACK);
//背景颜色
Paint paint =
new
Paint();
paint.setTextSize(
25
);
paint.setColor(Color.WHITE);
//文字颜色
canvas.drawText(
"小球碰撞检测"
,
50
,
20
, paint);
//画出小球
for
(
int
i =
0
; i <
5
; i++) {
if
(ballArray[i] !=
null
) {
ballArray[i].drawSelf(canvas);
//当前小球绘画出自己
}
}
//画出障碍物
for
(
int
i =
0
; i < obstructList.size(); i++) {
obstructList.
get
(i).drawSelf(canvas);
}
}
@Override
public
boolean onTouchEvent(MotionEvent event) {
int
x = (
int
) event.getX();
int
y = (
int
) event.getY();
if
(event.getAction() ==
0
) {
//按下
//记录按下时X,Y的坐标
xDown = x;
yDown = y;
//生成第一个球
Ball ball =
new
Ball(x, y,
0
,
0
,
20
);
if
(ballArray[ballPointer] !=
null
) {
ballArray[ballPointer].ballThread.flag =
false
;
//关闭小球移动线程
ballArray[ballPointer].ballThread =
null
;
}
ballArray[ballPointer] = ball;
}
else
if
(event.getAction() ==
1
) {
//抬起
int
xOffset = x - xDown;
int
yOffset = y - yDown;
double sin = yOffset / Math.sqrt(xOffset * xOffset + yOffset * yOffset);
double cos = xOffset / Math.sqrt(xOffset * xOffset + yOffset * yOffset);
ballArray[ballPointer].startTimeX = System.nanoTime();
//当前小球开始时间
ballArray[ballPointer].startTimeY = System.nanoTime();
ballArray[ballPointer].vX = (float) (
500
* cos);
//当前小球的速度
ballArray[ballPointer].vY = (float) (
500
* sin);
ballArray[ballPointer].ballThread.start();
//开启小球移动线程
ballPointer ++;
//下一个小球
if
(ballPointer >=
5
) {
ballPointer =
0
;
}
}
return
true
;
}
}
阅读全文
0 0
- Android游戏入门 SurfaceView应用----手指发动小球
- 17、Android之SurfaceView实例自定义SurfaceView的应用——小球跟着手指移动
- 【Android应用实例之三】跟随手指的小球——自定义SurfaceView应用
- Android应用小实例--跟随手指的小球
- Android应用小实例--跟随手指的小球
- Android跟随手指的小球
- android --小球跟随手指滑动
- 【Android应用实例之二】跟随手指的小球——自定义View应用
- Android游戏开发入门讲解-SurfaceView-1
- Android游戏开发入门讲解-SurfaceView-2
- Android游戏开发入门:SurfaceView+SurfaceHolder+Thread
- Android+之小球跟着手指动
- Android+之小球跟着手指动
- Android+之小球跟着手指动
- Android开发之跟随手指的小球
- Android 自定义view实例:跟踪手指小球
- Android---26---跟随手指移动的小球
- Android开发跟随手指的小球Demo
- Linux操作系统课后参考答案
- c++11标准线程库用法总结
- 二分查表(又称:折半查表)
- 坚持#第214天~零基础自学云计算基础语言应用11~15节
- ClassNotFoundException:MappingJacksonHttpMessageConverter
- Android游戏入门 SurfaceView应用----手指发动小球
- 最优装载问题(贪心基础)
- mac tree命令
- mxnet 框架的搭建
- 甲级Test1002
- C#中的socket编程入门实例
- 【广告算法工程师入门 22】机制设计-传统机制设计演变与收入优化思考
- 判断一个单向链表是不是回文链
- LeetCode-Subsets & Subsets II