[python/turtle] First icon redesign

This commit is contained in:
Léa Saviot
2018-12-07 16:58:59 +01:00
parent e836593ff9
commit c95e291dd1
2 changed files with 55 additions and 42 deletions

View File

@@ -6,7 +6,12 @@ extern "C" {
#include "../../port.h"
#include "turtle_icon.h"
static constexpr KDSize k_iconSize = KDSize(9, 9);
// TODO add icon in the names
static constexpr KDCoordinate k_turtleSize = 15;
static constexpr KDCoordinate k_turtleBodySize = 5;
static constexpr KDCoordinate k_turtleHeadSize = 3;
static constexpr KDCoordinate k_turtlePawSize = 2;
constexpr KDColor Turtle::k_defaultColor;
template <typename T> static inline T * allocate(size_t count) {
@@ -165,7 +170,7 @@ bool Turtle::hasUnderneathPixelBuffer() {
if (m_underneathPixelBuffer != nullptr) {
return true;
}
m_underneathPixelBuffer = allocate<KDColor>(k_iconSize.width() * k_iconSize.height());
m_underneathPixelBuffer = allocate<KDColor>(k_turtleSize * k_turtleSize);
return (m_underneathPixelBuffer != nullptr);
}
@@ -203,46 +208,55 @@ bool Turtle::hasDotBuffers() {
}
KDRect Turtle::iconRect() const {
KDPoint iconOffset = KDPoint(-k_iconSize.width()/2 + 1, -k_iconSize.height()/2 + 1);
return KDRect(position().translatedBy(iconOffset), k_iconSize);
}
const KDColor * Turtle::icon() {
if (m_iconsPixels == nullptr) {
m_iconsPixels = allocate<KDColor>(k_iconSize.width() * k_iconSize.height() * k_numberOfIcons);
if (m_iconsPixels == nullptr) {
return nullptr;
}
Ion::decompress(
ImageStore::TurtleIcon->compressedPixelData(),
reinterpret_cast<uint8_t *>(m_iconsPixels),
ImageStore::TurtleIcon->compressedPixelDataSize(),
sizeof(KDColor) * k_iconSize.width() * k_iconSize.height() * k_numberOfIcons
);
}
int frame = (m_heading / (2*M_PI)) * k_numberOfIcons + 0.5;
if (frame < 0) {
frame = k_numberOfIcons - ((-frame) % k_numberOfIcons) - 1;
} else {
frame = frame % k_numberOfIcons;
}
int offset = frame * k_iconSize.width() * k_iconSize.height();
return &m_iconsPixels[offset];
KDPoint iconOffset = KDPoint(-k_turtleSize/2, -k_turtleSize/2);
return KDRect(position().translatedBy(iconOffset), k_turtleSize, k_turtleSize);
}
bool Turtle::draw() {
MicroPython::ExecutionEnvironment::currentExecutionEnvironment()->displaySandbox();
const KDColor * i = icon();
if (m_visible && i && hasUnderneathPixelBuffer()) {
if (m_visible && hasUnderneathPixelBuffer()) {
KDContext * ctx = KDIonContext::sharedContext();
KDRect rect = iconRect();
ctx->getPixels(rect, m_underneathPixelBuffer);
ctx->fillRectWithPixels(rect, i, nullptr);
// Get the pixels underneath the turtle
ctx->getPixels(iconRect(), m_underneathPixelBuffer);
// Draw the body
KDRect drawingRect = KDRect(
position().translatedBy(KDPoint(-k_turtleBodySize/2, -k_turtleBodySize/2)),
k_turtleBodySize,
k_turtleBodySize); // TODO make special method with enum class Paw Head Body Whole
ctx->fillRect(drawingRect, m_color);
KDCoordinate membersOffsetLength = 6;
// Draw the head
KDCoordinate headOffsetX = membersOffsetLength * sin(m_heading);
KDCoordinate headOffsetY = -membersOffsetLength * cos(m_heading);
KDPoint headOffset(headOffsetX, headOffsetY);
drawingRect = KDRect(
position().translatedBy(headOffset).translatedBy(KDPoint(-k_turtleHeadSize/2, -k_turtleHeadSize/2)),
k_turtleHeadSize,
k_turtleHeadSize); // TODO make special method with enum class Paw Head Body Whole
ctx->fillRect(drawingRect, m_color);
// Draw the paws
membersOffsetLength = 5;
constexpr int numberOfPaws = 4;
constexpr float angles[numberOfPaws] = {M_PI_2/2, M_PI_2+M_PI_2/2, M_PI+M_PI_2/2, M_PI+M_PI_2+M_PI_2/2};
constexpr float anglesEven[numberOfPaws] = {M_PI_2/2, M_PI_2+M_PI_2/2, M_PI+M_PI_2/2, M_PI+M_PI_2+M_PI_2/2};
for (int i = 0; i < numberOfPaws; i++) {
float pawX = membersOffsetLength * sin(m_heading+angles[i]);
float pawY = -membersOffsetLength * cos(m_heading+angles[i]);
KDCoordinate pawOffsetX = ((int)pawX) - (pawX < 0 ? 1 : 0);
KDCoordinate pawOffsetY = ((int)pawY) - (pawY < 0 ? 1 : 0);
KDPoint pawOffset(pawOffsetX, pawOffsetY);
drawingRect = KDRect(
position().translatedBy(pawOffset), // The paw is too small to need to offset it
k_turtlePawSize,
k_turtlePawSize); // TODO make special method with enum class Paw Head Body Whole
ctx->fillRect(drawingRect, m_color);
}
m_drawn = true;
}

View File

@@ -34,8 +34,7 @@ public:
m_drawn(false),
m_underneathPixelBuffer(nullptr),
m_dotMask(nullptr),
m_dotWorkingPixelBuffer(nullptr),
m_iconsPixels(nullptr)
m_dotWorkingPixelBuffer(nullptr)
{
}
@@ -76,7 +75,6 @@ private:
static constexpr int k_invertedYAxisCoefficient = -1;
static constexpr KDCoordinate k_xOffset = Ion::Display::Width / 2;
static constexpr KDCoordinate k_yOffset = (Ion::Display::Height - Metric::TitleBarHeight) / 2;
static constexpr int k_numberOfIcons = 8;
static constexpr uint8_t k_defaultSpeed = 3;
static constexpr uint8_t k_maxSpeed = 10;
static constexpr KDColor k_defaultColor = KDColorBlack;
@@ -92,16 +90,18 @@ private:
KDRect iconRect() const;
const KDColor * icon();
// Interruptible methods that return true if they have been interrupted
bool draw();
bool dot(mp_float_t x, mp_float_t y);
void erase();
/* The frame's center is the center of the screen, the x axis goes to the
* right and the y axis goes upwards. */
mp_float_t m_x;
mp_float_t m_y;
/* The heading is the angle in radians between the direction of the turtle and
* the X axis, in the trigonometric direction. */
mp_float_t m_heading;
KDColor m_color;
@@ -116,7 +116,6 @@ private:
KDColor * m_underneathPixelBuffer;
uint8_t * m_dotMask;
KDColor * m_dotWorkingPixelBuffer;
KDColor * m_iconsPixels;
};
#endif