add astar
This commit is contained in:
parent
d27c9bd1ef
commit
71025fc7fa
7 changed files with 157 additions and 19 deletions
2
makefile
2
makefile
|
@ -11,7 +11,7 @@ INC_FLAGS := $(addprefix -I,$(INC_DIRS))
|
||||||
CPPFLAGS ?= $(INC_FLAGS) -MMD -MP
|
CPPFLAGS ?= $(INC_FLAGS) -MMD -MP
|
||||||
|
|
||||||
$(TARGET): $(OBJS)
|
$(TARGET): $(OBJS)
|
||||||
$(CC) $(LDFLAGS) $(OBJS) -o $@ $(LOADLIBES) $(LDLIBS) -lSDL2
|
$(CC) $(LDFLAGS) $(OBJS) -o $@ $(LOADLIBES) $(LDLIBS) -lSDL2 -lSDL2_image -lSDL2_ttf
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
|
|
133
src/ai.c
Normal file
133
src/ai.c
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "data.h"
|
||||||
|
|
||||||
|
#define MAX_UNITS 100
|
||||||
|
#define MAX_BUILDINGS 50
|
||||||
|
|
||||||
|
typedef struct Node {
|
||||||
|
int x, y;
|
||||||
|
int gCost; // Cost from start node
|
||||||
|
int hCost; // Heuristic cost to target node
|
||||||
|
struct Node* parent;
|
||||||
|
} Node;
|
||||||
|
|
||||||
|
// Function to calculate the distance between two points using Manhattan distance
|
||||||
|
int calculateDistance(int x1, int y1, int x2, int y2) {
|
||||||
|
return abs(x1 - x2) + abs(y1 - y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isUnitOrBuildingAtPosition(GameData* data, int x, int y) {
|
||||||
|
for (int i = 0; i < MAX_UNITS; i++) {
|
||||||
|
if (data->units[i].unitID != -1 && data->units[i].x == x && data->units[i].y == y) {
|
||||||
|
// Found a unit at the position
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_BUILDINGS; i++) {
|
||||||
|
if (data->buildings[i].buildingID != -1 && data->buildings[i].x == x && data->buildings[i].y == y) {
|
||||||
|
// Found a building at the position
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No unit or building found at the position
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A* algorithm implementation
|
||||||
|
void aStarPathfinding(GameData* map, int startX, int startY, int targetX, int targetY) {
|
||||||
|
// Create start and target nodes
|
||||||
|
Node startNode = {startX, startY, 0, 0, NULL};
|
||||||
|
Node targetNode = {targetX, targetY, 0, 0, NULL};
|
||||||
|
|
||||||
|
// Create open and closed lists
|
||||||
|
Node* openList = malloc(sizeof(Node) * MAP_SIZE * MAP_SIZE);
|
||||||
|
Node* closedList = malloc(sizeof(Node) * MAP_SIZE * MAP_SIZE);
|
||||||
|
int openListCount = 0;
|
||||||
|
int closedListCount = 0;
|
||||||
|
|
||||||
|
// Add start node to open list
|
||||||
|
openList[openListCount++] = startNode;
|
||||||
|
|
||||||
|
while (openListCount > 0) {
|
||||||
|
// Find the node with the lowest fCost in the open list
|
||||||
|
int currentIndex = 0;
|
||||||
|
for (int i = 0; i < openListCount; i++) {
|
||||||
|
if (openList[i].gCost + openList[i].hCost < openList[currentIndex].gCost + openList[currentIndex].hCost) {
|
||||||
|
currentIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move current node to the closed list
|
||||||
|
Node currentNode = openList[currentIndex];
|
||||||
|
openList[currentIndex] = openList[--openListCount];
|
||||||
|
closedList[closedListCount++] = currentNode;
|
||||||
|
|
||||||
|
// Check if we have reached the target node
|
||||||
|
if (currentNode.x == targetNode.x && currentNode.y == targetNode.y) {
|
||||||
|
// Path found, reconstruct and print the path
|
||||||
|
while (currentNode.parent != NULL) {
|
||||||
|
printf("(%d, %d) -> ", currentNode.x, currentNode.y);
|
||||||
|
currentNode = *currentNode.parent;
|
||||||
|
}
|
||||||
|
printf("(%d, %d)\n", startX, startY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate neighboring nodes
|
||||||
|
for (int i = -1; i <= 1; i++) {
|
||||||
|
for (int j = -1; j <= 1; j++) {
|
||||||
|
if (i == 0 && j == 0) continue;
|
||||||
|
|
||||||
|
int neighborX = currentNode.x + i;
|
||||||
|
int neighborY = currentNode.y + j;
|
||||||
|
|
||||||
|
// Ignore invalid neighbors or obstacles
|
||||||
|
if (neighborX < 0 || neighborX >= MAP_SIZE || neighborY < 0 || neighborY >= MAP_SIZE ||
|
||||||
|
map->currentMap.tileData[neighborX][neighborY] == 1 || isUnitOrBuildingAtPosition(map, neighborX, neighborY)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate neighbor costs
|
||||||
|
int gCost = currentNode.gCost + 1; // Assuming uniform movement cost
|
||||||
|
int hCost = calculateDistance(neighborX, neighborY, targetNode.x, targetNode.y);
|
||||||
|
|
||||||
|
// Check if neighbor is in the closed list
|
||||||
|
bool inClosedList = false;
|
||||||
|
for (int k = 0; k < closedListCount; k++) {
|
||||||
|
if (closedList[k].x == neighborX && closedList[k].y == neighborY) {
|
||||||
|
inClosedList = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inClosedList) {
|
||||||
|
// Check if neighbor is in the open list
|
||||||
|
bool inOpenList = false;
|
||||||
|
for (int k = 0; k < openListCount; k++) {
|
||||||
|
if (openList[k].x == neighborX && openList[k].y == neighborY) {
|
||||||
|
inOpenList = true;
|
||||||
|
if (gCost < openList[k].gCost) {
|
||||||
|
openList[k].gCost = gCost;
|
||||||
|
openList[k].parent = ¤tNode;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inOpenList) {
|
||||||
|
// Add neighbor to open list
|
||||||
|
openList[openListCount++] = (Node){neighborX, neighborY, gCost, hCost, ¤tNode};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(openList);
|
||||||
|
free(closedList);
|
||||||
|
}
|
|
@ -7,6 +7,7 @@
|
||||||
#define MAX_MISSIONS 10
|
#define MAX_MISSIONS 10
|
||||||
#define MAX_RESOURCES 50
|
#define MAX_RESOURCES 50
|
||||||
#define MAP_SIZE 100
|
#define MAP_SIZE 100
|
||||||
|
#define numLEVELS 50
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int playerID;
|
int playerID;
|
||||||
|
@ -36,7 +37,7 @@ typedef struct {
|
||||||
char mapName[50];
|
char mapName[50];
|
||||||
int mapWidth;
|
int mapWidth;
|
||||||
int mapHeight;
|
int mapHeight;
|
||||||
int tileData[MAP_SIZE][MAP_SIZE];
|
uint4_t tileData[MAP_SIZE][MAP_SIZE];
|
||||||
int playerStartingPositions[MAX_PLAYERS][2]; // [x, y] coordinates for each player
|
int playerStartingPositions[MAX_PLAYERS][2]; // [x, y] coordinates for each player
|
||||||
int resourceLocations[MAX_RESOURCES][2]; // [x, y] coordinates for each resource
|
int resourceLocations[MAX_RESOURCES][2]; // [x, y] coordinates for each resource
|
||||||
} Map;
|
} Map;
|
||||||
|
@ -87,7 +88,7 @@ typedef struct {
|
||||||
} UnitData;
|
} UnitData;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GameData data;
|
GameData data[numLEVELS];
|
||||||
BuildingData buildings[100];
|
BuildingData buildings[100];
|
||||||
UnitData units[100];
|
UnitData units[100];
|
||||||
} Game;
|
} Game;
|
||||||
|
|
14
src/draw.h
14
src/draw.h
|
@ -11,17 +11,3 @@
|
||||||
void drawGameData(SDL_Renderer *renderer, const GameData *gameData, SDL_Texture *tileTexture, SDL_Texture *unitTexture, SDL_Texture *buildingTexture);
|
void drawGameData(SDL_Renderer *renderer, const GameData *gameData, SDL_Texture *tileTexture, SDL_Texture *unitTexture, SDL_Texture *buildingTexture);
|
||||||
|
|
||||||
#endif /* DRAW_H */
|
#endif /* DRAW_H */
|
||||||
#define MAP_SIZE 96
|
|
||||||
#ifndef DRAW_H
|
|
||||||
#define DRAW_H
|
|
||||||
|
|
||||||
#include <SDL2/SDL.h>
|
|
||||||
|
|
||||||
// Define the size of your tiles in pixels
|
|
||||||
#define TILE_SIZE 32
|
|
||||||
#include "data.h"
|
|
||||||
|
|
||||||
// Function prototype for drawing game data
|
|
||||||
void drawGameData(SDL_Renderer *renderer, const GameData *gameData, SDL_Texture *tileTexture, SDL_Texture *unitTexture, SDL_Texture *buildingTexture);
|
|
||||||
|
|
||||||
#endif /* DRAW_H */
|
|
||||||
|
|
19
src/main.c
19
src/main.c
|
@ -4,12 +4,19 @@
|
||||||
#include "draw.h"
|
#include "draw.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
|
#include <SDL2/SDL_ttf.h>
|
||||||
|
#include <SDL2/SDL_image.h>
|
||||||
|
|
||||||
const int SCREEN_WIDTH = 800;
|
const int SCREEN_WIDTH = 800;
|
||||||
const int SCREEN_HEIGHT = 600;
|
const int SCREEN_HEIGHT = 600;
|
||||||
|
|
||||||
|
void updateGameState() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
SDL_Init(SDL_INIT_VIDEO);
|
SDL_Init(SDL_INIT_VIDEO);
|
||||||
|
TTF_Init();
|
||||||
SDL_Window* window = SDL_CreateWindow("RTS Game", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
SDL_Window* window = SDL_CreateWindow("RTS Game", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
||||||
SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
|
SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
|
||||||
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
|
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
|
||||||
|
@ -18,6 +25,16 @@ int main(int argc, char* argv[]) {
|
||||||
bool quit = false;
|
bool quit = false;
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
|
|
||||||
|
// Load textures for tiles, units, and buildings
|
||||||
|
SDL_Texture* unitTexture = IMG_LoadTexture(renderer, "path/to/unit_texture.png");
|
||||||
|
SDL_Texture* buildingTexture = IMG_LoadTexture(renderer, "path/to/building_texture.png");
|
||||||
|
SDL_Texture* tileTexture = IMG_LoadTexture(renderer, "path/to/tile_texture.png");
|
||||||
|
|
||||||
|
// Assuming you have a GameData instance named gameData
|
||||||
|
GameData gameData;
|
||||||
|
// Initialize gameData here...
|
||||||
|
|
||||||
|
|
||||||
while (!quit) {
|
while (!quit) {
|
||||||
// Event handling
|
// Event handling
|
||||||
while (SDL_PollEvent(&event) != 0) {
|
while (SDL_PollEvent(&event) != 0) {
|
||||||
|
@ -35,7 +52,7 @@ int main(int argc, char* argv[]) {
|
||||||
SDL_RenderClear(renderer);
|
SDL_RenderClear(renderer);
|
||||||
|
|
||||||
// Render game objects
|
// Render game objects
|
||||||
renderGame(renderer); // You need to define this function to render the game
|
drawGameData(renderer, &gameData, tileTexture, unitTexture, buildingTexture);
|
||||||
|
|
||||||
// Update the screen
|
// Update the screen
|
||||||
SDL_RenderPresent(renderer);
|
SDL_RenderPresent(renderer);
|
||||||
|
|
1
src/ui.c
1
src/ui.c
|
@ -1,6 +1,7 @@
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
#include <SDL2/SDL_ttf.h>
|
||||||
|
|
||||||
bool isPointInsideRect(int x, int y, SDL_Rect rect) {
|
bool isPointInsideRect(int x, int y, SDL_Rect rect) {
|
||||||
return (x >= rect.x && x <= rect.x + rect.w && y >= rect.y && y <= rect.y + rect.h);
|
return (x >= rect.x && x <= rect.x + rect.w && y >= rect.y && y <= rect.y + rect.h);
|
||||||
|
|
2
src/ui.h
2
src/ui.h
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
#include <SDL2/SDL_ttf.h>
|
||||||
|
|
||||||
// Structure representing a button
|
// Structure representing a button
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -10,7 +11,6 @@ typedef struct {
|
||||||
bool clicked;
|
bool clicked;
|
||||||
void (*onClick)();
|
void (*onClick)();
|
||||||
char text[50];
|
char text[50];
|
||||||
char text[50];
|
|
||||||
} Button;
|
} Button;
|
||||||
|
|
||||||
// Function prototypes
|
// Function prototypes
|
||||||
|
|
Loading…
Reference in a new issue