gameplay: add cursor movement
This commit is contained in:
parent
375bec919e
commit
7f93d324d4
Binary file not shown.
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
@ -55,6 +55,7 @@ def mkGlyph(s):
|
|||
0x21A5: 13,
|
||||
0x039B: 14,
|
||||
# 15 is combined with a diacritic (from CASIO's custom charset)
|
||||
0x2295: 16,
|
||||
0x25A1: 0x7f,
|
||||
}
|
||||
if ord(s) >= 0x20 and ord(s) <= 0x7f:
|
||||
|
|
|
@ -51,7 +51,8 @@ void Camera::moveToFollow(WorldCoord p)
|
|||
namespace Nooncraft {
|
||||
|
||||
void renderCamera(int x, int y, Camera *camera, WorldCoord playerPos,
|
||||
GlyphCluster playerCluster)
|
||||
GlyphCluster playerCluster, WorldCoord cursorPos,
|
||||
GlyphCluster cursorCluster)
|
||||
{
|
||||
if(!camera)
|
||||
return;
|
||||
|
@ -61,30 +62,33 @@ void renderCamera(int x, int y, Camera *camera, WorldCoord playerPos,
|
|||
for(int dx = r.xmin; dx <= r.xmax; dx++) {
|
||||
int wx = camera->center.x + dx;
|
||||
int wy = camera->center.y + dy;
|
||||
GlyphCluster c;
|
||||
|
||||
if(!camera->world->worldBorder.contains(WorldCoord(wx, wy))) {
|
||||
continue;
|
||||
}
|
||||
else if(WorldCoord(wx, wy) == playerPos) {
|
||||
renderCluster(x+2*dx, y+2*dy, playerCluster);
|
||||
c = playerCluster;
|
||||
}
|
||||
else if(camera->world->isPointOnWorldBorder(wx, wy)) {
|
||||
GlyphCluster c('{', '}', '{', '}');
|
||||
renderCluster(x+2*dx, y+2*dy, c);
|
||||
c = GlyphCluster('{', '}', '{', '}');
|
||||
}
|
||||
else {
|
||||
Block b = camera->world->cellAt(wx, wy);
|
||||
BlockInfo *info = Nooncraft::getBlockInfo(b);
|
||||
if(info) {
|
||||
renderCluster(x+2*dx, y+2*dy, info->cluster);
|
||||
c = info->cluster;
|
||||
}
|
||||
else {
|
||||
char str[5];
|
||||
sprintf(str, "%04X", 0x55);
|
||||
GlyphCluster c(str[0], str[1], str[2], str[3]);
|
||||
renderCluster(x+2*dx, y+2*dy, c);
|
||||
c = GlyphCluster(str[0], str[1], str[2], str[3]);
|
||||
}
|
||||
}
|
||||
|
||||
if(WorldCoord(wx, wy) == cursorPos)
|
||||
c = cursorCluster.applyOver(c);
|
||||
renderCluster(x+2*dx, y+2*dy, c);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ struct Camera
|
|||
namespace Nooncraft {
|
||||
|
||||
void renderCamera(int x, int y, Camera *camera, WorldCoord playerPos,
|
||||
GlyphCluster playerCluster);
|
||||
GlyphCluster playerCluster, WorldCoord cursorPos,
|
||||
GlyphCluster cursorCluster);
|
||||
|
||||
} /* namespace Nooncraft */
|
||||
|
|
19
src/game.cpp
19
src/game.cpp
|
@ -15,5 +15,24 @@ bool Game::movePlayerBy(WorldCoord dir, bool camera_follow)
|
|||
this->playerPos = candidatePos;
|
||||
if(camera_follow)
|
||||
this->camera->moveToFollow(this->playerPos);
|
||||
this->moveCursorBy(dir);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Game::moveCursorBy(WorldCoord dir)
|
||||
{
|
||||
WorldCoord candidatePos = this->cursorPos + dir;
|
||||
int reachDistance = 3;
|
||||
|
||||
WorldRect reach(
|
||||
this->playerPos.x - reachDistance,
|
||||
this->playerPos.x + reachDistance,
|
||||
this->playerPos.y - reachDistance,
|
||||
this->playerPos.y + reachDistance);
|
||||
|
||||
if(!reach.contains(candidatePos))
|
||||
return false;
|
||||
|
||||
this->cursorPos = this->world->limits.clampPoint(candidatePos);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ struct Game
|
|||
Camera *camera;
|
||||
|
||||
WorldCoord playerPos;
|
||||
WorldCoord cursorPos;
|
||||
|
||||
/* Move the player by specified amount. */
|
||||
bool movePlayerBy(WorldCoord dir, bool camera_follow=true);
|
||||
|
|
33
src/main.cpp
33
src/main.cpp
|
@ -56,7 +56,9 @@ static void renderGame(Game *game)
|
|||
|
||||
GlyphCluster playerCluster(GLYPH_DEGREE_UNDERLINE, ' ',
|
||||
GLYPH_CAPITAL_LAMBDA, ' ');
|
||||
Nooncraft::renderCamera(26, 12, camera, game->playerPos, playerCluster);
|
||||
GlyphCluster cursorCluster(0, GLYPH_OPLUS, 0, 0);
|
||||
Nooncraft::renderCamera(26, 12, camera, game->playerPos, playerCluster,
|
||||
game->cursorPos, cursorCluster);
|
||||
|
||||
GlyphCluster invLeft(' ', GLYPH_PARALLEL_TO, ' ', GLYPH_PARALLEL_TO);
|
||||
GlyphCluster invRight(GLYPH_PARALLEL_TO, ' ', GLYPH_PARALLEL_TO, ' ');
|
||||
|
@ -101,6 +103,8 @@ int main(void)
|
|||
game.world = world;
|
||||
game.camera = camera;
|
||||
game.playerPos = world->findSpawnPoint();
|
||||
// TODO: Potential world border overflow here (unlikely)
|
||||
game.cursorPos = game.playerPos + WorldCoord::Right;
|
||||
|
||||
volatile int nextFrame = 1;
|
||||
int t = timer_configure(TIMER_ANY, 1000000/20, GINT_CALL_SET(&nextFrame));
|
||||
|
@ -135,14 +139,25 @@ int main(void)
|
|||
}
|
||||
|
||||
/* Clamp speed to 10 blocks/s */
|
||||
if(keydown(KEY_LEFT) && (tick % 2) == 0)
|
||||
game.movePlayerBy(WorldCoord::Left);
|
||||
if(keydown(KEY_RIGHT) && (tick % 2) == 0)
|
||||
game.movePlayerBy(WorldCoord::Right);
|
||||
if(keydown(KEY_UP) && (tick % 2) == 0)
|
||||
game.movePlayerBy(WorldCoord::Up);
|
||||
if(keydown(KEY_DOWN) && (tick % 2) == 0)
|
||||
game.movePlayerBy(WorldCoord::Down);
|
||||
if(tick % 2 == 0) {
|
||||
if(keydown(KEY_LEFT) && !keydown(KEY_SHIFT))
|
||||
game.movePlayerBy(WorldCoord::Left);
|
||||
if(keydown(KEY_RIGHT) && !keydown(KEY_SHIFT))
|
||||
game.movePlayerBy(WorldCoord::Right);
|
||||
if(keydown(KEY_UP) && !keydown(KEY_SHIFT))
|
||||
game.movePlayerBy(WorldCoord::Up);
|
||||
if(keydown(KEY_DOWN) && !keydown(KEY_SHIFT))
|
||||
game.movePlayerBy(WorldCoord::Down);
|
||||
|
||||
if(keydown(KEY_LEFT) && keydown(KEY_SHIFT))
|
||||
game.moveCursorBy(WorldCoord::Left);
|
||||
if(keydown(KEY_RIGHT) && keydown(KEY_SHIFT))
|
||||
game.moveCursorBy(WorldCoord::Right);
|
||||
if(keydown(KEY_UP) && keydown(KEY_SHIFT))
|
||||
game.moveCursorBy(WorldCoord::Up);
|
||||
if(keydown(KEY_DOWN) && keydown(KEY_SHIFT))
|
||||
game.moveCursorBy(WorldCoord::Down);
|
||||
}
|
||||
}
|
||||
|
||||
timer_stop(t);
|
||||
|
|
14
src/render.h
14
src/render.h
|
@ -32,15 +32,17 @@ enum {
|
|||
GLYPH_UP_ARROW_BAR = 13, /* U+21A5 UPWARDS ARROW FROM BAR */
|
||||
GLYPH_CAPITAL_LAMBDA = 14, /* U+039B GREEK CAPITAL LETTER LAMBDA */
|
||||
GLYPH_DEGREE_UNDERLINE = 15, /* U+00B0 U+0331 */
|
||||
GLYPH_OPLUS = 16, /* U+2295 CIRCLED PLUS */
|
||||
};
|
||||
|
||||
/* A cluster of 4 glyphs. Can be conversion-constructed from a multi-byte
|
||||
character literal like 'AXE '. */
|
||||
struct GlyphCluster
|
||||
{
|
||||
GlyphCluster(): glyphs {0,0,0,0} {}
|
||||
|
||||
GlyphCluster(Glyph g1, Glyph g2, Glyph g3, Glyph g4):
|
||||
glyphs {g1, g2, g3, g4}
|
||||
{}
|
||||
glyphs {g1, g2, g3, g4} {}
|
||||
|
||||
GlyphCluster(int mbliteral) {
|
||||
this->glyphs[0] = mbliteral >> 24;
|
||||
|
@ -49,6 +51,14 @@ struct GlyphCluster
|
|||
this->glyphs[3] = mbliteral & 0xff;
|
||||
}
|
||||
|
||||
GlyphCluster applyOver(GlyphCluster const &other) {
|
||||
return GlyphCluster(
|
||||
this->glyphs[0] ? this->glyphs[0] : other.glyphs[0],
|
||||
this->glyphs[1] ? this->glyphs[1] : other.glyphs[1],
|
||||
this->glyphs[2] ? this->glyphs[2] : other.glyphs[2],
|
||||
this->glyphs[3] ? this->glyphs[3] : other.glyphs[3]);
|
||||
}
|
||||
|
||||
Glyph glyphs[4];
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue