Update
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@ -9,4 +9,5 @@ build/
|
|||||||
star-invaders
|
star-invaders
|
||||||
*.kra
|
*.kra
|
||||||
*.xcf
|
*.xcf
|
||||||
*.png
|
*.png
|
||||||
|
*.*~
|
||||||
4
Makefile
4
Makefile
@ -1,8 +1,8 @@
|
|||||||
# Simple Makefile using sdl-config for SDL flags
|
# Simple Makefile using sdl-config for SDL flags
|
||||||
CC := gcc
|
CC := clang
|
||||||
SDL_CFLAGS := $(shell sdl2-config --cflags)
|
SDL_CFLAGS := $(shell sdl2-config --cflags)
|
||||||
SDL_LIBS := $(shell sdl2-config --libs)
|
SDL_LIBS := $(shell sdl2-config --libs)
|
||||||
CFLAGS := -Wall -Wextra -std=c99 $(SDL_CFLAGS)
|
CFLAGS := -Wall -Wextra -std=c99 -g $(SDL_CFLAGS)
|
||||||
SRCDIR := src
|
SRCDIR := src
|
||||||
SOURCES := $(wildcard $(SRCDIR)/*.c)
|
SOURCES := $(wildcard $(SRCDIR)/*.c)
|
||||||
BUILD_DIR := build
|
BUILD_DIR := build
|
||||||
|
|||||||
BIN
res/bullet.bmp
Normal file
BIN
res/bullet.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
47
src/bullet.c
47
src/bullet.c
@ -1,9 +1,21 @@
|
|||||||
#include "bullet.h"
|
#include "bullet.h"
|
||||||
|
#include "game.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
void initBullet(Bullet *bullet, int x, int y) {
|
||||||
|
bullet->rect.x = x;
|
||||||
|
bullet->rect.y = y;
|
||||||
|
bullet->rect.w = 50; // Bullet width
|
||||||
|
bullet->rect.h = 50; // Bullet height
|
||||||
|
bullet->active = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void updateBullets(Bullet *bullets, int *bulletCount, SDL_Renderer* renderer) {
|
void updateBullets(Bullet *bullets, int *bulletCount, SDL_Renderer* renderer) {
|
||||||
int bulletSpeed = 7;
|
int bulletSpeed = 7;
|
||||||
|
|
||||||
for (int i = 0; i < *bulletCount; i++) {
|
for (int i = 0; i < MAX_BULLETS; i++) {
|
||||||
if (bullets[i].active) {
|
if (bullets[i].active) {
|
||||||
// Move bullet upward
|
// Move bullet upward
|
||||||
bullets[i].rect.y -= bulletSpeed;
|
bullets[i].rect.y -= bulletSpeed;
|
||||||
@ -11,32 +23,31 @@ void updateBullets(Bullet *bullets, int *bulletCount, SDL_Renderer* renderer) {
|
|||||||
// Deactivate if bullet goes off screen
|
// Deactivate if bullet goes off screen
|
||||||
if (bullets[i].rect.y < 0) {
|
if (bullets[i].rect.y < 0) {
|
||||||
bullets[i].active = 0;
|
bullets[i].active = 0;
|
||||||
|
(*bulletCount)--;
|
||||||
} else {
|
} else {
|
||||||
// Draw bullet
|
// Draw bullet using global textures
|
||||||
SDL_SetRenderDrawColor(renderer, 255, 255, 0, 255);
|
SDL_RenderCopy(renderer, textures.bulletTexture, NULL, &bullets[i].rect);
|
||||||
SDL_RenderFillRect(renderer, &bullets[i].rect);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void fireBullet(Bullet *bullets, int *bulletCount, SDL_Rect* rect) {
|
void fireBullet(Bullet *bullets, int *bulletCount, SDL_Rect* rect) {
|
||||||
if (*bulletCount < MAX_BULLETS) {
|
for (int i = 0; i < MAX_BULLETS; i++) {
|
||||||
bullets[*bulletCount].rect.x = rect->x + rect->w / 2 - 2;
|
if (!bullets[i].active) {
|
||||||
bullets[*bulletCount].rect.y = rect->y - 10;
|
bullets[i].rect.x = rect->x;
|
||||||
bullets[*bulletCount].rect.w = 4;
|
bullets[i].rect.y = rect->y;
|
||||||
bullets[*bulletCount].rect.h = 10;
|
bullets[i].active = 1;
|
||||||
bullets[*bulletCount].active = 1;
|
(*bulletCount)++;
|
||||||
(*bulletCount)++;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanupUnrenderedBullets(Bullet* bullets, int* bulletCount) {
|
void cleanupBullets(Bullet *bullets, int *bulletCount) {
|
||||||
for (int i = 0; i < *bulletCount; i++){
|
// Deactivate all bullets and reset count
|
||||||
if(bullets[i].active == 0){
|
for (int i = 0; i < MAX_BULLETS; i++) {
|
||||||
memmove(&bullets[i], &bullets[i + 1], sizeof(Bullet) * (*bulletCount - i - 1));
|
bullets[i].active = 0;
|
||||||
(*bulletCount)--;
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
*bulletCount = 0;
|
||||||
}
|
}
|
||||||
@ -10,8 +10,11 @@ typedef struct {
|
|||||||
int active;
|
int active;
|
||||||
} Bullet;
|
} Bullet;
|
||||||
|
|
||||||
|
/* Initialize an existing Bullet struct */
|
||||||
|
void initBullet(Bullet *bullet, int x, int y);
|
||||||
|
|
||||||
void updateBullets(Bullet *bullets, int *bulletCount, SDL_Renderer *renderer);
|
void updateBullets(Bullet *bullets, int *bulletCount, SDL_Renderer *renderer);
|
||||||
void fireBullet(Bullet *bullets, int *bulletCount, SDL_Rect *rect);
|
void fireBullet(Bullet *bullets, int *bulletCount, SDL_Rect *rect);
|
||||||
void cleanupUnrenderedBullets(Bullet* bullets, int* bulletCount);
|
void cleanupBullets(Bullet *bullets, int *bulletCount);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
25
src/game.h
Normal file
25
src/game.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef GAME_H
|
||||||
|
#define GAME_H
|
||||||
|
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
|
#define FPS 60
|
||||||
|
#define FRAME_DELAY (1000 / FPS) // Milliseconds per frame
|
||||||
|
#define SCREEN_WIDTH 800
|
||||||
|
#define SCREEN_HEIGHT 600
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *spaceshipPath;
|
||||||
|
char *backgroundPath;
|
||||||
|
char *bulletPath;
|
||||||
|
} AssetPaths;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
SDL_Texture *bulletTexture;
|
||||||
|
SDL_Texture *playerTexture;
|
||||||
|
SDL_Texture *backgroundTexture;
|
||||||
|
} Textures;
|
||||||
|
|
||||||
|
extern Textures textures;
|
||||||
|
|
||||||
|
#endif /* GAME_H */
|
||||||
280
src/main.c
280
src/main.c
@ -1,25 +1,150 @@
|
|||||||
#include "bullet.h"
|
#include "bullet.h"
|
||||||
|
#include "game.h"
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define FPS 60
|
Textures textures = {0}; // global textures storage (initialized to NULL pointers)
|
||||||
#define FRAME_DELAY (1000 / FPS) // Milliseconds per frame
|
|
||||||
#define SCREEN_WIDTH 800
|
|
||||||
#define SCREEN_HEIGHT 600
|
|
||||||
|
|
||||||
void handlePlayer(SDL_Renderer *renderer, Player *player, int speed, const Uint8 *keys) {
|
int loadTextures(SDL_Renderer *renderer, AssetPaths *paths) {
|
||||||
if (keys[SDL_SCANCODE_LEFT] || keys[SDL_SCANCODE_A]) {
|
SDL_Surface *bulletSurface = SDL_LoadBMP(paths->bulletPath);
|
||||||
movePlayerLeft(player, speed);
|
if (!bulletSurface) {
|
||||||
}
|
fprintf(stderr, "Could not load bullet image: %s\n", SDL_GetError());
|
||||||
if (keys[SDL_SCANCODE_RIGHT] || keys[SDL_SCANCODE_D]) {
|
return 0;
|
||||||
movePlayerRight(player, speed, SCREEN_WIDTH);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render player flipped vertically
|
textures.bulletTexture = SDL_CreateTextureFromSurface(renderer, bulletSurface);
|
||||||
renderPlayerFlipped(renderer, player, SDL_FLIP_VERTICAL);
|
SDL_FreeSurface(bulletSurface);
|
||||||
|
if (!textures.bulletTexture) {
|
||||||
|
fprintf(stderr, "Could not create bullet texture: %s\n", SDL_GetError());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Surface *playerSurface = SDL_LoadBMP(paths->spaceshipPath);
|
||||||
|
if (!playerSurface) {
|
||||||
|
fprintf(stderr, "Could not load player image: %s\n", SDL_GetError());
|
||||||
|
SDL_DestroyTexture(textures.bulletTexture);
|
||||||
|
textures.bulletTexture = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
textures.playerTexture = SDL_CreateTextureFromSurface(renderer, playerSurface);
|
||||||
|
SDL_FreeSurface(playerSurface);
|
||||||
|
if (!textures.playerTexture) {
|
||||||
|
fprintf(stderr, "Could not create player texture: %s\n", SDL_GetError());
|
||||||
|
SDL_DestroyTexture(textures.bulletTexture);
|
||||||
|
textures.bulletTexture = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load background (non-fatal) */
|
||||||
|
SDL_Surface *bgSurface = SDL_LoadBMP(paths->backgroundPath);
|
||||||
|
if (!bgSurface) {
|
||||||
|
fprintf(stderr, "Could not load background %s: %s\n", paths->backgroundPath, SDL_GetError());
|
||||||
|
textures.backgroundTexture = NULL;
|
||||||
|
} else {
|
||||||
|
textures.backgroundTexture = SDL_CreateTextureFromSurface(renderer, bgSurface);
|
||||||
|
SDL_FreeSurface(bgSurface);
|
||||||
|
if (!textures.backgroundTexture) {
|
||||||
|
fprintf(stderr, "Could not create background texture: %s\n", SDL_GetError());
|
||||||
|
textures.backgroundTexture = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse command-line arguments. Returns:
|
||||||
|
* 0 -> continue normally
|
||||||
|
* 1 -> printed help/version, should exit success
|
||||||
|
* -1 -> error in args, should exit failure
|
||||||
|
*/
|
||||||
|
static int handleArguments(int argc, char *argv[], char **resLocation) {
|
||||||
|
for (int args = 1; args < argc; args++) {
|
||||||
|
if (strcmp(argv[args], "--help") == 0 || strcmp(argv[args], "-h") == 0) {
|
||||||
|
printf("Star Invaders Help:\n");
|
||||||
|
printf("Use arrow keys or A/D to move the spaceship left and right.\n");
|
||||||
|
printf("Press SPACE to fire bullets.\n");
|
||||||
|
printf("Press ESC or close the window to exit the game.\n");
|
||||||
|
printf("Use --res-location or -rl to specify the resource location.\n");
|
||||||
|
return 1;
|
||||||
|
} else if (strcmp(argv[args], "--version") == 0 || strcmp(argv[args], "-v") == 0) {
|
||||||
|
printf("Star Invaders Version 1.0.0\n");
|
||||||
|
return 1;
|
||||||
|
} else if (strcmp(argv[args], "--res-location") == 0 || strcmp(argv[args], "-rl") == 0) {
|
||||||
|
if (args + 1 >= argc) {
|
||||||
|
fprintf(stderr, "Missing value for %s\n", argv[args]);
|
||||||
|
printf("Use --help or -h for usage information.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*resLocation = argv[++args];
|
||||||
|
} else {
|
||||||
|
printf("Unknown argument: %s\n", argv[args]);
|
||||||
|
printf("Use --help or -h for usage information.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetPaths *getResources(const char *resLocation) {
|
||||||
|
AssetPaths *paths = (AssetPaths *)malloc(sizeof(AssetPaths));
|
||||||
|
if (!paths) {
|
||||||
|
fprintf(stderr, "Out of memory\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t pathLen;
|
||||||
|
const char *shipFile = "spaceship.bmp";
|
||||||
|
const char *bgFile = "background.bmp";
|
||||||
|
const char *bulletFile = "bullet.bmp";
|
||||||
|
|
||||||
|
pathLen = strlen(resLocation) + strlen(shipFile) + 2;
|
||||||
|
paths->spaceshipPath = (char *)malloc(pathLen);
|
||||||
|
if (!paths->spaceshipPath) {
|
||||||
|
free(paths);
|
||||||
|
fprintf(stderr, "Out of memory\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (resLocation[strlen(resLocation) - 1] == '/') {
|
||||||
|
snprintf(paths->spaceshipPath, pathLen, "%s%s", resLocation, shipFile);
|
||||||
|
} else {
|
||||||
|
snprintf(paths->spaceshipPath, pathLen, "%s/%s", resLocation, shipFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
pathLen = strlen(resLocation) + strlen(bgFile) + 2;
|
||||||
|
paths->backgroundPath = (char *)malloc(pathLen);
|
||||||
|
if (!paths->backgroundPath) {
|
||||||
|
free(paths->spaceshipPath);
|
||||||
|
free(paths);
|
||||||
|
fprintf(stderr, "Out of memory\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (resLocation[strlen(resLocation) - 1] == '/') {
|
||||||
|
snprintf(paths->backgroundPath, pathLen, "%s%s", resLocation, bgFile);
|
||||||
|
} else {
|
||||||
|
snprintf(paths->backgroundPath, pathLen, "%s/%s", resLocation, bgFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
pathLen = strlen(resLocation) + strlen(bulletFile) + 2;
|
||||||
|
paths->bulletPath = (char *)malloc(pathLen);
|
||||||
|
if (!paths->bulletPath) {
|
||||||
|
free(paths->backgroundPath);
|
||||||
|
free(paths->spaceshipPath);
|
||||||
|
free(paths);
|
||||||
|
fprintf(stderr, "Out of memory\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (resLocation[strlen(resLocation) - 1] == '/') {
|
||||||
|
snprintf(paths->bulletPath, pathLen, "%s%s", resLocation, bulletFile);
|
||||||
|
} else {
|
||||||
|
snprintf(paths->bulletPath, pathLen, "%s/%s", resLocation, bulletFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
return paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
@ -29,74 +154,31 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
char *resLocation = "./res/";
|
char *resLocation = "./res/";
|
||||||
|
int argResult = handleArguments(argc, argv, &resLocation);
|
||||||
for (int args = 1; args < argc; args++) {
|
if (argResult == 1) {
|
||||||
if (strcmp(argv[args], "--help") == 0 ||
|
SDL_Quit();
|
||||||
strcmp(argv[args], "-h") == 0) {
|
return EXIT_SUCCESS;
|
||||||
printf("Star Invaders Help:\n");
|
} else if (argResult == -1) {
|
||||||
printf("Use arrow keys or A/D to move the spaceship left and right.\n");
|
|
||||||
printf("Press SPACE to fire bullets.\n");
|
|
||||||
printf("Press ESC or close the window to exit the game.\n");
|
|
||||||
printf("Use --res-location or -rl to specify the resource location.\n");
|
|
||||||
SDL_Quit();
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
} else if (strcmp(argv[args], "--version") == 0 ||
|
|
||||||
strcmp(argv[args], "-v") == 0) {
|
|
||||||
printf("Star Invaders Version 1.0.0\n");
|
|
||||||
SDL_Quit();
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
} else if (strcmp(argv[args], "--res-location") == 0 ||
|
|
||||||
strcmp(argv[args], "-rl") == 0) {
|
|
||||||
resLocation = argv[args + 1];
|
|
||||||
args++;
|
|
||||||
} else {
|
|
||||||
printf("Unknown argument: %s\n", argv[args]);
|
|
||||||
printf("Use --help or -h for usage information.\n");
|
|
||||||
SDL_Quit();
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("Using resource location: %s\n", resLocation);
|
|
||||||
|
|
||||||
// Build full paths for assets
|
|
||||||
size_t pathLen;
|
|
||||||
char *spaceshipPath;
|
|
||||||
char *backgroundPath;
|
|
||||||
const char *shipFile = "spaceship.bmp";
|
|
||||||
const char *bgFile = "background.bmp";
|
|
||||||
|
|
||||||
pathLen = strlen(resLocation) + strlen(shipFile) + 2;
|
|
||||||
spaceshipPath = (char *)malloc(pathLen);
|
|
||||||
if (!spaceshipPath) {
|
|
||||||
fprintf(stderr, "Out of memory\n");
|
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
if (resLocation[strlen(resLocation) - 1] == '/') {
|
|
||||||
snprintf(spaceshipPath, pathLen, "%s%s", resLocation, shipFile);
|
|
||||||
} else {
|
|
||||||
snprintf(spaceshipPath, pathLen, "%s/%s", resLocation, shipFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
pathLen = strlen(resLocation) + strlen(bgFile) + 2;
|
AssetPaths *paths = getResources(resLocation);
|
||||||
backgroundPath = (char *)malloc(pathLen);
|
if (!paths) {
|
||||||
if (!backgroundPath) {
|
fprintf(stderr, "Could not load resources\n");
|
||||||
free(spaceshipPath);
|
|
||||||
fprintf(stderr, "Out of memory\n");
|
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
if (resLocation[strlen(resLocation) - 1] == '/') {
|
|
||||||
snprintf(backgroundPath, pathLen, "%s%s", resLocation, bgFile);
|
|
||||||
} else {
|
|
||||||
snprintf(backgroundPath, pathLen, "%s/%s", resLocation, bgFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_Window *window = SDL_CreateWindow("Star Invaders", SDL_WINDOWPOS_CENTERED,
|
SDL_Window *window = SDL_CreateWindow("Star Invaders", SDL_WINDOWPOS_CENTERED,
|
||||||
SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH,
|
SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH,
|
||||||
SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
|
SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
|
||||||
if (!window) {
|
if (!window) {
|
||||||
fprintf(stderr, "Could not create window: %s\n", SDL_GetError());
|
fprintf(stderr, "Could not create window: %s\n", SDL_GetError());
|
||||||
|
free(paths->backgroundPath);
|
||||||
|
free(paths->bulletPath);
|
||||||
|
free(paths->spaceshipPath);
|
||||||
|
free(paths);
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
@ -106,42 +188,46 @@ int main(int argc, char *argv[]) {
|
|||||||
if (!renderer) {
|
if (!renderer) {
|
||||||
fprintf(stderr, "Could not create renderer: %s\n", SDL_GetError());
|
fprintf(stderr, "Could not create renderer: %s\n", SDL_GetError());
|
||||||
SDL_DestroyWindow(window);
|
SDL_DestroyWindow(window);
|
||||||
|
free(paths->backgroundPath);
|
||||||
|
free(paths->bulletPath);
|
||||||
|
free(paths->spaceshipPath);
|
||||||
|
free(paths);
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int speed = 5;
|
if (!loadTextures(renderer, paths)) {
|
||||||
|
fprintf(stderr, "Could not create game textures: %s\n", SDL_GetError());
|
||||||
|
free(paths->backgroundPath);
|
||||||
|
free(paths->bulletPath);
|
||||||
|
free(paths->spaceshipPath);
|
||||||
|
free(paths);
|
||||||
|
SDL_Quit();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
// Bullets array
|
// Bullets array
|
||||||
Bullet bullets[MAX_BULLETS];
|
|
||||||
int bulletCount = 0;
|
int bulletCount = 0;
|
||||||
|
Bullet bullets[MAX_BULLETS];
|
||||||
for (int i = 0; i < MAX_BULLETS; i++) {
|
for (int i = 0; i < MAX_BULLETS; i++) {
|
||||||
bullets[i].active = 0;
|
initBullet(&bullets[i], 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create player
|
// Create player
|
||||||
Player *player = createPlayer(renderer, spaceshipPath, 400, 500);
|
Player *player = createPlayer(400, 500);
|
||||||
if (!player) {
|
if (!player) {
|
||||||
SDL_DestroyRenderer(renderer);
|
SDL_DestroyRenderer(renderer);
|
||||||
SDL_DestroyWindow(window);
|
SDL_DestroyWindow(window);
|
||||||
free(spaceshipPath);
|
free(paths->spaceshipPath);
|
||||||
free(backgroundPath);
|
free(paths->backgroundPath);
|
||||||
|
free(paths);
|
||||||
|
if (textures.bulletTexture) SDL_DestroyTexture(textures.bulletTexture);
|
||||||
|
if (textures.playerTexture) SDL_DestroyTexture(textures.playerTexture);
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load background
|
/* background is loaded into textures.backgroundTexture by loadTextures */
|
||||||
SDL_Texture *background = NULL;
|
|
||||||
SDL_Surface *bgSurface = SDL_LoadBMP(backgroundPath);
|
|
||||||
if (!bgSurface) {
|
|
||||||
fprintf(stderr, "Could not load background %s: %s\n", backgroundPath, SDL_GetError());
|
|
||||||
} else {
|
|
||||||
background = SDL_CreateTextureFromSurface(renderer, bgSurface);
|
|
||||||
SDL_FreeSurface(bgSurface);
|
|
||||||
if (!background) {
|
|
||||||
fprintf(stderr, "Could not create background texture: %s\n", SDL_GetError());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Main loop flag
|
// Main loop flag
|
||||||
int running = 1;
|
int running = 1;
|
||||||
@ -171,16 +257,16 @@ int main(int argc, char *argv[]) {
|
|||||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
||||||
SDL_RenderClear(renderer);
|
SDL_RenderClear(renderer);
|
||||||
// Draw background if available
|
// Draw background if available
|
||||||
if (background) {
|
if (textures.backgroundTexture) {
|
||||||
SDL_RenderCopy(renderer, background, NULL, NULL);
|
SDL_RenderCopy(renderer, textures.backgroundTexture, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update and draw bullets
|
// Update and draw bullets
|
||||||
updateBullets(bullets, &bulletCount, renderer);
|
updateBullets(bullets, &bulletCount, renderer);
|
||||||
cleanupUnrenderedBullets(bullets, &bulletCount);
|
// cleanupUnrenderedBullets(bullets, &bulletCount); // removed
|
||||||
|
|
||||||
// Handle player movement and rendering
|
// Handle player movement and rendering
|
||||||
handlePlayer(renderer, player, speed, keys);
|
handlePlayer(renderer, player, playerSpeed, keys);
|
||||||
|
|
||||||
// Present the rendered frame
|
// Present the rendered frame
|
||||||
SDL_RenderPresent(renderer);
|
SDL_RenderPresent(renderer);
|
||||||
@ -193,11 +279,17 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
destroyPlayer(player);
|
destroyPlayer(player);
|
||||||
if (background) {
|
|
||||||
SDL_DestroyTexture(background);
|
// Cleanup bullets (deactivate all)
|
||||||
}
|
cleanupBullets(bullets, &bulletCount);
|
||||||
free(spaceshipPath);
|
|
||||||
free(backgroundPath);
|
if (textures.bulletTexture) SDL_DestroyTexture(textures.bulletTexture);
|
||||||
|
if (textures.playerTexture) SDL_DestroyTexture(textures.playerTexture);
|
||||||
|
if (textures.backgroundTexture) SDL_DestroyTexture(textures.backgroundTexture);
|
||||||
|
|
||||||
|
free(paths->spaceshipPath);
|
||||||
|
free(paths->backgroundPath);
|
||||||
|
free(paths);
|
||||||
SDL_DestroyRenderer(renderer);
|
SDL_DestroyRenderer(renderer);
|
||||||
SDL_DestroyWindow(window);
|
SDL_DestroyWindow(window);
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
|||||||
51
src/player.c
51
src/player.c
@ -1,27 +1,25 @@
|
|||||||
#include "player.h"
|
#include "player.h"
|
||||||
|
#include "game.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
Player *createPlayer(SDL_Renderer *renderer, const char *imagePath, int x,
|
int playerSpeed = 5;
|
||||||
int y) {
|
|
||||||
|
void handlePlayer(SDL_Renderer *renderer, Player *player, int playerSpeed, const Uint8 *keys) {
|
||||||
|
if (keys[SDL_SCANCODE_LEFT] || keys[SDL_SCANCODE_A]) {
|
||||||
|
movePlayerLeft(player, playerSpeed);
|
||||||
|
}
|
||||||
|
if (keys[SDL_SCANCODE_RIGHT] || keys[SDL_SCANCODE_D]) {
|
||||||
|
movePlayerRight(player, playerSpeed, SCREEN_WIDTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render player flipped vertically
|
||||||
|
renderPlayerFlipped(renderer, player, SDL_FLIP_VERTICAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
Player *createPlayer(int x, int y) {
|
||||||
Player *player = (Player *)malloc(sizeof(Player));
|
Player *player = (Player *)malloc(sizeof(Player));
|
||||||
|
|
||||||
SDL_Surface *surface = SDL_LoadBMP(imagePath);
|
|
||||||
if (!surface) {
|
|
||||||
fprintf(stderr, "Could not load image %s: %s\n", imagePath, SDL_GetError());
|
|
||||||
free(player);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
player->texture = SDL_CreateTextureFromSurface(renderer, surface);
|
|
||||||
SDL_FreeSurface(surface);
|
|
||||||
|
|
||||||
if (!player->texture) {
|
|
||||||
fprintf(stderr, "Could not create texture: %s\n", SDL_GetError());
|
|
||||||
free(player);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
player->rect.x = x;
|
player->rect.x = x;
|
||||||
player->rect.y = y;
|
player->rect.y = y;
|
||||||
player->rect.w = 50;
|
player->rect.w = 50;
|
||||||
@ -31,30 +29,29 @@ Player *createPlayer(SDL_Renderer *renderer, const char *imagePath, int x,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void renderPlayer(SDL_Renderer *renderer, Player *player) {
|
void renderPlayer(SDL_Renderer *renderer, Player *player) {
|
||||||
SDL_RenderCopy(renderer, player->texture, NULL, &player->rect);
|
SDL_RenderCopy(renderer, textures.playerTexture, NULL, &player->rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderPlayerFlipped(SDL_Renderer *renderer, Player *player,
|
void renderPlayerFlipped(SDL_Renderer *renderer, Player *player,
|
||||||
SDL_RendererFlip flip) {
|
SDL_RendererFlip flip) {
|
||||||
SDL_RenderCopyEx(renderer, player->texture, NULL, &player->rect, 0, NULL,
|
SDL_RenderCopyEx(renderer, textures.playerTexture, NULL, &player->rect, 0, NULL,
|
||||||
flip);
|
flip);
|
||||||
}
|
}
|
||||||
|
|
||||||
void movePlayerLeft(Player *player, int speed) {
|
void movePlayerLeft(Player *player, int playerSpeed) {
|
||||||
if (player->rect.x - speed >= 0) {
|
if (player->rect.x - playerSpeed >= 0) {
|
||||||
player->rect.x -= speed;
|
player->rect.x -= playerSpeed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void movePlayerRight(Player *player, int speed, int screenWidth) {
|
void movePlayerRight(Player *player, int playerSpeed, int screenWidth) {
|
||||||
if (player->rect.x + player->rect.w + speed <= screenWidth) {
|
if (player->rect.x + player->rect.w + playerSpeed <= screenWidth) {
|
||||||
player->rect.x += speed;
|
player->rect.x += playerSpeed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroyPlayer(Player *player) {
|
void destroyPlayer(Player *player) {
|
||||||
if (player) {
|
if (player) {
|
||||||
SDL_DestroyTexture(player->texture);
|
|
||||||
free(player);
|
free(player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
12
src/player.h
12
src/player.h
@ -4,17 +4,19 @@
|
|||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
SDL_Texture *texture;
|
|
||||||
SDL_Rect rect;
|
SDL_Rect rect;
|
||||||
} Player;
|
} Player;
|
||||||
|
|
||||||
Player *createPlayer(SDL_Renderer *renderer, const char *imagePath, int x,
|
extern int playerSpeed;
|
||||||
int y);
|
|
||||||
|
void handlePlayer(SDL_Renderer *renderer, Player *player, int playerSpeed, const Uint8 *keys);
|
||||||
|
|
||||||
|
Player *createPlayer(int x, int y);
|
||||||
void renderPlayer(SDL_Renderer *renderer, Player *player);
|
void renderPlayer(SDL_Renderer *renderer, Player *player);
|
||||||
void renderPlayerFlipped(SDL_Renderer *renderer, Player *player,
|
void renderPlayerFlipped(SDL_Renderer *renderer, Player *player,
|
||||||
SDL_RendererFlip flip);
|
SDL_RendererFlip flip);
|
||||||
void movePlayerLeft(Player *player, int speed);
|
void movePlayerLeft(Player *player, int playerSpeed);
|
||||||
void movePlayerRight(Player *player, int speed, int screenWidth);
|
void movePlayerRight(Player *player, int playerSpeed, int screenWidth);
|
||||||
void destroyPlayer(Player *player);
|
void destroyPlayer(Player *player);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user