Primer commit

This commit is contained in:
2024-08-21 07:35:52 +02:00
commit b1785cf5f1
11 changed files with 570 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
*.exe
*.dll

5
Makefile Normal file
View File

@@ -0,0 +1,5 @@
source := source/*.cpp
executable_name := pelota
windows:
g++ $(source) -lmingw32 -lws2_32 -lSDL2main -lSDL2 -lSDL2_image -o $(executable_name).exe

BIN
resources/pelota.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 542 B

97
source/ball.cpp Normal file
View File

@@ -0,0 +1,97 @@
#include "ball.h"
#include "defines.h"
// Constructor
Ball::Ball(int x, int y, int w, int h, int vx, int vy, Texture *texture)
{
this->x = x;
this->y = y;
this->w = w;
this->h = h;
this->vx = vx;
this->vy = vy;
sprite = new Sprite(texture);
sprite->setPos({x, y});
sprite->setSize(w, h);
sprite->setClip({0, 0, 24, 24});
color = {255, 255, 255};
}
// Destructor
Ball::~Ball()
{
if (sprite)
{
delete sprite;
}
}
// Actualiza la lógica de la clase
void Ball::update()
{
const int luckyX = (rand() % 2) + 1;
const int luckyY = (rand() % 2) + 1;
bool collision = false;
// Actualiza la posición
x += vx;
y += vy;
// Comprueba las colisiones con el borde de la ventana
if (x < 0)
{
x = 0;
vx = luckyX;
collision = true;
}
if (x + w > SCREEN_WIDTH)
{
x = SCREEN_WIDTH - w;
vx = -luckyX;
collision = true;
}
if (y < 0)
{
y = 0;
vy = luckyY;
collision = true;
}
if (y + h > SCREEN_HEIGHT)
{
y = SCREEN_HEIGHT - h;
vy = -luckyY;
collision = true;
}
if (collision)
{
color = {rand() % 255, rand() % 255, rand() % 255};
}
// Actualiza la posición del sprite
sprite->setPos({x, y});
sprite->update();
}
// Pinta la clase
void Ball::render()
{
sprite->setColor(color.r, color.g, color.b);
sprite->render();
}
// Establece el valor de la velocidad
void Ball::setVx(int value)
{
vx = value;
}
// Establece el valor de la velocidad
void Ball::setVy(int value)
{
vy = value;
}

36
source/ball.h Normal file
View File

@@ -0,0 +1,36 @@
#pragma once
#include "sprite.h"
#include "texture.h"
#include "defines.h"
class Ball
{
private:
Sprite *sprite; // Sprite para pintar la clase
int x; // Posición x
int y; // Posición y
int w; // Ancho
int h; // Alto
int vx, vy; // Velocidad
color_t color; // Color de la pelota
public:
// Constructor
Ball(int x, int y, int w, int h, int vx, int vy, Texture *texture);
// Destructor
~Ball();
// Actualiza la lógica de la clase
void update();
// Pinta la clase
void render();
// Establece el valor de la velocidad
void setVx(int value);
// Establece el valor de la velocidad
void setVy(int value);
};

10
source/defines.h Normal file
View File

@@ -0,0 +1,10 @@
#pragma once
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 240
#define NUM_BALLS 100
struct color_t
{
int r,g,b;
};

168
source/main.cpp Normal file
View File

@@ -0,0 +1,168 @@
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include "texture.h"
#include "ball.h"
#include "defines.h"
#include <iostream>
SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
SDL_Event *event;
Texture *texture = nullptr;
Ball *ball[NUM_BALLS];
bool shouldExit = false;
Uint32 ticks = 0;
bool init()
{
// Initialization flag
bool success = true;
// Initialize SDL
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf("SDL could not initialize! SDL Error: %s\n", SDL_GetError());
success = false;
}
else
{
// Set texture filtering to linear
if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"))
{
printf("Warning: Linear texture filtering not enabled!");
}
// Create window
window = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH * 2, SCREEN_HEIGHT * 2, SDL_WINDOW_SHOWN);
if (window == NULL)
{
printf("Window could not be created! SDL Error: %s\n", SDL_GetError());
success = false;
}
else
{
// Create renderer for window
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (renderer == NULL)
{
printf("Renderer could not be created! SDL Error: %s\n", SDL_GetError());
success = false;
}
else
{
// Initialize renderer color
SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
// Initialize PNG loading
int imgFlags = IMG_INIT_PNG;
if (!(IMG_Init(imgFlags) & imgFlags))
{
printf("SDL_image could not initialize! SDL_image Error: %s\n", IMG_GetError());
success = false;
}
SDL_RenderSetLogicalSize(renderer, SCREEN_WIDTH, SCREEN_HEIGHT);
}
}
}
event = new SDL_Event();
texture = new Texture(renderer, "resources/pelota.png");
for (int i = 0; i < NUM_BALLS; ++i)
{
ball[i] = new Ball(rand() % SCREEN_WIDTH, rand() % SCREEN_HEIGHT, 24, 24, 1, 1, texture);
}
ticks = SDL_GetTicks();
return success;
}
void close()
{
// Destroy window
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
window = NULL;
renderer = NULL;
if (event)
{
delete event;
}
if (texture)
{
delete texture;
}
for (int i = 0; i < NUM_BALLS; ++i)
{
if (ball[i])
{
delete ball[i];
}
}
// Quit SDL subsystems
IMG_Quit();
SDL_Quit();
}
void checkEvents()
{
// Comprueba los eventos que hay en la cola
while (SDL_PollEvent(event) != 0)
{
// Evento de salida de la aplicación
if (event->type == SDL_QUIT)
{
shouldExit = true;
break;
}
}
}
void update()
{
if (SDL_GetTicks() - ticks > 15)
{
ticks = SDL_GetTicks();
for (int i = 0; i < NUM_BALLS; ++i)
{
ball[i]->update();
}
}
}
void render()
{
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
for (int i = 0; i < NUM_BALLS; ++i)
{
ball[i]->render();
}
SDL_RenderPresent(renderer);
}
int main(int argc, char *args[])
{
init();
while (!shouldExit)
{
update();
checkEvents();
render();
}
close();
return 0;
}

67
source/sprite.cpp Normal file
View File

@@ -0,0 +1,67 @@
#include "sprite.h"
// Constructor
Sprite::Sprite(Texture *texture)
{
this->texture = texture;
pos = {0, 0, 0, 0};
clip = {0, 0, 0, 0};
frame = 0;
numFrames = 3;
animationSpeed = 20;
animationCounter = 0;
}
// Destructor
Sprite::~Sprite()
{
}
// Establece la posición del sprite
void Sprite::setPos(SDL_Point pos)
{
this->pos.x = pos.x;
this->pos.y = pos.y;
}
// Pinta el sprite
void Sprite::render()
{
texture->render(&clip, &pos);
}
// Actualiza la lógica de la clase
void Sprite::update()
{
animationCounter++;
if (animationCounter % animationSpeed == 0)
{
animate();
}
}
// Establece el rectangulo de la textura que se va a pintar
void Sprite::setClip(SDL_Rect clip)
{
this->clip = clip;
}
// Establece el tamaño del sprite
void Sprite::setSize(int w, int h)
{
this->pos.w = w;
this->pos.h = h;
}
// Anima el sprite
void Sprite::animate()
{
frame = (frame + 1) % numFrames;
clip.x = frame * pos.w;
}
// Modulación de color
void Sprite::setColor(int r, int g, int b)
{
texture->setColor(r, g, b);
}

44
source/sprite.h Normal file
View File

@@ -0,0 +1,44 @@
#pragma once
#include <SDL2/SDL.h>
#include "texture.h"
class Sprite
{
private:
Texture *texture; // Textura con los gráficos del sprite
SDL_Rect pos; // Posición y tamaño del sprite
SDL_Rect clip; // Parte de la textura que se va a dibujar
int frame; // Frame a dibujar de la textura definido en clip
int numFrames; // Numero total de frames
int animationSpeed; // Velocidad de animación
int animationCounter; // Contador para la animación
// Anima el sprite
void animate();
public:
// Constructor
Sprite(Texture *texture);
// Destructor
~Sprite();
// Establece la posición del sprite
void setPos(SDL_Point pos);
// Pinta el sprite
void render();
// Actualiza la lógica de la clase
void update();
// Establece el rectangulo de la textura que se va a pintar
void setClip(SDL_Rect clip);
// Establece el tamaño del sprite
void setSize(int w, int h);
// Modulación de color
void setColor(int r, int g, int b);
};

101
source/texture.cpp Normal file
View File

@@ -0,0 +1,101 @@
#include <SDL2/SDL_image.h>
#include <stdio.h>
#include <string>
#include "texture.h"
Texture::Texture(SDL_Renderer *renderer)
{
this->renderer = renderer;
texture = NULL;
width = 0;
height = 0;
}
Texture::Texture(SDL_Renderer *renderer, std::string filepath)
{
this->renderer = renderer;
texture = NULL;
width = 0;
height = 0;
loadFromFile(filepath);
}
Texture::~Texture()
{
free();
}
bool Texture::loadFromFile(std::string path)
{
// Get rid of preexisting texture
free();
// The final texture
SDL_Texture *newTexture = NULL;
// Load image at specified path
SDL_Surface *loadedSurface = IMG_Load(path.c_str());
if (loadedSurface == NULL)
{
printf("Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError());
}
else
{
// Color key image
SDL_SetColorKey(loadedSurface, SDL_TRUE, SDL_MapRGB(loadedSurface->format, 0, 0xFF, 0xFF));
// Create texture from surface pixels
newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface);
if (newTexture == NULL)
{
printf("Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError());
}
else
{
// Get image dimensions
width = loadedSurface->w;
height = loadedSurface->h;
}
// Get rid of old loaded surface
SDL_FreeSurface(loadedSurface);
}
// Return success
texture = newTexture;
return texture != NULL;
}
void Texture::free()
{
// Free texture if it exists
if (texture != NULL)
{
SDL_DestroyTexture(texture);
texture = NULL;
width = 0;
height = 0;
}
}
void Texture::render(SDL_Rect *src, SDL_Rect *dst)
{
// Render to screen
SDL_RenderCopy(renderer, texture, src, dst);
}
int Texture::getWidth()
{
return width;
}
int Texture::getHeight()
{
return height;
}
// Modulación de color
void Texture::setColor(int r, int g, int b)
{
SDL_SetTextureColorMod(texture, r, g, b);
}

40
source/texture.h Normal file
View File

@@ -0,0 +1,40 @@
#pragma once
#include <SDL2/SDL.h>
#include <iostream>
// Texture wrapper class
class Texture
{
private:
SDL_Renderer *renderer;
SDL_Texture *texture;
// Image dimensions
int width;
int height;
public:
// Initializes variables
Texture(SDL_Renderer *renderer);
Texture(SDL_Renderer *renderer, std::string filepath);
// Deallocates memory
~Texture();
// Loads image at specified path
bool loadFromFile(std::string path);
// Deallocates texture
void free();
// Renders texture at given point
void render(SDL_Rect *src = nullptr, SDL_Rect *dst = nullptr);
// Gets image dimensions
int getWidth();
int getHeight();
// Modulación de color
void setColor(int r, int g, int b);
};