Skip to content

Instantly share code, notes, and snippets.

@nikp123
Created August 17, 2019 18:06
Show Gist options
  • Save nikp123/24e6e22ec66618fdfb85762b89796dea to your computer and use it in GitHub Desktop.
Save nikp123/24e6e22ec66618fdfb85762b89796dea to your computer and use it in GitHub Desktop.
// 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