Java Video Tutorial 10

Java Video Tutorial 10In this tutorial I do something kind of crazy. I try to teach programming logic by writing code right out of my head. You probably won’t understand everything in this video, but that’s OK.

I continue making a simple game in Java. I specifically make a method that allows my monsters to move on the game board without landing on each other and blocks them from falling off the board.

If you missed part 1 definitely check out Java Video Tutorial pt 1.

The code follows the video. It is heavily commented and will help you better understand the video, so definitely look at it.

If you like videos like this share it

Code From the Video

MONSTERTWO.JAVA

import java.util.Arrays;

import org.apache.commons.lang3.ArrayUtils;

// Basic class definition
// public means this class can be used by other classes
// Class names should begin with a capital letter
// A file can't contain two public classes. It can contain classes that are not public
// If you place class files in the same folder the java compiler will be able to find them

public class MonsterTwo{
	// Creates a multidimensional array of chars
	static char[][] battleBoard = new char[10][10];
	
	// This static method builds an empty battle board
	public static void buildBattleBoard(){
		
		// Cycles through the array and gives a default value of * to everything
		
		for(char[] row : battleBoard)
			Arrays.fill(row, '*');
	}
	
	// Redraws the board
	public static void redrawBoard()
	{
		
		int k = 1;
		while(k <= 30){ System.out.print('-'); k++; }
		System.out.println();
		
		for(int i = 0; i < battleBoard.length; i++)
		{
			for(int j = 0; j < battleBoard[i].length; j++)
			{
				System.out.print("|" + battleBoard[i][j] + "|");
			}
			System.out.println();
			
		}
		k = 1;
		while(k <= 30){ System.out.print('-'); k++; }
		System.out.println();
	}
	
	// Class Variables or Fields
	// You declare constants with final
	
	public final String TOMBSTONE = "Here Lies a Dead monster";
	
	// private fields are not visible outside of the class
	private int health = 500;
	private int attack = 20;
	private int movement = 2;
	
	// Monitors whether the monster is alive or dead
	private boolean alive = true;
	
	// public variables are visible outside of the class
	// You should have as few as possible public fields
	public String name = "Big Monster";
	public int xPosition = 0;
	public int yPosition = 0;
	public char nameChar1 = 'B';
	public static int numOfMonsters = 0;
	
	
	// Class Methods
	// Accessor Methods are used to get and set the values of private fields
	
	public int getAttack()
	{
		return attack;
	}
	
	public int getMovement()
	{
		return movement;
	}
	
	public int getHealth()
	{
		return health;
	}
	
	public boolean getAlive()
	{
		return alive;
	}
	
	// You can create multiple versions using the same method name
	// Now setHealth can except an attack that contains decimals
	// When overloading a method you can't just change the return type
	// Focus on creating methods that except different parameters
	
	public void setHealth(int decreaseHealth)
	{
		health = health - decreaseHealth;
		if (health < 0)
		{
			alive = false;
		}
	}
	
	public void setHealth(double decreaseHealth)
	{
		int intDecreaseHealth = (int) decreaseHealth;
		health = health - intDecreaseHealth;
		if (health < 0)
		{
			alive = false;
		}
	}
	
	public void moveMonster(MonsterTwo[] monster, int arrayItemIndex)
	{
		// isSpaceOpen will be used to track whether the space the
		// monster plans to move into is occupied
		boolean isSpaceOpen = true;
		
		// Define the maximum x and y for the battle board
		// It's 1 less because the array index starts at 0
		int maxXBoardSpace = battleBoard.length - 1;
		int maxYBoardSpace = battleBoard[0].length - 1;
		
		
		// while loop used to make sure I don't move a monster
		// into an occupied space
		while(isSpaceOpen)
		{
		
		// Randomly generate move direction N, S, E, or W
		int randMoveDirection = (int) (Math.random() * 4);
		
		// Randomly generate move distance based on max move distance
		int randMoveDistance = (int) (Math.random() * (this.getMovement() + 1));
		
		// Prints move distance and move direction
		System.out.println(randMoveDistance + " " + randMoveDirection);
		
		// Erase monsters character on the board by replacing it with a *
		
		battleBoard[this.yPosition][this.xPosition] = '*';
		

			
		if(randMoveDirection == 0)
		{
			// Find new xPosition & yPosition based on the current position on the board
			// If statements won't allow monster to move off the board
			
			if((this.yPosition - randMoveDistance) < 0)
			{
				this.yPosition = 0;
			} else {
				this.yPosition = this.yPosition - randMoveDistance;
			}
		} else if (randMoveDirection == 1) {
			if((this.xPosition + randMoveDistance) > maxXBoardSpace)
			{
				this.xPosition = maxXBoardSpace;
			} else {
				this.xPosition = this.xPosition + randMoveDistance;
			}
		} else if (randMoveDirection == 2) {
			if((this.yPosition + randMoveDistance) > maxYBoardSpace)
			{
				this.yPosition = maxYBoardSpace;
			} else {
				this.yPosition = this.yPosition + randMoveDistance;
			}
		} else {
			if((this.xPosition - randMoveDistance) < 0)
			{
				this.xPosition = 0;
			} else {
				this.xPosition = this.xPosition - randMoveDistance;
			}
		}
		
		// monster.length returns the number of items in the array monster
		for (int i = 0; i < monster.length; i++)
		{
			// if statement skips checking the same monster position against itself
			
			if (i == arrayItemIndex)
			{
				continue;
			} 
			
			// onMySpace receives the monster array, index for the object I'm 
			// checking currently, and the index for the monster sent to 
			// this function
			
			if(onMySpace(monster, i, arrayItemIndex))
			{
				// If a monster tries to move to an occupied space the
				// while loop repeats after I break out of the for loop
				
				isSpaceOpen = true;
				break;
			} else {
				// There was no monster in the space so end the while loop
				isSpaceOpen = false;
				
			}
			
		}
		
		} // End of while loop
		
		// Set the value in the array to the first letter of the monster
		battleBoard[this.yPosition][this.xPosition] = this.nameChar1;	
	}
	
	// Checks if one monster is trying to move into the same x/y position as 
	// another monster
	public boolean onMySpace(MonsterTwo[] monster, int indexToChk1, int indexToChk2)
	{
		// Checks if the 2 monsters have the same x/y position
		if((monster[indexToChk1].xPosition)==(monster[indexToChk2].xPosition)&&(monster[indexToChk1].yPosition)==(monster[indexToChk2].yPosition))
		{
			// If they are equal return true so a new x/y position is calculated
			
			return true;
			
		} else {
			
			// If false I know the x/y position isn't occupied
			return false;
		}
	}
	
	
	/* The Constructor
	 * Code that is executed when an object is created from this class definition
	 * The method name is the same as the class
	 * The constructor is only executed once per object
	 * The constructor can't return a value
	 */
	
	public MonsterTwo(int health, int attack, int movement, String name)
	{
		this.health = health;
		this.attack = attack;
		this.movement = movement;
		this.name = name;
		/* If the attributes had the same names as the class health, attack, movement
		 * You could refer to the objects fields by proceeding them with this
		 * this.health = health;
		 * this.attack = attack;
		 * objectFieldName = attributeFieldName;
		 */
		
		// Define the maximum x and y for the battle board
		// It's 1 less because the array index starts at 0
		int maxXBoardSpace = battleBoard.length - 1;
		int maxYBoardSpace = battleBoard[0].length - 1;
		
		// The random starting position for a monster
		int randNumX, randNumY;
		
		// We use a do loop because we always want to define a start 
		// position for each monster
		
		do {
		// Calculate start position based on max board space
		randNumX = (int) (Math.random() * maxXBoardSpace);
		randNumY = (int) (Math.random() * maxYBoardSpace);
		} while(battleBoard[randNumY][randNumX] != '*');
		// Only allow monster to start on a space with a * on it
		
		// Assign x and y position to the object that called this method
		this.xPosition = randNumX;
		this.yPosition = randNumY;
		
		// Assign character in the array based on the first initial
		// of the monsters name charAt(0) returns first letter of name
		this.nameChar1 = this.name.charAt(0);
		
		// Put first character of monster in the array
		battleBoard[this.yPosition][this.xPosition] = this.nameChar1;
		
		numOfMonsters++; // Adds 1 to the number of monsters on the board
	}
	
	// You can overload constructors like any other method
	// The following constructor is the one provided by default if you don't create any other constructors
	// Default Constructor
	
	public MonsterTwo()
	{
		numOfMonsters++; // Adds 1 to the number of monsters on the board
	}
	
public static void main(String[] args)
{
	
	
	
}
	
}

LESSONTEN.JAVA

import java.util.Arrays;
import org.apache.commons.lang3.ArrayUtils;

// Basic class definition
// public means this class can be used by other classes
// Class names should begin with a capital letter
// A file can't contain two public classes. It can contain classes that are not public
// If you place class files in the same folder the java compiler will be able to find them

/* The Goal of this tutorial is to make a game like this
------------------------------
|*||*||*||*||*||*||*||*||*||*|
|*||*||*||*||*||*||*||*||*||*|
|*||*||*||*||*||*||*||*||*||*|
|*||M||F||*||*||*||*||*||*||*|
|*||*||*||*||*||*||*||*||*||*|
|*||*||*||*||*||*||*||*||*||*|
|*||*||*||*||*||*||*||*||*||*|
|P||*||*||*||*||*||*||*||*||*|
|*||*||*||*||D||*||*||*||*||*|
|*||*||*||*||*||*||*||*||*||*|
------------------------------
[9,9]

 */

public class LessonTen {
	
	public static void main(String[] args)
	{
		
		MonsterTwo.buildBattleBoard();
		
		// char[][] tempBattleBoard = new char[10][10];
		
		// ObjectName[] ArrayName = new ObjectName[4];
		
		MonsterTwo[] Monsters = new MonsterTwo[4];
		
		// MonsterTwo(int health, int attack, int movement, String name)
		
		Monsters[0] = new MonsterTwo(1000, 20, 1, "Frank");
		Monsters[1] = new MonsterTwo(500, 40, 2, "Drac");
		Monsters[2] = new MonsterTwo(1000, 20, 1, "Paul");
		Monsters[3] = new MonsterTwo(1000, 20, 1, "George");
		
		MonsterTwo.redrawBoard();
		
	
	for (MonsterTwo m : Monsters)
	{
		
		if(m.getAlive())
		{
			int arrayItemIndex = ArrayUtils.indexOf(Monsters, m);
			m.moveMonster(Monsters, arrayItemIndex);
		}
		
	}
	
	MonsterTwo.redrawBoard();
	
	
}
}

24 Responses to “Java Video Tutorial 10”

  1. Punit says:

    getting an error:
    “Exception in thread “main” java.lang.Error: Unresolved compilation problem:
    ArrayUtils cannot be resolved”

    in this line…

    “int arrayItemIndex = ArrayUtils.indexOf(Monsters, m);”

  2. Punit says:

    okay, working now…
    thanks..

  3. Jon says:

    I understand the need for ‘this.’ in front of member variables when you need to disambiguate member variables from method arguments of the same name. You seem to use ‘this.’ in many places where they are not strictly necessary. Is this just a personal preference (possbily to help remind you that what follows is a member variable) or is there another reason?

    Also, thanks for the great videos. I’m actually watching the videos and translating your code into C++ as a vehicle to learn C++ programming. Working out very well (so far)!

    • Derek Banas says:

      I over did it with this in these early videos. You are correct that they aren’t normally needed except in the situation you mentioned. For some reason people get confused by this so I wanted to make sure the used it when needed even if it was over used. In later tutorials I stop doing that.

      I’ll eventually make a c++ tutorial. I just want to finish java first. I wish I would have made complete tutorials in the past like I do now. C++ will be covered completely as well when I get to it.

  4. omar says:

    I have the exact same code… i think, yet my board is not drawn properly. It just prints a single row with all the symbols from the board.

    • Derek Banas says:

      Feel free to skip to the next tutorial in the series. I review everything as it continues

    • Tom says:

      Omar,

      I think your problem is that you are using println() instead print() in both while loops: while(k <= 30){ System.out.print('-'); k++; }

      Also try double quotes instead of single quotes in System.out.print('-'); I don't why that last part let it work for me, but it worked.

  5. Tom says:

    Hi Derek,

    In your code you have:

    // Randomly generate move direction N, S, E, or W
    int randMoveDirection = (int) (Math.random() * 4);

    I haven’t run the program to see the functionality of it yet. But shouldn’t it be (Math.random() * 5; since there are 4 directions a monster can move? In earlier tutorials I believe you indicated that when using Math.random() it must be one value above the numbers you wish to generate.

    Great tutorials, by the way. I’m loving it!

    • Derek Banas says:

      You may be correct. I can’t remember this tutorial very well. I didn’t particularly like the way parts 8 and 10 came out.

      I constantly try new ways of teaching. Here was one of the first times I started to program 100% out of my head. I was trying to teach the way a person thinks when programming. I think I failed here, but eventually by doing this I have succeeded in later tutorials.

      I now regularly program 100% out of my head. I hope that in trying to improve my overall tutorials, that you don’t feel that you have wasted your time. I promise that aside from parts 8 and 10 that the rest of the tutorial series is very good. At least they are as good as I could make them. I hope that makes sense

  6. Raj says:

    You are awesome Dude. Keep doing this.

  7. Talib says:

    Your tutorials are really awesome!!! I just wish you could provide some kind of practice questions or task after a series of tutorials so that would be great..

    Any ways you are great man!! Cheers

  8. Vineet says:

    Java Video Tutorial 10 is not working… Is there anyway you can get it back up?

  9. Leila says:

    Hi Derek,

    Thank you very much for the great tutorials. You are making the world to be a better place and I really appreciate your hard work.

    I have a request from you. I understand your tutorials. But, how can we practice. I mean to have problems to think on our own as an assignments.

    Thank you.

    • Derek Banas says:

      You’re very welcome 🙂 For practice one path would be to look at my Android development tutorials. I make one app after another there.

      I thought of the Java tutorial as a type of video API. I thought the best way to watch it was to print out the code and then take notes as you watch in your own words. Then you could go back and use what you learned for anything.

      In the Android tutorials I have started to teach while making apps. This is much harder for me, but people seem to enjoy that style. I’ll continue to try and get better 🙂

  10. James says:

    Hi Derek,

    Don’t keep saying this Lesson 10 is a “failure”….I don’t think this “over kill” coding of the fly is bad at all. I enjoy it a lot.
    You showed an excellent coding practice, based upon your rich experience.

    James

  11. Fahad says:

    what does the Arrayutils.indexof() do ??

    and thanks for everything man , keep going !!

Leave a Reply

Your email address will not be published.

Google+