Skip to content

Instantly share code, notes, and snippets.

@jkoppel
Created November 29, 2017 07:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jkoppel/c8d91fcd99f7c7d0ba5ef7d2004f4981 to your computer and use it in GitHub Desktop.
Save jkoppel/c8d91fcd99f7c7d0ba5ef7d2004f4981 to your computer and use it in GitHub Desktop.
Coroutine refactoring
Original inspiration (verbatim code):
void combatManager::ArcShot(icon *icn, int fromX, int fromY, int targX, int targY)
{
bool firingLeft = false;
if (fromX > targX)
firingLeft = true;
int imageIdx = 0; // changes the sprite when its angle changes
// temporarily save the screen so we can clear it from the projectile sprite later
// #3
bitmap *savedscreen = new bitmap(0, INTERNAL_WINDOW_WIDTH, INTERNAL_WINDOW_HEIGHT);
gpWindowManager->screenBuffer->CopyTo(savedscreen, 0, 0, 0, 0, INTERNAL_WINDOW_WIDTH, INTERNAL_WINDOW_HEIGHT);
std::vector<COORD> points;
// compute next point
const int NUM_FRAMES = 24; // equals to the number of frames for the whole arc path
while (next point is not null {
if (i % 3 == 0) // every 3rd cycle
if(imageIdx < (icn->numSprites - 1))
imageIdx++; // changes the sprite of projectile
// #3
savedscreen->CopyTo(gpWindowManager->screenBuffer, 0, 0, 0, 0, INTERNAL_WINDOW_WIDTH, INTERNAL_WINDOW_HEIGHT); // clear the screen from the previous projectile sprite
icn->CombatClipDrawToBuffer(points[i].X, points[i].Y, imageIdx, NULL, firingLeft, 0, 0, 0);
gpWindowManager->UpdateScreenRegion(0, 0, INTERNAL_WINDOW_WIDTH, INTERNAL_WINDOW_HEIGHT);
// gfCombatSpeedMod is 1 or .5ish
glTimers = (signed __int64)((double)KBTickCount() + (double)40 * gfCombatSpeedMod[giCombatSpeed]); // #2
DelayTil(&glTimers); // #2 .. blocking timer
// compute next point
}
delete savedscreen;
this->DrawFrame(1, 0, 0, 0, 1, 1, 1); // clear screen from the projectile
}
Refactored Python pseudocode:
def get_coord(...):
for ...:
velY -= gravity
x += velX
y += velY
yield (x, y)
doOtherThing()
def draw_projectile(...):
color = true # that's why it's useful to use generators here
for fr in projectile.frames:
color = !color
draw(fr, point, color)
next_point = yield # yield nothing!
coords = get_coord()
drawings = draw_projectile()
timing = get_timing()
for coord in coords:
drawings.next(coord)
timing.next()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment