From 1024d1e7ad00363a947235b6a632245e15ab8406 Mon Sep 17 00:00:00 2001 From: Ivan Mahonin Date: Apr 29 2021 11:58:23 +0000 Subject: spriteUpdate --- diff --git a/doc/helianthus-doc-ru.odt b/doc/helianthus-doc-ru.odt index 690fdcf..7204845 100644 Binary files a/doc/helianthus-doc-ru.odt and b/doc/helianthus-doc-ru.odt differ diff --git a/src/animation.c b/src/animation.c index 61ea7fe..190e5f0 100644 --- a/src/animation.c +++ b/src/animation.c @@ -2,6 +2,7 @@ #include #include "private.h" +#include "sprite.h" #include "world.h" #include "animation.h" @@ -486,8 +487,8 @@ Animation createAnimation(const char *path) { return createAnimationEx(path, TRUE, FALSE, FALSE); } void animationDestroy(Animation animation) { - for(int i = worldGetSpriteCount() - 1; i >= 0; --i) { - Sprite s = worldGetSprite(i); + for(int i = spritesGetCount() - 1; i >= 0; --i) { + Sprite s = spritesGet(i); if (spriteGetAnimation(s) == animation) spriteSetNoAnimation(s); } diff --git a/src/sprite.c b/src/sprite.c index 4c7efc2..e95c120 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -503,9 +503,9 @@ void spriteSetDestroy(Sprite sprite, SpriteCallback destroy) { sprite->destroyCallback = destroy; } -int worldGetSpriteCount() +int spritesGetCount() { return sprites.count; } -Sprite worldGetSprite(int i) +Sprite spritesGet(int i) { return (Sprite)heliArrayGetValue(&sprites, i); } @@ -595,13 +595,11 @@ void heliSpriteSort(HeliArray *sprites) { } } - void spriteDraw(Sprite sprite) { if (sprite->visible) heliSpriteDraw(sprite); if (sprite->debug) heliSpriteDrawDebug(sprite); } - void drawSprites() { heliSpriteSort(&spritesSorted); for(int i = 0; i < spritesSorted.count; ++i) { @@ -614,65 +612,62 @@ void drawSprites() { } } -void heliSpriteUpdate(double dt) { - // auto-remove - for(int i = sprites.count - 1; i >= 0; --i) { - if (i < sprites.count) { - Sprite s = (Sprite)sprites.items[i].value; - if (s->frozen) continue; - if (s->lifeTime >= -HELI_PRECISION) { - s->lifeTime -= dt; - if (s->lifeTime <= HELI_PRECISION) - s->lifeTime = 0; - } +int spriteUpdate(Sprite sprite, double time) { + if (sprite->lifeTime >= -HELI_PRECISION) { + sprite->lifeTime -= time; + if (sprite->lifeTime <= HELI_PRECISION) { + sprite->lifeTime = 0; + spriteDestroy(sprite); + return FALSE; } } - for(int i = sprites.count - 1; i >= 0; --i) { - if (i < sprites.count) { - Sprite s = (Sprite)sprites.items[i].value; - if (s->lifeTime == 0) spriteDestroy(s); - } + + double vx = sprite->vx + sprite->ax*time; + double vy = sprite->vy + sprite->ay*time; + + double weight = spriteGetTouchWeight(sprite); + double dvf = fabs(weight * sprite->friction * sprite->touchFriction)*time; + if (dvf > HELI_PRECISION) { + double nx = sprite->wx / weight; + double ny = sprite->wy / weight; + double vb = nx*vx + ny*vy; + double vs = ny*vx - nx*vy; + if (vs > dvf + HELI_PRECISION) vs -= dvf; else + if (vs < -dvf - HELI_PRECISION) vs += dvf; else vs = 0; + vx = nx*vb + ny*vs; + vy = ny*vb - nx*vs; } - // update - for(int i = 0; i < sprites.count; ++i) { - Sprite s = (Sprite)sprites.items[i].value; - if (s->frozen) continue; - double vx = s->vx + s->ax*dt; - double vy = s->vy + s->ay*dt; - - double weight = spriteGetTouchWeight(s); - double dvf = fabs(weight*s->friction*s->touchFriction)*dt; - if (dvf > HELI_PRECISION) { - double nx = s->wx/weight; - double ny = s->wy/weight; - double vb = nx*vx + ny*vy; - double vs = ny*vx - nx*vy; - if (vs > dvf + HELI_PRECISION) vs -= dvf; else - if (vs < -dvf - HELI_PRECISION) vs += dvf; else vs = 0; - vx = nx*vb + ny*vs; - vy = ny*vb - nx*vs; - } - - double dvaf = fabs(s->airFriction)*dt; - if (dvaf > HELI_PRECISION) { - double v = sqrt(vx*vx + vy*vy), vn = v; - if (v > dvaf + HELI_PRECISION) vn -= dvaf; else - if (v < -dvaf - HELI_PRECISION) vn += dvaf; else vn = 0; - double k = vn > HELI_PRECISION ? vn/v : 0; - vx *= k; - vy *= k; + double dvaf = fabs(sprite->airFriction)*time; + if (dvaf > HELI_PRECISION) { + double v = sqrt(vx*vx + vy*vy), vn = v; + if (v > dvaf + HELI_PRECISION) vn -= dvaf; else + if (v < -dvaf - HELI_PRECISION) vn += dvaf; else vn = 0; + double k = vn > HELI_PRECISION ? vn/v : 0; + vx *= k; + vy *= k; + } + + sprite->vx = vx; + sprite->vy = vy; + autoRotate(sprite); + spriteResetTouch(sprite); + + sprite->x += sprite->vx * time; + sprite->y += sprite->vy * time; + if (!sprite->rotateToDirection) + sprite->rotation += sprite->rotationSpeed*time; + + return TRUE; +} + +void heliSpriteUpdate(double dt) { + for(int i = spritesGetCount() - 1; i >= 0; --i) { + if (i < spritesGetCount()) { + Sprite s = spritesGet(i); + if (!spriteGetFrozen(s)) + spriteUpdate(spritesGet(i), dt); } - - s->vx = vx; - s->vy = vy; - autoRotate(s); - spriteResetTouch(s); - - s->x += s->vx*dt; - s->y += s->vy*dt; - if (!s->rotateToDirection) - s->rotation += s->rotationSpeed*dt; } } @@ -680,8 +675,8 @@ HeliArray* heliSpriteGetGroups(Sprite sprite) { return &sprite->groups; } void heliSpriteFinish() { - while(worldGetSpriteCount()) - { spriteDestroy(worldGetSprite(0)); } + while(spritesGetCount()) + { spriteDestroy(spritesGet(0)); } heliArrayDestroy(&sprites); heliArrayDestroy(&spritesSorted); } diff --git a/src/sprite.h b/src/sprite.h index 6c48426..7694f8a 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -143,7 +143,12 @@ void spriteSetUserData(Sprite sprite, void *data); void spriteSetDestroy(Sprite sprite, SpriteCallback destroy); +int spriteUpdate(Sprite sprite, double time); void spriteDraw(Sprite sprite); +int spritesGetCount(); +Sprite spritesGet(int i); + + #endif diff --git a/src/world.h b/src/world.h index c931c9b..7d8d4ab 100644 --- a/src/world.h +++ b/src/world.h @@ -44,9 +44,6 @@ int questionBox3(const char *question, const char *answer0, const char *answer1, int askText(const char *question, char *answer, int maxAnswerSize); int askTextEx(const char *question, char *answer, int maxAnswerSize, int multiline, int password); -int worldGetSpriteCount(); -Sprite worldGetSprite(int i); - int worldGetWidth(); void worldSetWidth(int width);