Skip to content

Commit 0c39def

Browse files
committed
Implement motion_setrotationstyle block
1 parent 25c7014 commit 0c39def

File tree

3 files changed

+124
-0
lines changed

3 files changed

+124
-0
lines changed

src/blocks/motionblocks.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <scratchcpp/compilerconstant.h>
66
#include <scratchcpp/sprite.h>
77
#include <scratchcpp/input.h>
8+
#include <scratchcpp/field.h>
89
#include <scratchcpp/value.h>
910
#include <scratchcpp/executioncontext.h>
1011
#include <scratchcpp/thread.h>
@@ -52,6 +53,7 @@ void MotionBlocks::registerBlocks(IEngine *engine)
5253
engine->addCompileFunction(this, "motion_changeyby", &compileChangeYBy);
5354
engine->addCompileFunction(this, "motion_sety", &compileSetY);
5455
engine->addCompileFunction(this, "motion_ifonedgebounce", &compileIfOnEdgeBounce);
56+
engine->addCompileFunction(this, "motion_setrotationstyle", &compileSetRotationStyle);
5557
}
5658

5759
CompilerValue *MotionBlocks::compileMoveSteps(Compiler *compiler)
@@ -299,6 +301,32 @@ CompilerValue *MotionBlocks::compileIfOnEdgeBounce(Compiler *compiler)
299301
return nullptr;
300302
}
301303

304+
CompilerValue *MotionBlocks::compileSetRotationStyle(Compiler *compiler)
305+
{
306+
Target *target = compiler->target();
307+
308+
if (target->isStage())
309+
return nullptr;
310+
311+
Sprite *sprite = static_cast<Sprite *>(target);
312+
Field *field = compiler->field("STYLE");
313+
314+
if (!field)
315+
return nullptr;
316+
317+
std::string option = field->value().toString();
318+
sprite->setRotationStyle(field->value().toString());
319+
320+
if (option == "left-right")
321+
compiler->addTargetFunctionCall("motion_set_left_right_style");
322+
else if (option == "don't rotate")
323+
compiler->addTargetFunctionCall("motion_set_do_not_rotate_style");
324+
else if (option == "all around")
325+
compiler->addTargetFunctionCall("motion_set_all_around_style");
326+
327+
return nullptr;
328+
}
329+
302330
extern "C" void motion_movesteps(Sprite *sprite, double steps)
303331
{
304332
double dir = sprite->direction();
@@ -667,6 +695,21 @@ extern "C" void motion_ifonedgebounce(Sprite *sprite)
667695
sprite->setPosition(fencedX, fencedY);
668696
}
669697

698+
extern "C" void motion_set_left_right_style(Sprite *sprite)
699+
{
700+
sprite->setRotationStyle(Sprite::RotationStyle::LeftRight);
701+
}
702+
703+
extern "C" void motion_set_do_not_rotate_style(Sprite *sprite)
704+
{
705+
sprite->setRotationStyle(Sprite::RotationStyle::DoNotRotate);
706+
}
707+
708+
extern "C" void motion_set_all_around_style(Sprite *sprite)
709+
{
710+
sprite->setRotationStyle(Sprite::RotationStyle::AllAround);
711+
}
712+
670713
extern "C" double motion_xposition(Sprite *sprite)
671714
{
672715
return sprite->x();

src/blocks/motionblocks.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class MotionBlocks : public IExtension
3131
static CompilerValue *compileChangeYBy(Compiler *compiler);
3232
static CompilerValue *compileSetY(Compiler *compiler);
3333
static CompilerValue *compileIfOnEdgeBounce(Compiler *compiler);
34+
static CompilerValue *compileSetRotationStyle(Compiler *compiler);
3435
};
3536

3637
} // namespace libscratchcpp

test/blocks/motion_blocks_test.cpp

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1822,3 +1822,83 @@ TEST_F(MotionBlocksTest, IfOnEdgeBounce)
18221822
builder.run();
18231823
}
18241824
}
1825+
1826+
TEST_F(MotionBlocksTest, SetRotationStyle)
1827+
{
1828+
// left-right
1829+
{
1830+
auto sprite = std::make_shared<Sprite>();
1831+
ScriptBuilder builder(m_extension.get(), m_engine, sprite);
1832+
1833+
builder.addBlock("motion_setrotationstyle");
1834+
builder.addDropdownField("STYLE", "left-right");
1835+
1836+
builder.build();
1837+
builder.run();
1838+
ASSERT_EQ(sprite->rotationStyle(), Sprite::RotationStyle::LeftRight);
1839+
}
1840+
1841+
m_engine->clear();
1842+
1843+
// don't rotate
1844+
{
1845+
auto sprite = std::make_shared<Sprite>();
1846+
ScriptBuilder builder(m_extension.get(), m_engine, sprite);
1847+
1848+
builder.addBlock("motion_setrotationstyle");
1849+
builder.addDropdownField("STYLE", "don't rotate");
1850+
1851+
builder.build();
1852+
builder.run();
1853+
ASSERT_EQ(sprite->rotationStyle(), Sprite::RotationStyle::DoNotRotate);
1854+
}
1855+
1856+
m_engine->clear();
1857+
1858+
// all around
1859+
{
1860+
auto sprite = std::make_shared<Sprite>();
1861+
ScriptBuilder builder(m_extension.get(), m_engine, sprite);
1862+
1863+
builder.addBlock("motion_setrotationstyle");
1864+
builder.addDropdownField("STYLE", "all around");
1865+
builder.build();
1866+
1867+
sprite->setRotationStyle(Sprite::RotationStyle::DoNotRotate);
1868+
builder.run();
1869+
ASSERT_EQ(sprite->rotationStyle(), Sprite::RotationStyle::AllAround);
1870+
}
1871+
1872+
m_engine->clear();
1873+
1874+
// invalid
1875+
{
1876+
auto sprite = std::make_shared<Sprite>();
1877+
ScriptBuilder builder(m_extension.get(), m_engine, sprite);
1878+
1879+
builder.addBlock("motion_setrotationstyle");
1880+
builder.addDropdownField("STYLE", "invalid");
1881+
builder.build();
1882+
1883+
sprite->setRotationStyle(Sprite::RotationStyle::LeftRight);
1884+
builder.run();
1885+
ASSERT_EQ(sprite->rotationStyle(), Sprite::RotationStyle::LeftRight);
1886+
1887+
sprite->setRotationStyle(Sprite::RotationStyle::AllAround);
1888+
builder.run();
1889+
ASSERT_EQ(sprite->rotationStyle(), Sprite::RotationStyle::AllAround);
1890+
}
1891+
1892+
m_engine->clear();
1893+
1894+
{
1895+
auto stage = std::make_shared<Stage>();
1896+
ScriptBuilder builder(m_extension.get(), m_engine, stage);
1897+
1898+
builder.addBlock("motion_setrotationstyle");
1899+
builder.addDropdownField("STYLE", "all around");
1900+
1901+
builder.build();
1902+
builder.run();
1903+
}
1904+
}

0 commit comments

Comments
 (0)