|
|
|
#define OLC_PGE_APPLICATION
|
|
|
|
#include "pixelGameEngine.h"
|
|
|
|
#include <random>
|
|
|
|
#include "gameDefines.h"
|
|
|
|
|
|
|
|
Meteos*game;
|
|
|
|
|
|
|
|
bool Meteos::OnUserCreate()
|
|
|
|
{
|
|
|
|
game=this;
|
|
|
|
|
|
|
|
SPRITES["blocks_test.png"].Load("assets/blocks_test.png");
|
|
|
|
|
|
|
|
std::random_device rd; //Will be used to obtain a seed for the random number engine
|
|
|
|
gen=std::mt19937(rd()); //Standard mersenne_twister_engine seeded with rd()
|
|
|
|
randBlockPos=std::uniform_int_distribution<>(0, 9);
|
|
|
|
coinFlip=std::uniform_int_distribution<>(0, 1);
|
|
|
|
|
|
|
|
gameBoard=Board({10,14},20.f,100.f,-20.f,1.0f,{3,0,0,0,0,0,0,0,0,0},SPRITES["blocks_test.png"]);
|
|
|
|
|
|
|
|
BlockClump c;
|
|
|
|
c.addBlock(0,2,BlockColor::RED);
|
|
|
|
c.addBlock(0,1,BlockColor::RED);
|
|
|
|
c.addBlock(1,0,BlockColor::RED);
|
|
|
|
c.addBlock(2,0,BlockColor::RED);
|
|
|
|
c.addBlock(0,0,BlockColor::RED);
|
|
|
|
c.y=120;
|
|
|
|
gameBoard.addClump(c);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Meteos::OnUserUpdate(float fElapsedTime)
|
|
|
|
{
|
|
|
|
fElapsedTime=std::min(fElapsedTime,1/60.f);
|
|
|
|
lastBlockSpawn+=fElapsedTime;
|
|
|
|
if (lastBlockSpawn>=gameBoard.spawnRate){
|
|
|
|
lastBlockSpawn-=gameBoard.spawnRate;
|
|
|
|
gameBoard.spawnBlock(randBlockPos(gen));
|
|
|
|
}
|
|
|
|
Clear(Pixel(32,32,255));
|
|
|
|
for (int x=-1;x<=gameBoard.boardSize.x;x++){
|
|
|
|
for (int y=0;y<=gameBoard.boardSize.y;y++){
|
|
|
|
if (x==-1||x==10||y==14){
|
|
|
|
FillRectDecal({(float)(gameBoard.drawOffset.x+x*12),(float)(gameBoard.drawOffset.y+y*12)},{12,12},Pixel(0,0,0,255));
|
|
|
|
} else {
|
|
|
|
DrawRectDecal({(float)(gameBoard.drawOffset.x+x*12),(float)(gameBoard.drawOffset.y+y*12)},{12,12},Pixel(255,255,255,64));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (int i=0;i<gameBoard.getBlockClumps().size();i++){
|
|
|
|
BlockClump&c=gameBoard.getBlockClumps()[i];
|
|
|
|
c.vspeed+=gameBoard.gravity*fElapsedTime;
|
|
|
|
if (c.vspeed>gameBoard.maxGravity){
|
|
|
|
c.vspeed=gameBoard.maxGravity;
|
|
|
|
}
|
|
|
|
for (int j=0;j<gameBoard.getBlockClumps().size();j++) {
|
|
|
|
if (i==j) continue;
|
|
|
|
BlockClump&c2=gameBoard.getBlockClumps()[j];
|
|
|
|
for (int k=0;k<c2.getBlocks().size();k++) {
|
|
|
|
Block&b2=c2.getBlocks()[k];
|
|
|
|
for (int l=0;l<c.getBlocks().size();l++) {
|
|
|
|
Block&b3=c.getBlocks()[l];
|
|
|
|
if (c2.getBlockPosition(b2).x==c.getBlockPosition(b3).x&&
|
|
|
|
c2.getBlockPosition(b2).y+12>=c.getBlockPosition(b3).y&&
|
|
|
|
c2.getBlockPosition(b2).y<=c.getBlockPosition(b3).y+12) {
|
|
|
|
float yDiff=c2.getBlockPosition(b2).y;
|
|
|
|
float snapYPos=c.getBlockPosition(b3).y;
|
|
|
|
yDiff-=snapYPos;
|
|
|
|
c2.y+=yDiff;
|
|
|
|
float influence=(float)c.getBlocks().size()/(c.getBlocks().size()+c2.getBlocks().size());
|
|
|
|
//Copy every block from one clump to the other
|
|
|
|
for (int m=0;m<c2.getBlocks().size();m++) {
|
|
|
|
Block&b4=c2.getBlocks()[m];
|
|
|
|
c.addBlock(b4.pos.x/12,(c2.getBlockPosition(b4).y-c.y)/12,b4.col);
|
|
|
|
}
|
|
|
|
if (c.vspeed>0) {
|
|
|
|
c.vspeed/=4;
|
|
|
|
}
|
|
|
|
if (c2.vspeed>0) {
|
|
|
|
c2.vspeed/=4;
|
|
|
|
}
|
|
|
|
c.vspeed=c.vspeed*influence+c2.vspeed*(1-influence);
|
|
|
|
gameBoard.removeClump(j--);
|
|
|
|
goto nextClumpCollisionCheck;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
nextClumpCollisionCheck:;
|
|
|
|
for (int j=0;j<c.getBlocks().size();j++){
|
|
|
|
Block&b=c.getBlocks()[j];
|
|
|
|
int col=b.pos.x/12;
|
|
|
|
for (int k=0;k<gameBoard.getBlocks(col).size();k++){
|
|
|
|
Block&b2=gameBoard.getBlocks(col)[k];
|
|
|
|
if (c.getBlockPosition(b).y+12>=b2.pos.y&&c.getBlockPosition(b).y<=b2.pos.y+12){
|
|
|
|
c.y-=c.getBlockPosition(b).y+12-b2.pos.y;
|
|
|
|
c.vspeed=0;
|
|
|
|
gameBoard.convertClump(i--);
|
|
|
|
goto nextClump;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (c.getBlockPosition(b).y>=gameBoard.yBottom) {
|
|
|
|
c.y-=c.getBlockPosition(b).y-gameBoard.yBottom;
|
|
|
|
c.vspeed=0;
|
|
|
|
gameBoard.convertClump(i--);
|
|
|
|
goto nextClump;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
c.y+=c.vspeed*fElapsedTime;
|
|
|
|
for (int j=0;j<c.getBlocks().size();j++){
|
|
|
|
Block&b=c.getBlocks()[j];
|
|
|
|
DrawPartialDecal(c.getBlockPosition(b)+gameBoard.drawOffset,gameBoard.tileset,{(float)(int)b.col*12,0},{12,12});
|
|
|
|
}
|
|
|
|
nextClump:;
|
|
|
|
}
|
|
|
|
for (BlockClump&c:gameBoard.getBlockClumps()){
|
|
|
|
std::vector<int>matchedBlockIDs;
|
|
|
|
for (Block&b:c.getBlocks()) {
|
|
|
|
b.addedToLaunchList=false;
|
|
|
|
}
|
|
|
|
for (int i=0;i<c.getBlocks().size();i++) {
|
|
|
|
Block&b=c.getBlocks()[i];
|
|
|
|
std::vector<int>tempMatchIDsX;
|
|
|
|
std::vector<int>tempMatchIDsY;
|
|
|
|
float targetX=b.pos.x;
|
|
|
|
float targetY=b.pos.y;
|
|
|
|
bool found=false;
|
|
|
|
tempMatchIDsX.push_back(i);
|
|
|
|
tempMatchIDsY.push_back(i);
|
|
|
|
rightCheck:
|
|
|
|
float checkX=targetX+12;
|
|
|
|
float checkY=targetY;
|
|
|
|
do{
|
|
|
|
found=false;
|
|
|
|
for (int j=0;j<c.getBlocks().size();j++){
|
|
|
|
Block&b2=c.getBlocks()[j];
|
|
|
|
if (i==j)continue;
|
|
|
|
if (b.col==b2.col&&b2.col!=BlockColor::LAUNCHED&&b2.pos.x==checkX&&b2.pos.y==checkY) {
|
|
|
|
found=true;
|
|
|
|
std::cout<<"Found match @ ("<<checkX<<","<<checkY<<") Block ("<<b2.pos<<")"<<b2.addedToLaunchList<<std::endl;
|
|
|
|
checkX+=12;
|
|
|
|
tempMatchIDsX.push_back(j);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}while(found);
|
|
|
|
leftCheck:
|
|
|
|
checkX=targetX-12;
|
|
|
|
checkY=targetY;
|
|
|
|
do{
|
|
|
|
found=false;
|
|
|
|
for (int j=0;j<c.getBlocks().size();j++){
|
|
|
|
Block&b2=c.getBlocks()[j];
|
|
|
|
if (i==j)continue;
|
|
|
|
if (b.col==b2.col&&b2.col!=BlockColor::LAUNCHED&&b2.pos.x==checkX&&b2.pos.y==checkY) {
|
|
|
|
found=true;
|
|
|
|
std::cout<<"Found match @ ("<<checkX<<","<<checkY<<") Block ("<<b2.pos<<")"<<b2.addedToLaunchList<<std::endl;
|
|
|
|
checkX-=12;
|
|
|
|
tempMatchIDsX.push_back(j);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}while(found);
|
|
|
|
upCheck:
|
|
|
|
checkX=targetX;
|
|
|
|
checkY=targetY-12;
|
|
|
|
do{
|
|
|
|
found=false;
|
|
|
|
for (int j=0;j<c.getBlocks().size();j++){
|
|
|
|
Block&b2=c.getBlocks()[j];
|
|
|
|
if (i==j)continue;
|
|
|
|
if (b.col==b2.col&&b2.col!=BlockColor::LAUNCHED&&b2.pos.x==checkX&&b2.pos.y==checkY) {
|
|
|
|
found=true;
|
|
|
|
std::cout<<"Found match @ ("<<checkX<<","<<checkY<<") Block ("<<b2.pos<<")"<<b2.addedToLaunchList<<std::endl;
|
|
|
|
checkY-=12;
|
|
|
|
tempMatchIDsY.push_back(j);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}while(found);
|
|
|
|
downCheck:
|
|
|
|
checkX=targetX;
|
|
|
|
checkY=targetY+12;
|
|
|
|
do{
|
|
|
|
found=false;
|
|
|
|
for (int j=0;j<c.getBlocks().size();j++){
|
|
|
|
Block&b2=c.getBlocks()[j];
|
|
|
|
if (i==j)continue;
|
|
|
|
if (b.col==b2.col&&b2.col!=BlockColor::LAUNCHED&&b2.pos.x==checkX&&b2.pos.y==checkY) {
|
|
|
|
found=true;
|
|
|
|
std::cout<<"Found match @ ("<<checkX<<","<<checkY<<") Block ("<<b2.pos<<")"<<b2.addedToLaunchList<<std::endl;
|
|
|
|
checkY+=12;
|
|
|
|
tempMatchIDsY.push_back(j);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}while(found);
|
|
|
|
if (tempMatchIDsX.size()>2||tempMatchIDsY.size()>2) {
|
|
|
|
if (tempMatchIDsX.size()>2) {
|
|
|
|
for (int i:tempMatchIDsX) {
|
|
|
|
Block&bb=c.getBlocks()[i];
|
|
|
|
if (!bb.addedToLaunchList) {
|
|
|
|
bb.addedToLaunchList=true;
|
|
|
|
matchedBlockIDs.push_back(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (tempMatchIDsY.size()>2) {
|
|
|
|
for (int i:tempMatchIDsY) {
|
|
|
|
Block&bb=c.getBlocks()[i];
|
|
|
|
if (!bb.addedToLaunchList) {
|
|
|
|
bb.addedToLaunchList=true;
|
|
|
|
matchedBlockIDs.push_back(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (int i:matchedBlockIDs) {
|
|
|
|
Block&b=c.getBlocks()[i];
|
|
|
|
std::cout<<"Launch Block ("<<b.pos<<")"<<b.addedToLaunchList<<std::endl;
|
|
|
|
b.col=BlockColor::LAUNCHED;
|
|
|
|
c.vspeed=gameBoard.launchSpd;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (int i=0;i<gameBoard.boardSize.x;i++){
|
|
|
|
for (Block&b:gameBoard.getBlocks(i)) {
|
|
|
|
float targetX=b.pos.x;
|
|
|
|
float targetY=b.pos.y;
|
|
|
|
bool found=false;
|
|
|
|
std::vector<Block*>matchedBlocksX;
|
|
|
|
std::vector<Block*>matchedBlocksY;
|
|
|
|
matchedBlocksX.push_back(&b);
|
|
|
|
matchedBlocksY.push_back(&b);
|
|
|
|
rightCheckGrounded:
|
|
|
|
float checkX=1;
|
|
|
|
float checkY=targetY;
|
|
|
|
do{
|
|
|
|
found=false;
|
|
|
|
if (i+checkX<gameBoard.boardSize.x) {
|
|
|
|
for (Block&b2:gameBoard.getBlocks(i+checkX)){
|
|
|
|
if (b.col==b2.col&&b2.col!=BlockColor::LAUNCHED&&b2.pos.x==b.pos.x+checkX*12&&b2.pos.y==checkY) {
|
|
|
|
found=true;
|
|
|
|
checkX++;
|
|
|
|
matchedBlocksX.push_back(&b2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}while(found);
|
|
|
|
leftCheckGrounded:
|
|
|
|
checkX=-1;
|
|
|
|
checkY=targetY;
|
|
|
|
do{
|
|
|
|
found=false;
|
|
|
|
if (i+checkX>=0) {
|
|
|
|
for (Block&b2:gameBoard.getBlocks(i+checkX)){
|
|
|
|
if (b.col==b2.col&&b2.col!=BlockColor::LAUNCHED&&b2.pos.x==b.pos.x+checkX*12&&b2.pos.y==checkY) {
|
|
|
|
found=true;
|
|
|
|
checkX--;
|
|
|
|
matchedBlocksX.push_back(&b2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}while(found);
|
|
|
|
upCheckGrounded:
|
|
|
|
checkX=targetX;
|
|
|
|
checkY=targetY-12;
|
|
|
|
do{
|
|
|
|
found=false;
|
|
|
|
for (Block&b2:gameBoard.getBlocks(i)){
|
|
|
|
if (b.pos.x==b2.pos.x&&b.pos.y==b2.pos.y)continue;
|
|
|
|
if (b.col==b2.col&&b2.col!=BlockColor::LAUNCHED&&b2.pos.x==checkX&&b2.pos.y==checkY) {
|
|
|
|
found=true;
|
|
|
|
checkY-=12;
|
|
|
|
matchedBlocksY.push_back(&b2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}while(found);
|
|
|
|
downCheckGrounded:
|
|
|
|
checkX=targetX;
|
|
|
|
checkY=targetY+12;
|
|
|
|
do{
|
|
|
|
found=false;
|
|
|
|
for (Block&b2:gameBoard.getBlocks(i)){
|
|
|
|
if (b.pos.x==b2.pos.x&&b.pos.y==b2.pos.y)continue;
|
|
|
|
if (b.col==b2.col&&b2.col!=BlockColor::LAUNCHED&&b2.pos.x==checkX&&b2.pos.y==checkY) {
|
|
|
|
found=true;
|
|
|
|
checkY+=12;
|
|
|
|
matchedBlocksY.push_back(&b2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}while(found);
|
|
|
|
if (matchedBlocksX.size()>2||matchedBlocksY.size()>2) {
|
|
|
|
BlockClump c;
|
|
|
|
c.y=b.pos.y-1;
|
|
|
|
if (matchedBlocksX.size()>2) {
|
|
|
|
for (Block*b2:matchedBlocksX) {
|
|
|
|
b2->col=BlockColor::LAUNCHED;
|
|
|
|
c.addBlockOnTopOf(b2->pos.x/12,b2->col);
|
|
|
|
b2->markedForRemoval=true;
|
|
|
|
}
|
|
|
|
for (Block*b2:matchedBlocksX) {
|
|
|
|
for (Block&b3:gameBoard.getBlocks(b2->pos.x/12)) {
|
|
|
|
if (!b3.markedForRemoval&&b3.pos.y<b2->pos.y) {
|
|
|
|
c.addBlockOnTopOf(b2->pos.x/12,b3.col);
|
|
|
|
b3.markedForRemoval=true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
c.vspeed=gameBoard.launchSpd;
|
|
|
|
}
|
|
|
|
if (matchedBlocksY.size()>2) {
|
|
|
|
for (int i=0;i<matchedBlocksY.size();i++) {
|
|
|
|
Block*b2=matchedBlocksY[i];
|
|
|
|
b2->col=BlockColor::LAUNCHED;
|
|
|
|
c.addBlockOnTopOf(b2->pos.x/12,b2->col);
|
|
|
|
b2->markedForRemoval=true;
|
|
|
|
}
|
|
|
|
for (int i=0;i<matchedBlocksY.size();i++) {
|
|
|
|
Block*b2=matchedBlocksY[i];
|
|
|
|
for (Block&b3:gameBoard.getBlocks(b2->pos.x/12)) {
|
|
|
|
if (!b3.markedForRemoval&&b3.pos.y<b2->pos.y) {
|
|
|
|
c.addBlockOnTopOf(b2->pos.x/12,b3.col);
|
|
|
|
b3.markedForRemoval=true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
c.vspeed=gameBoard.launchSpd;
|
|
|
|
}
|
|
|
|
gameBoard.addClump(c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (int y=0;y<gameBoard.getBlocks(i).size();y++){
|
|
|
|
Block&b=gameBoard.getBlocks(i)[y];
|
|
|
|
if (b.markedForRemoval){
|
|
|
|
gameBoard.removeBlock(i,y--);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
b.addedToLaunchList=false;
|
|
|
|
DrawPartialDecal(b.pos+gameBoard.drawOffset,gameBoard.tileset,{(float)(int)b.col*12,0},{12,12});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main()
|
|
|
|
{
|
|
|
|
Meteos instance;
|
|
|
|
if (instance.Construct(256, 240, 4, 4))
|
|
|
|
instance.Start();
|
|
|
|
return 0;
|
|
|
|
}
|