PDA

Просмотр полной версии : Дописать консольную игру С++.


leshax
13.01.2010, 23:25
Наклепать 1 уровень, добавить лабиринт, возможность ставить бомбы... короче нужна стабильная версия bomberman в консоле на основе Model-view-controller.

15$



#include "iostream"
#include "windows.h"
#include "conio.h"
#include "vector"
#include "time.h"
using namespace std;

enum{DIR_UP, DIR_DOWN, DIR_LEFT,DIR_RIGHT};

class Player;

class View{
class Pixel
{
public:
char data;
int color;

Pixel(){
data = ' ';
color = 7;
}

bool operator != (const Pixel& p){
return this->data == p.data && this->color == p.color ? false : true;
}

bool operator == (const Pixel& p){
return this->data == p.data && this->color == p.color ? true : false;
}

};
HANDLE hOut;
Pixel** matrix;
Pixel** virtMatrix;
public:

View(){
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
matrix = new Pixel*[24];
virtMatrix = new Pixel*[24];
for(int i = 0; i < 24; i++){
matrix[i] = new Pixel[79];
virtMatrix[i] = new Pixel[79];
}
}

void DrawChar(int x, int y, char c = ' ', int color=7)const{
static COORD charCoords;
charCoords.X = x;
charCoords.Y = y;
SetConsoleCursorPosition(hOut, charCoords);
SetConsoleTextAttribute(hOut, color);
cout << c;
}

void Draw(){
for(int i = 0; i < 24; i++){
for(int j = 0; j < 79; j++){

if(matrix[i][j] != virtMatrix[i][j]){
matrix[i][j] = virtMatrix[i][j];
DrawChar(j, i, matrix[i][j].data, matrix[i][j].color);
}
virtMatrix[i][j].data = ' ';
virtMatrix[i][j].color = 7;
}
}
}

void PutPixel(int x, int y, char c = ' ', int color=7){
virtMatrix[y][x].data = c;
virtMatrix[y][x].color = color;

}

};

class Actor
{
protected:


int color;
char symbol;

public:

int x;
int y;


Actor(){
color = symbol = x = y = -1;
}

Actor(int x, int y, int color, char symbol){
this->x = x;
this->y = y;
this->color = color;
this->symbol = symbol;
}

virtual void Update(int elapsedTime) = 0;
virtual bool TryToStep(int x, int y) = 0;
virtual void Draw(View& view){
view.PutPixel(x, y, symbol, color);
}

};

class Game{

View view;

// time stuff
DWORD beginTime;
DWORD elapsedTime;
DWORD lastUpdateTime;
DWORD currentUpdateTime;
// time stuff

bool play;


public:

static vector<Actor*> actors;
static char input;
static bool extInput;
static Player player;

Game() : view()
{
beginTime = GetTickCount();

elapsedTime = lastUpdateTime = currentUpdateTime = -1;
play = true;
}

void AddMob(Actor* mob){
actors.push_back(mob);
}

void Start()
{
lastUpdateTime = GetTickCount();
while(play){

if(_kbhit()){
input = _getch();
if(input == 0){
extInput = true;
input = _getch();
}
else{
extInput = false;
}
}
Update();
Draw();
Sleep(15);
}
}

void Draw()
{
for(int i = 0; i < actors.size(); i++){
actors[i]->Draw(view);
}

((Actor*)(&player))->Draw(view);

view.Draw();
}

void Update(){

//time stuff
currentUpdateTime = GetTickCount();
elapsedTime = currentUpdateTime - lastUpdateTime;
lastUpdateTime = currentUpdateTime;
//time stuff

for(int i = 0; i < actors.size(); i++){
actors[i]->Update(elapsedTime);
}
((Actor*)(&player))->Update(elapsedTime);



}



};


vector<Actor*> Game::actors = vector<Actor*>();
char Game::input = 0;
bool Game::extInput = false;

class MovingMob : public Actor
{
protected:
int dir;

int timeSinceLastUpdate;
int timeBetweenUpdates;
public:
MovingMob() : Actor(){
timeSinceLastUpdate = timeBetweenUpdates = dir = -1;
}

MovingMob(int x, int y, int color, char symbol, int dir) : Actor(x, y, color, symbol)
{
this->dir = dir;
timeSinceLastUpdate = 0;
timeBetweenUpdates = 150;
}

virtual bool TryToStep(int x, int y){

for(int i = 0; i < Game::actors.size(); i++){
if( Game::actors[i]->x == x && Game::actors[i]->y == y)
{
return false;
}
}


return x >= 0 && x < 79 && y >=0 && y < 24 ? true : false;

}

virtual void Update(int elapsedTime) = 0;
};

class RandomMovingMob : public MovingMob
{
public:
RandomMovingMob() : MovingMob()
{

}

RandomMovingMob(int x, int y, int color, char symbol, int dir) : MovingMob(x, y, color, symbol, dir)
{

}

void Update(int elapsedTime){
timeSinceLastUpdate += elapsedTime;
if(timeSinceLastUpdate >= timeBetweenUpdates){
timeSinceLastUpdate = 0;
if( rand()%10 > 7 )
{
dir = rand()%4;
}

int newX = x, newY = y;

switch(dir){
case DIR_DOWN:
newY++;
break;
case DIR_UP:
newY--;
break;
case DIR_LEFT:
newX--;
break;
case DIR_RIGHT:
newX++;
break;
default:
return;
}

if(TryToStep(newX, newY)){
x = newX;
y = newY;
}
else
{
dir = rand()%4;
}
}
}
};







class Player : public MovingMob
{
public:
Player() : MovingMob(10, 10, 10, 'P', DIR_UP)
{
timeBetweenUpdates = 100;
timeSinceLastUpdate = 0;
}

void Update(int elapsedTime){
timeSinceLastUpdate += elapsedTime;

if(timeSinceLastUpdate >= timeBetweenUpdates){
timeSinceLastUpdate = 0;
int newX = x, newY = y;
switch(Game::input){
case 'w':
dir = DIR_UP;
break;
case 's':
dir = DIR_DOWN;
break;
case 'a':
dir = DIR_LEFT;
break;
case 'd':
dir = DIR_RIGHT;
break;
}
switch(dir){
case DIR_DOWN:
newY++;
break;
case DIR_UP:
newY--;
break;
case DIR_LEFT:
newX--;
break;
case DIR_RIGHT:
newX++;
break;
default:
return;
}

if(TryToStep(newX, newY)){
x = newX;
y = newY;
}
}
}
};

Player Game::player = Player();

void main(){
srand(time(0));
Game g;
RandomMovingMob* pMob;

for(int i = 0; i < 15; i++){
pMob = new RandomMovingMob(i*2, i, i+1, '0'+i, DIR_UP);
g.AddMob(pMob);
}

g.Start();
}