rotate point around center of sprite in food scene
This commit is contained in:
parent
8f2bb74449
commit
598c62976b
21
Release.key
21
Release.key
|
@ -1,21 +0,0 @@
|
|||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v2.0.15 (GNU/Linux)
|
||||
|
||||
mQENBFdEgZoBCAD06orQfic7gtx/akz9QG5I9p0hjLDurZUdqL5QcV11IkvXar99
|
||||
tWforuy4tr74oUwQVn9E6GtVejwjGZfJ60qQSOs8Jye/qdtDiVg9ORFa+hDji9+X
|
||||
NW22ZjVYlwfwGejXwsk8KiLYmd5nT2UftXHadInBaWj8SGtX/fDiGJmt6rBTPVs/
|
||||
JSvNF3NNi95Pnwsji9LVLGAJzHO/2h1qvK8tmGaMEAgXYuYEhZ+K2ld4c609aV1Q
|
||||
WZkZakz+l9AGd1K6wy4TFgQSBoRgGZJNdDGAmorL5y/mrH/rG/9YG5BNHbhklHp+
|
||||
Obn5iWBPfoHVke2XbrjSOtYetIrPE+UUFDQLABEBAAG0OmhvbWU6UGl2YWw4MSBP
|
||||
QlMgUHJvamVjdCA8aG9tZTpQaXZhbDgxQGJ1aWxkLm9wZW5zdXNlLm9yZz6JAT4E
|
||||
EwECACgFAldEgZoCGwMFCQQesAAGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJ
|
||||
EF0O8jNk4jAxoUgH/3YwxTPIAXCwcetRQbf3lp5N/MaV5sMf8fiV5Uy1HBKn2HMi
|
||||
Gm75axQlMJTC39FTbq0CT/3nfeUhvsk1ipk41KpkukcrDpGvppZYEkzj8zxEXfiq
|
||||
Ow78lWD66jpY184rTpsLLt4IcqqH1QMC7fQV9b8mzR5WmBRUhnO+l6oIT3fccZ9D
|
||||
faNfXl/+CuAX+S6i7kJRyHIN07T0tKaZMyIGSiw7bhQ8L/0NZ9vn57J+KC6f5SEG
|
||||
kmEs/j1AltsRI8R6Z9alT0XSjnwW6o281mbpir/12A2O/9mxVhFrcgHdB2yl3JCN
|
||||
OgSX8LnHTDnjmMCmCWVz73QQDVrZJmJ0ltwVBO+IRgQTEQIABgUCV0SBmgAKCRA7
|
||||
MBG3a51lI1fSAKCA+sfj77Uv1D4g+sK7lbE0AyJKagCfdFQQ9lCfmEQ1wfZyOCvs
|
||||
GSV0JlA=
|
||||
=1rpz
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
|
@ -6,49 +6,42 @@
|
|||
#include <libgba-sprite-engine/gba/tonc_bios.h>
|
||||
#include "bullet.h"
|
||||
|
||||
// in 1/256 pixels
|
||||
#define SPEED 50
|
||||
#define FIXED_POINT_BASE 1000
|
||||
#define SPEED_DELTA 1
|
||||
|
||||
u32 length(VECTOR a) {
|
||||
return Sqrt(a.x * a.x + a.y * a.y);
|
||||
void Bullet::setDestination(VECTOR destination) {
|
||||
auto currentPos = sprite->getPos();
|
||||
this->dest = destination;
|
||||
|
||||
diff.x = (destination.x - currentPos.x);
|
||||
diff.y = (destination.y - currentPos.y);
|
||||
directionToCover.x = diff.x * FIXED_POINT_BASE;
|
||||
directionToCover.y = diff.y * FIXED_POINT_BASE;
|
||||
|
||||
TextStream::instance().setText(std::string("covering: ") + std::to_string(directionToCover.x) + std::string(",") + std::to_string(directionToCover.y), 15, 1);
|
||||
}
|
||||
|
||||
u32 distance(VECTOR a, VECTOR b) {
|
||||
return length({a.x - b.x, a.y - b.y});
|
||||
}
|
||||
|
||||
VECTOR normalize(VECTOR a) {
|
||||
u32 l = length(a);
|
||||
return { a.x / l, a.y / l };
|
||||
}
|
||||
|
||||
void Bullet::setDestination(VECTOR vec) {
|
||||
this->dest = vec;
|
||||
}
|
||||
|
||||
// TODO https://gamedev.stackexchange.com/questions/23447/moving-from-ax-y-to-bx1-y1-with-constant-speed
|
||||
void Bullet::tick() {
|
||||
auto pos = sprite->getPos();
|
||||
int xdiff = 1, ydiff = 1;
|
||||
auto x = sprite->getX(), y = sprite->getY();
|
||||
|
||||
if(abs(pos.x - dest.x) > abs(pos.y - dest.y)) {
|
||||
xdiff += 1;
|
||||
} else {
|
||||
ydiff += 1;
|
||||
if(directionToCover.x != 0) {
|
||||
if(directionToCover.x > 0) {
|
||||
directionToCover.x -= FIXED_POINT_BASE;
|
||||
x += SPEED_DELTA;
|
||||
} else {
|
||||
directionToCover.x += FIXED_POINT_BASE;
|
||||
x -= SPEED_DELTA;
|
||||
}
|
||||
}
|
||||
if(directionToCover.y != 0) {
|
||||
if(directionToCover.y > 0) {
|
||||
directionToCover.y -= FIXED_POINT_BASE;
|
||||
y += SPEED_DELTA;
|
||||
} else {
|
||||
directionToCover.y += FIXED_POINT_BASE;
|
||||
y -= SPEED_DELTA;
|
||||
}
|
||||
}
|
||||
|
||||
if(pos.x > dest.x) {
|
||||
vel.x -= 1 * xdiff;
|
||||
} else if(pos.x < dest.x) {
|
||||
vel.x = 1 * xdiff;
|
||||
}
|
||||
if(pos.y > dest.y) {
|
||||
vel.y -= 1 * ydiff;
|
||||
} else if(pos.y < dest.y) {
|
||||
vel.y = 1 * ydiff;
|
||||
}
|
||||
|
||||
TextStream::instance().setText(std::string("pos/dest: (") + std::to_string(pos.x) + std::string(",") + std::to_string(pos.y) + std::string(") (") + std::to_string(dest.x) + std::string(",") + std::to_string(dest.y) + std::string(")"), 16, 1);
|
||||
|
||||
sprite->setVelocity(vel.x, vel.y);
|
||||
}
|
||||
sprite->moveTo(x, y);
|
||||
}
|
||||
|
|
|
@ -13,14 +13,14 @@ class Bullet {
|
|||
private:
|
||||
std::unique_ptr<Sprite> sprite;
|
||||
VECTOR dest;
|
||||
VECTOR vel;
|
||||
VECTOR direction;
|
||||
VECTOR diff;
|
||||
VECTOR directionToCover;
|
||||
|
||||
public:
|
||||
Bullet(std::unique_ptr<Sprite> sprite) : sprite(std::move(sprite)), dest(VECTOR()) {}
|
||||
|
||||
void tick();
|
||||
void setDestination(VECTOR vec);
|
||||
void setDestination(VECTOR destination);
|
||||
bool isOffScreen() { return sprite->isOffScreen(); }
|
||||
Sprite* getSprite() { return sprite.get(); }
|
||||
};
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include "bullet.h"
|
||||
#include "bullet_data.h"
|
||||
|
||||
#define AVATAR_ROTATION_DIFF (128 * 2)
|
||||
#define AVATAR_ROTATION_DIFF (128 * 6)
|
||||
#define MAX_AMOUNT_OF_BULLETS 40
|
||||
#define BULLET_COOLDOWN_START 20
|
||||
|
||||
|
@ -41,25 +41,20 @@ void FoodScene::removeBulletsOffScreen() {
|
|||
bullets.end());
|
||||
}
|
||||
|
||||
std::string hex(int val) {
|
||||
std::stringstream sstream;
|
||||
sstream << std::hex << val;
|
||||
std::string result = sstream.str();
|
||||
return result;
|
||||
}
|
||||
VECTOR FoodScene::rotateAround(VECTOR center, VECTOR point) {
|
||||
s32 centerx = center.x, centery = center.y;
|
||||
s32 defaultx = point.x, defaulty = point.y;
|
||||
|
||||
u32 hex_int(u32 decimalValue) {
|
||||
return (((decimalValue) & 0xF) + (((decimalValue) >> 4) * 10));
|
||||
}
|
||||
s32 cos = lu_cos(avatarRotation) >> 4;
|
||||
s32 sin = lu_sin(avatarRotation) >> 4;
|
||||
|
||||
VECTOR randomDestinations[6] = {
|
||||
{GBA_SCREEN_WIDTH, GBA_SCREEN_HEIGHT},
|
||||
{0, 0},
|
||||
{GBA_SCREEN_WIDTH / 2, GBA_SCREEN_HEIGHT},
|
||||
{GBA_SCREEN_WIDTH, GBA_SCREEN_HEIGHT / 2},
|
||||
{GBA_SCREEN_WIDTH, 0},
|
||||
{0, GBA_SCREEN_HEIGHT}
|
||||
};
|
||||
// affine matriches are 8.8 fixed point numbers, so shift all input 8 spaces up and forth
|
||||
// possibilities: instead of between [-1.0, 1.0] it's between [-256, +256]
|
||||
// 90° rotation in inversed y-axis needs to flip sin sign
|
||||
return {
|
||||
( cos * (defaultx - centerx) + sin * (defaulty - centery) + (centerx << 8)) >> 8,
|
||||
(-sin * (defaultx - centerx) + cos * (defaulty - centery) + (centery << 8)) >> 8};
|
||||
}
|
||||
|
||||
void FoodScene::tick(u16 keys) {
|
||||
avatar->animateToFrame(0);
|
||||
|
@ -74,17 +69,10 @@ void FoodScene::tick(u16 keys) {
|
|||
removeBulletsOffScreen();
|
||||
TextStream::instance().setText(std::string("bullets: ") + std::to_string(bullets.size()), 1, 1);
|
||||
TextStream::instance().setText(std::string("cooldown: ") + std::to_string(bulletCooldown), 2, 1);
|
||||
TextStream::instance().setText(std::string("angle pa/pb: ") + hex(avatar->getMatrix()->pa) + std::string("/") + hex(avatar->getMatrix()->pb), 3, 1);
|
||||
TextStream::instance().setText(std::string("angle pc/pd: ") + hex(avatar->getMatrix()->pc) + std::string("/") + hex(avatar->getMatrix()->pd), 4, 1);
|
||||
|
||||
/*
|
||||
int defaultx = hex_int(GBA_SCREEN_WIDTH / 2 - 20), defaulty = hex_int(GBA_SCREEN_HEIGHT - 20);
|
||||
TextStream::instance().setText(std::string("angle pa/pb: ") + std::to_string(avatar->getMatrix()->pa) + std::string("/") + std::to_string(avatar->getMatrix()->pb), 3, 1);
|
||||
TextStream::instance().setText(std::string("angle pc/pd: ") + std::to_string(avatar->getMatrix()->pc) + std::string("/") + std::to_string(avatar->getMatrix()->pd), 4, 1);
|
||||
|
||||
auto newx = toDecimal((avatar->getMatrix()->pa * defaultx + avatar->getMatrix()->pb * defaulty) >> 8);
|
||||
auto newy = toDecimal((avatar->getMatrix()->pc * defaultx + avatar->getMatrix()->pd * defaulty) >> 8);
|
||||
|
||||
TextStream::instance().setText(std::string("translated x/y: ") + std::to_string(newx) + std::string(",") + std::to_string(newy), 16, 1);
|
||||
*/
|
||||
if(keys & KEY_LEFT) {
|
||||
avatarRotation -= AVATAR_ROTATION_DIFF;
|
||||
} else if(keys & KEY_RIGHT) {
|
||||
|
@ -98,7 +86,9 @@ void FoodScene::tick(u16 keys) {
|
|||
bullets.push_back(createBullet());
|
||||
|
||||
auto &b = bullets.at(bullets.size() - 1);
|
||||
b->setDestination(randomDestinations[rand() % 6]);
|
||||
auto destination = rotateAround(avatar->getCenter(), defaultBulletTarget);
|
||||
TextStream::instance().setText(std::string("shooting dest: ") + std::to_string(destination.x) + std::string(",") + std::to_string(destination.y), 16, 1);
|
||||
b->setDestination(destination);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,4 +126,7 @@ void FoodScene::load() {
|
|||
.withLocation(GBA_SCREEN_WIDTH + 20, GBA_SCREEN_HEIGHT + 20)
|
||||
.buildPtr();
|
||||
bulletCooldown = BULLET_COOLDOWN_START;
|
||||
|
||||
// rotation of a point on a circle within the resolution means our radius should be big enough
|
||||
defaultBulletTarget = { GBA_SCREEN_WIDTH / 2, GBA_SCREEN_HEIGHT + (GBA_SCREEN_WIDTH / 2) - avatar->getCenter().y};
|
||||
}
|
|
@ -23,6 +23,9 @@ private:
|
|||
std::unique_ptr<Bullet> createBullet();
|
||||
void removeBulletsOffScreen();
|
||||
|
||||
VECTOR rotateAround(VECTOR center, VECTOR point);
|
||||
VECTOR defaultBulletTarget;
|
||||
|
||||
public:
|
||||
explicit FoodScene(const std::shared_ptr<GBAEngine> &engine);
|
||||
FoodScene(FoodScene& other) = delete;
|
||||
|
|
|
@ -84,14 +84,16 @@ public:
|
|||
void update();
|
||||
|
||||
void moveTo(int x, int y);
|
||||
void moveTo(VECTOR location);
|
||||
bool collidesWith(Sprite &s2);
|
||||
|
||||
void flipVertically(bool flip);
|
||||
void flipHorizontally(bool flip);
|
||||
|
||||
u32 getTileIndex() { return tileIndex; }
|
||||
VECTOR getPos() { return VECTOR {x, y}; }
|
||||
VECTOR getVelocity() { return VECTOR { dx, dy}; }
|
||||
VECTOR getPos() { return {x, y}; }
|
||||
VECTOR getCenter() { return { x + w / 2, y + h / 2 }; }
|
||||
VECTOR getVelocity() { return { dx, dy}; }
|
||||
u32 getDx() { return dx; }
|
||||
u32 getDy() { return dy; }
|
||||
u32 getX() { return x; }
|
||||
|
|
|
@ -18,6 +18,10 @@ Sprite::Sprite(const void *imageData, int imageSize, int x, int y, SpriteSize si
|
|||
setAttributesBasedOnSize(size);
|
||||
}
|
||||
|
||||
void Sprite::moveTo(VECTOR location) {
|
||||
moveTo(location.x, location.y);
|
||||
}
|
||||
|
||||
void Sprite::moveTo(int x, int y) {
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
|
|
Loading…
Reference in New Issue