简体   繁体   English

游戏“蠕虫”的模拟。 物理。 as3

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM