Help us understand the problem. What is going on with this article?

Throwing ball on PowerApps

More than 1 year has passed since last update.

In many games, it is very important to naturally realise physical phenomena such as jumps, collisions, reflections, and bounds.
My previous post, it has been shown that the motion of projectile with air resistance and gravity can be realized on PowerApps.

In this post, I would explain how we can treat bounce and reflection events on PowerApps.
In addition to the implementation on PowerApps, will refer to a basic approach for these events with some mathematical expressions.

Physics

Throwing ball

First, the motion of throwing ball is described by Equation of motion for Projectile with gravity and air resistance.
motionofball.PNG
It is very important to estimate velocity u(t) and v(t) in order to realise bounce and reflection.
Next, we consider the event of bounce and reflection, it is not much difficult.

Bounce

Both before & after the bounce, the motion of ball is given by EoM of projectile.
The only difference is its velocity.

As you can find from following figure, vertical component of velocity is flipped after the bounce, and (may) bit decreased which is expressed by ε*.
* ε : coefficient of restitution.
Value of ε is determined by material of floor/wall. If floor is made by metal, ε is almost 1 (no velocity loss), but if floor is dirt, ε becomes much smaller than 1.

bounce.PNG
So, the motion of ball after bounce is projectile motion with initial velocity ua and va

Reflection

As is the case in bounce, the effect of reflection is simply realised by following relation. In contrast to the case of bounce, horizontal component of velocity becomes opposite to one before reflection.
reflection.PNG

PowerApps

Now, you can implement these motion and effects into PowerApps!
Fine things aside, my app is constructed by 3 objects (ball, wall, and floor)+ 1 timer control.

X and Y Properties of ball object are as;

Ball.X
X0+ (vx0/AirResist.Text)* (1-Exp(-1*AirResist.Text * T))
Ball.Y
Y0-(vy0/AirResist.Text)*(1+GravityConst.Text/(AirResist.Text*vy0)) * (1-Exp(-1*AirResist.Text * T)) + GravityConst.Text * T/AirResist.Text

where X0, Y0 are initial position of ball, and vx0 , vy0 are initial velocity.

In order to move ball object, context variable T (time) is updated on every timer end;

Timer.OnTimerEnd
T: T + Timer.Duration/1000

Typically Timer.Duration is 50~100 millisecond. The ball now moves, but not sufficient.
We have to implement the effect of bounce and reflection. The whole block of code for OnTimerEnd is given by;

Timer.OnTimerEnd
If(
    //[Reflection] 
    //1. Flip sign of velocity X and set as initial velocity vx0
    //2. Initialize time T (Recast @next OnTimerEnd)
    Xnow > MainScreen.Width-Wall.Width-Ball.Width,
    UpdateContext(
        {
            T:0,
            vx0: -1.0*vxnow* (100-VelocityLoss.Text)/100,
            vy0: vynow,
            X0: Ball.X,
            Y0: Ball.Y,
            Xnow: Ball.X
        }
    ),
    If(
        //[Bounce] 
        //1. Flip sign of velocity Y and set as initial velocity vy0
        //2. Initialize time T (Recast @next OnTimerEnd)
        Ynow > MainScreen.Height-Floor.Height-Ball.Height,
        UpdateContext(
            {
                T: 0,
                X0: Ball.X,
                Y0: Ball.Y,
                vx0: vxnow,
                vy0: -1.0*vynow * (100-VelocityLoss.Text)/100,
                Ynow: Ball.Y
            }
        ),
        UpdateContext(
            {
                vxnow: vx0 * Exp(-1 * AirResist.Text * (T+Timer.Duration/1000)),
                vynow: vy0 * (1 + GravityConst.Text/(AirResist.Text * vy0)) * (Exp(-1 * AirResist.Text * (T + Timer.Duration/1000))) - GravityConst.Text/AirResist.Text,
                //Xnow,Ynow show the position of Ball at the next step
                Xnow: X0 + (vx0/AirResist.Text) * (1-Exp(-1 * AirResist.Text * (T + 2*Timer.Duration/1000))),
                Ynow: Y0-(vy0/AirResist.Text) * (1 + GravityConst.Text/(AirResist.Text * vy0)) * (1-Exp(-1 * AirResist.Text * (T + 2*Timer.Duration/1000))) + GravityConst.Text * (T + 2*Timer.Duration/1000)/AirResist.Text,
                T: T + Timer.Duration/1000
            }
        )
    )
)

First part of above, Xnow > MainScreen.Width-Wall.Width-Ball.Width, determine whether the ball collides with wall or not. It true, set current velocity/position into initial velocity/position for next projectile.
Also, second part, Ynow > MainScreen.Height-Floor.Height-Ball.Height, determine the condition of bounce event. If true, as in the case of reflection, set current velocity/position into initial velocity/position for next projectile.

That's all physics and implementation of My App!
You can download this app from PowerApps Community Gallery !

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした