Skip to content

Commit 14c3d56

Browse files
authored
Merge pull request #570 from scratchcpp/sensing_colositouchingcolor
Implement sensing_coloristouchingcolor block
2 parents eea2f63 + 4d57b32 commit 14c3d56

File tree

17 files changed

+145
-0
lines changed

17 files changed

+145
-0
lines changed

include/scratchcpp/ispritehandler.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ class LIBSCRATCHCPP_EXPORT ISpriteHandler
9292

9393
/*! Used to check whether the sprite touches the given color. */
9494
virtual bool touchingColor(const Value &color) const = 0;
95+
96+
/*! Used to check whether the mask part of the sprite touches the given color. */
97+
virtual bool touchingColor(const Value &color, const Value &mask) const = 0;
9598
};
9699

97100
} // namespace libscratchcpp

include/scratchcpp/istagehandler.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ class LIBSCRATCHCPP_EXPORT IStageHandler
6969

7070
/*! Used to check whether the stage touches the given color. */
7171
virtual bool touchingColor(const Value &color) const = 0;
72+
73+
/*! Used to check whether the mask part of the stage touches the given color. */
74+
virtual bool touchingColor(const Value &color, const Value &mask) const = 0;
7275
};
7376

7477
} // namespace libscratchcpp

include/scratchcpp/sprite.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ class LIBSCRATCHCPP_EXPORT Sprite
8282

8383
bool touchingPoint(double x, double y) const override;
8484
bool touchingColor(const Value &color) const override;
85+
bool touchingColor(const Value &color, const Value &mask) const override;
8586

8687
void setGraphicsEffectValue(IGraphicsEffect *effect, double value) override;
8788

include/scratchcpp/stage.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class LIBSCRATCHCPP_EXPORT Stage : public Target
5656

5757
bool touchingPoint(double x, double y) const override;
5858
bool touchingColor(const Value &color) const override;
59+
bool touchingColor(const Value &color, const Value &mask) const override;
5960

6061
void setGraphicsEffectValue(IGraphicsEffect *effect, double value) override;
6162

include/scratchcpp/target.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ class LIBSCRATCHCPP_EXPORT Target
101101
virtual bool touchingPoint(double x, double y) const;
102102
bool touchingEdge() const;
103103
virtual bool touchingColor(const Value &color) const;
104+
virtual bool touchingColor(const Value &color, const Value &mask) const;
104105

105106
double graphicsEffectValue(IGraphicsEffect *effect) const;
106107
virtual void setGraphicsEffectValue(IGraphicsEffect *effect, double value);

src/blocks/sensingblocks.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ void SensingBlocks::registerBlocks(IEngine *engine)
3232
// Blocks
3333
engine->addCompileFunction(this, "sensing_touchingobject", &compileTouchingObject);
3434
engine->addCompileFunction(this, "sensing_touchingcolor", &compileTouchingColor);
35+
engine->addCompileFunction(this, "sensing_coloristouchingcolor", &compileColorIsTouchingColor);
3536
engine->addCompileFunction(this, "sensing_distanceto", &compileDistanceTo);
3637
engine->addCompileFunction(this, "sensing_askandwait", &compileAskAndWait);
3738
engine->addCompileFunction(this, "sensing_answer", &compileAnswer);
@@ -60,6 +61,7 @@ void SensingBlocks::registerBlocks(IEngine *engine)
6061
// Inputs
6162
engine->addInput(this, "TOUCHINGOBJECTMENU", TOUCHINGOBJECTMENU);
6263
engine->addInput(this, "COLOR", COLOR);
64+
engine->addInput(this, "COLOR2", COLOR2);
6365
engine->addInput(this, "DISTANCETOMENU", DISTANCETOMENU);
6466
engine->addInput(this, "QUESTION", QUESTION);
6567
engine->addInput(this, "KEY_OPTION", KEY_OPTION);
@@ -139,6 +141,13 @@ void SensingBlocks::compileTouchingColor(Compiler *compiler)
139141
compiler->addFunctionCall(&touchingColor);
140142
}
141143

144+
void SensingBlocks::compileColorIsTouchingColor(Compiler *compiler)
145+
{
146+
compiler->addInput(COLOR2); // target color
147+
compiler->addInput(COLOR); // mask color
148+
compiler->addFunctionCall(&colorIsTouchingColor);
149+
}
150+
142151
void SensingBlocks::compileDistanceTo(Compiler *compiler)
143152
{
144153
Input *input = compiler->input(DISTANCETOMENU);
@@ -525,6 +534,12 @@ unsigned int SensingBlocks::touchingColor(VirtualMachine *vm)
525534
return 0;
526535
}
527536

537+
unsigned int SensingBlocks::colorIsTouchingColor(VirtualMachine *vm)
538+
{
539+
vm->replaceReturnValue(vm->target()->touchingColor(*vm->getInput(0, 2), *vm->getInput(1, 2)), 2);
540+
return 1;
541+
}
542+
528543
unsigned int SensingBlocks::keyPressed(VirtualMachine *vm)
529544
{
530545
vm->replaceReturnValue(vm->engine()->keyPressed(vm->getInput(0, 1)->toString()), 1);

src/blocks/sensingblocks.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class SensingBlocks : public IBlockSection
2222
{
2323
TOUCHINGOBJECTMENU,
2424
COLOR,
25+
COLOR2,
2526
DISTANCETOMENU,
2627
QUESTION,
2728
KEY_OPTION,
@@ -64,6 +65,7 @@ class SensingBlocks : public IBlockSection
6465

6566
static void compileTouchingObject(Compiler *compiler);
6667
static void compileTouchingColor(Compiler *compiler);
68+
static void compileColorIsTouchingColor(Compiler *compiler);
6769
static void compileDistanceTo(Compiler *compiler);
6870
static void compileAskAndWait(Compiler *compiler);
6971
static void compileAnswer(Compiler *compiler);
@@ -95,6 +97,8 @@ class SensingBlocks : public IBlockSection
9597

9698
static unsigned int touchingColor(VirtualMachine *vm);
9799

100+
static unsigned int colorIsTouchingColor(VirtualMachine *vm);
101+
98102
static unsigned int keyPressed(VirtualMachine *vm);
99103
static unsigned int mouseDown(VirtualMachine *vm);
100104
static unsigned int mouseX(VirtualMachine *vm);

src/scratch/sprite.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,15 @@ bool Sprite::touchingColor(const Value &color) const
503503
return impl->iface->touchingColor(color);
504504
}
505505

506+
/*! Overrides Target#touchingColor(). */
507+
bool Sprite::touchingColor(const Value &color, const Value &mask) const
508+
{
509+
if (!impl->iface)
510+
return false;
511+
512+
return impl->iface->touchingColor(color, mask);
513+
}
514+
506515
/*! Overrides Target#setGraphicsEffectValue(). */
507516
void Sprite::setGraphicsEffectValue(IGraphicsEffect *effect, double value)
508517
{

src/scratch/stage.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,15 @@ bool Stage::touchingColor(const Value &color) const
185185
return impl->iface->touchingColor(color);
186186
}
187187

188+
/*! Overrides Target#touchingColor(). */
189+
bool Stage::touchingColor(const Value &color, const Value &mask) const
190+
{
191+
if (!impl->iface)
192+
return false;
193+
194+
return impl->iface->touchingColor(color, mask);
195+
}
196+
188197
/*! Overrides Target#setGraphicsEffectValue(). */
189198
void Stage::setGraphicsEffectValue(IGraphicsEffect *effect, double value)
190199
{

src/scratch/target.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,12 @@ bool Target::touchingColor(const Value &color) const
520520
return false;
521521
}
522522

523+
/*! Returns true if the mask part of the Target is touching the given color (RGB triplet). */
524+
bool Target::touchingColor(const Value &color, const Value &mask) const
525+
{
526+
return false;
527+
}
528+
523529
/*! Returns the value of the given graphics effect. */
524530
double Target::graphicsEffectValue(IGraphicsEffect *effect) const
525531
{

test/blocks/sensing_blocks_test.cpp

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ TEST_F(SensingBlocksTest, RegisterBlocks)
127127
// Blocks
128128
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "sensing_touchingobject", &SensingBlocks::compileTouchingObject));
129129
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "sensing_touchingcolor", &SensingBlocks::compileTouchingColor));
130+
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "sensing_coloristouchingcolor", &SensingBlocks::compileColorIsTouchingColor));
130131
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "sensing_distanceto", &SensingBlocks::compileDistanceTo));
131132
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "sensing_askandwait", &SensingBlocks::compileAskAndWait));
132133
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "sensing_answer", &SensingBlocks::compileAnswer));
@@ -155,6 +156,7 @@ TEST_F(SensingBlocksTest, RegisterBlocks)
155156
// Inputs
156157
EXPECT_CALL(m_engineMock, addInput(m_section.get(), "TOUCHINGOBJECTMENU", SensingBlocks::TOUCHINGOBJECTMENU));
157158
EXPECT_CALL(m_engineMock, addInput(m_section.get(), "COLOR", SensingBlocks::COLOR));
159+
EXPECT_CALL(m_engineMock, addInput(m_section.get(), "COLOR2", SensingBlocks::COLOR2));
158160
EXPECT_CALL(m_engineMock, addInput(m_section.get(), "DISTANCETOMENU", SensingBlocks::DISTANCETOMENU));
159161
EXPECT_CALL(m_engineMock, addInput(m_section.get(), "QUESTION", SensingBlocks::QUESTION));
160162
EXPECT_CALL(m_engineMock, addInput(m_section.get(), "KEY_OPTION", SensingBlocks::KEY_OPTION));
@@ -454,6 +456,79 @@ TEST_F(SensingBlocksTest, TouchingColorImpl)
454456
ASSERT_TRUE(vm.getInput(0, 1)->toBool());
455457
}
456458

459+
TEST_F(SensingBlocksTest, ColorIsTouchingColor)
460+
{
461+
Compiler compiler(&m_engineMock);
462+
463+
// color (#FF00FF) is touching color (#FFFF00)
464+
auto block1 = std::make_shared<Block>("a", "sensing_coloristouchingcolor");
465+
addValueInput(block1, "COLOR", SensingBlocks::COLOR, "#FF00FF");
466+
addValueInput(block1, "COLOR2", SensingBlocks::COLOR2, "#FFFF00");
467+
468+
// color (null block) is touching color (null block)
469+
auto block2 = std::make_shared<Block>("b", "sensing_coloristouchingcolor");
470+
addDropdownInput(block2, "COLOR", SensingBlocks::COLOR, "", createNullBlock("c"));
471+
addDropdownInput(block2, "COLOR2", SensingBlocks::COLOR2, "", createNullBlock("d"));
472+
473+
compiler.init();
474+
475+
EXPECT_CALL(m_engineMock, functionIndex(&SensingBlocks::colorIsTouchingColor)).WillOnce(Return(1));
476+
compiler.setBlock(block1);
477+
SensingBlocks::compileColorIsTouchingColor(&compiler);
478+
479+
EXPECT_CALL(m_engineMock, functionIndex(&SensingBlocks::colorIsTouchingColor)).WillOnce(Return(1));
480+
compiler.setBlock(block2);
481+
SensingBlocks::compileColorIsTouchingColor(&compiler);
482+
483+
compiler.end();
484+
485+
ASSERT_EQ(compiler.bytecode(), std::vector<unsigned int>({ vm::OP_START, vm::OP_CONST, 0, vm::OP_CONST, 1, vm::OP_EXEC, 1, vm::OP_NULL, vm::OP_NULL, vm::OP_EXEC, 1, vm::OP_HALT }));
486+
ASSERT_EQ(compiler.constValues(), std::vector<Value>({ "#FFFF00", "#FF00FF" }));
487+
}
488+
489+
TEST_F(SensingBlocksTest, ColorIsTouchingColorImpl)
490+
{
491+
static unsigned int bytecode1[] = { vm::OP_START, vm::OP_CONST, 0, vm::OP_CONST, 1, vm::OP_EXEC, 0, vm::OP_HALT };
492+
static unsigned int bytecode2[] = { vm::OP_START, vm::OP_CONST, 2, vm::OP_CONST, 3, vm::OP_EXEC, 0, vm::OP_HALT };
493+
static BlockFunc functions[] = { &SensingBlocks::colorIsTouchingColor };
494+
static Value constValues[] = { "#FF00FF", "#FFFF00", 1946195606, 238 };
495+
496+
TargetMock target;
497+
Sprite sprite;
498+
VirtualMachine vm(&target, nullptr, nullptr);
499+
vm.setFunctions(functions);
500+
vm.setConstValues(constValues);
501+
502+
EXPECT_CALL(target, touchingColor(constValues[0], constValues[1])).WillOnce(Return(false));
503+
vm.setBytecode(bytecode1);
504+
vm.run();
505+
506+
ASSERT_EQ(vm.registerCount(), 1);
507+
ASSERT_FALSE(vm.getInput(0, 1)->toBool());
508+
509+
EXPECT_CALL(target, touchingColor(constValues[0], constValues[1])).WillOnce(Return(true));
510+
vm.reset();
511+
vm.run();
512+
513+
ASSERT_EQ(vm.registerCount(), 1);
514+
ASSERT_TRUE(vm.getInput(0, 1)->toBool());
515+
516+
EXPECT_CALL(target, touchingColor(constValues[2], constValues[3])).WillOnce(Return(false));
517+
vm.reset();
518+
vm.setBytecode(bytecode2);
519+
vm.run();
520+
521+
ASSERT_EQ(vm.registerCount(), 1);
522+
ASSERT_FALSE(vm.getInput(0, 1)->toBool());
523+
524+
EXPECT_CALL(target, touchingColor(constValues[2], constValues[3])).WillOnce(Return(true));
525+
vm.reset();
526+
vm.run();
527+
528+
ASSERT_EQ(vm.registerCount(), 1);
529+
ASSERT_TRUE(vm.getInput(0, 1)->toBool());
530+
}
531+
457532
TEST_F(SensingBlocksTest, DistanceTo)
458533
{
459534
Compiler compiler(&m_engineMock);

test/mocks/spritehandlermock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,5 @@ class SpriteHandlerMock : public ISpriteHandler
3838
MOCK_METHOD(bool, touchingClones, (const std::vector<Sprite *> &), (const, override));
3939
MOCK_METHOD(bool, touchingPoint, (double, double), (const, override));
4040
MOCK_METHOD(bool, touchingColor, (const Value &), (const, override));
41+
MOCK_METHOD(bool, touchingColor, (const Value &, const Value &), (const, override));
4142
};

test/mocks/stagehandlermock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,5 @@ class StageHandlerMock : public IStageHandler
2929
MOCK_METHOD(bool, touchingClones, (const std::vector<Sprite *> &), (const, override));
3030
MOCK_METHOD(bool, touchingPoint, (double, double), (const, override));
3131
MOCK_METHOD(bool, touchingColor, (const Value &), (const, override));
32+
MOCK_METHOD(bool, touchingColor, (const Value &, const Value &), (const, override));
3233
};

test/mocks/targetmock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class TargetMock : public Target
2828
MOCK_METHOD(bool, touchingPoint, (double, double), (const, override));
2929

3030
MOCK_METHOD(bool, touchingColor, (const Value &), (const, override));
31+
MOCK_METHOD(bool, touchingColor, (const Value &, const Value &), (const, override));
3132

3233
MOCK_METHOD(void, setGraphicsEffectValue, (IGraphicsEffect *, double), (override));
3334
MOCK_METHOD(void, clearGraphicsEffects, (), (override));

test/scratch_classes/sprite_test.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,7 @@ TEST(SpriteTest, TouchingColor)
825825
{
826826
Sprite sprite;
827827
ASSERT_FALSE(sprite.touchingColor(0));
828+
ASSERT_FALSE(sprite.touchingColor(0, 0));
828829

829830
SpriteHandlerMock iface;
830831
EXPECT_CALL(iface, init);
@@ -836,6 +837,12 @@ TEST(SpriteTest, TouchingColor)
836837

837838
EXPECT_CALL(iface, touchingColor(v2)).WillOnce(Return(true));
838839
ASSERT_TRUE(sprite.touchingColor(v2));
840+
841+
EXPECT_CALL(iface, touchingColor(v1, v2)).WillOnce(Return(false));
842+
ASSERT_FALSE(sprite.touchingColor(v1, v2));
843+
844+
EXPECT_CALL(iface, touchingColor(v2, v1)).WillOnce(Return(true));
845+
ASSERT_TRUE(sprite.touchingColor(v2, v1));
839846
}
840847

841848
TEST(SpriteTest, GraphicsEffects)

test/scratch_classes/stage_test.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ TEST(SpriteTest, TouchingColor)
222222
{
223223
Stage stage;
224224
ASSERT_FALSE(stage.touchingColor(0));
225+
ASSERT_FALSE(stage.touchingColor(0, 0));
225226

226227
StageHandlerMock iface;
227228
EXPECT_CALL(iface, init);
@@ -233,6 +234,12 @@ TEST(SpriteTest, TouchingColor)
233234

234235
EXPECT_CALL(iface, touchingColor(v2)).WillOnce(Return(true));
235236
ASSERT_TRUE(stage.touchingColor(v2));
237+
238+
EXPECT_CALL(iface, touchingColor(v1, v2)).WillOnce(Return(false));
239+
ASSERT_FALSE(stage.touchingColor(v1, v2));
240+
241+
EXPECT_CALL(iface, touchingColor(v2, v1)).WillOnce(Return(true));
242+
ASSERT_TRUE(stage.touchingColor(v2, v1));
236243
}
237244

238245
TEST(StageTest, GraphicsEffects)

test/scratch_classes/target_test.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,7 @@ TEST(TargetTest, TouchingColor)
716716
Target target;
717717
Value v;
718718
ASSERT_FALSE(target.touchingColor(v));
719+
ASSERT_FALSE(target.touchingColor(v, v));
719720
}
720721

721722
TEST(TargetTest, GraphicsEffects)

0 commit comments

Comments
 (0)