Of course, snow landing is not difficult, let’s do some fun, what if there is an obstacle on the ground, this scene is actually like our app page at the bottom of a row of buttons, the more obvious is the floating button, we want to drop snow on their head, what should we do?


1. What kind of snowflakes hit obstacles

It’s actually quite simple, assuming that snowflakes are all balls, no, they’re all round, as long as:

Distance from snowflake center to obstacle center <= obstacle radius,

Think he hit the wall:

Assuming obstacle attributes:

  Offset circlePosition = Offset(screenSize.width/2,  screenSize.height);
  double circleRadius = 50;
Copy the code

So here’s a way to tell:

Bool _checkDangerous(SnowBasicInfo snow) {// We pass snow x, Double xToBarrier = (circlePosition.dx - (snow.x)).abs(); double yToBarrier = (circlePosition.dy - (snow.y)).abs(); Double distance = pow((xToBarrier * xToBarrier + yToBarrier* yToBarrier), 0.5); return distance < circleRadius; }Copy the code

Use the above method to determine if snowflakes are dangerous, but what if you say snowflakes are bigger than obstacles? That you say what I do ~ of course whatever he do, I don’t do anyway.

2. What if YOU hit a wall

When a snowflake hits a wall, let’s say it hits the ground the same way it does, it turns into a strip, well, it’s just an arc, not a line segment, so the question is, how do you figure out arcs

Here, pick up your math book and look at this picture:

The blue part of the figure is actually the arc we want. The small circle is the snowflake, and the large circle is the obstacle. The small circle is calculated separately on the left and right side of the obstacle.

In the figure on the left, we only need to ask the Angle θ corresponding to the position of point S to know the starting Angle of the arc, radian corresponds to 2 times of Angle 1, radius is the radius of the obstacle.

  • Small r is the radius of snowflake, which is determined by the snowflake variation coefficientsnow.r And the width of the snowflake map:snow.r * snowImage.width.toDouble() / 2
  • Big R is the radius of obstacle:circleRadius
  • centerX, centerYIs the coordinates of obstacles
  • x, yIs the coordinates of snowflake center at that time:(snow.x, snow.y)


On the right, I just want Angle 1, which is relatively easy,

I’ve written all the formulas in the diagram and now I just have to code them:

As with snow landing, we add attributes to snow:

class SnowBasicInfo { ... Rect touchRect; // startAngle double startAngle; // Double swipeAngle; // double stroke; Bool touchBarrier = false; . }Copy the code

As with the previous snow fall, we expect the snow to increase over time, but we have to use the same stupid method as before, which is a growth factor:

var multip = pow((snows.where((element) => element.touchRect != null).length / 10 ), 0.5);
Copy the code

We add this logic before the snow melts:

if(snow.r ! = 0 && (_checkDangerous(snow) || snow.touchBarrier)) { snow.touchBarrier = true; if(snow.touchRect == null) { var multip = pow((snows.where((element) => element.touchRect ! = null).length / 10), 0.5); var angleSnow = atan((snow.r * snowImage.width.toDouble() / 2) / circleRadius); snow.touchRect = Rect.fromCircle(center: circlePosition, radius: circleRadius); Snow. Stroke = multip * snow. R * 10; snow.startAngle = snow.x < circlePosition.dx ? pi + asin((circlePosition.dy - snow.y) / circleRadius) - angleSnow : 2* pi -(asin((circlePosition.dy - snow.y) / circleRadius)); snow.swipeAngle = snow.x < circlePosition.dx ? angleSnow * 2 * snow.r / 2: -angleSnow * 2 * snow.r / 2; } else {} // Canvas. DrawArc uses the same stroke as before on the ground oh canvas. DrawArc (snow. TouchRect, snow. false, snowBarrierPainter.. strokeWidth = snow.stroke); continue; }Copy the code

Ok, in fact, this is just a translation of the above draft, so that you can see the effect of the GIF at the top, is it easy as long as you think carefully?

3. What if snow could slide down the barrier…

We can choose to add a special effect, when the snow falls on the obstacle, the snow on the obstacle will slowly slide against the obstacle and get thinner and thinner over time

After all, I’ve never seen snow before, only xjbyy…

It doesn’t work very well, so I don’t do it on top. It’s as simple as adding the initial Angle of rotation to the side after the snow hits the wall:

if(snow.touchRect == null) { ... } else { snow.startAngle = snow.x <= circlePosition.dx ? snow.startAngle - pi / 1000 : snow.startAngle + pi / 1000; if(snow.startAngle < pi || snow.startAngle > 2 * pi) { snow.invalid = true; snow.melted = true; continue; } snow.stroke = snow.stroke -0.001; }Copy the code

At this point, the story is over, if you have a better idea, come to touch fish duck ~

Touch more fish?

  • Make snow fall on your screen – Prequel
  • Let snow fall on your screen – Post ii
  • Make snow fall on your screen – Extras

If you are interested in related content, welcome to touch fish duck: github.com/SpiciedCrab…