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
|
||||
|
||||
$(TARGET): $(OBJS)
|
||||
$(CC) $(LDFLAGS) $(OBJS) -o $@ $(LOADLIBES) $(LDLIBS) -lSDL2
|
||||
$(CC) $(LDFLAGS) $(OBJS) -o $@ $(LOADLIBES) $(LDLIBS) -lSDL2 -lSDL2_image -lSDL2_ttf
|
||||
|
||||
.PHONY: 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_RESOURCES 50
|
||||
#define MAP_SIZE 100
|
||||
#define numLEVELS 50
|
||||
|
||||
typedef struct {
|
||||
int playerID;
|
||||
|
@ -36,7 +37,7 @@ typedef struct {
|
|||
char mapName[50];
|
||||
int mapWidth;
|
||||
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 resourceLocations[MAX_RESOURCES][2]; // [x, y] coordinates for each resource
|
||||
} Map;
|
||||
|
@ -87,7 +88,7 @@ typedef struct {
|
|||
} UnitData;
|
||||
|
||||
typedef struct {
|
||||
GameData data;
|
||||
GameData data[numLEVELS];
|
||||
BuildingData buildings[100];
|
||||
UnitData units[100];
|
||||
} 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);
|
||||
|
||||
#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 "input.h"
|
||||
#include "ui.h"
|
||||
#include <SDL2/SDL_ttf.h>
|
||||
#include <SDL2/SDL_image.h>
|
||||
|
||||
const int SCREEN_WIDTH = 800;
|
||||
const int SCREEN_HEIGHT = 600;
|
||||
|
||||
void updateGameState() {
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
TTF_Init();
|
||||
SDL_Window* window = SDL_CreateWindow("RTS Game", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
||||
SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
|
||||
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
|
||||
|
@ -18,6 +25,16 @@ int main(int argc, char* argv[]) {
|
|||
bool quit = false;
|
||||
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) {
|
||||
// Event handling
|
||||
while (SDL_PollEvent(&event) != 0) {
|
||||
|
@ -35,7 +52,7 @@ int main(int argc, char* argv[]) {
|
|||
SDL_RenderClear(renderer);
|
||||
|
||||
// Render game objects
|
||||
renderGame(renderer); // You need to define this function to render the game
|
||||
drawGameData(renderer, &gameData, tileTexture, unitTexture, buildingTexture);
|
||||
|
||||
// Update the screen
|
||||
SDL_RenderPresent(renderer);
|
||||
|
|
1
src/ui.c
1
src/ui.c
|
@ -1,6 +1,7 @@
|
|||
#include "ui.h"
|
||||
#include <stdbool.h>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_ttf.h>
|
||||
|
||||
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);
|
||||
|
|
2
src/ui.h
2
src/ui.h
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_ttf.h>
|
||||
|
||||
// Structure representing a button
|
||||
typedef struct {
|
||||
|
@ -10,7 +11,6 @@ typedef struct {
|
|||
bool clicked;
|
||||
void (*onClick)();
|
||||
char text[50];
|
||||
char text[50];
|
||||
} Button;
|
||||
|
||||
// Function prototypes
|
||||
|
|
Loading…
Reference in a new issue