【问题标题】:An analogue of the game "Worms". Physics. as3游戏“蠕虫”的类似物。物理。 as3
【发布时间】:2015-09-24 20:10:46
【问题描述】:

请写一个弹丸从地面反弹的函数。我如何找到碰撞的角度,反射角应该是多少,或者至少知道碰撞点?

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);
        }
    }
}

【问题讨论】:

  • 请描述您当前看到的错误或不良行为。
  • 您发布的代码似乎根本没有任何弹丸。

标签: actionscript-3


【解决方案1】:

这有几个部分,看起来你真的不知道从哪里开始。

就像其他人提到的那样,您的对象(弹丸、角色等)的运动应该由vector 表示,即x 和y 速度。 (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的碰撞表面。

这应该让你开始。

【讨论】:

  • 谢谢!在职的。超级。
【解决方案2】:

平坦的水平地面:

//Check next movementstep
if((vel_y + pos_y) > terrainBottom) {
   vel_y = -vel_y*DampingFactor;
}

对于一般情况,您需要使用三角函数将 vel_x、vel_y 转换为上述情况。

【讨论】:

  • if((vel_y + pos_y) > terrainBottom) 它是什么?
  • 弹丸在y方向的速度,弹丸的y位置和地面的y坐标。
【解决方案3】:

与上一个答案一样,使用 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

这是为了完美的弹性碰撞,即在撞击时不会损失速度。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多