[英]An analogue of the game "Worms". Physics. as3
Help please write a function of the projectile bounce off the ground.请帮忙写一个弹丸离地反弹的函数。 How do I find the angle of the collision, and what should be the reflection angle or at least learn the point of collision?
我如何找到碰撞的角度,反射角度应该是多少或至少了解碰撞点?
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);
}
}
}
There's several parts to this, and it seems you don't really know where to begin.这有几个部分,似乎您真的不知道从哪里开始。
Like the others have mentioned, your object (projectile, character, etc) movement should be represented by a vector , ie x and y velocity.就像其他人提到的那样,您的对象(弹丸、角色等)的运动应由向量表示,即 x 和 y 速度。 (A
Point
can represent a vector.) (一个
Point
可以代表一个向量。)
Next, to detect angle of collision on pixel-based terrain like you have, you can do a series of point (pixel) hit tests in a radius around the object .接下来,要像您一样检测基于像素的地形上的碰撞角度,您可以在对象周围的半径内进行一系列点(像素)命中测试。 This will give you a collection of hit points, which you define as vectors from the center of the object.
这将为您提供一组命中点,您将其定义为来自对象中心的向量。 Average the vectors and you have your collision angle.
平均向量,你有你的碰撞角度。
Here's a function I've used to do this:这是我用来执行此操作的函数:
/**
* 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);
}
This uses hitTestPoint()
but since your terrain is BitmapData
you could just use getPixel32()
and check the alpha value .这使用
hitTestPoint()
但由于您的地形是BitmapData
您可以只使用getPixel32()
并检查 alpha 值。
You could also use Collision Detection Kit , which uses a similar approach under the hood, with a bunch of extra features.您还可以使用Collision Detection Kit ,它在幕后使用类似的方法,并具有许多额外的功能。
Once you have the angle of collision, you can define a perpendicular vector as the collision surface to reflect the projectile's vector .一旦你有了碰撞的角度,你就可以定义一个垂直向量作为碰撞表面来反映射弹的向量。
That should get you started.这应该让你开始。
Flat, horizontal ground:平坦、水平地面:
//Check next movementstep
if((vel_y + pos_y) > terrainBottom) {
vel_y = -vel_y*DampingFactor;
}
for the general case you need to transform vel_x, vel_y into the case shown above using trigonometric functions.对于一般情况,您需要使用三角函数将 vel_x, vel_y 转换为上述情况。
As in the previous answer, use vel_x and vel_y to represent the motion of your character in vector form.与之前的答案一样,使用 vel_x 和 vel_y 以矢量形式表示角色的运动。 Use these values to increase your x and y co-ordinates at each iteration.
使用这些值在每次迭代时增加 x 和 y 坐标。 In your example you are using vel_x = 0, vel_y = 1, because you are increasing the y-coordinate by 1 each time.
在您的示例中,您使用 vel_x = 0, vel_y = 1,因为您每次都将 y 坐标增加 1。
If a surface has an an angle A measured counter-clockwise from the horizontal then x_vel and y_vel after bouncing (relfecting) on the surface will be x_vel.cos2A + y_vel.sin2A and x_vel.sin2A - y_vel.cos2A respectively.如果一个表面有一个从水平方向逆时针测量的角度 A,那么 x_vel 和 y_vel 在表面上反弹(反射)后将分别是 x_vel.cos2A + y_vel.sin2A 和 x_vel.sin2A - y_vel.cos2A。 To see how this is derived see planetmath
要了解这是如何得出的,请参阅Planetmath
This is for a perfectly elastic collision, ie no loss of speed on impact.这是为了完全弹性碰撞,即碰撞时没有速度损失。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.