Skip to content
Permalink
ca0c4fafae
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
433 lines (374 sloc) 12.5 KB
package controller;
import java.awt.image.BufferedImage;
import java.io.File;
import model.Object;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import model.Map;
import model.Merchant;
import model.Player;
import view.MapUI;
import view.StartScreen;
import model.Character;
public class RPGame {
// Window properties
public static final int WIDTH = 1206;
public static final int HEIGHT = 929;
// Inventory lists from file
private ArrayList<String> merchantInventoryList1 = new ArrayList<String>(); // merchant 1's inventory list
private ArrayList<String> merchantInventoryList2 = new ArrayList<String>(); // merchant 2's inventory list
private ArrayList<String> merchantInventoryList3 = new ArrayList<String>(); // merchant 3's inventory list
private ArrayList<String> playerInventoryList = new ArrayList<String>(); // the player's inventory list
// Character instances
private Player _player;
private Merchant _merchant1;
private Merchant _merchant2;
private Merchant _merchant3;
private Merchant _misc1;
// Map instance
private Map map;
// MapUI instance and properties
private MapUI mapui;
// Current game properties
public boolean _movement = true;
private int _currentDay;
private int _transactionLimit;
public RPGame(int transactionLimit, int tileSize) {
// Initializing member variables
_currentDay = 1;
_transactionLimit = transactionLimit;
// Calculating number of rows and columns for map
int rows = (HEIGHT - 29)/tileSize;
int cols = (WIDTH - 6)/tileSize;
// Read inventory lists from file
inventoryFromFile();
// Build merchant and player instances
buildMerchants();
buildPlayer("test", 500);
// Initialiing Map instance and adding the player, objects, and merchants to the map
map = new Map(rows, cols);
Object object = new Object(rows/2, cols/2 - 1, "house");
map.initializePlayer(_player, rows/2, cols/2);
map.initializeMerchant(_merchant1, rows/2, 1);
map.initializeMerchant(_merchant2, rows-2, cols/2);
map.initializeMerchant(_merchant3, rows/2, cols-2);
map.initializeObject(object, rows/2, cols/2 - 1);
// Creating the MapUI instance and Sprites cooresponding to characters
mapui = new MapUI(map, this, tileSize);
mapui.createPlayerSprite(rows/2, cols/2);
mapui.addMerchantSprite(rows/2, 1);
mapui.addMerchantSprite(rows-2, cols/2);
mapui.addMerchantSprite(rows/2, cols-2);
mapui.addObject(object);
buildRandomEnvironment(250);
// Creating JFrame window
JFrame frame = new JFrame("The Merchant RPG");
try {
frame.setIconImage(loadIcon());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Adding MapUI instance to window
frame.add(mapui);
// Setting properties of JFrame
frame.setSize(RPGame.WIDTH, RPGame.HEIGHT);
frame.setResizable(false);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
}
public BufferedImage loadIcon() throws IOException {
BufferedImage img = null;
try {
img = ImageIO.read(new File("src/images/icon.png"));
return img;
} catch (IOException e) {
System.out.println("File not found");
return null;
}
}
/**
* This method scans the inventory.txt file located in src\config. It will read lines of the format <stringname> <price> and store them in the inventory list member variables
*
*/
public void inventoryFromFile() {
Scanner fileScanner = null;
try {
fileScanner = new Scanner(new File("src/config/inventory.txt")); // inventory.txt must be located the config folder
int currentMerchant = 0; // keeps track of which merchant's inventory the scanner is reading
String token = null;
String item = null;
while(fileScanner.hasNextLine()) { // loops as long as there is another line to read
token = fileScanner.next();
if (token.equals("merchant"))
currentMerchant = fileScanner.nextInt();
else {
item = token + " " + fileScanner.nextInt(); // a string containing the item name and price
if (currentMerchant == 1)
merchantInventoryList1.add(item);
else if (currentMerchant == 2)
merchantInventoryList2.add(item);
else if (currentMerchant == 3)
merchantInventoryList3.add(item);
playerInventoryList.add(item);
}
if (fileScanner.hasNextLine()) // only advances to the next line if there is one to read
fileScanner.nextLine();
}
} catch (FileNotFoundException e) { // if inventory.txt is deleted or missing
System.out.println("Inventory file not found");
e.printStackTrace();
}
}
/**
* Generates all three merchants
* will add them to the map, but function is not written yet
*/
public void buildMerchants()
{
_merchant1 = new Merchant("Cheap Merchant", 300, merchantInventoryList1, 0);
_merchant2 = new Merchant("Medium Merchant", 600, merchantInventoryList2, merchantInventoryList1.size());
_merchant3 = new Merchant("Expensive Merchant", 1000, merchantInventoryList3, merchantInventoryList1.size()+ merchantInventoryList2.size());
}
/**
* Generates the player
* @param name Player name
* @param startingCash Amount of cash the player starts with
*/
public void buildPlayer(String name, int startingCash)
{
_player = new Player(name, startingCash, playerInventoryList);
}
public void buildRandomEnvironment(int size) {
int clusterCount = 0;
boolean newCluster = true;
for (int i = 0; i < size; i++) {
if (clusterCount == 6) {
clusterCount = 0;
newCluster = true;
}
Random randomGenerator = new Random();
int row = randomGenerator.nextInt(map.getRows()-1);
int col = randomGenerator.nextInt(map.getCols()-1);
while (map.isOccupied(col, row) || closeToCharacter(row, col) || (!newCluster && !(map.isOccupiedByObject(col + 1, row) || map.isOccupiedByObject(col - 1, row) || map.isOccupiedByObject(col, row + 1) || map.isOccupiedByObject(col, row - 1) || map.isOccupiedByObject(col - 1, row - 1) || map.isOccupiedByObject(col + 1, row + 1) || map.isOccupiedByObject(col - 1, row + 1) || map.isOccupiedByObject(col + 1, row - 1)))) {
row = randomGenerator.nextInt(map.getRows()-1);
col = randomGenerator.nextInt(map.getCols()-1);
}
Object object = new Object(row, col, "tree");
map.initializeObject(object, row, col);
mapui.addObject(object);
clusterCount++;
newCluster = false;
}
}
public boolean closeToCharacter(int row, int col) {
Object o = new Object(row, col, "");
if (distanceBetween(o, _merchant1) < 90)
return true;
if (distanceBetween(o, _merchant2) < 90)
return true;
if (distanceBetween(o, _merchant3) < 90)
return true;
if (distanceBetween(o, _player) < 90)
return true;
return false;
}
public int distanceBetween(Character a, Character b) {
return (int) Math.sqrt(Math.pow((a.getCol()-b.getCol())*30, 2) + Math.pow((a.getRow()-b.getRow())*30, 2));
}
/**
* This method returns the specified merchant inventory list
*
* @param merchant number
* @return the specified merchant's inventory list
*/
public ArrayList<String> getMerchantInventoryList(int merchantNumber) {
if (merchantNumber == 1)
return merchantInventoryList1;
else if (merchantNumber == 2)
return merchantInventoryList2;
else if (merchantNumber == 3)
return merchantInventoryList3;
else
{
System.out.println("Invalid merchant number");
return null;
}
}
/**
* This method returns the player's inventory list
*
* @return the player's inventory list
*/
public ArrayList<String> getPlayerInventoryList() {
return playerInventoryList;
}
/**
* This method will create a new instance of Transaction which runs independently
*
* @param player
* @param targetMerchant The merchant that the player is trading with
*/
public void createTransaction(Player player, Merchant targetMerchant)
{
if(_transactionLimit > 0)
{
toggleMovement("OFF");
Transaction newTransaction = new Transaction(player, targetMerchant, this);
newTransaction.runTransaction();
_transactionLimit -= 1;
}
else
{
System.out.println("The shops are closed.");
}
}
/**
* Will refresh number of transactions the Player has available
*
*/
private void refreshTransactionLimit(){
_transactionLimit = 3;
}
/**
* This method will advance the game to the next day, therefore refreshing Merchant cash,
* incrementing the Merchant's max cash every 3 days, refreshing the player's _transactionLimit,
* Will call setDailyRandomPercentage, scaleAllAdjustedPrices, refreshCash, incrementBaseCash
*
*/
public void advanceDailyCycle(){
Merchant[] allMerchants = {_merchant1, _merchant2, _merchant3};
_merchant1.setDailyRandomPercentage(50,200); //these methods have to be separated since they all take different percentages
_merchant2.setDailyRandomPercentage(80,500);
_merchant3.setDailyRandomPercentage(10,1000);
scaleAllMerchantPrices(allMerchants); //will scale all the prices of the items that the merchants hold based on their dailyRandomPercent
if( (_currentDay % 6) == 0) //will increase the merchant's base cash every 6 days
{
int multiplier = (int) Math.floor(_currentDay / 10) + 1;
addAndRefreshCash(_merchant1, multiplier * 100);
addAndRefreshCash(_merchant2, multiplier * 100);
addAndRefreshCash(_merchant3, multiplier * 100);
}
else //if not on a third day, will just refresh the merchant's cash amount
{
for(Merchant m : allMerchants)
{
m.refreshCash();
}
}
refreshTransactionLimit();
_currentDay++;
}
/**
* Will call scaleAllAdjustedPrices method on all the merchants in the array provided
*
* @param merchants The array of merchants that the method will loop through
*/
private void scaleAllMerchantPrices(Merchant[] merchants)
{
for(Merchant m : merchants)
{
m.scaleAllAdjustedPrices();
}
}
/**
* Will call addCash on the merchant provided then refreshes their cash
*
* @param targetMerchant The merchant whose base cash you want to increase
* @param increaseAmount The amount that the base cash increases by
*/
public void addAndRefreshCash (Merchant targetMerchant, int increaseAmount)
{
targetMerchant.addCash(increaseAmount);
targetMerchant.refreshCash();
}
/**
* Updates the MapUI to move characters and detect events
*
*/
public void updateMapUI() {
mapui.move();
mapui.repaint();
}
/**
* Toggles the movement on or off based on the input
* @param command either "ON" or "OFF"
*/
public void toggleMovement(String command)
{
if(command.equals("ON"))
_movement = true;
else if(command.equals("OFF"))
_movement = false;
else
System.out.println("Invalid movement toggle command");
}
/**
* Returns the player
* @return Returns the player
*/
public Player getPlayer()
{
return _player;
}
/**
* Returns a merchant based off of the input number
* @param merchantNum The number of the merchant you want
* @return Returns the merchant that you specified
*/
public Merchant getMerchant(int merchantNum)
{
if(merchantNum == 1)
return _merchant1;
else if(merchantNum == 2)
return _merchant2;
else
return _merchant3;
}
/**
* Getter for the current day number
* @return The day number
*/
public int getDay()
{
return _currentDay;
}
/**
*
* @return Movement variable
*/
public boolean getMovement()
{
return _movement;
}
/**
* Main method used to test the GUI components since test classes do not maintain the GUI
* @param args no need for input
* @throws InterruptedException
* @throws IOException
*/
public static void main(String[] args) throws InterruptedException, IOException
{
// Initialize the start screen
StartScreen startScreen = new StartScreen();
boolean ready = false;
while(ready == false)
{
System.out.println("");
ready = startScreen.getStatus();
}
int fps = 300; // Frames per second
RPGame rpgGame = new RPGame(3, 30);
// MAIN GAME LOOP
while (true) {
rpgGame.updateMapUI();
Thread.sleep(1000/fps); // Controls the speed of the game
}
}
}