This is my first time writing a game in C++/SDL and I decided to post the code here so you can tell me what I am doing wrong.
main.cpp
#include <SDL.h>
#include "Game.h"
int screenWidth = 640;
int screenHeight = 480;
const char* title = "Pong Clone";
Game game;
int main(int argc, char* args[])
{
game.init(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, screenWidth, screenHeight, false);
while (game.running())
{
game.eventHandler();
game.render();
}
return 0;
}
Game.h
#ifndef GAME_H
#define GAME_H
#include <SDL.h>
#include <iostream>
#include <string>
#include "GameObject.h"
class Game
{
public:
bool init(const char* title, int xPos, int yPos, int width, int height, bool flags);
void eventHandler();
void render();
void clean();
void collision();
void reset();
bool running() { return m_Running; }
private:
SDL_Window* window;
SDL_Renderer* renderer;
int screenWidth;
int screenHeight;
int xSpeed, ySpeed;
bool m_Running;
GameObject* paddle;
GameObject* ball;
};
#endif
Game.cpp
#include "Game.h"
#include <stdlib.h>
#include <time.h>
//player speed
int playerVelocity = 0;
int playerSpeed = 15;
bool Game::init(const char* title, int xPos, int yPos, int width, int height, bool flags)
{
// screen and renderer initialization
screenWidth = width;
screenHeight = height;
window = SDL_CreateWindow(title, xPos, yPos, screenWidth, screenHeight, flags);
if (window == nullptr)
{
std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
}
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (renderer == nullptr)
{
std::cout << "SDL_CreateRenderer Error: " << SDL_GetError() << std::endl;
}
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
//game objects
ball = new GameObject();
paddle = new GameObject();
//image load
ball->load("Assets/ball.png", "ball", renderer);
paddle->load("Assets/paddle.png", "paddle", renderer);
//starting speed and directions
xSpeed = rand() % 8 + 5;
ySpeed = rand() % 8 + 5;
reset();
m_Running = true;
return true;
}
void Game::reset()
{
// center screen position
ball->setPosition((screenWidth - (ball->getW() / 2)) / 2, (screenHeight - (ball->getH() / 2)) / 2);
}
void Game::eventHandler()
{
// ball speed
ball->setX(ball->getX() + xSpeed);
ball->setY(ball->getY() - ySpeed);
// game loop
SDL_Event event;
if (SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_QUIT:
{
m_Running = false;
break;
}
case SDL_KEYDOWN:
{
switch( event.key.keysym.sym )
{
case SDLK_UP:
{
playerVelocity = -playerSpeed;
break;
}
case SDLK_DOWN:
{
playerVelocity = playerSpeed;
break;
}
default:
break;
}
break;
}
case SDL_KEYUP:
{
switch( event.key.keysym.sym )
{
case SDLK_UP:
{
if (playerVelocity < 0)
playerVelocity = 0;
break;
}
case SDLK_DOWN:
{
if (playerVelocity > 0)
playerVelocity = 0;
break;
}
default:
break;
}
break;
}
default:
break;
}
}
paddle->setY(paddle->getY() + playerVelocity);
collision();
}
void Game::render()
{
// render game objects
SDL_RenderClear(renderer);
ball->draw(renderer, "ball", ball->getX(), ball->getY());
paddle->draw(renderer, "paddle", paddle->getX(), paddle->getY());
SDL_RenderPresent(renderer);
}
void Game::collision()
{
// top collision
if (ball->getY() < 0)
{
ySpeed = -ySpeed;
}
// paddle collision
else if (ball->getX() <= paddle->getX() + paddle->getW() &&
(ball->getY() >= paddle->getY() && ball->getY() <= paddle->getY() + paddle->getH()))
{
xSpeed = -xSpeed;
}
// bottom collision
else if (ball->getY() >= (screenHeight - ball->getH()))
{
ySpeed = -ySpeed;
}
// player collision
else if (ball->getX() >= (screenWidth - ball->getW()))
{
xSpeed = -xSpeed;
}
// reset ball location
else if (ball->getX() < 0)
{
xSpeed = rand() % 8 + 5;
ySpeed = rand() % 8 + 5;
reset();
}
}
GameObject.h
#ifndef GAMEOBJECT_H
#define GAMEOBJECT_H
#include <SDL.h>
#include <SDL_image.h>
#include <string>
#include <iostream>
class GameObject
{
public:
bool load(std::string filename, std::string id, SDL_Renderer* renderer);
void draw(SDL_Renderer* renderer, std::string id, int x, int y);
void setX(int x);
void setY(int y);
int getX();
int getY();
int getW();
int getH();
void setPosition(int x, int y);
private:
SDL_Renderer* renderer;
SDL_Surface* tempImage;
SDL_Texture* texture;
SDL_Rect srcRect;
SDL_Rect dstRect;
};
#endif
GameObject.cpp
#include "GameObject.h"
bool GameObject::load(std::string filename, std::string id, SDL_Renderer* renderer)
{
// image load manager
tempImage = IMG_Load(filename.c_str());
texture = SDL_CreateTextureFromSurface(renderer, tempImage);
SDL_FreeSurface(tempImage);
SDL_QueryTexture(texture, NULL, NULL, &srcRect.w, &srcRect.h);
dstRect.w = srcRect.w;
dstRect.h = srcRect.h;
return true;
}
void GameObject::draw(SDL_Renderer* renderer, std::string id, int x, int y)
{
// image draw
dstRect.x = x;
dstRect.y = y;
SDL_RenderCopy(renderer, texture, &srcRect, &dstRect);
}
void GameObject::setX(int x)
{
dstRect.x = x;
}
void GameObject::setY(int y)
{
dstRect.y = y;
}
int GameObject::getX()
{
return dstRect.x;
}
int GameObject::getY()
{
return dstRect.y;
}
int GameObject::getW()
{
return dstRect.w;
}
int GameObject::getH()
{
return dstRect.h;
}
void GameObject::setPosition(int x, int y)
{
dstRect.x = x;
dstRect.y = y;
}
I'm still working on AI/2nd player and score.
My main problem right now is: how do I correctly randomize the starting direction of the ball? How can I increase the ball speed after each bounce?