Results 1 to 10 of 10
  1. #1
    Join Date
    Oct 2011
    Posts
    92

    evil Monkeys some bugs to fix at i5_VTM07

    Ok, finally I ended lesson i5_07_Finalizing_Graphics, before I move on to the next, I would like to fix some bugs that the game has, some of them already accomplished, however there’re some that may require a little more time for me to fix…

    Hopefully, someone already saw the same things that I experienced and has the answer for some of these problems, so here it goes (thank you for any help in advance to fix them):

    evil Monkeys cheat!!!

    1 - I notice that, sometimes the evil Monkeys “jump” through the TILE_WALLS, this specialy true if the player is in the other side of the WALL. UPDATE: They do not jump, they walk diagonally and that allows them to pass through empty spaces that exist between 2 or more TILE_WALLs.

    2 – Random game level creation is fun, but sometimes (normally at the 3th or higher level) , one or more evil monkeys are created exactly where the player starts, and therefore the player loses all it’s lifes.

    3 – When the player "dies" close to the startup position, the evil monkeys will be very close to the player (and in higher levels with higher speeds) and when the player resets to the default position the evilMonkeys will "kill" the player without chance to run away (it would be nice that each time a player loses a life the enemies "that were left before the player died" be reset back to their initial start position giving a better chance of survival to the player (in higher levels where speed is higher this may be important).

    Player cheats!!!
    1 – Although I already change the code accordantly with the “Thread of Information”, I can no longer break through the outside TILE WALLS, but I still can “delete” the image inside the game square if I fire fireballs when next to the TILE WALLS, after they’re deleted I can fire through them and kill evil monkeys…

    2 – If the player pass through evil monkeys fast enough (pressing continuously the keyboard), it will not die!!!

    3 - (UPDATE) Is not possible to kill enemies when the enemies are +1 relative position to the player. This happens because the fireballs are fired +2 positions (depending of the player direction) after the player position.

    Any answer will appreciated.
    Thank you all
    Last edited by JMSPT; 12-03-2011 at 10:14 AM.

  2. #2
    Join Date
    Oct 2011
    Posts
    92
    Ok some extra bug updates

    Game start Window!!!

    1 – Menu shortcuts don’t work (I’m using wxWidgets-2.9.2 that may work differently from the version that the VTM was made)
    2 – The window may not get focus when the game is started

  3. #3
    Join Date
    Oct 2011
    Posts
    92
    UPDATE (please let me know if anyone found additional alternatives)

    evilMonkeys cheat!!!

    1 –FIXED

    Under Sprite.cpp

    Changed from:

    Code:
    bool Sprite::isValidLevelMove(int xpos, int ypos)
    {
       if (xpos >= 0 && xpos < level->getWidth() &&
             ypos >= 0 && ypos < level->getHeight() &&
             level->level[xpos][ypos] != TILE_WALL )
          return true;
       return false;
    }

    TO
    Code:
    bool Sprite::isValidLevelMove(int xpos, int ypos)
    {
    	int currentX = (int)this->getX(); 
    	int currentY = (int)this->getY(); 
    
    	//Validate invalid diagonal coords
    	if ((currentX - 1) == xpos && (currentY - 1) == ypos)
    		return false;
    	else if ((currentX - 1) == xpos && (currentY + 1) == ypos)
    		return false;
    	else if ((currentX + 1) == xpos && (currentY - 1) == ypos)
    		return false;
    	else if ((currentX + 1) == xpos && (currentY + 1) == ypos)
    		return false;
    
       if (xpos >= 0 && xpos < level->getWidth() &&
             ypos >= 0 && ypos < level->getHeight() &&
             level->level[xpos][ypos] != TILE_WALL )
          return true;
    
       return false;
    }
    2 –FIXED. To fix point 2, I changed the original code in level.cpp under “void Level::addEnemies” function.

    Code:
    void Level::addEnemies(int num, int speed)
    {
    	int i = num;
    	while (i > 0)
    	{
    		int xpos = int((float(rand() % 100) / 100) * (width - 2) + 1);
    		int ypos = int((float(rand() % 100) / 100) * (height - 2) + 1);
    
    		if (level[xpos][ypos] != TILE_WALL)
    		{
    			Enemy *temp = new Enemy(this, drawArea, SPRITE_ENEMY, (float)xpos, float(ypos));
    			temp->setSpeed(speed);
    			temp->addGoal(player);
    			addNPC((Sprite *)temp);
    			i--;
    		}
    	}
    }
    to

    Code:
    void Level::addEnemies(int num, int speed)
    {
    	int i = num;
    	while (i > 0)
    	{
    		int xpos = int((float(rand() % 100) / 100) * (width - 5) + 5);
    		int ypos = int((float(rand() % 100) / 100) * (height - 5) + 5);
    
    		if (level[xpos][ypos] != TILE_WALL)
    		{
    			Enemy *temp = new Enemy(this, drawArea, SPRITE_ENEMY, (float)xpos, float(ypos));
    			temp->setSpeed(speed);
    			temp->addGoal(player);
    			addNPC((Sprite *)temp);
    			i--;
    		}
    	}
    }
    3 - FIXED
    Fixed using Aholio suggestion. I'll post as son as possible.

    Player cheats

    1 – FIXED. To fix this point I edit the mage.cpp under “Mage::castSpell” function.

    Code:
    void Mage::castSpell(void)
    {
       if (facingDirection.x == 0 && facingDirection.y == 0)
          return;
    
       if (facingDirection.y < -1 && facingDirection.y < -1)
          return;
    
       Fireball *temp = new Fireball(level, drawArea, SPRITE_FIREBALL, (int)pos.x + facingDirection.x,
          (int)pos.y + facingDirection.y, facingDirection.x, facingDirection.y);
    
       if (temp->move(facingDirection.x, facingDirection.y))
       {
          temp->update();
          level->addNPC((Sprite *)temp);
       }
       else
          update();
    }
    to

    Code:
    void Mage::castSpell(void)
    {
       if (facingDirection.x == 0 && facingDirection.y == 0)
          return;
    
       if (facingDirection.y < -1 && facingDirection.y < -1)
          return;
    
        if (!(isValidLevelMove(((int)pos.x + (int)facingDirection.x), ((int)pos.y + (int)facingDirection.y))))
    	   return;
    
       Fireball *temp = new Fireball(level, drawArea, SPRITE_FIREBALL, (int)pos.x + facingDirection.x,
          (int)pos.y + facingDirection.y, facingDirection.x, facingDirection.y);
    
       if (temp->move(facingDirection.x, facingDirection.y))
       {
          temp->update();
          level->addNPC((Sprite *)temp);
       }
       else
          update();
    }
    2 – FIXED

    In AppFrame.cpp
    Changed from

    Code:
    gameWindow->Connect(-1, -1, wxEVT_KEY_DWON,(wxObjectEventFunction) &AppFrame::OnKey, NULL, this);
    TO

    Code:
    gameWindow->Connect(-1, -1, wxEVT_KEY_UP,(wxObjectEventFunction) &AppFrame::OnKey, NULL, this);
    3 - FIXED - UPDATED
    Changes made in Fireball.cpp and Mage.cpp

    OLD CODE Fireball.cpp

    Code:
    void Fireball::idleUpdate(void)
    { 
       if ((isValidLevelMove((int)pos.x, (int)pos.y)) && ((facingDirection.x + facingDirection.y) != 0))
       { 
          if (Sprite::move(facingDirection.x, facingDirection.y))
          {
             list <Sprite *>::iterator Iter;
    		
             for (Iter = level->npc.begin(); Iter != level->npc.end(); Iter++)
             {
                if ((*Iter)->classID != classID && 
                   (int)(*Iter)->getX() ==(int)pos.x && (int)(*Iter)->getY() ==(int)pos.y)
                {
                   (*Iter)->addLives(-1);
                   addLives(-1);
                }
             }
          }
          else
             addLives(-1);
       } 
    }
    CHANGED TO

    Code:
    void Fireball::idleUpdate(void)
    {
    	int x = pos.x;
    	int y = pos.y;
    
       if ((isValidLevelMove((int)pos.x, (int)pos.y)) && ((facingDirection.x + facingDirection.y) != 0))
       { 
          if (Sprite::move(facingDirection.x, facingDirection.y))
          {
             list <Sprite *>::iterator Iter;
    		
             for (Iter = level->npc.begin(); Iter != level->npc.end(); Iter++)
             {
                if ((*Iter)->classID != classID && 
                   (int)(*Iter)->getX() == (int)pos.x && (int)(*Iter)->getY() ==(int)pos.y ||
    	       (int)(*Iter)->getX() == x && (int)(*Iter)->getY() == y)
                {
                   (*Iter)->addLives(-1);
                   addLives(-1);
                }
             }
          }
          else
             addLives(-1);
       } 
    }
    OLD CODE Mage.cpp

    Code:
    void Mage::castSpell(void)
    {
       if (facingDirection.x == 0 && facingDirection.y == 0)
          return;
    
       if (facingDirection.y < -1 && facingDirection.y < -1)
          return;
    
        if (!(isValidLevelMove(((int)pos.x + (int)facingDirection.x), ((int)pos.y + (int)facingDirection.y))))
    	   return;
    
       Fireball *temp = new Fireball(level, drawArea, SPRITE_FIREBALL, (int)pos.x + facingDirection.x,
          (int)pos.y + facingDirection.y, facingDirection.x, facingDirection.y);
    
       if (temp->move(facingDirection.x, facingDirection.y))
       {
          temp->update();
          level->addNPC((Sprite *)temp);
       }
       else
          update();
    }
    CHANGED TO

    Code:
    void Mage::castSpell(void)
    {
       if (facingDirection.x == 0 && facingDirection.y == 0)
          return;
    
       if (facingDirection.y < -1 && facingDirection.y < -1)
          return;
    
        if (!(isValidLevelMove(((int)pos.x + (int)facingDirection.x), ((int)pos.y + (int)facingDirection.y))))
    	   return;
    
       Fireball *temp = new Fireball(level, drawArea, SPRITE_FIREBALL, (int)pos.x,
            (int)pos.y, facingDirection.x, facingDirection.y);
    
       if (temp->move(facingDirection.x, facingDirection.y))
       {
    	   temp->update();
    	   level->addNPC((Sprite *)temp);
    	   update();
       }
       else
          update();
    }

    Game start Window

    1 – FIXED. Using AppFrame.cpp under AppFrame::AppFrame , changed the following

    Code:
    menuFile->Append(ID_New,"&New);
    menuFile->Append(ID_Load,"&Load");
    menuFile->AppendSeparator();
    menuFile->Append(ID_About,"&About");
    menuFile->AppendSeparator();
    menuFile->Append(ID_Exit,"&Exit");
    to

    Code:
    menuFile->Append(ID_New,_T("New\tCtrl-N"));
    menuFile->Append(ID_Load,_T("Load\tCtrl-L"));
    menuFile->AppendSeparator();
    menuFile->Append(ID_About,_T("About\tCtrl-A"));
    menuFile->AppendSeparator();
    menuFile->Append(ID_Exit,_T("Exit\tCtrl-E"));
    2 – FIXED. Using AppFrame.cpp under “AppFrame::AppFrame “ added the following at the very end of the code

    Code:
    gameWindow->SetFocus();
    Additional suggestions are welcome.
    Last edited by JMSPT; 12-05-2011 at 09:17 AM.

  4. #4
    Join Date
    Oct 2011
    Posts
    92
    No one comments?!!

  5. #5
    Join Date
    Oct 2005
    Location
    Seattle, WA
    Posts
    501
    3 - Add a start position element to the enemy class. When an enemy is created, record its start position. After the player dies, or when he respawns, iterate through the list of enemies and move each one to its start position.

  6. #6
    Join Date
    Oct 2011
    Posts
    92
    Quote Originally Posted by Aholio View Post
    3 - Add a start position element to the enemy class. When an enemy is created, record its start position. After the player dies, or when he respawns, iterate through the list of enemies and move each one to its start position.
    Thanks Aholio, that worked Great!!!

  7. #7
    Join Date
    Oct 2005
    Location
    Seattle, WA
    Posts
    501
    Glad I could help, although I think you could have come up with the solution yourself. It looks like you have a good understanding of what is going on. If you are looking for ways to challenge yourself and/or improve the game, you can try a different pathfinding method. I would suggest A*. It's cool to see the enemies figure out ways around obstacles.

  8. #8
    Join Date
    Oct 2011
    Posts
    92
    Quote Originally Posted by Aholio View Post
    Glad I could help, although I think you could have come up with the solution yourself. It looks like you have a good understanding of what is going on. If you are looking for ways to challenge yourself and/or improve the game, you can try a different pathfinding method. I would suggest A*. It's cool to see the enemies figure out ways around obstacles.
    Cool, I like that Idea, will try do that

  9. #9
    Join Date
    Jul 2005
    Posts
    29

    Fix for the fix

    Quote Originally Posted by JMSPT View Post
    UPDATE (please let me know if anyone found additional alternatives)

    Player cheats

    1 – FIXED. To fix this point I edit the mage.cpp under “Mage::castSpell” function.

    Code:
    void Mage::castSpell(void)
    {
       if (facingDirection.x == 0 && facingDirection.y == 0)
          return;
    
       if (facingDirection.y < -1 && facingDirection.y < -1)
          return;
    
       Fireball *temp = new Fireball(level, drawArea, SPRITE_FIREBALL, (int)pos.x + facingDirection.x,
          (int)pos.y + facingDirection.y, facingDirection.x, facingDirection.y);
    
       if (temp->move(facingDirection.x, facingDirection.y))
       {
          temp->update();
          level->addNPC((Sprite *)temp);
       }
       else
          update();
    }
    to

    Code:
    void Mage::castSpell(void)
    {
       if (facingDirection.x == 0 && facingDirection.y == 0)
          return;
    
       if (facingDirection.y < -1 && facingDirection.y < -1)
          return;
    
        if (!(isValidLevelMove(((int)pos.x + (int)facingDirection.x), ((int)pos.y + (int)facingDirection.y))))
    	   return;
    
       Fireball *temp = new Fireball(level, drawArea, SPRITE_FIREBALL, (int)pos.x + facingDirection.x,
          (int)pos.y + facingDirection.y, facingDirection.x, facingDirection.y);
    
       if (temp->move(facingDirection.x, facingDirection.y))
       {
          temp->update();
          level->addNPC((Sprite *)temp);
       }
       else
          update();
    }
    Additional suggestions are welcome.



    This is a problem with this fix you can not call isValidLevelMove() the way you are calling it. It needs to look like this.

    Code:
    void Mage::castSpell(void)
    {
       if (facingDirection.x == 0 && facingDirection.y == 0)
          return;
    
       if (facingDirection.y < -1 && facingDirection.y < -1)
          return;
    
        if (!(this->isValidLevelMove(((int)pos.x + (int)facingDirection.x), ((int)pos.y + (int)facingDirection.y))))
    	   return;
    
       Fireball *temp = new Fireball(level, drawArea, SPRITE_FIREBALL, (int)pos.x + facingDirection.x,
          (int)pos.y + facingDirection.y, facingDirection.x, facingDirection.y);
    
       if (temp->move(facingDirection.x, facingDirection.y))
       {
          temp->update();
          level->addNPC((Sprite *)temp);
       }
       else
          update();
    }
    I know this thread is rather old but for people who actually watch and want to learn and have a complete solution for the evil monkeys program they need to know where to look for the issues that are still present after using the code from the thread of information.

  10. #10
    Join Date
    Jul 2010
    Posts
    472
    A quick note, and this is just from skimming so it may not be a necessary change... I think in castSpell, it should be facingDirection.x < -1 && facingDirection.y < -1.

    Well done on the fixing, though!
    "It's most impressive when it's least expected."

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •