Primer commit

la pilota no deixa de botar mai
This commit is contained in:
2024-08-21 10:42:37 +02:00
commit 36cb6154d7
11 changed files with 574 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: 128 B

107
source/ball.cpp Normal file
View File

@@ -0,0 +1,107 @@
#include "ball.h"
#include "defines.h"
// Constructor
Ball::Ball(float x, float vx, float vy, color_t color, Texture *texture)
{
this->x = x;
this->y = 0.0f;
this->w = BALL_SIZE;
this->h = BALL_SIZE;
this->vx = vx;
this->vy = vy;
sprite = new Sprite(texture);
sprite->setPos({(int)x, (int)y});
sprite->setSize(BALL_SIZE, BALL_SIZE);
sprite->setClip({0, 0, BALL_SIZE, BALL_SIZE});
this->color = color;
g = GRAVITY;
onFloor = false;
stopped = false;
}
// Destructor
Ball::~Ball()
{
if (sprite)
{
delete sprite;
}
}
// Actualiza la lógica de la clase
void Ball::update()
{
if (stopped)
{
return;
}
// Actualiza la posición
x += vx;
y += vy;
// Aplica la gravedad
if (!onFloor)
{
vy += g;
}
// Comprueba las colisiones con el lateral izquierdo
if (x < 0)
{
x = 0;
vx = -vx;
}
// Comprueba las colisiones con el lateral derecho
if (x + w > SCREEN_WIDTH)
{
x = SCREEN_WIDTH - w;
vx = -vx;
}
// Comprueba las colisiones con la parte superior
if (y < 0)
{
y = 0;
vy = -vy;
}
// Comprueba las colisiones con la parte inferior
// if (y + h > SCREEN_HEIGHT)
if ((y + h > SCREEN_HEIGHT) && (vy > 0))
{
// y = SCREEN_HEIGHT - h;
vy = -vy * LOSS;
std::cout << vy << std::endl;
if (abs(vy) < 0.5f)
{
vy = 0.0f;
onFloor = true;
}
}
// Aplica rozamiento al rodar por el suelo
if (onFloor)
{
vx = vx * 0.97f;
if (abs(vx) < 0.1f)
{
vx = 0.0f;
stopped = true;
exit(0);
}
}
// Actualiza la posición del sprite
sprite->setPos({(int)x, (int)y});
sprite->update();
}
// Pinta la clase
void Ball::render()
{
sprite->setColor(color.r, color.g, color.b);
sprite->render();
}

33
source/ball.h Normal file
View File

@@ -0,0 +1,33 @@
#pragma once
#include "sprite.h"
#include "texture.h"
#include "defines.h"
class Ball
{
private:
Sprite *sprite; // Sprite para pintar la clase
float x; // Posición x
float y; // Posición y
int w; // Ancho
int h; // Alto
float vx, vy; // Velocidad
float g; // Gravedad
color_t color; // Color de la pelota
bool onFloor; // Indica si la pelota está ya en el suelo
bool stopped; // Indica si la pelota ha terminado de moverse;
public:
// Constructor
Ball(float x, float vx, float vy, color_t color, Texture *texture);
// Destructor
~Ball();
// Actualiza la lógica de la clase
void update();
// Pinta la clase
void render();
};

12
source/defines.h Normal file
View File

@@ -0,0 +1,12 @@
#pragma once
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 240
#define BALL_SIZE 8
#define GRAVITY 0.2f
#define LOSS 0.75f
struct color_t
{
int r,g,b;
};

185
source/main.cpp Normal file
View File

@@ -0,0 +1,185 @@
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include "texture.h"
#include "ball.h"
#include "defines.h"
#include <iostream>
#include <vector>
SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
SDL_Event *event;
Texture *texture = nullptr;
std::vector<Ball *> balls;
int test[5] = {1, 10, 100, 500, 1000};
bool shouldExit = false;
Uint32 ticks = 0;
void initBalls()
{
for (int i = 0; i < test[0]; ++i)
{
const int sign = ((rand() % 2) * 2) - 1;;
const float x = SCREEN_WIDTH / 2 - BALL_SIZE / 2;
const float vx = (((rand() % 20) + 10) * 0.1f) * sign;
const float vy = ((rand() % 40) - 20) * 0.1f;
const color_t color = {(rand() % 192) + 32, (rand() % 192) + 32, (rand() % 192) + 32};
Ball *b = new Ball(x, vx, vy, color, texture);
balls.push_back(b);
}
}
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");
ticks = SDL_GetTicks();
srand (time(NULL));
initBalls();
return success;
}
void close()
{
// Destroy window
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
window = nullptr;
renderer = nullptr;
if (event)
{
delete event;
event = nullptr;
}
if (texture)
{
delete texture;
texture = nullptr;
}
for (auto ball : balls)
{
if (ball)
{
delete ball;
ball = nullptr;
}
}
balls.clear();
// 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 (auto ball : balls)
{
ball->update();
}
}
}
void render()
{
SDL_SetRenderDrawColor(renderer, 32, 32, 32, 255);
SDL_RenderClear(renderer);
for (auto ball : balls)
{
ball->render();
}
SDL_RenderPresent(renderer);
}
int main(int argc, char *args[])
{
init();
while (!shouldExit)
{
update();
checkEvents();
render();
}
close();
return 0;
}

52
source/sprite.cpp Normal file
View File

@@ -0,0 +1,52 @@
#include "sprite.h"
// Constructor
Sprite::Sprite(Texture *texture)
{
this->texture = texture;
pos = {0, 0, 0, 0};
clip = {0, 0, 0, 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()
{
}
// 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;
}
// Modulación de color
void Sprite::setColor(int r, int g, int b)
{
texture->setColor(r, g, b);
}

37
source/sprite.h Normal file
View File

@@ -0,0 +1,37 @@
#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
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);
};