Created
November 29, 2017 07:04
-
-
Save jkoppel/c8d91fcd99f7c7d0ba5ef7d2004f4981 to your computer and use it in GitHub Desktop.
Coroutine refactoring
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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