Complexificando a `Unit`
Descoberta
Então, no último post falei sobre usar class no lugar de struct, mas agora que pesquisei sobre descobri que Cnão suporta class kkkk, bom, acho que vou ter que me manter com o struct mesmo mas pelo que estou vendo é possível colocar functions dentro do struct então acho que da para fazer o que eu planejava com a class no struct mesmo kkkk *rindo de nervoso*.
Fase de pesquisa
Encontrei esse outro site onde parece ensinar a implementar uma espécie de class dentro do C então já vou seguir ele já e testar no meu Unit, já aproveito também e já começo a separar os arquivos. Mas o que acho estrnaho é que ele está usando apenas struct e não typedef struct não sei qual é a diferença, mas isso é só um desabafo. Outra coisa que estranho é aquele tal de extern não acho que seja um export já que já separei arquivos e não precisei usar ele.
Fase de teste
Separei em 3 arquivos, agora possuo main.c, unit.c e unit.h, para separar precisei alterar o código e para ter certeza que ele ainda está funcionando eu quero "buildar" ele novamente, mas com 3 arquivos já ficou mais chato de "buildar" então vou criar um Makefile simples.
build:
gcc main.c unit.c -o game -lraylib -lm
E como esperado, depois de executar make o código está cheio de erros kkkkk que delícia, isso porque eu só estou tentando fazer igual a parte 1. C Classes do tutorial.
[Alguns minutos depois]
Ao que parece eu nunca ia acertar mesmo, eu estava tentando instânciar a Unit class diretamente em main.c mas me lembrei que a segunda parte do tutorial ensinava como eu deveria fazer essa parte e irmão, como eu estava longe kkkk, bom, segui o tutorial e "buildou" que é uma delícia, mas agora quando eu executo o jogo a janela abre e fecha :D
[Alguns segundos depois]
Eu ia escrever dizendo que meu tempo estava acabando e que iria parar por agora, mas antes de finalizar dei uma última olhada e por sorte o arquivo que estava aberto era o unit.c que é onde o problema morava. Acontece que eu esqueci de colocar o .new=&new no meu UnitClass, então coloquei ele e decidi testar a última vez, e não é que funcionou lisinho kkkkk.
Esses são os meus arquivos atuais:
main.c
#include "raylib.h"
#include "raymath.h"
#include <math.h>
#include "unit.h"
typedef struct Target {
Vector2 pos;
Color color;
int width; // radius
int speedX;
int speedY;
} Target;
int main(void) {
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "Tower Defense");
SetTargetFPS(60);
const int size = 50;
Vector2 screenCenter = { screenWidth/2-size/2, screenHeight/2-size/2};
struct Unit unit = Unit.new(size, size, screenCenter, RED);
Target target = {0};
target.pos = (Vector2){ unit.pos.x-size*2+size/2, unit.pos.y-size*2+size/2 };
target.color = BLUE;
target.width = size/2;
target.speedX = 10;
target.speedY = 10;
while (!WindowShouldClose()) {
// Calculate movement of target
target.pos.x += target.speedX;
target.pos.y += target.speedY;
if (target.pos.x >= screenWidth-target.width/2 || target.pos.x <= 0+target.width/2) target.speedX *= -1;
if (target.pos.y >= screenHeight-target.width/2 || target.pos.y <= 0+target.width/2) target.speedY *= -1;
// Calculate Unit angle
Vector2 unitDir = Vector2Subtract(target.pos, unit.pos);
float unitAngle = atan2f(unitDir.y, unitDir.x) * RAD2DEG;
unit.angle = unitAngle;
BeginDrawing();
ClearBackground(RAYWHITE);
DrawRectanglePro(unit.body, unit.origin, unit.angle, unit.color);
DrawCircle(target.pos.x, target.pos.y, target.width, target.color);
EndDrawing();
}
CloseWindow();
return 0;
}
unit.c
#include "unit.h"
static struct Unit new(int width, int height, Vector2 pos, Color color) {
Vector2 origin = { width/2, width/2 };
Rectangle body = { pos.x, pos.y, width, height };
float angle = 0;;
return (struct Unit){
.pos = pos,
.origin = origin,
.body = body,
.color = color,
.width = width,
.height = height,
.angle = angle
};
}
const struct UnitClass Unit = {.new=&new};
unit.h
#include "raylib.h"
struct Unit {
Vector2 pos;
Vector2 origin;
Rectangle body;
Color color;
int width;
int height;
float angle;
};
extern const struct UnitClass {
struct Unit (*new)(int width, int height, Vector2 pos, Color color);
} Unit;
Conclusão
Enfim, esqueci de colocar o objetivo dessa sessão mas o que eu tinha em mente era refatorar o Unit struct para class, não aconteceu como eu esperava já que C não suporta class mas de certa forma chegamos lá.
Para as próximas sessões acredito que eu deveria criar uma class para Enemy e trocar o Target já criando os arquivos de enemy, depois gerar um movimento simples para ele, sem pathfinding ainda já que só quero conseguir testar melhor as Units.
Basicamente esses são os próximos objetivos:
- Criar
Enemy class - Adicionar movimento simples para
Enemy class - Substituir
TargetpelaEnemy class - Garantir que tudo ainda funciona como funcionava
- Criar
Bullet class - Configurar
Bullet classpara andar sempre em uma direção - Configurar
Unit classpara conseguir atirarBullet classquando ver um inimigo - Configurar prioridade de
Enemy classnaUnit class
Por enquanto esse é o plano para as próximas sessões, não são coisas complicadas de fazer mas talvez esteja faltando um pouco de recompensa no meio do caminho, sabe? Mas não vou poder pensar nisso agora, vai ficar para a próxima sessão.
De qualquer forma aceito ideias, sugetões ou qualquer outra forma de contribuição, obrigado e até a próxima sess
Fontes
Como implementar class em C
Implementando class em C
Lembrete
- Pesquisar a diferença entre
structetypedef structemC - Pesquisar o que é
externemC