请帮助写下弹丸从地面反弹的功能。如何找到碰撞的角度,反射角应该是什么,或者至少要了解碰撞点?
package {
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.geom.Point;
import flash.geom.Matrix;
import flash.events.Event;
import flash.events.MouseEvent;
public class worms extends Sprite {
public var terrain_bmpd=new BitmapData(550,200,true,0xFF00FF00);//This is the Bitmap of the terrain
public var terrain_bmp=new Bitmap(terrain_bmpd);//and this the BitmapData
public var character=new Sprite();//The character will work as a worm
public var hole=new Sprite();//That's the hole we need
public var hole_matrix:Matrix;//The hole_matrix is used to set the position of the hole
public var left_foot:Point;
public var right_foot:Point;//These are the feet of the character. We will use it to check collisions
public function worms() {
draw_objects();//This function draws the character, the terrain and the hole.
stage.addEventListener(Event.ENTER_FRAME,fall);
}
public function fall(e:Event) {
/*This function will move down the character if there isn't a collision
between the terrain and the "feet" of the character*/
for (var i:int=0; i<10; i++) {//We want to check every pixel if there's acollision, so we won't move the character 10 pixels all at once
left_foot=new Point(character.x-5,character.y+10);
right_foot=new Point(character.x+5,character.y+10);
if (!(terrain_bmpd.hitTest(new
Point(terrain_bmp.x,terrain_bmp.y),0x01,left_foot))&&!(terrain_bmpd.hitTest(new Point(terrain_bmp.x,terrain_bmp.y),0x01,right_foot))) {
character.y++;//If there aren't any collisions, make the character fall one pixel
}
}
}
public function draw_objects() {
terrain_bmp.y=200;//The terrain shouldn't be at the top of the stage!
stage.addChild(terrain_bmp);//We can make the terrain visible
character.graphics.beginFill(0x0000FF);//Let's draw the character. It will be a blue rectangle.
character.graphics.drawRect(-5,-10,10,20);
character.x=250;
stage.addChild(character);
hole.graphics.beginFill(0x000000);//Now we draw the hole. It doesn't matter the colour.
hole.graphics.drawCircle(0,0,30);
}
}
}
答案 0 :(得分:1)
这有几个部分,看起来你真的不知道从哪里开始。
与其他人提到的一样,你的物体(抛射物,角色等)的运动应该用vector表示,即x和y速度。 (A Point
可以表示向量。)
接下来,要像你一样检测基于像素的地形上的碰撞角度,你可以在radius around the object中进行一系列点(像素)命中测试。这将为您提供一组生命点,您可以从对象的中心定义为矢量。 Average the vectors and you have your collision angle.
这是我以前执行此操作的功能:
/**
* Test for a hit against a shape based on a point and radius,
* returns the angle of the hit or NaN if no hit.
* Like hitTestPoint, xPos and yPos must be in stage coordinates.
*/
function hitTestAngle(shape:Sprite, xPos:Number, yPos:Number, radius:Number, samples:uint = 90):Number {
const PI2:Number = Math.PI * 2, SAMPLE:Number = 1 / samples;
var dx:Number, dy:Number, a:Number, tx:Number = 0, ty:Number = 0, hits:int = 0;
var i:int = samples;
while(i--){
a = PI2 * (i * SAMPLE);
dx = radius * Math.cos(a);
dy = radius * Math.sin(a);
if(shape.hitTestPoint(xPos + dx, yPos + dy, true)){
hits++;
tx += dx;
ty += dy;
}
}
if(!hits)
return NaN;
return Math.atan2(ty, tx) * (180 / Math.PI);
}
这使用hitTestPoint()
,但由于您的地形为BitmapData
,因此您可以使用getPixel32()
和check the alpha value。
你也可以使用Collision Detection Kit,它使用类似的方法,带有一堆额外的功能。
一旦有了碰撞角度,就可以将perpendicular vector定义为reflect the projectile's vector的碰撞面。
这应该让你开始。
答案 1 :(得分:0)
平坦的水平地面:
//Check next movementstep
if((vel_y + pos_y) > terrainBottom) {
vel_y = -vel_y*DampingFactor;
}
对于一般情况,您需要使用三角函数将vel_x,vel_y转换为上面显示的情况。
答案 2 :(得分:0)
与上一个答案一样,使用vel_x和vel_y来表示角色在矢量形式中的运动。使用这些值可以在每次迭代时增加x和y坐标。在您的示例中,您使用的是vel_x = 0,vel_y = 1,因为您每次都将y坐标增加1。
如果表面有一个角度A,从水平方向逆时针测量,那么x_vel和y_vel在表面上反弹(再反射)之后将是 分别为x_vel.cos2A + y_vel.sin2A和x_vel.sin2A - y_vel.cos2A。要查看其来源,请参阅planetmath
这是一次完美的弹性碰撞,即撞击时没有速度损失。