* Nearest unit and/or building is found (no sqrt method used).

* Preliminar unit/building selection algorithm.
* Added cursor onscreen.
- Removed old Peasant sprites. Only 2 sprites needed!
This commit is contained in:
XaviDCR92 2017-03-09 23:59:53 +01:00
parent 8ec41b4410
commit f416816883
20 changed files with 1611 additions and 1176 deletions

View File

@ -45,7 +45,19 @@ uint8_t BuildingGetHpFromID(uint8_t id)
return BuildingHPTable[id];
}
void BuildingDraw(TYPE_CAMERA * ptrCamera, TYPE_BUILDING * ptrBuilding)
void BuildingSelectedOptions(TYPE_BUILDING * ptrBuilding)
{
char str[8];
GfxDrawRectangle(0, Y_SCREEN_RESOLUTION - 8, X_SCREEN_RESOLUTION, 8, GFX_WHITE);
snprintf(str, 8, "HP=%d", ptrBuilding->hp);
GfxPrintTextFont(str, font3x3, 4, Y_SCREEN_RESOLUTION - 4);
}
void BuildingDraw(TYPE_CAMERA * ptrCamera, TYPE_BUILDING * ptrBuilding, bool bSelected)
{
uint8_t id = ptrBuilding->id;
@ -65,7 +77,24 @@ void BuildingDraw(TYPE_CAMERA * ptrCamera, TYPE_BUILDING * ptrBuilding)
ptrBuilding->x,
ptrBuilding->y );
GfxDrawSprite(&BarracksSpr);
GfxDrawSprite(BuildingSprTable[id]);
if( (bSelected == true) && (ptrBuilding->selected == false) )
{
TYPE_COLLISION_BLOCK cb;
cb = CameraApplyCoordinatesToCoordinates(ptrCamera, ptrBuilding->x, ptrBuilding->y);
GfxDrawCircle(cb.x + 3, cb.y + 3, BuildingGetWidthFromID(ptrBuilding->id) >> 2, GFX_GRAY);
}
else if(ptrBuilding->selected == true)
{
TYPE_COLLISION_BLOCK cb;
cb = CameraApplyCoordinatesToCoordinates(ptrCamera, ptrBuilding->x, ptrBuilding->y);
GfxDrawCircle(cb.x + 3, cb.y + 3, BuildingGetWidthFromID(ptrBuilding->id) >> 2, GFX_BLACK);
}
}

View File

@ -37,7 +37,8 @@ void BuildingInit(void);
uint8_t BuildingGetHpFromID(uint8_t id);
uint8_t BuildingGetWidthFromID(uint8_t id);
uint8_t BuildingGetHeightFromID(uint8_t id);
void BuildingDraw(TYPE_CAMERA * ptrCamera, TYPE_BUILDING * ptrBuilding);
void BuildingDraw(TYPE_CAMERA * ptrCamera, TYPE_BUILDING * ptrBuilding, bool bSelected);
void BuildingSelectedOptions(TYPE_BUILDING * ptrBuilding);
#ifdef __cplusplus
}

View File

@ -28,6 +28,20 @@ void CameraInit(TYPE_CAMERA * ptrCamera)
ptrCamera->Speed_Timer = SPEED_CALCULATION_TIME;
}
TYPE_COLLISION_BLOCK CameraApplyCoordinatesToCoordinates( TYPE_CAMERA * ptrCamera,
uint16_t x,
uint16_t y )
{
TYPE_COLLISION_BLOCK cb;
memset(&cb, 0, sizeof(TYPE_COLLISION_BLOCK));
cb.x = x + ptrCamera->X_Offset;
cb.y = y + ptrCamera->Y_Offset;
return cb;
}
void CameraApplyCoordinatesToSprite(TYPE_CAMERA * ptrCamera,
TYPE_SPRITE * spr,
uint16_t x,

View File

@ -29,6 +29,9 @@ extern "C"
void CameraInit(TYPE_CAMERA * ptrCamera);
void CameraHandler(TYPE_CAMERA * ptrCamera);
TYPE_COLLISION_BLOCK CameraApplyCoordinatesToCoordinates( TYPE_CAMERA * ptrCamera,
uint16_t x,
uint16_t y );
void CameraApplyCoordinatesToSprite(TYPE_CAMERA * ptrCamera,
TYPE_SPRITE * spr,
uint16_t x,

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -29,6 +29,7 @@ typedef struct t_Building
uint8_t hp;
uint8_t id;
bool built;
bool selected;
}TYPE_BUILDING;
typedef struct t_Unit
@ -37,7 +38,10 @@ typedef struct t_Unit
uint16_t y;
uint8_t hp;
uint8_t id;
bool dir; // False = up-down; true = left-right
bool walk;
bool alive;
bool selected;
}TYPE_UNIT;
typedef struct t_CollisionBlock

View File

@ -3,6 +3,7 @@
* **************************************/
#include "Gameplay.h"
#include "MouseSpr.c"
/* **************************************
* Defines *
@ -20,6 +21,7 @@ Player GamePlayers[GAME_MAX_PLAYERS];
static const char PauseMenuOption_0[] PROGMEM = "Resume";
static const char PauseMenuOption_1[] PROGMEM = "Quit";
static TYPE_SPRITE MouseSpr;
static const char * const PauseMenuOptions[] PROGMEM = {PauseMenuOption_0,
PauseMenuOption_1 };
@ -79,6 +81,13 @@ void GameInit(void)
GamePlayers[i].Init();
}
MouseSpr.Data = MouseSprData;
MouseSpr.color = GFX_INVERT;
MouseSpr.rotation = NOROT;
MouseSpr.flip = NOFLIP;
MouseSpr.x = (X_SCREEN_RESOLUTION >> 1) - 4;
MouseSpr.y = (Y_SCREEN_RESOLUTION >> 1) - 4;
GfxInit();
GameLoop();
@ -125,6 +134,8 @@ void GameGraphics(void)
{
GamePlayers[i].DrawHandler();
}
GfxDrawSprite(&MouseSpr);
}
void GameLoop(void)

24
Gfx.cpp
View File

@ -28,12 +28,16 @@ void GfxDrawSprite(TYPE_SPRITE * ptrSprite)
{
if(GfxIsSpriteInsideScreenArea(ptrSprite) == true)
{
int8_t orig_color = gb.display.getColor();
gb.display.setColor(ptrSprite->color, GFX_WHITE);
gb.display.drawBitmap( ptrSprite->x,
ptrSprite->y,
ptrSprite->Data,
ptrSprite->rotation,
ptrSprite->flip );
gb.display.setColor(orig_color);
}
}
@ -170,6 +174,26 @@ void GfxPrintText(const char * str, uint8_t x, uint8_t y)
GfxPrintTextFont(str, font3x5, x, y);
}
void GfxDrawCircle(uint16_t x, uint16_t y, uint8_t radius, int8_t color)
{
if(GfxIsInsideScreenArea(x, y, radius, radius) == true)
{
int8_t orig_color = gb.display.getColor();
gb.display.setColor(color);
gb.display.drawCircle(x, y, radius);
gb.display.setColor(orig_color);
}
}
void GfxDrawRectangle(uint8_t x, uint8_t y, uint8_t w, uint8_t h, int8_t color)
{
int8_t orig_color = gb.display.getColor();
gb.display.setColor(color);
gb.display.fillRect(x, y, w, h);
gb.display.setColor(orig_color);
}
void GfxShowResources(TYPE_RESOURCES * ptrResources)
{
char str[8];

2
Gfx.h
View File

@ -46,6 +46,8 @@ typedef struct
* *************************************/
void GfxDrawSprite(TYPE_SPRITE * ptrSprite);
void GfxDrawCircle(uint16_t x, uint16_t y, uint8_t radius, int8_t color);
void GfxDrawRectangle(uint8_t x, uint8_t y, uint8_t w, uint8_t h, int8_t color);
bool GfxRefreshNeeded(void);
void GfxShowKeyboard(char * str, uint8_t length);
uint8_t GfxGetWidthFromSpriteData(const uint8_t * sprData);

View File

@ -35,9 +35,10 @@
#ifdef __cplusplus
extern Gamebuino gb;
#endif //__cplusplus
extern const uint8_t font3x5[];
extern const uint8_t font3x3[];
#endif //__cplusplus
/* *************************************
* Global prototypes

View File

@ -27,7 +27,7 @@ clean:
rm $(OBJ_DIR)/*.o -f -r
build: $(addprefix $(OBJ_DIR)/,main.o Gameplay.o System.o Gfx.o Pad.o \
Player.o Camera.o Menu.o Building.o)
Player.o Camera.o Unit.o Menu.o Building.o)
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CXX) $< -o $@ $(INCLUDE) $(DEFINE) $(CC_FLAGS)

View File

@ -1,27 +1,29 @@
static byte PROGMEM Peasant_LeftRight_Spr[] =
// Default direction: Down
const uint8_t PROGMEM Peasant_Walking_SprData[] =
{
8,8, //width and height
B00011000,
B00100100,
B00110010,
B01001010,
B01001010,
B00110010,
B00100100,
B00011000,
};
static byte PROGMEM Peasant_Walking_UpDown_Spr[] =
{
8,8, //width and height
B00000010,
B00011101,
B01100111,
B10100101,
B10011001,
B11000010,
B10111100,
B01100000,
B10111100,
B11000010,
B10011001,
B10100101,
B01100111,
B00011101,
B00000010,
};
const uint8_t PROGMEM Peasant_SprData[] =
{
8,8, //width and height
B00000000,
B00111100,
B01000010,
B10011001,
B10100101,
B01100110,
B00011000,
B00000000,
};

View File

@ -14,7 +14,6 @@
Player::Player(void)
{
}
Player::~Player(void)
@ -29,14 +28,23 @@ void Player::Init(void)
unit_i = 0;
bldg_i = 0;
selectedUnit = NULL;
selectedBuilding = NULL;
CameraInit(&Camera);
BuildingInit();
UnitInit();
for(i = 0; i < PLAYER_MAX_BUILDINGS; i++)
{
memset(&buildings[i], 0, sizeof(TYPE_BUILDING));
}
for(i = 0; i < PLAYER_MAX_UNITS; i++)
{
memset(&units[i], 0, sizeof(TYPE_UNIT));
}
TYPE_COLLISION_BLOCK cl;
Resources.Wood = 25;
@ -45,39 +53,56 @@ void Player::Init(void)
cl.x = SystemRand(0, 20);
cl.y = SystemRand(0, 20);
cl.w = BuildingGetWidthFromID(0);
cl.h = BuildingGetHeightFromID(0);
cl.w = BuildingGetWidthFromID(BARRACKS);
cl.h = BuildingGetHeightFromID(BARRACKS);
if(createBuilding(0, cl) == false)
if(createBuilding(BARRACKS, cl) == false)
{
GfxPrintText_Flash(F("Failed to create building!"));
}
}
bool Player::createUnit(uint8_t id)
{
if(unit_i < PLAYER_MAX_UNITS)
{
units[unit_i++] = id;
return true;
}
else
{
return false;
}
return false;
cl.x = SystemRand(48, 56);
cl.y = SystemRand(48, 56);
cl.w = UnitGetWidthFromID(PEASANT);
cl.h = UnitGetHeightFromID(PEASANT);
if(createUnit(PEASANT, cl) == false)
{
GfxPrintText_Flash(F("Failed to create unit!"));
}
}
void Player::DrawHandler(void)
{
uint8_t i;
bool bAnyoneSelected = false;
//GfxRenderTiles(&Camera);
for(i = 0; i < PLAYER_MAX_BUILDINGS; i++)
{
BuildingDraw(&Camera, &buildings[i]);
TYPE_BUILDING * b = &buildings[i];
bool selected = (b == selectedBuilding);
BuildingDraw(&Camera, b, selected);
if( (b->selected == true) && (bAnyoneSelected == false) )
{
bAnyoneSelected = true;
BuildingSelectedOptions(b);
}
}
for(i = 0; i < PLAYER_MAX_UNITS; i++)
{
TYPE_UNIT * u = &units[i];
bool selected = (u == selectedUnit);
UnitDraw(&Camera, u, selected);
if( (u->selected == true) && (bAnyoneSelected == false) )
{
bAnyoneSelected = true;
UnitSelectedOptions(u);
}
}
}
@ -165,13 +190,117 @@ bool Player::createBuilding(uint8_t id, TYPE_COLLISION_BLOCK cb)
return false;
}
void Player::Handler(void)
bool Player::createUnit(uint8_t id, TYPE_COLLISION_BLOCK cb)
{
if(unit_i < PLAYER_MAX_UNITS)
{
units[unit_i].id = id;
units[unit_i].x = cb.x;
units[unit_i].y = cb.y;
units[unit_i].hp = UnitGetHpFromID(id);
units[unit_i].alive = true;
unit_i++;
return true;
}
else
{
return false;
}
return false;
}
TYPE_COLLISION_BLOCK Player::GetCursorPos(void)
{
TYPE_COLLISION_BLOCK cb;
cb.x = (X_SCREEN_RESOLUTION >> 1) - 4 - Camera.X_Offset;
cb.y = (Y_SCREEN_RESOLUTION >> 1) - 4 - Camera.Y_Offset;
cb.w = 8;
cb.h = 8;
return cb;
}
void Player::UnitBuildingSelection(void)
{
uint16_t i;
TYPE_UNIT * nearest_unit = NULL;
uint32_t nearest_unit_dist = 0xFFFFFFFF; // Set maximum value
uint32_t dist;
for(i = 0; i < PLAYER_MAX_UNITS; i++)
{
TYPE_UNIT * u = &units[i];
TYPE_COLLISION_BLOCK cursor_cb = GetCursorPos();
TYPE_COLLISION_BLOCK u_cb = {u->x, u->y, UnitGetWidthFromID(u->id), UnitGetHeightFromID(u->id) };
uint16_t dist_x = (u_cb.x - cursor_cb.x);
uint16_t dist_y = (u_cb.y - cursor_cb.y);
dist = (dist_x * dist_x) + (dist_y * dist_y);
if(dist < nearest_unit_dist)
{
nearest_unit_dist = dist;
nearest_unit = u;
}
}
TYPE_BUILDING * nearest_building = NULL;
uint32_t nearest_building_dist = 0xFFFFFFFF; // Set maximum value
for(i = 0; i < PLAYER_MAX_BUILDINGS; i++)
{
TYPE_BUILDING * b = &buildings[i];
TYPE_COLLISION_BLOCK cursor_cb = GetCursorPos();
TYPE_COLLISION_BLOCK u_cb = {b->x, b->y, BuildingGetWidthFromID(b->id), BuildingGetHeightFromID(b->id) };
uint16_t dist_x = (u_cb.x + (u_cb.w >> 1) - cursor_cb.x + 4);
uint16_t dist_y = (u_cb.y + (u_cb.h >> 1) - cursor_cb.y + 4);
dist = (dist_x * dist_x) + (dist_y * dist_y);
if(dist < nearest_building_dist)
{
nearest_building_dist = dist;
nearest_building = b;
}
}
if(nearest_building_dist <= nearest_unit_dist)
{
selectedUnit = NULL;
selectedBuilding = nearest_building;
}
else
{
selectedUnit = nearest_unit;
selectedBuilding = NULL;
}
char buf[8];
snprintf(buf, 8, "%lu", nearest_building_dist);
GfxPrintText(buf, X_SCREEN_RESOLUTION - 32, 16);
snprintf(buf, 8, "%lu", nearest_unit_dist);
GfxPrintText(buf, X_SCREEN_RESOLUTION - 32, 24);
}
void Player::Handler(void)
{
CameraHandler(&Camera);
UnitBuildingSelection();
if(PadButtonReleased(PAD_A) == true)
{
TYPE_COLLISION_BLOCK cl;
/*TYPE_COLLISION_BLOCK cl;
cl.x = SystemRand(0, 32);
cl.y = SystemRand(0, 32);
@ -185,6 +314,26 @@ void Player::Handler(void)
else
{
GfxPrintText_Flash(F("Building built!\0"));
}*/
for(int i = 0; i < PLAYER_MAX_UNITS; i++)
{
TYPE_UNIT * u = &units[i];
if(selectedUnit == u)
{
u->selected = true;
}
}
for(int i = 0; i < PLAYER_MAX_BUILDINGS; i++)
{
TYPE_BUILDING * b = &buildings[i];
if(selectedBuilding == b)
{
b->selected = true;
}
}
}

View File

@ -9,6 +9,7 @@
#include "GameStructures.h"
#include "Camera.h"
#include "Building.h"
#include "Unit.h"
/* **************************************
* Defines *
@ -37,22 +38,26 @@ class Player
char * getName(void) {return name;}
void setHuman(bool value) { human = value; }
bool isHuman(void) {return human;}
bool createUnit(uint8_t id);
bool createUnit(uint8_t id, TYPE_COLLISION_BLOCK cb);
bool createBuilding(uint8_t id, TYPE_COLLISION_BLOCK cb);
uint8_t getPopulation(void) {return (unit_i + 1);}
uint8_t getBuildings(void) {return (bldg_i + 1);}
private:
bool checkNewBuildingPosition(TYPE_COLLISION_BLOCK * cb);
char name[PLAYER_NAME_LENGTH];
uint8_t units[PLAYER_MAX_UNITS];
TYPE_BUILDING buildings[PLAYER_MAX_BUILDINGS];
uint8_t id;
uint8_t unit_i;
uint8_t bldg_i;
bool human;
TYPE_CAMERA Camera;
TYPE_RESOURCES Resources;
bool checkNewBuildingPosition(TYPE_COLLISION_BLOCK * cb);
void UnitBuildingSelection(void);
TYPE_COLLISION_BLOCK GetCursorPos(void);
char name[PLAYER_NAME_LENGTH];
TYPE_UNIT units[PLAYER_MAX_UNITS];
TYPE_BUILDING buildings[PLAYER_MAX_BUILDINGS];
TYPE_UNIT* selectedUnit;
TYPE_BUILDING* selectedBuilding;
uint8_t id;
uint8_t unit_i;
uint8_t bldg_i;
bool human;
TYPE_CAMERA Camera;
TYPE_RESOURCES Resources;
//Print _serial;
};

Binary file not shown.

Before

Width:  |  Height:  |  Size: 246 B

After

Width:  |  Height:  |  Size: 246 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 246 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 246 B

View File

@ -15,58 +15,76 @@
/* Sprites */
static TYPE_SPRITE PeasantSpr;
static TYPE_SPRITE PeasantShadowSpr;
static TYPE_SPRITE PeasantWalkingSpr;
/* Tables */
static uint8_t UnitHPTable[] = { 25 };
static TYPE_SPRITE * UnitSprTable[] = {&PeasantSpr};
static TYPE_SPRITE * UnitShadowSprTable[] = {&PeasantShadowSpr};
static TYPE_SPRITE * UnitWalkingSprTable[] = {&PeasantWalkingSpr};
void UnitInit(void)
{
PeasantSpr.Data = PeasantSpr_Data;
PeasantSpr.w = GfxGetWidthFromSpriteData(PeasantSpr_Data);
PeasantSpr.h = GfxGetHeightFromSpriteData(PeasantSpr_Data);
PeasantSpr.Data = Peasant_SprData;
PeasantSpr.w = GfxGetWidthFromSpriteData(Peasant_SprData);
PeasantSpr.h = GfxGetHeightFromSpriteData(Peasant_SprData);
PeasantSpr.flip = 0;
PeasantSpr.rotation = 0;
PeasantSpr.color = GFX_BLACK;
PeasantShadowSpr.Data = PeasantShadowSpr_Data;
PeasantShadowSpr.w = GfxGetWidthFromSpriteData(PeasantShadowSpr_Data);
PeasantShadowSpr.h = GfxGetHeightFromSpriteData(PeasantShadowSpr_Data);
PeasantShadowSpr.flip = 0;
PeasantShadowSpr.rotation = 0;
PeasantShadowSpr.color = GFX_GRAY;
PeasantWalkingSpr.Data = Peasant_Walking_SprData;
PeasantWalkingSpr.w = GfxGetWidthFromSpriteData(Peasant_Walking_SprData);
PeasantWalkingSpr.h = GfxGetHeightFromSpriteData(Peasant_Walking_SprData);
PeasantWalkingSpr.flip = 0;
PeasantWalkingSpr.rotation = 0;
PeasantWalkingSpr.color = GFX_BLACK;
}
uint8_t UnitGetHpFromID(uint8_t id)
{
return UnitHPTable[id];
}
void UnitDraw(TYPE_CAMERA * ptrCamera, TYPE_UNIT * ptrUnit)
void UnitDraw(TYPE_CAMERA * ptrCamera, TYPE_UNIT * ptrUnit, bool bSelected)
{
uint8_t id = ptrUnit->id;
TYPE_SPRITE * ptrSpr;
static uint8_t walk_counter = 0;
static bool mirror = false;
if(ptrUnit->built == false)
if(ptrUnit->alive == false)
{
return;
}
CameraApplyCoordinatesToSprite( ptrCamera,
UnitShadowSprTable[id],
ptrUnit->x - 6,
ptrUnit->y );
GfxDrawSprite(UnitShadowSprTable[id]);
ptrSpr = ptrUnit->walk ? UnitWalkingSprTable[id] : UnitSprTable[id];
ptrSpr->rotation = ptrUnit->dir ? ROTCCW : NOROT;
ptrSpr->flip = mirror ? FLIPH : NOFLIP;
CameraApplyCoordinatesToSprite( ptrCamera,
UnitSprTable[id],
ptrSpr,
ptrUnit->x,
ptrUnit->y );
GfxDrawSprite(&PeasantSpr);
GfxDrawSprite(ptrSpr);
if( (bSelected == true) && (ptrUnit->selected == false) )
{
TYPE_COLLISION_BLOCK cb;
cb = CameraApplyCoordinatesToCoordinates(ptrCamera, ptrUnit->x, ptrUnit->y);
GfxDrawCircle(cb.x + 3, cb.y + 3, UnitGetWidthFromID(ptrUnit->id) >> 2, GFX_GRAY);
}
else if(ptrUnit->selected == true)
{
TYPE_COLLISION_BLOCK cb;
cb = CameraApplyCoordinatesToCoordinates(ptrCamera, ptrUnit->x, ptrUnit->y);
GfxDrawCircle(cb.x + 3, cb.y + 3, UnitGetWidthFromID(ptrUnit->id) >> 2, GFX_BLACK);
}
if(++walk_counter > 10)
{
walk_counter = 0;
mirror = mirror ? true : false;
}
}
uint8_t UnitGetWidthFromID(uint8_t id)
@ -79,3 +97,12 @@ uint8_t UnitGetHeightFromID(uint8_t id)
return GfxGetHeightFromSpriteData(UnitSprTable[id]->Data);
}
uint8_t UnitGetHpFromID(uint8_t id)
{
return UnitHPTable[id];
}
void UnitSelectedOptions(TYPE_UNIT* ptrUnit)
{
}