28static const SkScalar kBallSize = 0.04f;
29static const SkScalar kShadowOpacity = 0.40f;
30static const SkScalar kShadowParallax = 0.04f;
31static const SkScalar kBackgroundStroke = 0.01f;
32static const uint32_t kBackgroundDashCount = 20;
34static const SkScalar kBallSpeedMax = 0.0020f;
35static const SkScalar kBallSpeedMin = 0.0005f;
36static const SkScalar kBallSpeedFuzz = 0.0002f;
38static const SkScalar kTimeScaleMin = 0.0f;
39static const SkScalar kTimeScaleMax = 5.0f;
53 const SkScalar vInterval = vMod < intervalLen ? vMod :
P - vMod;
55 return vInterval +
min;
72 const auto r = rr->getRRect().rect();
85 const SkRect fieldBounds = kBounds.makeOutset(kBallSize / 2, kBallSize / 2);
89 kPaddleSize.
width() / 2,
90 kPaddleSize.
width() / 2);
91 fBall.initialize(ball,
95 fPaddle0.initialize(paddle,
99 fPaddle1.initialize(paddle,
106 bgPath.
moveTo(kBounds.left() , fieldBounds.
top())
107 .
lineTo(kBounds.right(), fieldBounds.
top())
111 for (uint32_t
i = 0;
i < kBackgroundDashCount; ++
i) {
112 bgPath.
moveTo(kBounds.centerX(),
113 kBounds.top() + (
i + 0.25f) * kBounds.height() / kBackgroundDashCount)
114 .
lineTo(kBounds.centerX(),
115 kBounds.top() + (
i + 0.75f) * kBounds.height() / kBackgroundDashCount);
121 bg_paint->setStrokeWidth(kBackgroundStroke);
127 ball_paint->setAntiAlias(
true);
128 paddle0_paint->setAntiAlias(
true);
129 paddle1_paint->setAntiAlias(
true);
130 shadow_paint->setAntiAlias(
true);
131 shadow_paint->setOpacity(kShadowOpacity);
151 this->updatePaddleStrategy();
157 fTimeScale =
SkTPin(fTimeScale - 0.1f, kTimeScaleMin, kTimeScaleMax);
160 fTimeScale =
SkTPin(fTimeScale + 0.1f, kTimeScaleMin, kTimeScaleMax);
163 fShowInval = !fShowInval;
172 if (fContentMatrix) {
180 fScene->render(canvas);
186 stroke.setAntiAlias(
true);
187 stroke.setColor(0xffff0000);
190 for (
const auto& r : ic) {
203 fPaddle0.posTick(dt);
204 fPaddle1.posTick(dt);
207 this->enforceConstraints();
209 fPaddle0.updateDom();
210 fPaddle1.updateDom();
233 update_pos(objectNode, corner);
237 shadowOffset.
scale(kShadowParallax);
238 const SkPoint shadowCorner = corner + shadowOffset;
240 update_pos(shadowNode, shadowCorner);
250 void enforceConstraints() {
252 if (fBall.pos.fY < kBounds.fTop || fBall.pos.fY >= kBounds.fBottom) {
253 fBall.spd.fY = -fBall.spd.fY;
254 fBall.pos.fY = box_reflect(fBall.pos.fY, kBounds.fTop, kBounds.fBottom);
258 if (fBall.pos.fX < kBounds.fLeft || fBall.pos.fX >= kBounds.fRight) {
259 fBall.spd.fX = this->fuzzBallSpeed(-fBall.spd.fX);
260 fBall.spd.fY = this->fuzzBallSpeed(fBall.spd.fY);
261 fBall.pos.fX = box_reflect(fBall.pos.fX, kBounds.fLeft, kBounds.fRight);
262 this->updatePaddleStrategy();
271 return sign *
SkTPin(fuzzed, kBallSpeedMin, kBallSpeedMax);
274 void updatePaddleStrategy() {
275 Object* pitcher = fBall.spd.fX > 0 ? &fPaddle0 : &fPaddle1;
276 Object* catcher = fBall.spd.fX > 0 ? &fPaddle1 : &fPaddle0;
279 std::tie(t, yIntercept) = find_yintercept(fBall.pos, fBall.spd, kBounds);
282 pitcher->spd.fY = (kBounds.centerY() - pitcher->pos.fY) / t;
285 catcher->spd.fY = (yIntercept - catcher->pos.fY) / t;
288 std::unique_ptr<sksg::Scene> fScene;
290 Object fPaddle0, fPaddle1, fBall;
295 bool fShowInval =
false;
constexpr SkColor SK_ColorBLUE
constexpr SkColor SK_ColorRED
constexpr SkColor SK_ColorBLACK
constexpr SkColor SK_ColorGREEN
static int sign(SkScalar x)
#define SkScalarMod(x, y)
static constexpr const T & SkTPin(const T &x, const T &lo, const T &hi)
bool onChar(SkUnichar uni) override
void draw(SkCanvas *canvas) override
bool animate(double nanos) override
void load(SkScalar w, SkScalar h) override
void resize(SkScalar w, SkScalar h) override
void drawRect(const SkRect &rect, const SkPaint &paint)
static SkMatrix RectToRect(const SkRect &src, const SkRect &dst, ScaleToFit mode=kFill_ScaleToFit)
void setColor(SkColor color)
void setAntiAlias(bool aa)
@ kStroke_Style
set to stroke geometry
SkPathBuilder & lineTo(SkPoint pt)
SkPathBuilder & moveTo(SkPoint pt)
static SkRRect MakeOval(const SkRect &oval)
static SkRRect MakeRectXY(const SkRect &rect, SkScalar xRad, SkScalar yRad)
SkScalar nextRangeScalar(SkScalar min, SkScalar max)
static sk_sp< Color > Make(SkColor c)
static sk_sp< Draw > Make(sk_sp< GeometryNode > geo, sk_sp< PaintNode > paint)
static sk_sp< Group > Make()
static sk_sp< Matrix > Make(const T &m)
static sk_sp< Path > Make()
static sk_sp< RRect > Make()
static std::unique_ptr< Scene > Make(sk_sp< RenderNode > root)
static float max(float r, float g, float b)
static float min(float r, float g, float b)
static SkMSec NanosToMSec(double nanos)
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
static constexpr SkPoint Make(float x, float y)
void scale(float scale, SkPoint *dst) const
constexpr float y() const
constexpr float x() const
SkScalar fBottom
larger y-axis bounds
constexpr float left() const
constexpr float top() const
SkScalar fLeft
smaller x-axis bounds
SkScalar fRight
larger x-axis bounds
constexpr float right() const
constexpr float centerY() const
static constexpr SkRect MakeWH(float w, float h)
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
constexpr float bottom() const
SkScalar fTop
smaller y-axis bounds
static constexpr SkSize Make(SkScalar w, SkScalar h)