Created
August 17, 2019 18:06
-
-
Save nikp123/24e6e22ec66618fdfb85762b89796dea to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// COMPILE with any C++ compiler and link with SDL2 | |
#include <iostream> | |
#include <vector> | |
#include <memory> | |
#include <SDL2/SDL.h> | |
#define WIN_HEIGHT 800 | |
#define WIN_WIDTH 800 | |
#define SCALE 10 | |
#define SHIP_SIZE 0.1 | |
#define SCORE_SIZE 0.4 | |
float cameraX=0.0, cameraY=0.0; | |
SDL_Window *gw; | |
SDL_Renderer *gr; | |
int score[2] = {0, 0}; | |
int timer = 0; | |
int toPixel(float x) { | |
return (x+SCALE/2)*WIN_HEIGHT/SCALE; | |
} | |
void drawObject(float x, float y, float a, const float verticies[][2], size_t size, Uint8 r) { | |
SDL_Point toDraw[size]; | |
for(int i=0; i < size; i++) { | |
toDraw[i].x = toPixel(cos(a)*verticies[i][0]-sin(a)*verticies[i][1]+x); | |
toDraw[i].y = toPixel(sin(a)*verticies[i][0]+cos(a)*verticies[i][1]+y); | |
} | |
SDL_SetRenderDrawColor(gr, 255*(r&4), 255*(r&2), 255*(r&1), 255); | |
SDL_RenderDrawLines(gr, toDraw, size); | |
} | |
void drawScore(){ | |
const float line[2][2] = {{0.0, 0.0}, {0.0, SCORE_SIZE}}; | |
for(int i = 0; i < score[1]; i++) drawObject(-SCALE/2+(i+1)*SCORE_SIZE, -SCALE/2, 0, line, 2, 7); | |
for(int i = 0; i < score[0]; i++) drawObject(SCALE/2-(i+1)*SCORE_SIZE, -SCALE/2, 0, line, 2, 7); | |
} | |
class player { | |
public: | |
// directions follow forwards, backwards, left, right | |
bool d[4]; | |
float x, y, a, ta; | |
bool alive; | |
player(float sx, float sy, float sa, Uint8 scolor) { | |
x=sx; | |
y=sy; | |
a=sa; | |
for(int i=0; i<4; i++) d[i]=false; | |
ta=0.0; | |
alive=true; | |
color=scolor; | |
} | |
void draw() { | |
drawObject(x, y, a, shape, 5, color); | |
} | |
void update() { | |
if(!(d[0]&&d[1])) { | |
if(d[0]) if(ta<0.05) ta+=0.0005; | |
if(d[1]) if(ta>-0.05) ta-=0.0005; | |
} | |
if(!(d[0]||d[1])) { | |
if(ta!=0.0) ta*=0.99; | |
} | |
if(!(d[2]&&d[3])) { | |
if(d[2]) if(aa<1.0) aa+=0.01; | |
if(d[3]) if(aa>-1.0) aa-=0.01; | |
} | |
aa-=aa*(ta/0.5); | |
if(!(d[2]||d[3])) { | |
if(aa!=0.0) aa*=0.9; | |
} | |
x+=sin(a)*ta; | |
if(x>SCALE/2) { x=SCALE/2; ta=0.0; } | |
if(x<-SCALE/2) { x=-SCALE/2; ta=0.0; } | |
y-=cos(a)*ta; | |
if(y>SCALE/2) { y=SCALE/2; ta=0.0; } | |
if(y<-SCALE/2) { y=-SCALE/2; ta=0.0; } | |
a-=3.14/6*aa; | |
} | |
private: | |
Uint8 color; | |
const float shape[5][2] = {{0.0, -0.1}, {-0.1, 0.1}, {0.0, 0.0}, {0.1, 0.1}, {0.0, -0.1}}; | |
float aa=0.0; | |
}; | |
class bullet { | |
public: | |
bullet(float px,float py,float pa, float ps, float shooterDiameter) { | |
a=pa; | |
ta=0.05+ps; | |
x=px+sin(a)*shooterDiameter; | |
y=py-cos(a)*shooterDiameter; | |
} | |
void draw(){ | |
drawObject(x, y, a, shape, 2, 2); | |
} | |
void update(player *p1, player *p2) { | |
x+=sin(a)*ta; | |
y-=cos(a)*ta; | |
if(p1->alive&&sqrt(pow(p1->x-x,2)+pow(p1->y-y,2))<SHIP_SIZE) { | |
score[0]++; | |
p1->alive = false; | |
destroy = true; | |
timer = SDL_GetTicks(); | |
} | |
if(p2->alive&&sqrt(pow(p2->x-x,2)+pow(p2->y-y,2))<SHIP_SIZE) { | |
score[1]++; | |
p2->alive = false; | |
destroy = true; | |
timer = SDL_GetTicks(); | |
} | |
if(SDL_GetTicks()-creation>5000) destroy=true; | |
} | |
bool suicideStatus() { | |
return destroy; | |
} | |
protected: | |
float x, y, a, ta; | |
private: | |
Uint32 creation = SDL_GetTicks(); | |
bool destroy = false; | |
const float shape[2][2] = {{0.0, 0.0}, {0.0, 0.1}}; | |
}; | |
int main() { | |
SDL_Init(SDL_INIT_EVERYTHING); | |
gw=SDL_CreateWindow("Spaceboopers!", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIN_WIDTH, WIN_HEIGHT, 0); | |
gr=SDL_CreateRenderer(gw,-1,0); | |
bool ripmygame = false; | |
player p1(-SCALE/2+SHIP_SIZE, 0.0, 1.57, 4); | |
player p2(SCALE/2-SHIP_SIZE, 0.0, 4.71, 1); | |
std::vector<std::unique_ptr<bullet>> b; | |
while(!ripmygame) { | |
SDL_Event e; | |
while(SDL_PollEvent(&e)){ | |
switch(e.type){ | |
case SDL_QUIT: | |
ripmygame = true; | |
break; | |
case SDL_KEYDOWN: | |
switch(e.key.keysym.scancode) { | |
case SDL_SCANCODE_W: p1.d[0] = true; break; | |
case SDL_SCANCODE_S: p1.d[1] = true; break; | |
case SDL_SCANCODE_A: p1.d[2] = true; break; | |
case SDL_SCANCODE_D: p1.d[3] = true; break; | |
case SDL_SCANCODE_UP: p2.d[0] = true; break; | |
case SDL_SCANCODE_DOWN: p2.d[1] = true; break; | |
case SDL_SCANCODE_LEFT: p2.d[2] = true; break; | |
case SDL_SCANCODE_RIGHT: p2.d[3] = true; break; | |
case SDL_SCANCODE_LSHIFT: | |
if(p1.alive) { | |
if(!(p1.d[2]|p1.d[3])) | |
b.push_back(std::make_unique<bullet>(p1.x, p1.y, p1.a, p1.ta, 0.2)); | |
} | |
break; | |
case SDL_SCANCODE_KP_0: | |
if(p2.alive) { | |
if(!(p2.d[2]|p2.d[3])) | |
b.push_back(std::make_unique<bullet>(p2.x, p2.y, p2.a, p2.ta, 0.2)); | |
} | |
break; | |
} | |
break; | |
case SDL_KEYUP: | |
switch(e.key.keysym.scancode) { | |
case SDL_SCANCODE_W: p1.d[0] = false; break; | |
case SDL_SCANCODE_S: p1.d[1] = false; break; | |
case SDL_SCANCODE_A: p1.d[2] = false; break; | |
case SDL_SCANCODE_D: p1.d[3] = false; break; | |
case SDL_SCANCODE_UP: p2.d[0] = false; break; | |
case SDL_SCANCODE_DOWN: p2.d[1] = false; break; | |
case SDL_SCANCODE_LEFT: p2.d[2] = false; break; | |
case SDL_SCANCODE_RIGHT: p2.d[3] = false; break; | |
} | |
break; | |
}} | |
if(timer&&(SDL_GetTicks()-timer>2000)) { | |
timer=0; | |
std::cout << "Score " << score[1] << "-" << score[0] << std::endl; | |
if(score[0]>9||score[1]>9) { | |
std::cout << "Player " << (int)(score[0]>score[1]? 2:1) << " wins!" << std::endl; | |
score[0]=0; | |
score[1]=0; | |
} | |
p1.~player(); | |
p2.~player(); | |
new(&p1) player(-SCALE/2+SHIP_SIZE, 0.0, 1.57, 4); | |
new(&p2) player(SCALE/2-SHIP_SIZE, 0.0, 4.71, 1); | |
} | |
if(p1.alive) p1.update(); | |
if(p2.alive) p2.update(); | |
for(int i=0; i<b.size();) { | |
b[i]->update(&p1, &p2); | |
if(b[i]->suicideStatus()) b.erase(b.begin()+i); | |
else i++; | |
} | |
SDL_SetRenderDrawColor(gr, 0, 0, 0, 0); | |
SDL_RenderClear(gr); | |
for(int i=0; i<b.size(); i++) b[i]->draw(); | |
if(p1.alive) p1.draw(); | |
if(p2.alive) p2.draw(); | |
drawScore(); | |
SDL_RenderPresent(gr); | |
SDL_Delay(1000/60); | |
} | |
SDL_DestroyRenderer(gr); | |
SDL_DestroyWindow(gw); | |
SDL_Quit(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment