int main(int argc, char *argv[]){
	sleepy = argc != 1? 0 : 1;//So that if a machine is playing, sleeps can be removed
	struct timespec delayTime;//
	delayTime.tv_sec = 0;//These three lines create something that nanosleep can use to sleep. Details can be changed to change sleep time
	delayTime.tv_nsec = 500*1000*1000;//Starting at 500,000,000 nanoseconds (0.5s). Can be reassigned.
	puts("This is an in-development version. The treasure and traps are always visible.");
	char dungeon[DUNGEON_X][DUNGEON_Y];
	uint8_t playerPos[2] = {1, 1};//Starting position for the player
	uint8_t playing = 1; //So we don't instantly exit
	uint8_t monsterPos[2] = {2, 2}; //Starting monster position - randomisation incoming
	uint8_t awake = 0; //The monster starts invisible. This doubles as 'is the monster active?'
	uint8_t trapPos[2][2] = {{1, 2}, {3, 5}}; //Two traps to wake the monster - will be randomised
	uint8_t treasurePos[2] = {2, 1}; //The treasure was once in the same place as the monster. Randomisation will need to ensure that this is never the case
	setUpDungeon(&dungeon, playerPos, trapPos, monsterPos, treasurePos);//Because setUpDungeon takes a pointer, and a bunch of positions to tell it where stuff goes
	//validateDungeon(&dungeon);//As does validateDungeon. Commented because reasons
	if (sleepy) nanosleep(&delayTime, NULL);//Wait a moment
	while(playing){//If you're not playing anymore, the game really ought to end
		system("clear");//We are now officially *NIX specific
		uint8_t isValidCommand = 0;//So that if the input is invalid, it can be ignored and retried without redrawing
		uint8_t ignoreNext = 0;//For invalid strings, helps prevent ignorance of next valid input
		int8_t parseReturn;
		setUpDungeon(&dungeon, playerPos, trapPos, monsterPos, treasurePos);//Because setUpDungeon takes a pointer to a char[][]
										    //and a bunch of positions so that all things are in their rightful places
		drawDungeon(&dungeon, playerPos, trapPos, monsterPos, awake, treasurePos);//drawDungeon must know all things' positions
		printPrompt(&dungeon, awake, playerPos, trapPos, monsterPos, treasurePos);
		char text[3];//Command char, \n and \0
		while(!isValidCommand){
			fgets(text, 3, stdin);//Technically, this reads a file. stdin is a file, though. Uses a pointer, the number of characters you want and file
			if((text[1] == '\n' && text[2] == '\0') || text[1] == '\0'){//If the only input characters are the command, \n and EOF, or the command is \nEOF
									//in the event that the previous command was invalid and of the correct length type.
									//Rejects strings terminated with ^D but no \n, and glitches out, but that's not the kind of thing
				if(ignoreNext || text[0] == '\n'){	//any normal person would be inputting, anyway. Machines will learn what constitutes valid, too
					ignoreNext = 0;
				}
				else{
					parseReturn = parseUserInput(&dungeon, text[0], &playerPos, &awake, &trapPos);
					isValidCommand = parseReturn == 1? 1 : 0;
				}
			}
			else{
				if(!ignoreNext){
				puts("Invalid command.");
				ignoreNext = 1;
				if (sleepy) nanosleep(&delayTime, NULL);
				}
			}
		}
		if (sleepy) nanosleep(&delayTime, NULL);
		doMonsterMove(&dungeon, playerPos, &monsterPos, &playing);
	}
	return 0;
}
示例#2
0
void game_loop(void)
{
    for (int x = 0; x < 16; x++)
            {
                //for each y value between 2 and 13
                for (int y = 0; y < 16; y++)
                {
                    randX = 6 + (rand() % (int)(12 - 6 + 1));
                    randY = 0 + (rand() % (int)(3 - 0 + 1));
                    //drawDungeonTile(randX, randY, x, y);
                    floorArray [x] [y] [0] = randX;
                    floorArray [x] [y] [1] = randY;
                }
            }

    player p1;
    //(speed, friction, sprint accel, max speed)
    //default: p1.setMovement(1.4, .4, 1.8, 4);
    p1.setMovement(1.4, .4, 1.8, 4);
    p1.setPosition(tileSize * 7, tileSize * 12);
    p1.setX(240);
    p1.setY(240);
    printf("%f, %f \n", p1.getX(), p1.getY());

    al_start_timer(timer);
 
    while (!done) {
        ALLEGRO_EVENT event;
        al_wait_for_event(event_queue, &event);
 
        if (event.type == ALLEGRO_EVENT_TIMER) 
        {
            if(key[keyW] && p1.getY() >= p1.getMaxSpeed() + 1)
            {
                p1.setDy( p1.getDy() - p1.getSpeed());
            }

            if(key[keyS] && p1.getY() <= screenH - squareSize - (p1.getMaxSpeed() + 1))
            {
                p1.setDy( p1.getDy() + p1.getSpeed());
            }

            if(key[keyA] && p1.getX() >= (p1.getMaxSpeed() + 1))
            {
                p1.setDx( p1.getDx() - p1.getSpeed());
            }

            if(key[keyD] && p1.getX() <= screenW - squareSize - (p1.getMaxSpeed() + 1))
            {
                p1.setDx( p1.getDx() + p1.getSpeed());
            }

            if(key[keyShift] && (key[keyW] || key[keyA] ||key[keyS] ||key[keyD])) 
            {
                p1.setDx(p1.getDx() * p1.getSprintAccel());
                p1.setDy(p1.getDy() * p1.getSprintAccel());
            }

            if (abs(p1.getDx()) > p1.getMaxSpeed())
            {
               if(p1.getDx() < 0)
               {
                  p1.setDx( -p1.getMaxSpeed());
               }
               if(p1.getDx() > 0)
               {
                  p1.setDx( p1.getMaxSpeed());
               }
            }

            //max velocity Y
            if (abs(p1.getDy()) > p1.getMaxSpeed())
            {
               if(p1.getDy() < 0)
               {
                  p1.setDy(-p1.getMaxSpeed());
               }
               if(p1.getDy() > 0)
               {
                  p1.setDy( p1.getMaxSpeed() );
               }
            }


            redraw = true;
            //update_logic();
            
            //update player position
            p1.setX(p1.getX() + p1.getDx());
            //X axis
            //detect and respond to collision with obstacles
            p1.setX(playerWallCollisionX(p1.getX(),p1.getDx(),p1.getY(),room111));
            p1.setDx(p1.getDx() * p1.getFriction());

            //Y axis
            p1.setY(p1.getY() + p1.getDy());
            p1.setY(playerWallCollisionY(p1.getY(),p1.getDy(),p1.getX(),room111));
            p1.setDy(p1.getDy() * p1.getFriction());


               if (textCounter)
               {
                  textCounter = textCounter + 1;
                  if (textCounter == 60)
                  {
                     textCounter = 0;
                  }
               }
            redraw = true;
         }

        //key pressed down
        else if (event.type == ALLEGRO_EVENT_KEY_DOWN) 
        {
            switch (event.keyboard.keycode)
            {
                case ALLEGRO_KEY_ESCAPE:
                done = true;

                case ALLEGRO_KEY_W:
                key[keyW] = true;
                break;

                case ALLEGRO_KEY_A:
                key[keyA] = true;
                break;

                case ALLEGRO_KEY_S:
                key[keyS] = true;
                break;

                case ALLEGRO_KEY_D:
                key[keyD] = true;
                break;

                case ALLEGRO_KEY_LSHIFT:
                key[keyShift] = true;
                break;
            }
        }

        //key released
        else if (event.type == ALLEGRO_EVENT_KEY_UP)
        {
            switch (event.keyboard.keycode)
            {
                case ALLEGRO_KEY_W:
                key[keyW] = false;
                break;

                case ALLEGRO_KEY_A:
                key[keyA] = false;
                break;

                case ALLEGRO_KEY_S:
                key[keyS] = false;
                break;

                case ALLEGRO_KEY_D:
                key[keyD] = false;
                break;

                case ALLEGRO_KEY_LSHIFT:
                key[keyShift] = false;
                break;
            }
        }
        
        else if(event.type == ALLEGRO_EVENT_MOUSE_AXES || ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY)
        {
           crosshair_x = event.mouse.x - crosshairSize/2;
           crosshair_y = event.mouse.y - crosshairSize/2;
        }
        
        if (redraw && al_is_event_queue_empty(event_queue)) {
            redraw = false;

            //Clear screen to green
            al_clear_to_color(al_map_rgb(0, 0, 0));

            //update_graphics();
            //graphics that will always be there
            drawDungeon(floorArray,room111);
            al_draw_bitmap(playerBitmap, p1.getX(), p1.getY(), 0);
            /*
            for (int i = 0; i < (sizeof(obstacles)/sizeof(*obstacles)); i++)
            {
                al_draw_bitmap(block, obstacles[i][0],obstacles[i][1],0);
            }
            */
            drawObstacles(obstacles,sizeof(obstacles)/sizeof(*obstacles));
            al_draw_bitmap(crosshair, crosshair_x, crosshair_y, 0);
            al_flip_display();
        }
    }

}
示例#3
0
void game_loop(void)
{
    //load font
    ALLEGRO_FONT *font = al_load_ttf_font("RobotoMono-Medium.ttf",10,0);
    //create floor array (will eventually make this a function)
    srand(time(NULL));
    for (int x = 0; x < 16; x++)
    {
        //for each y value between 2 and 13
        for (int y = 0; y < 16; y++)
        {
            randX = 6 + (rand() % (int)(12 - 6 + 1));
            randY = 0 + (rand() % (int)(3 - 0 + 1));
            //drawDungeonTile(randX, randY, x, y);
            floorArray [x] [y] [0] = randX;
            floorArray [x] [y] [1] = randY;
        }
    }

    Player p1;
    //(speed, friction, sprint accel, max speed)
    //default: p1.setMovement(1.4, .4, 1.8, 4);
    p1.setMovement(1.4, .4, 1.8, 3);
    p1.setPosition(tileSize * 7, tileSize * 12);
    p1.setCurrentRoom(111);
    p1.setInitial(tileSize,tileSize,240,240);
    p1.setH(tileSize);
    p1.setW(tileSize);
    p1.setAnimation(tileSize * 0, tileSize * 0,0,0,9,4,0);
    p1.canMove = true;
    p1.vincible = true;
    p1.blinking = false;
    p1.blinkTimer = 5;
    p1.setMaxHP(100);
    p1.setCurrentHP(100);
    int tempBlinkTimer = p1.blinkTimer;
    p1.knockback = 0;
    p1.knockbackTimer = 0;
    p1.setBound(19,27,7,3, 14,8,9,24);
    p1.canRotate = true;
    //p1.setX(240);
    //p1.setY(240);
    p1.leavingTransport = 0;
    //init player prototypes
    void movePlayerUp(Player &p);
    void movePlayerDown(Player &p);
    void movePlayerLeft(Player &p);
    void movePlayerRight(Player &p);
    void sprintPlayer(Player &p);
    void maxSpeedPlayer(Player &p);
    void maxWalkSpeedPlayer(Player &p);
    void updatePlayer(Player &p);
    void collidePlayerWallX(Player &p, int obstacles [16][16]);
    void collidePlayerWallY(Player &p, int obstacles [16][16]);
    void collidePlayerMonster(Player &p, Monster m[]);
    void drawPlayer(Player &p);
    void resetPlayerAnimation(Player &p);

    //load current room map
    Room currentRoom;
    currentRoom.getWalkRoom(p1.getCurrentRoom());
    //currentRoom.getCollideRoom(p1.getCurrentRoom());

    //load all objects
    objectArray currentArray;
    currentArray.getObjects(p1.getCurrentRoom());

    //load current room transporters
    Transporter currentTrans;
    currentTrans.exitNumber = 0;

    //init monsters prototypes
    Monster currentMonsters[numMonsters];
    //load current room's monsters
    getMonsters(currentMonsters, currentArray.array);
    void getMonsters (Monster m[], int array[][16]);
    void drawMonsters (Monster m[]);
    void collideMonsterWallX(Monster m[], int obstacles [16][16]);
    void collideMonsterWallY(Monster m[], int obstacles [16][16]);
    void updateMonstersX (Monster currentMonsters[]);
    void updateMonstersY (Monster currentMonsters[]);
    //void seekMonsters (Monster m[], Player p);
    void seekMonsters (Monster &m, float x, float y);
    void seekPathMonsters (Monster &m, Player p);
    void pathfindMonsters (Monster &m, Player p, int obstacles [16][16], int mt);
    void newPathfindMonster (Monster &m, Player p, int obstacles [16][16]);
    int monsterDebug = 1;

    Weapon stick(15, 32, 4, 0, 20, bash, none);
    stick.setAnimation(tileSize * 0, tileSize * 0,0,0,2,3,0);
    void updateWeapon(Player &p, Weapon &w);
    void collideWeaponMonster(Weapon w, Monster m[], Player p);
    void resetAttack (Player p, Weapon &w);
    void attackWeapon(Player p, Weapon &w);
    void drawWeapon(Player p, Weapon &w);

    void drawCutscene(int num, int message);
    void closingSplash(void);
    Cutscene currentCutscene;
    currentCutscene.cutsceneFont = al_load_ttf_font("data/slkscr.ttf",32,0);

    int vincibleTimer = 0;
    int pathCounter = 0;
    bool showHitboxes = false;
    bool createCutscene = false;
    bool inCutscene = false;
    bool runSeekPath = false;
    al_start_timer(timer);
 
    while (!done) {
        ALLEGRO_EVENT event;
        al_wait_for_event(event_queue, &event);
 
        if (event.type == ALLEGRO_EVENT_TIMER) 
        {
            if(key[keyW])
            {
                movePlayerUp(p1);
            }
            else if(key[keyS])
            {
                movePlayerDown(p1);
            }

            if(key[keyA])
            {
                movePlayerLeft(p1);
            }
            else if(key[keyD])
            {
                movePlayerRight(p1);
            }

            if(!(key[keyW] || key[keyA] ||key[keyS] ||key[keyD])) 
            {
                resetPlayerAnimation(p1);
            }

            if(key[keyShift] && (key[keyW] || key[keyA] ||key[keyS] ||key[keyD])) 
            {
                sprintPlayer(p1);
            }
            else
            {
                maxWalkSpeedPlayer(p1);
            }
                maxSpeedPlayer(p1);
            if(key[keySpace])
            {
                //printf("ATTACK!\n");
            }
            if (runSeekPath)
            {
                //seekPathMonsters(currentMonsters[1],p1);
                //pathfindMonsters(
            }
            else
            {
                currentMonsters[1].setDx(0);
                currentMonsters[1].setDy(0);
            }
            
            //update player position
            p1.setX(p1.getX() + p1.getDx());
            collidePlayerMonster(p1,currentMonsters);
            //printf("player DX: %f\n",p1.getDx());
            //printf("player DY: %f\n",p1.getDy());
            //X axis
            //detect and respond to collision with obstacles
            collidePlayerWallX(p1,currentRoom.collideArray);
            if(p1.canMove)
            {
                p1.setDx(p1.getDx() * p1.getFriction());
            }
            //knockback timer

            //Y axis
            p1.setY(p1.getY() + p1.getDy());
            collidePlayerWallY(p1,currentRoom.collideArray);
            p1.setDy(p1.getDy() * p1.getFriction());

            //Monster movement and wall collisions
                for (int i = 0; i < numMonsters; i++)
                {
                    if (currentMonsters[i].isLive)
                    {
                        newPathfindMonster( currentMonsters[i], p1, currentRoom.collideArray);
                    }
                }
            //seekMonsters(currentMonsters[1],p1.getX(), p1.getY());
            for (int i = 0; i < numMonsters; i++)
            {
                if (currentMonsters[i].isLive)
                {
                    //seekPathMonsters(currentMonsters[i],p1);
                    seekMonsters(currentMonsters[i],currentMonsters[i].destX, currentMonsters[i].destY);
                }
            }
            //weapon updating
            updateWeapon(p1,stick);
            collideWeaponMonster(stick, currentMonsters, p1);
            updateMonstersX(currentMonsters);
            collideMonsterWallX(currentMonsters,currentRoom.collideArray);
            updateMonstersY(currentMonsters);
            collideMonsterWallY(currentMonsters,currentRoom.collideArray);


            //if able to transport
            if (p1.leavingTransport == 0)
            {
                //check for collisions with transporter
                currentTrans.exitNumber = currentTrans.playerTransCollision(p1.getX(), p1.getY(),currentArray.array);
                if (currentTrans.exitNumber)
                {
                    currentTrans.fromNumber = p1.getCurrentRoom();
                    p1.leavingTransport = 1;
                }
            }

            //if transporting
            if ( p1.leavingTransport == 1)
            {
                //set room to move to
                p1.setCurrentRoom(currentTrans.exitNumber);
                currentRoom.getWalkRoom(p1.getCurrentRoom());
                //currentRoom.getCollideRoom(p1.getCurrentRoom());
                currentArray.getObjects(p1.getCurrentRoom());
                getMonsters(currentMonsters, currentArray.array);
                //must set player's location to the location of the exit portal in the new room
                currentTrans.getDestination(currentArray.array);
                p1.setX(currentTrans.destination[0] + tileSize/2);
                p1.setY(currentTrans.destination[1] + tileSize/2);
                currentTrans.destination[0] = 0;
                currentTrans.destination[1] = 0;
                p1.leavingTransport = 0;
            }

            //functions for drawing the player (will need to go elsewhere eventually)
            //invincible timer
            if (p1.vincible == false)
            {
                vincibleTimer ++;
                tempBlinkTimer --;

                p1.blinking = true;
                //printf("p1 blinking? %d, %d\n",p1.blinking, tempBlinkTimer);
                if (tempBlinkTimer < 0)
                {
                    p1.blinking = false;
                    if ( tempBlinkTimer == p1.blinkTimer * (-3))
                    {
                        tempBlinkTimer = p1.blinkTimer;
                    }
                }
                if (vincibleTimer == invincibleTime)
                {
                    p1.vincible = true;
                    p1.blinking = false;
                    vincibleTimer = 0;
                    //printf ("vincible Again \n");
                }
            }
            pathCounter ++;
            if (pathCounter == 90) {pathCounter = 0;}

            redraw = true;
         }

        //key pressed down
        else if (event.type == ALLEGRO_EVENT_KEY_DOWN) 
        {
            switch (event.keyboard.keycode)
            {
                case ALLEGRO_KEY_ESCAPE:
                done = true;

                case ALLEGRO_KEY_W:
                key[keyW] = true;
                break;

                case ALLEGRO_KEY_A:
                key[keyA] = true;
                break;

                case ALLEGRO_KEY_S:
                key[keyS] = true;
                break;

                case ALLEGRO_KEY_D:
                key[keyD] = true;
                break;

                case ALLEGRO_KEY_C:
                key[keyC] = true;
                if (!inCutscene)
                {
                    currentCutscene.openDialog ("data/cutscenes/1");
                    createCutscene = 1;
                }
                if (inCutscene)
                {
                    currentCutscene.currentMessage ++;
                }
                while(1)
                break;

                case ALLEGRO_KEY_LSHIFT:
                key[keyShift] = true;
                break;

                case ALLEGRO_KEY_SPACE:
                key[keySpace] = true;
                runSeekPath = true;
                //pathfindMonsters( currentMonsters[1], p1, currentRoom.collideArray, pathCounter);
                newPathfindMonster( currentMonsters[1], p1, currentRoom.collideArray);
                attackWeapon(p1,stick);
                break;
            }
        }

        //key released
        else if (event.type == ALLEGRO_EVENT_KEY_UP)
        {
            switch (event.keyboard.keycode)
            {
                case ALLEGRO_KEY_W:
                key[keyW] = false;
                break;

                case ALLEGRO_KEY_A:
                key[keyA] = false;
                break;

                case ALLEGRO_KEY_S:
                key[keyS] = false;
                break;

                case ALLEGRO_KEY_D:
                key[keyD] = false;
                break;

                case ALLEGRO_KEY_C:
                key[keyC] = false;
                break;

                case ALLEGRO_KEY_LSHIFT:
                key[keyShift] = false;
                break;

                case ALLEGRO_KEY_SPACE:
                key[keySpace] = false;
                resetAttack(p1, stick);
                break;
            }
        }
        
        else if(event.type == ALLEGRO_EVENT_MOUSE_AXES || ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY)
        {
           crosshair_x = event.mouse.x - crosshairSize/2;
           crosshair_y = event.mouse.y - crosshairSize/2;
        }
        
        if (redraw && al_is_event_queue_empty(event_queue)) {
            redraw = false;
            //Clear screen to black
            al_clear_to_color(al_map_rgb(0, 0, 0));

            if (createCutscene == true)
            {
                al_set_target_bitmap(cutsceneBackdrop);
                al_clear_to_color(al_map_rgb(0, 0, 0));
            }

            //update_graphics();
            //graphics that will always be there
            if (!inCutscene)
            {
                drawDungeon(floorArray,currentRoom.walkArray);
                drawDungeon(floorArray,currentRoom.collideArray);
                for (int i = 0; i < 16; i++)
                {
                    for (int j = 0; j < 16; j++)
                    {
                        al_draw_textf(font, al_map_rgb(255,255,255),j*tileSize,i*tileSize,ALLEGRO_ALIGN_LEFT,"%d,%d",j+1,i+1);
                    }
                }

                if (transDebug) currentTrans.drawTransporters(currentArray.array);
                drawMonsters(currentMonsters);
                
                if (p1.getDir() != UP && p1.getDir() != LEFT)
                {
                    if (p1.blinking == false)
                    {
                        drawPlayer(p1);
                    }
                }
                drawWeapon(p1,stick);

                if (p1.getDir() == UP || p1.getDir() == LEFT)
                {
                    if (p1.blinking == false)
                    {
                        drawPlayer(p1);
                    }
                }

                al_draw_textf(font, al_map_rgb(255,255,255),0,tileSize*0,ALLEGRO_ALIGN_LEFT,"playerHP: %d",p1.getCurrentHP());
                for (int i = 1; i < numMonsters; i++)
                {
                    if (currentMonsters[i].getCurrentHP() > -10000 && currentMonsters[i].getCurrentHP() <10000)
                    {
                        al_draw_textf(font, al_map_rgb(255,255,255),tileSize * 4 * i,tileSize*15,ALLEGRO_ALIGN_LEFT,"monster %d HP: %d",i,currentMonsters[i].getCurrentHP());
                    }
                }
            }
            if (inCutscene)
            {
                currentCutscene.drawCutscene(1, 1);
            }
            //al_draw_bitmap(crosshair, crosshair_x, crosshair_y, 0);

            if (createCutscene == true)
            {
                inCutscene = true;
                createCutscene = false;
                al_set_target_bitmap(al_get_backbuffer(display));
                //al_lock_bitmap(cutsceneBackdrop);
                inCutscene = true;
            }
            al_flip_display();
        }
    }
}
示例#4
0
void game_loop(void)
{
    //load font
    ALLEGRO_FONT *font = al_load_ttf_font("RobotoMono-Medium.ttf",12,0);
    //create floor array (will eventually make this a function)
    srand(time(NULL));
    for (int x = 0; x < 16; x++)
            {
                //for each y value between 2 and 13
                for (int y = 0; y < 16; y++)
                {
                    randX = 6 + (rand() % (int)(12 - 6 + 1));
                    randY = 0 + (rand() % (int)(3 - 0 + 1));
                    //drawDungeonTile(randX, randY, x, y);
                    floorArray [x] [y] [0] = randX;
                    floorArray [x] [y] [1] = randY;
                }
            }

    Player p1;
    //(speed, friction, sprint accel, max speed)
    //default: p1.setMovement(1.4, .4, 1.8, 4);
    p1.setMovement(1.4, .4, 1.8, 3);
    p1.setPosition(tileSize * 7, tileSize * 12);
    p1.setCurrentRoom(111);
    p1.setInitial(tileSize,tileSize,240,240);
    p1.setH(tileSize);
    p1.setW(tileSize);
    p1.setAnimation(tileSize * 0, tileSize * 0,0,0,9,4,0);
    p1.canMove = true;
    p1.vincible = true;
    p1.blinking = false;
    p1.blinkTimer = 5;
    int tempBlinkTimer = p1.blinkTimer;
    p1.knockback = 0;
    p1.knockbackTimer = 0;
    p1.setBound(19,27,7,3, 14,8,9,24);
    //p1.setX(240);
    //p1.setY(240);
    p1.leavingTransport = 0;
    //init player prototypes
    void movePlayerUp(Player &p);
    void movePlayerDown(Player &p);
    void movePlayerLeft(Player &p);
    void movePlayerRight(Player &p);
    void sprintPlayer(Player &p);
    void maxSpeedPlayer(Player &p);
    void maxWalkSpeedPlayer(Player &p);
    void updatePlayer(Player &p);
    void collidePlayerWallX(Player &p, int obstacles [16][16]);
    void collidePlayerWallY(Player &p, int obstacles [16][16]);
    void collidePlayerMonster(Player &p, Monster m[]);
    void drawPlayer(Player &p);
    void resetPlayerAnimation(Player &p);

    //load current room map
    Room currentRoom;
    currentRoom.getRoom(p1.getCurrentRoom());

    //load all objects
    objectArray currentArray;
    currentArray.getObjects(p1.getCurrentRoom());

    //load current room transporters
    Transporter currentTrans;
    currentTrans.exitNumber = 0;

    //init monsters prototypes
    Monster currentMonsters[numMonsters];
    getMonsters(currentMonsters, currentArray.array);
    void getMonsters (Monster m[], int array[][16]);
    void drawMonsters (Monster m[]);
    void collideMonsterWallX(Monster m[], int obstacles [16][16]);
    void collideMonsterWallY(Monster m[], int obstacles [16][16]);
    void updateMonstersX (Monster currentMonsters[]);
    void updateMonstersY (Monster currentMonsters[]);
    void seekMonsters (Monster m[], Player p);
    int monsterDebug = 1;
    //load current room's monsters
    //currentMonsters.getObjects(p1.getCurrentRoom());

    int vincibleTimer = 0;
    bool showHitboxes = false;
    al_start_timer(timer);
 
    while (!done) {
        ALLEGRO_EVENT event;
        al_wait_for_event(event_queue, &event);
 
        if (event.type == ALLEGRO_EVENT_TIMER) 
        {
            if(key[keyW])
            {
                movePlayerUp(p1);
            }
            else if(key[keyS])
            {
                movePlayerDown(p1);
            }

            if(key[keyA])
            {
                movePlayerLeft(p1);
            }
            else if(key[keyD])
            {
                movePlayerRight(p1);
            }

            if(!(key[keyW] || key[keyA] ||key[keyS] ||key[keyD])) 
            {
                resetPlayerAnimation(p1);
            }

            if(key[keyShift] && (key[keyW] || key[keyA] ||key[keyS] ||key[keyD])) 
            {
                sprintPlayer(p1);
                maxSpeedPlayer(p1);
            }
            else
            {
                maxWalkSpeedPlayer(p1);
            }


            //Monster movement and wall collisions
            seekMonsters(currentMonsters,p1);
            updateMonstersX(currentMonsters);
            collideMonsterWallX(currentMonsters,currentRoom.array);
            updateMonstersY(currentMonsters);
            collideMonsterWallY(currentMonsters,currentRoom.array);

            redraw = true;
            
            //update player position
            p1.setX(p1.getX() + p1.getDx());
            collidePlayerMonster(p1,currentMonsters);
            //printf("player DX: %f\n",p1.getDx());
            //printf("player DY: %f\n",p1.getDy());
            //X axis
            //detect and respond to collision with obstacles
            collidePlayerWallX(p1,currentRoom.array);
            if(p1.canMove)
            {
                p1.setDx(p1.getDx() * p1.getFriction());
            }
            //knockback timer

            //Y axis
            p1.setY(p1.getY() + p1.getDy());
            collidePlayerWallY(p1,currentRoom.array);
            p1.setDy(p1.getDy() * p1.getFriction());

            //if able to transport
            if (p1.leavingTransport == 0)
            {
                //check for collisions with transporter
                currentTrans.exitNumber = currentTrans.playerTransCollision(p1.getX(), p1.getY(),currentArray.array);
                if (currentTrans.exitNumber)
                {
                    currentTrans.fromNumber = p1.getCurrentRoom();
                    p1.leavingTransport = 1;
                }
            }

            //if transporting
            if ( p1.leavingTransport == 1)
            {
                //set room to move to
                p1.setCurrentRoom(currentTrans.exitNumber);
                currentRoom.getRoom(p1.getCurrentRoom());
                currentArray.getObjects(p1.getCurrentRoom());
                getMonsters(currentMonsters, currentArray.array);
                //must set player's location to the location of the exit portal in the new room
                currentTrans.getDestination(currentArray.array);
                p1.setX(currentTrans.destination[0] + tileSize/2);
                p1.setY(currentTrans.destination[1] + tileSize/2);
                currentTrans.destination[0] = 0;
                currentTrans.destination[1] = 0;
                p1.leavingTransport = 0;
            }

            //functions for drawing the player (will need to go elsewhere eventually)
            //invincible timer
            if (p1.vincible == false)
            {
                vincibleTimer ++;
                tempBlinkTimer --;

                p1.blinking = true;
                //printf("p1 blinking? %d, %d\n",p1.blinking, tempBlinkTimer);
                if (tempBlinkTimer < 0)
                {
                    p1.blinking = false;
                    if ( tempBlinkTimer == p1.blinkTimer * (-3))
                    {
                        tempBlinkTimer = p1.blinkTimer;
                    }
                }
                if (vincibleTimer == invincibleTime)
                {
                    p1.vincible = true;
                    p1.blinking = false;
                    vincibleTimer = 0;
                    //printf ("vincible Again \n");
                }
            }
            //animation frame counter

            redraw = true;
         }

        //key pressed down
        else if (event.type == ALLEGRO_EVENT_KEY_DOWN) 
        {
            switch (event.keyboard.keycode)
            {
                case ALLEGRO_KEY_ESCAPE:
                done = true;

                case ALLEGRO_KEY_W:
                key[keyW] = true;
                break;

                case ALLEGRO_KEY_A:
                key[keyA] = true;
                break;

                case ALLEGRO_KEY_S:
                key[keyS] = true;
                break;

                case ALLEGRO_KEY_D:
                key[keyD] = true;
                break;

                case ALLEGRO_KEY_LSHIFT:
                key[keyShift] = true;
                break;
            }
        }

        //key released
        else if (event.type == ALLEGRO_EVENT_KEY_UP)
        {
            switch (event.keyboard.keycode)
            {
                case ALLEGRO_KEY_W:
                key[keyW] = false;
                break;

                case ALLEGRO_KEY_A:
                key[keyA] = false;
                break;

                case ALLEGRO_KEY_S:
                key[keyS] = false;
                break;

                case ALLEGRO_KEY_D:
                key[keyD] = false;
                break;

                case ALLEGRO_KEY_LSHIFT:
                key[keyShift] = false;
                break;
            }
        }
        
        else if(event.type == ALLEGRO_EVENT_MOUSE_AXES || ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY)
        {
           crosshair_x = event.mouse.x - crosshairSize/2;
           crosshair_y = event.mouse.y - crosshairSize/2;
        }
        
        if (redraw && al_is_event_queue_empty(event_queue)) {
            redraw = false;

            //Clear screen to green
            al_clear_to_color(al_map_rgb(0, 0, 0));

            //update_graphics();
            //graphics that will always be there
            drawDungeon(floorArray,currentRoom.array);
            if (transDebug) currentTrans.drawTransporters(currentArray.array);
            drawMonsters(currentMonsters);
            
            //Monster debug hitbox
            if (showHitboxes)
            {
                for (int i = 0; i < numMonsters; i ++)
                {
                    if (currentMonsters[i].isLive == 1)
                    {
                        //al_draw_rectangle(BBBitmap, currentMonsters[i].getX() + currentMonsters[i].getBoundOffsetW(), currentMonsters[i].getY() + currentMonsters[i].getBoundOffsetH(), 0);
            al_draw_rectangle(currentMonsters[i].getX() + currentMonsters[i].getBoundOffsetW(), currentMonsters[i].getY() + currentMonsters[i].getBoundOffsetH(), currentMonsters[i].getX() + currentMonsters[i].getBoundOffsetW() + currentMonsters[i].getBoundW(), currentMonsters[i].getY() + currentMonsters[i].getBoundOffsetH() + currentMonsters[i].getBoundH(), al_map_rgb(255,0,0),1);
            al_draw_rectangle(currentMonsters[i].getX() + currentMonsters[i].getWallOffsetW(), currentMonsters[i].getY() + currentMonsters[i].getWallOffsetH(), currentMonsters[i].getX() + currentMonsters[i].getWallOffsetW() + currentMonsters[i].getWallW(), currentMonsters[i].getY() + currentMonsters[i].getWallOffsetH() + currentMonsters[i].getWallH(), al_map_rgb(0,255,0),1);
                    }
                }
            }
            if (p1.blinking == false)
            {
                drawPlayer(p1);
            }
            //player debug hitbox
            if (showHitboxes)
            {
                al_draw_rectangle(p1.getX() + p1.getBoundOffsetW(), p1.getY() + p1.getBoundOffsetH(), p1.getX() + p1.getBoundOffsetW() + p1.getBoundW(), p1.getY() + p1.getBoundOffsetH() + p1.getBoundH(), al_map_rgb(255,0,0),1);
                al_draw_rectangle(p1.getX() + p1.getWallOffsetW(), p1.getY() + p1.getWallOffsetH(), p1.getX() + p1.getWallOffsetW() + p1.getWallW(), p1.getY() + p1.getWallOffsetH() + p1.getWallH(), al_map_rgb(0,255,0),1);
            }
            al_draw_text(font, al_map_rgb(255,255,255),0,tileSize*15,ALLEGRO_ALIGN_LEFT,"TEXT!");
            //al_draw_bitmap(crosshair, crosshair_x, crosshair_y, 0);
            al_flip_display();
        }
    }
}