zoukankan
html css js c++ java
碰撞检测示例:CollisionDetection
import
javax.microedition.lcdui.
*
;
import
javax.microedition.midlet.
*
;
import
java.io.
*
;
import
java.io.IOException;
import
java.util.Random;
public
class
CollisionDetection
extends
MIDlet
implements
CommandListener, Runnable
{
private
boolean
running;
//
主循环的判断
private
boolean
FirstComet
=
true
;
//
首次碰撞检测
private
int
AimingX;
//
检测线的x轴初始位置
private
int
AimingY;
//
检测线的y轴初始位置
private
int
AimingDirX;
//
检测线的x轴初始方向
private
int
AimingDirY;
//
检测线的y轴初始方向
private
int
Kills
=
0
;
//
杀死的次数
private
int
CometX;
//
彗星的x轴初始位置
private
int
CometY;
//
彗星的y轴初始位置
private
int
CometXvec;
//
彗星的x轴初始方向
private
int
CometYvec;
//
彗星的y轴初始方向
private
int
Count
=
30
;
//
private
long
frameTime
=
0
;
//
private
long
lastFrameTime
=
0
;
//
private
static
final
int
SENSITIVITY
=
10
;
//
灵敏度
private
int
Side
=
0
;
//
private
long
LastSide
=
0
;
//
private
static
final
int
PLAYER_RADIUS
=
16
;
//
恒星的半径
private
static
final
int
ENEMY_RADIUS
=
8
;
//
彗星的半径
private
int
COLLISION_LENGTH
=
PLAYER_RADIUS
+
ENEMY_RADIUS;
//
碰撞的长度=恒星的半径+彗星的半径
private
int
COLLISION_LIMIT
=
COLLISION_LENGTH
*
COLLISION_LENGTH;
//
碰撞的区间为碰撞长度的平方
private
MyCanvas myCanvas;
//
内部画布类
private
Display display;
//
显示屏幕
private
Graphics myGraphics;
//
图形参数
private
Random random
=
new
Random();
//
随机数
private
Command quit;
//
退出命令
class
MyCanvas
extends
Canvas
//
内部为画布类
{
protected
void
paint(Graphics graphics)
{
int
PlayerVectorX;
//
检测线的X轴向量
int
PlayerVectorY;
//
检测线的Y轴向量
int
EnemyVectorX;
//
彗星的X轴向量
int
EnemyVectorY;
//
彗星的Y轴向量
//
中心位置
int
CenterX
=
getWidth()
/
2
;
//
X轴的中心位置为屏幕宽度的一半
int
CenterY
=
getHeight()
/
2
;
//
Y轴的中心位置为屏幕高度的一半
int
LoopCount
=
4
;
//
myGraphics
=
graphics;
//
传递图形参数
if
(FirstComet)
//
第一次的彗星
{
NewComet();
//
设置新彗星的位置参数
FirstComet
=
false
;
//
}
frameTime
=
System.currentTimeMillis();
//
当前帧的时间
long
Duration
=
frameTime
-
lastFrameTime;
//
持续时间为当前帧的时间减去上一帧的时间
while
((Duration
>
5
)
&&
(LoopCount
>
0
))
//
{
LoopCount
--
;
//
计算器自减1次
myGraphics.setColor(
0
,
0
,
0
);
//
myGraphics.drawLine (CenterX,CenterY,AimingX,AimingY);
//
绘制正向检测线
PlayerVectorX
=
(AimingX
-
CenterX);
//
检测线的X轴向量=检测线X端点到X轴中心点的矢量
PlayerVectorY
=
(AimingY
-
CenterY);
//
检测线的Y轴向量=检测线X端点到Y轴中心点的矢量
myGraphics.drawLine (CenterX
-
PlayerVectorX,CenterY
-
PlayerVectorY,CenterX,CenterY);
//
绘制反向检测线
AimingX
+=
AimingDirX;
//
检测线沿着X轴方向走
AimingY
+=
AimingDirY;
//
检测线沿着Y轴方向走
/** */
/**
左角 上边 右角
(上角) +----+ (上角)
+ +
左边 + + 右边
+ +
(下角) +----+ (下角)
左角 下边 右角
*/
if
((AimingX
>=
getWidth())
&&
(AimingY
==
0
))
//
检测线超出右边上角
{
AimingX
=
getWidth()
-
1
;
AimingDirX
=
0
;
AimingDirY
=
1
;
}
;
if
((AimingX
<
0
)
&&
(AimingY
==
0
))
//
检测线超出左边上角
{
AimingX
=
0
;
AimingDirX
=
0
;
AimingDirY
=
1
;
}
;
if
((AimingX
>=
getWidth())
&&
(AimingY
==
(getHeight()
-
1
)))
//
检测线超出右边下角
{
AimingX
=
getWidth()
-
1
;
AimingDirX
=
0
;
AimingDirY
=-
1
;
}
;
if
((AimingX
<
0
)
&&
(AimingY
==
(getHeight()
-
1
)))
//
检测线超出左边下角
{
AimingX
=
0
;
AimingDirX
=
0
;
AimingDirY
=-
1
;
}
;
if
((AimingY
>=
getHeight())
&&
(AimingX
==
0
))
//
检测线超出下边左角
{
AimingY
=
getHeight()
-
1
;
AimingDirX
=
1
;
AimingDirY
=
0
;
}
;
if
((AimingY
<
0
)
&&
(AimingX
==
0
))
//
检测线超出上边左角
{
AimingY
=
0
;
AimingDirX
=
1
;
AimingDirY
=
0
;
}
;
if
((AimingY
>=
getHeight())
&&
(AimingX
==
(getWidth()
-
1
)))
//
检测线超出下边右角
{
AimingY
=
getHeight()
-
1
;
AimingDirX
=-
1
;
AimingDirY
=
0
;
}
;
if
((AimingY
<
0
)
&&
(AimingX
==
(getWidth()
-
1
)))
//
检测线超出上边右角
{
AimingY
=
0
;
AimingDirX
=-
1
;
AimingDirY
=
0
;
}
;
Duration
-=
5
;
//
持续时间自减5毫秒
//
<核心检测算法部分>{
PlayerVectorX
=
(AimingX
-
CenterX);
//
检测线的X轴向量=检测线X端点到X轴中心点的矢量
PlayerVectorY
=
(AimingY
-
CenterY);
//
检测线的Y轴向量=检测线Y端点到Y轴中心点的矢量
EnemyVectorX
=
(CenterX
-
CometX);
//
彗星的X轴向量=X轴中心点到彗星X端点的矢量
EnemyVectorY
=
(CenterY
-
CometY);
//
彗星的Y轴向量=Y轴中心点到彗星Y端点的矢量
Side
=
EnemyVectorX
*
PlayerVectorY
-
PlayerVectorX
*
EnemyVectorY;
//
边界值=彗星的X轴向量*检测线的Y轴向量-检测线的X轴向量*彗星的Y轴向量
if
(((Side
>=
0
)
&&
(Side
<
SENSITIVITY))
||
((Side
<=
0
)
&&
(Side
>
SENSITIVITY)))
//
{
//
碰撞检测的边界值在0与灵敏度区间的时候
Kills
++
;
NewComet();
}
if
(Side
<=
0
)
{
if
(LastSide
>
0
)
{
//
当前边界值为负,而上一个边界值为正时
Kills
++
;
NewComet();
}
}
else
{
if
(LastSide
<
0
)
{
//
当前边界值为正,而上一个边界值为负时
Kills
++
;
NewComet();
}
}
LastSide
=
Side;
Count
--
;
if
(Count
==
0
)
{
Count
=
30
;
CometX
+=
CometXvec;
CometY
+=
CometYvec;
int
Length
=
EnemyVectorX
*
EnemyVectorX
+
EnemyVectorY
*
EnemyVectorY;
//
if
(Length
<=
COLLISION_LIMIT)
//
当长度在碰撞区间内时
{
//
恒星、彗星大碰撞,退出程序
destroyApp(
true
);
notifyDestroyed();
}
//
绘制彗星
for
(
int
i
=
0
;i
<
8
;i
++
)
{
myGraphics.setColor(
31
*
i,
30
*
i,
24
*
i);
myGraphics.fillArc(CometX
-
CometXvec
*
(
7
-
i)
-
8
,CometY
-
CometYvec
*
(
7
-
i)
-
8
,
16
,
16
,
0
,
360
);
}
}
//
}<核心检测算法部分>
//
绘制检测线
myGraphics.setColor(
128
,
192
,
255
);
myGraphics.drawLine (CenterX,CenterY,AimingX,AimingY);
//
绘制正向检测线
myGraphics.drawLine (CenterX
-
PlayerVectorX,CenterY
-
PlayerVectorY,CenterX,CenterY);
//
绘制反向检测线
lastFrameTime
=
frameTime;
}
//
绘制恒星
myGraphics.setColor(
128
,
160
,
255
);
//
设置恒星的颜色
myGraphics.fillArc(CenterX
-
16
,CenterY
-
16
,
32
,
32
,
0
,
360
);
//
在离中心位置偏移x,y长度各为16象素的地方画直径为32的实心圆
myGraphics.drawString(
"
"
+
Kills,
0
,
0
,Graphics.LEFT
|
Graphics.TOP);
//
碰撞次数显示
}
protected
void
keyPressed(
int
keyCode)
//
监听手机按键事件
{
int
Key;
try
{
Key
=
getGameAction(keyCode);
//
取键值
}
catch
(Exception e)
{
Key
=
0
;
}
if
(Key
==
FIRE)
//
按fire或者ok键
{
AimingDirX
=-
AimingDirX;
//
取x反方向
AimingDirY
=-
AimingDirY;
//
取y反方向
}
}
}
public
CollisionDetection()
//
构造函数
{
myCanvas
=
new
MyCanvas();
//
创建画布对象
quit
=
new
Command(
"
Quit
"
,Command.EXIT,
2
);
//
创建退出命令
myCanvas.addCommand(quit);
//
为画布添加退出命令
myCanvas.setCommandListener(
this
);
//
为画布设置命令监听器
running
=
true
;
//
主循环判断赋初值
AimingY
=
0
;
//
检测线的y轴初始位置
AimingX
=
myCanvas.getWidth()
/
2
;
//
检测线的x轴初始位置
AimingDirX
=
1
;
//
检测线的x轴初始方向
AimingDirY
=
0
;
//
检测线的y轴初始方向
lastFrameTime
=
System.currentTimeMillis();
//
开始记录为上一帧的时间
Thread t
=
new
Thread(
this
);
//
创建一个新线程
t.start();
//
启动线程
}
private
void
NewComet()
//
新的彗星产生
{
//
清屏
myGraphics.setColor(
0
,
0
,
0
);
myGraphics.fillRect(
0
,
0
,myCanvas.getWidth(),myCanvas.getHeight());
if
(rnd(
2
)
==
0
)
//
随机为偶数
{
//
along top or bot
CometX
=
rnd(myCanvas.getWidth());
CometXvec
=
rnd(
4
);
if
(rnd(
2
)
==
0
)
//
随机数为偶数
{
//
along top
CometY
=
0
;
CometYvec
=
5
-
CometXvec;
}
else
{
CometY
=
myCanvas.getHeight()
-
1
;
CometYvec
=
-
(
5
-
CometXvec);
}
if
(CometX
>
myCanvas.getWidth()
/
2
)
CometXvec
=-
CometXvec;
}
else
{
//
along left or right
CometY
=
rnd( myCanvas.getHeight());
CometYvec
=
rnd(
4
);
if
(rnd(
2
)
==
0
)
//
随机数为偶数
{
//
along left
CometX
=
0
;
CometXvec
=
5
-
CometYvec;
}
else
{
CometX
=
myCanvas.getWidth()
-
1
;
CometXvec
=
-
(
5
-
CometYvec);
}
if
(CometY
>
myCanvas.getHeight()
/
2
)
CometYvec
=-
CometYvec;
}
}
public
void
startApp()
//
启动程序
{
Display.getDisplay(
this
).setCurrent(myCanvas);
//
当前屏幕显示为画布
myCanvas.repaint();
//
画布重绘
}
public
void
pauseApp()
//
暂停程序
{
myCanvas.repaint();
//
画布重绘
}
public
void
destroyApp(
boolean
unconditional)
//
销毁程序
{
}
public
void
commandAction(Command c, Displayable s)
//
命令处理
{
if
(c
==
quit)
//
退出命令
{
destroyApp(
true
);
//
销毁程序
notifyDestroyed();
//
通知程序服务管理销毁
}
}
public
void
run()
//
主循环
{
while
(running)
{
myCanvas.repaint();
//
画布重绘
myCanvas.serviceRepaints();
//
使用强制刷屏
}
}
private
int
rnd(
int
bound)
{
return
Math.abs(random.nextInt()
%
bound);
//
取bound范围内的一个随机正数(绝对值)
}
}
查看全文
相关阅读:
mysql_example
windows 下 解决 go get 或 dep init 更新不了问题
golang反射
Windows下修改hosts并且让他立即生效
Windows不重启就使环境变量修改生效
swoole进程-2
swoole进程
swoole协程
区间素数筛法
AOJ
原文地址:https://www.cnblogs.com/bluespot/p/876795.html
最新文章
foxmail 6.5升级到7.0版本后,旧邮件的导入处理
Oracle11g中Exp命令空表不能导出的问题
像装软件一样装系统 Win8下怎么装Win7
Spring MVC 教程,快速入门,深入分析
Koala logoJava EE 应用开发平台 Koala
Android AVD创建及设置中各参数详解
关于AVD无法使用问题
Android 启动模拟器是出现“Failed to allocate memory: 8”错误提示的原因及解决办法
Android SDK 4.0.3 开发环境配置及运行
手机客户端交互设计原则及信息展现方式
热门文章
2-AII--BroadcastReceiver有序广播
1-AII--BroadcastReceiver广播的静态注册与动态注册
4-AI--Activity跳转动画
关于正整数、质数与公因数及哥德巴赫猜想
2-AI--Activity启动方式
1-AI--Activity生命周期
SpringBoot-16-之整合MyBatis-xml篇+单元测试
剑心
SpringBoot-18-之AOP+log4j 记录访问请求信息
golang redis_example
Copyright © 2011-2022 走看看