Skip to content

Commit 28f6733

Browse files
committed
Implement motion_movesteps
1 parent b255dc7 commit 28f6733

File tree

3 files changed

+73
-1
lines changed

3 files changed

+73
-1
lines changed

src/blocks/motionblocks.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
// SPDX-License-Identifier: Apache-2.0
22

3+
#include <scratchcpp/iengine.h>
4+
#include <scratchcpp/compiler.h>
5+
#include <scratchcpp/sprite.h>
6+
#include <cmath>
7+
38
#include "motionblocks.h"
49

510
using namespace libscratchcpp;
611

12+
static const double pi = std::acos(-1); // TODO: Use std::numbers::pi in C++20
13+
714
std::string MotionBlocks::name() const
815
{
916
return "Motion";
@@ -21,4 +28,21 @@ Rgb MotionBlocks::color() const
2128

2229
void MotionBlocks::registerBlocks(IEngine *engine)
2330
{
31+
engine->addCompileFunction(this, "motion_movesteps", &compileMoveSteps);
32+
}
33+
34+
CompilerValue *MotionBlocks::compileMoveSteps(Compiler *compiler)
35+
{
36+
CompilerValue *steps = compiler->addInput("STEPS");
37+
compiler->addTargetFunctionCall("motion_movesteps", Compiler::StaticType::Void, { Compiler::StaticType::Number }, { steps });
38+
return nullptr;
39+
}
40+
41+
extern "C" void motion_movesteps(Target *target, double steps)
42+
{
43+
if (!target->isStage()) {
44+
Sprite *sprite = static_cast<Sprite *>(target);
45+
double dir = sprite->direction();
46+
sprite->setPosition(sprite->x() + std::sin(dir * pi / 180) * steps, sprite->y() + std::cos(dir * pi / 180) * steps);
47+
}
2448
}

src/blocks/motionblocks.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ class MotionBlocks : public IExtension
1515
Rgb color() const override;
1616

1717
void registerBlocks(IEngine *engine) override;
18+
19+
private:
20+
static CompilerValue *compileMoveSteps(Compiler *compiler);
1821
};
1922

2023
} // namespace libscratchcpp

test/blocks/motion_blocks_test.cpp

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,60 @@
1+
#include <scratchcpp/project.h>
2+
#include <scratchcpp/test/scriptbuilder.h>
3+
#include <scratchcpp/sprite.h>
4+
#include <scratchcpp/stage.h>
15
#include <enginemock.h>
26

37
#include "../common.h"
48
#include "blocks/motionblocks.h"
59

610
using namespace libscratchcpp;
11+
using namespace libscratchcpp::test;
712

813
class MotionBlocksTest : public testing::Test
914
{
1015
public:
11-
void SetUp() override { m_extension = std::make_unique<MotionBlocks>(); }
16+
void SetUp() override
17+
{
18+
m_extension = std::make_unique<MotionBlocks>();
19+
m_engine = m_project.engine().get();
20+
m_extension->registerBlocks(m_engine);
21+
}
1222

1323
std::unique_ptr<IExtension> m_extension;
24+
Project m_project;
25+
IEngine *m_engine = nullptr;
1426
EngineMock m_engineMock;
1527
};
28+
29+
TEST_F(MotionBlocksTest, MoveSteps)
30+
{
31+
{
32+
auto sprite = std::make_shared<Sprite>();
33+
ScriptBuilder builder(m_extension.get(), m_engine, sprite);
34+
35+
builder.addBlock("motion_movesteps");
36+
builder.addValueInput("STEPS", 30.25);
37+
38+
sprite->setX(5.2);
39+
sprite->setY(-0.25);
40+
sprite->setDirection(-61.42);
41+
42+
builder.build();
43+
builder.run();
44+
ASSERT_EQ(std::round(sprite->x() * 100) / 100, -21.36);
45+
ASSERT_EQ(std::round(sprite->y() * 100) / 100, 14.22);
46+
}
47+
48+
m_engine->clear();
49+
50+
{
51+
auto stage = std::make_shared<Stage>();
52+
ScriptBuilder builder(m_extension.get(), m_engine, stage);
53+
54+
builder.addBlock("motion_movesteps");
55+
builder.addValueInput("STEPS", 30.25);
56+
57+
builder.build();
58+
builder.run();
59+
}
60+
}

0 commit comments

Comments
 (0)