Data Technician
✔️ HL Verified
Discord Member
This game is fun Especially when you get 1 hitted by last boos xD
GJ Sub ^^
GJ Sub ^^
That will be the last of that kind of post I'll allow in here. Constructive criticisms or comments, or find peace in silence.Good. You look smarter than I thought sub.
#include "SDL.h"
#include "SDL_image.h"
#include "SDL_ttf.h"
#include <string>
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;
const int DOT_WIDTH = 20;
const int DOT_HEIGHT = 20;
const int BLOCK_WIDTH = 50;
const int BLOCK_HEIGHT = 10;
const int PLATFORM_WIDTH = 100;
const int PLATFORM_HEIGHT = 15;
const int PLATFORM_VEL = 200;
SDL_Event event;
SDL_Surface *dot = NULL;
SDL_Surface *platform = NULL;
SDL_Surface *block = NULL;
SDL_Surface *screen = NULL;
SDL_Surface *message = NULL;
SDL_Surface *message2 = NULL;
SDL_Surface *LivesMessage = NULL;
TTF_Font *font = NULL;
SDL_Color textColor = { 0, 0, 0 };
SDL_Surface *load_image( std::string filename )
{
//The image that's loaded
SDL_Surface* loadedImage = NULL;
//The optimized surface that will be used
SDL_Surface* optimizedImage = NULL;
//Load the image
loadedImage = IMG_Load( filename.c_str() );
//If the image loaded
if( loadedImage != NULL )
{
//Create an optimized surface
optimizedImage = SDL_DisplayFormat( loadedImage );
//Free the old surface
SDL_FreeSurface( loadedImage );
//If the surface was optimized
if( optimizedImage != NULL )
{
//Color key surface
SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, SDL_MapRGB( optimizedImage->format, 0, 0xFF, 0xFF ) );
}
}
//Return the optimized surface
return optimizedImage;
}
void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL )
{
//Holds offsets
SDL_Rect offset;
//Get offsets
offset.x = x;
offset.y = y;
//Blit
SDL_BlitSurface( source, clip, destination, &offset );
}
bool init()
{
//Initialize all SDL subsystems
if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
{
return false;
}
//Set up the screen
screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );
//If there was an error in setting up the screen
if( screen == NULL )
{
return false;
}
if( TTF_Init() == -1 )
{
return false;
}
//Set the window caption
SDL_WM_SetCaption( "Dan's Pong", NULL );
//If everything initialized fine
return true;
}
bool load_files()
{
//Load the dot image
dot = load_image( "dot.png" );
//If there was a problem in loading the dot
if ( dot == NULL )
{
return false;
}
platform = load_image( "platform.png" );
if (platform == NULL)
{
return false;
}
block = load_image("block.png");
if (block == NULL)
{
return false;
}
font = TTF_OpenFont( "lazy.ttf", 28 );
if( font == NULL )
{
return false;
}
return true;
}
void clean_up()
{
SDL_FreeSurface( dot );
SDL_FreeSurface(platform);
SDL_FreeSurface(block);
SDL_FreeSurface( message );
SDL_FreeSurface( message2 );
SDL_FreeSurface( LivesMessage );
TTF_CloseFont( font );
SDL_Quit();
}
class Block
{
private:
float x, y;
bool onscreen;
public:
Block();
void show();
float GetLocation();
bool GetOnScreen();
void SetOnScreen(bool onoff);
void SetXY(float Setx, float Sety);
};
class Platform
{
private:
float x, y;
float xVel, yVel;
public:
Platform();
void handle_input();
void move( Uint32 deltaTicks);
void show();
float GetLocation();
};
class Dot
{
private:
float x, y;
float xVel, yVel;
public:
Dot();
void Dot::move(Uint32 deltaTicks);
int CheckBallCollision(Uint32 deltaTicks, float PlatformLocation, float BlockLocation, bool start);
void show();
void SetVelocity(float x, float y);
};
class Timer
{
private:
//The clock time when the timer started
int startTicks;
//The ticks stored when the timer was paused
int pausedTicks;
//The timer status
bool paused;
bool started;
public:
//Initializes variables
Timer();
//The various clock actions
void start();
void stop();
void pause();
void unpause();
//Gets the timer's time
int get_ticks();
//Checks the status of the timer
bool is_started();
bool is_paused();
};
Block::Block()
{
onscreen = 1;
}
void Block::show()
{
apply_surface( (int)x, (int)y, block, screen);
}
float Block::GetLocation()
{
float location1;
location1 = x + 25;
return location1;
}
bool Block::GetOnScreen()
{
return onscreen;
}
void Block::SetOnScreen(bool onoff)
{
onscreen = onoff;
}
void Block::SetXY(float Setx, float Sety)
{
x = Setx;
y = Sety;
}
Platform::Platform()
{
//Initialize the offsets
x = (SCREEN_WIDTH / 2) - 50;
y = 400;
//Initialize the velocity
xVel = 0;
yVel = 0;
}
float Platform::GetLocation()
{
float location;
location = x + 50;
return location;
}
void Platform::handle_input()
{
if (event.type == SDL_KEYDOWN)
{
switch (event.key.keysym.sym)
{
case SDLK_LEFT: xVel -= PLATFORM_VEL; break;
case SDLK_RIGHT: xVel += PLATFORM_VEL; break;
}
}
else if (event.type == SDL_KEYUP)
{
switch (event.key.keysym.sym)
{
case SDLK_LEFT: xVel += PLATFORM_VEL; break;
case SDLK_RIGHT: xVel -= PLATFORM_VEL; break;
}
}
}
void Platform::move(Uint32 deltaTicks )
{
x += xVel * ( deltaTicks / 1000.f);
if (x < 0)
{
x = 0;
}
else if( x + PLATFORM_WIDTH > SCREEN_WIDTH)
{
x = SCREEN_WIDTH - PLATFORM_WIDTH;
}
}
void Platform::show()
{
apply_surface( (int)x, (int)y, platform, screen );
}
Dot::Dot()
{
x = (SCREEN_WIDTH / 2) - 10;
y = 379;
xVel = 0;
yVel = 0;
}
void Dot::move(Uint32 deltaTicks)
{
y += yVel * (deltaTicks / 1000.f);
x += xVel * (deltaTicks / 1000.f);
}
int Dot::CheckBallCollision(Uint32 deltaTicks, float PlatformLocation, float BlockLocation, bool start)
{
//make the ball follow the platform
if (start == false)
{
x = PlatformLocation - 10;
}
//If the dot went too far to the left
if (x < 0)
{
x = 0;
return 1;
}
//or the right
else if (x + DOT_WIDTH > SCREEN_WIDTH)
{
x = SCREEN_WIDTH - DOT_WIDTH;
return 2;
}
//If the dot went too far up
if (y < 0)
{
y = 0;
return 3;
}
//or down
else if (y + DOT_HEIGHT > SCREEN_HEIGHT + DOT_HEIGHT)
{
y = 379;
x = PlatformLocation - 10;
return 4;
}
//if we hit the platform
else if (y <= 401 && y >= 386)
{
//if we hit the left
if (x >= (PlatformLocation - DOT_WIDTH) - 51 && x <= (PlatformLocation - 10) - 17)
return 8;
//If we hit the center
if (x >= (PlatformLocation - DOT_WIDTH) - 16 && x < (PlatformLocation - 10) + 16)
return 5;
//If we hit the right
if (x <= (PlatformLocation - DOT_WIDTH) + 51 && x >= (PlatformLocation - 10) + 17)
return 9;
}
//if we hit blocks 1st row
else if (y <= 31 && y >= 20)
{
if (x >= BlockLocation - 50 && x <= BlockLocation)
{
return 6;
}
}
//if we hit the blocks 2nd row
else if (y >= 31 && y <= 41)
{
if (x >= BlockLocation - 50 && x <= BlockLocation)
{
return 7;
}
}
return 0;
}
void Dot::show()
{
//Show the dot
apply_surface( (int)x, (int)y, dot, screen );
}
void Dot::SetVelocity(float x, float y)
{
xVel = x;
yVel = y;
}
Timer::Timer()
{
//Initialize the variables
startTicks = 0;
pausedTicks = 0;
paused = false;
started = false;
}
void Timer::start()
{
//Start the timer
started = true;
//Unpause the timer
paused = false;
//Get the current clock time
startTicks = SDL_GetTicks();
}
void Timer::stop()
{
//Stop the timer
started = false;
//Unpause the timer
paused = false;
}
void Timer::pause()
{
//If the timer is running and isn't already paused
if( ( started == true ) && ( paused == false ) )
{
//Pause the timer
paused = true;
//Calculate the paused ticks
pausedTicks = SDL_GetTicks() - startTicks;
}
}
void Timer::unpause()
{
//If the timer is paused
if( paused == true )
{
//Unpause the timer
paused = false;
//Reset the starting ticks
startTicks = SDL_GetTicks() - pausedTicks;
//Reset the paused ticks
pausedTicks = 0;
}
}
int Timer::get_ticks()
{
//If the timer is running
if( started == true )
{
//If the timer is paused
if( paused == true )
{
//Return the number of ticks when the timer was paused
return pausedTicks;
}
else
{
//Return the current time minus the start time
return SDL_GetTicks() - startTicks;
}
}
//If the timer isn't running
return 0;
}
bool Timer::is_started()
{
return started;
}
bool Timer::is_paused()
{
return paused;
}
int main( int argc, char* args[] )
{
bool quit = false;
bool start = false;
Dot myDot;
Platform myPlatform;
float x = 14;
float y = 20;
float rBlockLocation = -1;
float &BlockLocation = rBlockLocation;
int CollisionReturnAnswer = -1;
int counter = 0;
int TextWidth1 = 0;
int TextWidth2 = 0;
int TextWidth3 = 0;
int h = 0;
int h2 = 0;
int BallLives = 3;
Block BlockObject[24];
for (counter = 0; counter < 24; counter++)
{
BlockObject[counter].SetXY(x, y);
x = x + 51;
if (counter == 11)
{
x = 14;
y = 31;
}
}
x = 0;
y = 0;
Timer delta;
if( init() == false )
{
return 1;
}
if( load_files() == false )
{
return 1;
}
delta.start();
Uint8 *keystates = SDL_GetKeyState( NULL );
float PlatformLocation = 0;
TTF_SizeText(font, "Press the left and right arrow keys to move.", &TextWidth1, &h);
TTF_SizeText(font, "Press the up arrow key to begin.", &TextWidth2, &h2);
TTF_SizeText(font, "Lives: 3", &TextWidth3, &h);
message = TTF_RenderText_Solid( font, "Press the left and right arrow keys to move.", textColor );
message2 = TTF_RenderText_Solid( font, "Press the up arrow key to begin.", textColor );
TextWidth1 = (SCREEN_WIDTH - TextWidth1) / 2;
TextWidth2 = (SCREEN_WIDTH - TextWidth2) / 2;
TextWidth3 = (SCREEN_WIDTH - TextWidth3) - 5;
while( quit == false )
{
while( SDL_PollEvent( &event ) )
{
myPlatform.handle_input();
if( event.type == SDL_QUIT )
{
quit = true;
}
}
if (start == false)
{
if( keystates[ SDLK_UP ] )
{
x = -250, y = -250;
start = true;
}
}
CollisionReturnAnswer = (myDot.CheckBallCollision( delta.get_ticks(), PlatformLocation, BlockLocation, start));
//left - Also, not sure how I'm supposed to really do collision. Should I put this into the function? I'm almost certain I'm doing it wrong in any case
if (CollisionReturnAnswer == 1)
{
x = 250;
}
//right
else if (CollisionReturnAnswer == 2)
{
x = -250;
}
//up
else if (CollisionReturnAnswer == 3)
{
y = 250;
}
//down
else if (CollisionReturnAnswer == 4)
{
myDot.SetVelocity(0, 0);
y = 0;
x = 0;
myDot.move(delta.get_ticks());
start = false;
BallLives--;
if (BallLives <= 0)
{
BallLives = 3;
counter = 0;
while (counter < 24)
{
BlockObject[counter].SetOnScreen(1);
counter++;
}
}
}
//contact with platform center
else if (CollisionReturnAnswer == 5)
{
y = -250;
}
//contact with platform left
else if (CollisionReturnAnswer == 8)
{
y = -250;
x = -250;
}
//contact with platform right
else if (CollisionReturnAnswer == 9)
{
y = -250;
x = 250;
}
//check contact with block; if contact, don't show onsreen
for (counter = 12; counter < 24; counter++)
{
BlockLocation = BlockObject[counter].GetLocation();
if (myDot.CheckBallCollision(delta.get_ticks(), PlatformLocation, BlockLocation, start) == 7 && BlockObject[counter].GetOnScreen() == 1)
{
y = 250;
BlockObject[counter].SetOnScreen(0);
}
}
for (counter = 0; counter < 12; counter++)
{
BlockLocation = BlockObject[counter].GetLocation();
if (myDot.CheckBallCollision(delta.get_ticks(), PlatformLocation, BlockLocation, start) == 6 && BlockObject[counter].GetOnScreen() == 1)
{
y = 250;
BlockObject[counter].SetOnScreen(0);
}
}
myPlatform.move(delta.get_ticks());
PlatformLocation = myPlatform.GetLocation();
myDot.SetVelocity(x, y);
myDot.move(delta.get_ticks());
delta.start();
SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0xFF, 0xFF, 0xFF ) );
myDot.show();
myPlatform.show();
if (start == false && BallLives == 3)
{
apply_surface( TextWidth1, 150, message, screen );
apply_surface( TextWidth2, 180, message2, screen );
}
if (BallLives == 3)
{
SDL_FreeSurface( LivesMessage );
LivesMessage = TTF_RenderText_Solid(font, "Lives: 3", textColor);
}
else if (BallLives == 2)
{
SDL_FreeSurface( LivesMessage );
LivesMessage = TTF_RenderText_Solid(font, "Lives: 2", textColor);
}
else if (BallLives == 1)
{
SDL_FreeSurface( LivesMessage );
LivesMessage = TTF_RenderText_Solid(font, "Lives: 1", textColor);
}
apply_surface( TextWidth3, 450, LivesMessage, screen);
for (counter = 0; counter < 24; counter++)
{
if (BlockObject[counter].GetOnScreen() == 1)
{
BlockObject[counter].show();
}
}
if( SDL_Flip( screen ) == -1 )
{
return 1;
}
}
clean_up();
return 0;
}
YES!!I still want to add levels to it, add powerups to it (ie: A random number of blocks would spawn red. If you break a red block, a powerup drops. If you catch the powerup, you can obviously use it. A powerup might be something like 3 balls spawning, or the ability to shoot lazers from your platform.) Also want to make it so that the ball will bounce if it hits the top of a block instead of just going through them.
https://rapidshare.com/files/2661720388/SubTetris.7z
http://i.imgur.com/8Un5t.png
So I made Tetris. I spent the majority of my free time in the past two or three weeks working on this. I rather like how it turned out, although it's still not 100% done. I want to add a slight pause and a visual cue when you clear a line, right now the line instantly disappears and it's kind of jarring. I also want to make the random number generator better, right now it's okay but it doesn't give out the pink shape very much at all. You can pause the game by pressing backspace, but I'll probably add a visual button you can click on to pause it. I'll probably also add a button to restart it, right now you can only restart it if you lose and press enter on the game over screen.
This is the code. If anyone knows how to code and wants to point out anything at all that I've done wrong, I'll greatly appreciate it and try to not make the same mistake in the future. The code started getting really sloppy towards the end when I was putting the text in, I was just really anxious to finish it.
classes.h
http://pastebin.com/NxKzkzdv
constants.h
http://pastebin.com/7KqJqhJq
functions.h
http://pastebin.com/xUW1gmy4
globals.h
http://pastebin.com/N7tM6daA
blocks.cpp
http://pastebin.com/Pi93b7J8
functions.cpp
http://pastebin.com/HhPxyCGy
globals.cpp
http://pastebin.com/4ThFDwmi
main.cpp
http://pastebin.com/Yt19HF6H
timer.cpp
http://pastebin.com/bebFXxTV
Weird when Sub gave me this link https://rapidshare.com/files/2661720388/SubTetris.7z it worked fine.. however the one before that didn't work but he said this one fixed itthis isn't working
says
program can't start because MSVCP100.DLL is missing from your computer. try reinstall the program to fix this problem.
It wasn't meant to be that advanced, making a menu would do a lot of work.. and he's planning to add VISUAL a pause button and increase the speed for every time you get like, 10 lines completed. You can already pause on backspace. In addition he plans to add that you can visually see the lines disappear instead of it being an instant action.. not sure if he bothers making the rest xDyteah i just had to download all teh C++ stuff n what not. well anyways
the game. u need to add instant drop button. i know right now u have down arrow doing that ... but it's not good cuz u accidently do it that way. slow down teh down arrow drop just a tad (very little bit not much at all) and add SPACE bar as instant drop. game will b much better. btw the whole adding something for a line being cleared is an overrated feature, tetris is quite cool without it. but anyways ... maybe add some combo bonuses ... say if u clear 4 lines with 1 drop .... and if u clear lines with consecutively from drop to drop. well anyways. i got pretty damn far. random generator not too bad. but could use a little tweak ....
and u need menu n what not .... and option to play easier mode n harder mode (basically speeds up or down)
heck if u had it so that you can pick a speed from 0-100 that's b badass ... u can play any custom speed u want from 0-100 (like volume control is set up) well anyways AMAZING STUFF!!! keep at it. is surprisingly clean
OOO and add feature to SAVE a block in que .... i always loved that feature >< hehehe
AND u ur missing a block shape. u need to make the reflection of the TEAL block.
and u need a HOW TO PLAY section
and PLEASE PLEASE PLEASE .... add a pause button ><