我正在开发一种使用射弹的游戏。所以我制作了一个Projectile类,当用户触摸屏幕时会创建一个新实例:
@Override
public boolean onTouch(View v, MotionEvent e){
float touch_x = e.getX();
float touch_y = e.getY();
new Projectile(touch_x, touch_y);
}
和弹丸类:
public class Projectile{
float target_x;
float target_y;
Path line;
public Projectile(float x, float y){
target_x = x;
target_y = y;
line = new Path();
line.moveTo(MyGame.mPlayerXPos, MyGame.mPlayerYPos);
line.lineTo(target_x, target_y);
}
}
所以这会产生一个2点的路径,玩家的位置和触摸坐标。我的问题是 - 你怎么能在这条线上获得积分?例如,如果我想在线的半点获得弹丸的x,y坐标,或者弹丸在100个刻度之后的位置(以X像素/刻度的速度移动)?
我还需要Projectile在到达最终点后继续移动..我是否需要使用line.addPath(line)来继续扩展路径?
修改
我设法使弹丸沿直线移动,但它们朝着奇怪的方向前进。我不得不捏造一些代码:
private void moveProjectiles(){
ListIterator<Projectile> it = Registry.proj.listIterator();
while ( it.hasNext() ){
Projectile p = it.next();
p.TimeAlive++;
double dist = p.TimeAlive * p.Speed;
float dx = (float) (Math.cos(p.Angle) * dist);
float dy = (float) (Math.sin(p.Angle) * dist);
p.xPos += dx;
p.yPos += -dy;
}
}
Angle
一定是问题..我正在使用这种方法,它完美地运作:
private double getDegreesFromTouchEvent(float x, float y){
double delta_x = x - mCanvasWidth/2;
double delta_y = mCanvasHeight/2 - y;
double radians = Math.atan2(delta_y, delta_x);
return Math.toDegrees(radians);
}
然而,对于屏幕中心上方的触摸,它返回0-180,对于下面的触摸,它返回0到-180。这是一个问题吗?
答案 0 :(得分:2)
对此进行建模的最佳方法是使用parametric equations。无需使用trig函数。
class Path {
private final float x1,y1,x2,y2,distance;
public Path( float x1, float y1, float x2, float y2) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.distance = Math.sqrt( (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
}
public Point position( float t) {
return new Point( (1-t)*x1 + t*x2,
(1-t)*y1 + t*y2);
}
public Point position( float ticks, float speed) {
float t = ticks * speed / distance;
return position( t);
}
}
Path p = new Path(...);
// get halfway point
p.position( 0.5);
// get position after 100 ticks at 1.5 pixels per tick
p.position( 100, 1.5);
答案 1 :(得分:1)
从几何图形中,如果是直线,则可以使用极坐标计算其上的任何点。
如果找到线的角度:
ang = arctan((target_y - player_y) / (target_x - player_x))
然后可以使用trig:
找到线上的任何点x = cos(ang) * dist_along_line
y = sin(ang) * dist_along_line
如果您想要中点,那么您只需将dist_along_line设为该线长度的一半:
dist_along_line = line_length / 2 = (sqrt((target_y - player_y)^2 + (target_x - player_x)^2)) / 2
如果你想考虑100个刻度后的点,以X像素/刻度的速度移动:
dist_along_line = 100 * X
希望有人可以使用android libs更直接地评论一种方法。
答案 2 :(得分:0)
首先,Path类用于绘制,而不是用于计算射弹位置。
因此,您的Projectile类可以具有以下属性:
float positionX;
float positionY;
float velocityX;
float velocityY;
速度是从targetX,targetY,playerX和playerY计算的,如下所示:
float distance = sqrt(pow(targetX - playerX, 2)+pow(targetY - playerY, 2))
velocityX = (targetX - playerX) * speed / distance;
velocityY = (targetY - playerY) * speed / distance;
你在20个滴答之后的位置是
x = positionX + 20 * velocityX;
y = positionY + 20 * velocityY;
到达terget所需的时间是 ticksToTarget =距离/速度;
halp way point的位置是
halfWayX = positionX + velocityX * (tickToTarget / 2);
halfWayY = positionY + velocityY * (tickToTarget / 2);