Saturday, April 17, 2021

[Java Code Sample] Point and click adventure game

 

Here's the full source code for the point and click adventure game that I made.


Screenshot:




Right clicking on certain locations on the screen will open a menu.

Then you can choose a command such as "Look", "Take", "Talk" etc.



Class structure:

Resources that I used:


This is kind of a long code so please check my video tutorial for more detail.



Code:


GameManager class



package Main;

import java.net.URL;

import Event.Event01;
import Event.Event02;

public class GameManager {
	
	ActionHandler aHandler = new ActionHandler(this);
	public UI ui = new UI(this);
	public Player player = new Player(this);
	public SceneChanger sChanger = new SceneChanger(this);
	Music music = new Music();
	SE se = new SE();

	public Event01 ev1 = new Event01(this);
	public Event02 ev2 = new Event02(this);
	
	// SOUND
	public URL fieldMusic = getClass().getClassLoader().getResource("audio//bensound-acousticbreeze.wav");
	public URL fieldMusic2 = getClass().getClassLoader().getResource("audio//bensound-ofeliasdream.wav");
	public URL deathSound = getClass().getClassLoader().getResource("audio//deathSound.wav");
	public URL hitSound = getClass().getClassLoader().getResource("audio//hitSound.wav");
	public URL healSound = getClass().getClassLoader().getResource("audio//healSound.wav");
	public URL itemSound = getClass().getClassLoader().getResource("audio//itemSound.wav");
	public URL enterSound = getClass().getClassLoader().getResource("audio//enterSound.wav");
	public URL guard_01 = getClass().getClassLoader().getResource("audio//guard_01.wav");
	public URL guard_02 = getClass().getClassLoader().getResource("audio//guard_02.wav");
	public URL guard_03 = getClass().getClassLoader().getResource("audio//guard_03.wav");
	public URL guard_04 = getClass().getClassLoader().getResource("audio//guard_04.wav");
	public URL currentMusic;

	public static void main(String[] args) {
		
		new GameManager();

	}
	public GameManager() {
		
		currentMusic = fieldMusic;
		playMusic(currentMusic);
		
		player.setPlayerDefaultStatus();
		sChanger.showSceen1();
	}
	
	public void playSE(URL url) {
		
		se.setFile(url);
		se.play(url);
	}
	public void playMusic(URL url) {
		
		music.setFile(url);
		music.play(url);
		music.loop(url);		
	}
	public void stopMusic(URL url) {
		
		music.stop(url);
	}
}


UI class



package Main;

import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

public class UI {

	GameManager gm;
	
	JFrame window;
	public JTextArea messageText;
	public JPanel bgPanel[] = new JPanel[10];
	public JLabel bgLabel[] = new JLabel[10];
	
	// PLAYER UI
	JPanel lifePanel;
	JLabel lifeLabel[] = new JLabel[6];
	JPanel inventoryPanel;
	public JLabel swordLabel, shieldLabel, lanternLabel;
	
	// GAME OVER UI
	public JLabel titleLabel;
	public JButton restartButton;
	
	
	public UI(GameManager gm) {
		
		this.gm = gm;
		
		createMainField();
		createPlayerField();
		createGameOverField();
		generateScene();
		
		window.setVisible(true);
	}
	
	public void createMainField() {
		
		window = new JFrame("AWESOME QUEST III");
		window.setSize(800,600);
		window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		window.getContentPane().setBackground(Color.black);
		window.setLayout(null);
		
		messageText = new JTextArea("THIS IS SMAPLE TEXT");
		messageText.setBounds(50,410,700,150);
		messageText.setBackground(Color.black);
		messageText.setForeground(Color.white);
		messageText.setEditable(false);
		messageText.setLineWrap(true);
		messageText.setWrapStyleWord(true);
		messageText.setFont(new Font("Book Antiqua", Font.PLAIN, 26));
		window.add(messageText);
	}
	public void createBackground(int bgNum, String bgFileName) {
		
		bgPanel[bgNum] = new JPanel();
		bgPanel[bgNum].setBounds(50,50,700,350);
		bgPanel[bgNum].setBackground(Color.black);
		bgPanel[bgNum].setLayout(null);
		bgPanel[bgNum].setVisible(false); 
		window.add(bgPanel[bgNum]);
		
		bgLabel[bgNum] = new JLabel();
		bgLabel[bgNum].setBounds(0,0,700,350);
		
		ImageIcon bgIcon = new ImageIcon(getClass().getClassLoader().getResource(bgFileName));
		bgLabel[bgNum].setIcon(bgIcon);				
	}
	public void createObject(int bgNum, int objx, int objy, int objWidth, int objHeight, String objFileName, 
			String choice1Name, String choice2Name, String choice3Name, String choice1Command, String Choice2Command, String Choice3Command) {
		
		// CREATE POP MENU
		JPopupMenu popMenu = new JPopupMenu();
		// CREATE POP MENU ITEMS
		JMenuItem menuItem[] = new JMenuItem[4]; // Use [1],[2],[3]
		menuItem[1] = new JMenuItem(choice1Name);
		menuItem[1].addActionListener(gm.aHandler);
		menuItem[1].setActionCommand(choice1Command);
		popMenu.add(menuItem[1]);
		
		menuItem[2] = new JMenuItem(choice2Name);
		menuItem[2].addActionListener(gm.aHandler);
		menuItem[2].setActionCommand(Choice2Command);
		popMenu.add(menuItem[2]);
		
		menuItem[3] = new JMenuItem(choice3Name);
		menuItem[3].addActionListener(gm.aHandler);
		menuItem[3].setActionCommand(Choice3Command);
		popMenu.add(menuItem[3]);
		
		// CREATE OBJECTS
		JLabel objectLabel = new JLabel();
		objectLabel.setBounds(objx,objy,objWidth,objHeight);
//		objectLabel.setOpaque(true);
//		objectLabel.setBackground(Color.blue);
		
		ImageIcon objectIcon = new ImageIcon(getClass().getClassLoader().getResource(objFileName));
		objectLabel.setIcon(objectIcon);
		
		objectLabel.addMouseListener(new MouseListener() {

			public void mouseClicked(MouseEvent e) {}
			public void mousePressed(MouseEvent e) {
				
				if(SwingUtilities.isRightMouseButton(e)) {
					popMenu.show(objectLabel, e.getX(), e.getY());
				}
				
			}
			public void mouseReleased(MouseEvent e) {}
			public void mouseEntered(MouseEvent e) {}
			public void mouseExited(MouseEvent e) {}
			
		});
		
		
		bgPanel[bgNum].add(objectLabel);
		
		
	}
	public void createArrowButton(int bgNum, int x, int y, int width, int height, String arrowFileName, String command) {
		
		ImageIcon arrowIcon = new ImageIcon(getClass().getClassLoader().getResource(arrowFileName));
		
		JButton arrowButton = new JButton();
		arrowButton.setBounds(x, y, width, height);
		arrowButton.setBackground(null);
		arrowButton.setContentAreaFilled(false);
		arrowButton.setFocusPainted(false);
		arrowButton.setIcon(arrowIcon);
		arrowButton.addActionListener(gm.aHandler);
		arrowButton.setActionCommand(command);
		arrowButton.setBorderPainted(false);
		
		bgPanel[bgNum].add(arrowButton);
	}
	public void createPlayerField() {
		
		lifePanel = new JPanel();
		lifePanel.setBounds(50,0,250,50);
		lifePanel.setBackground(Color.black);
		lifePanel.setLayout(new GridLayout(1,5));
		window.add(lifePanel);
		
		ImageIcon lifeIcon = new ImageIcon(getClass().getClassLoader().getResource("heart.png"));
		Image image = lifeIcon.getImage().getScaledInstance(35, 35, Image.SCALE_DEFAULT);
		lifeIcon = new ImageIcon(image);
		
		int i=1;
		while(i<6) {
			lifeLabel[i] = new JLabel();
			lifeLabel[i].setIcon(lifeIcon);
			lifePanel.add(lifeLabel[i]);
			i++;
		}
		
		inventoryPanel = new JPanel();
		inventoryPanel.setBounds(650,0,100,50);
		inventoryPanel.setBackground(Color.black);
		inventoryPanel.setLayout(new GridLayout(1,3));
		window.add(inventoryPanel);
		
		// CREATE  ITEMS
		swordLabel = new JLabel();
		ImageIcon swordIcon = new ImageIcon(getClass().getClassLoader().getResource("plain-dagger.png"));
		image = swordIcon.getImage().getScaledInstance(35, 35, Image.SCALE_DEFAULT);
		swordIcon = new ImageIcon(image);
		swordLabel.setIcon(swordIcon);
		inventoryPanel.add(swordLabel);
		
		shieldLabel = new JLabel();
		ImageIcon shieldIcon = new ImageIcon(getClass().getClassLoader().getResource("dragon-shield.png"));
		image = shieldIcon.getImage().getScaledInstance(35, 35, Image.SCALE_DEFAULT);
		shieldIcon = new ImageIcon(image);
		shieldLabel.setIcon(shieldIcon);
		inventoryPanel.add(shieldLabel);
		
		lanternLabel = new JLabel();
		ImageIcon lanternIcon = new ImageIcon(getClass().getClassLoader().getResource("lanternflame.png"));
		image = lanternIcon.getImage().getScaledInstance(35, 35, Image.SCALE_DEFAULT);
		lanternIcon = new ImageIcon(image);
		lanternLabel.setIcon(lanternIcon);
		inventoryPanel.add(lanternLabel);
		
	}
	public void createGameOverField() {
		
		titleLabel = new JLabel("",JLabel.CENTER);
		titleLabel.setBounds(200,150,400,200);
		titleLabel.setForeground(Color.red);
		titleLabel.setFont(new Font("Times New Roman", Font.PLAIN, 70));
		titleLabel.setVisible(false);
		window.add(titleLabel);
		
		restartButton = new JButton();
		restartButton.setBounds(340,320,120,50);
		restartButton.setBorder(null);
		restartButton.setBackground(null);
		restartButton.setForeground(Color.white);
		restartButton.setFocusPainted(false);
		restartButton.addActionListener(gm.aHandler);
		restartButton.setActionCommand("restart");
		restartButton.setVisible(false);
		window.add(restartButton);
	}
	
	public void generateScene() {
		
		// SCENE 1
		createBackground(1,"greenbg700x350.png");
		createObject(1,440,140,200,200,"hut 200x200.png", "Look", "Talk", "Rest", "lookHut", "talkHut", "restHut");
		createObject(1,70,180,150,150,"guard 150x150.png", "Look", "Talk", "Attack", "lookGuard", "talkGuard", "attackGuard");
		createObject(1,310,280,70,70,"chest 70x70.png", "Look", "Talk", "Open", "lookChest", "talkChest", "openChest");
		createArrowButton(1,0,150,50,50,"leftarrow 50x50.png","goScene2");
		bgPanel[1].add(bgLabel[1]);
		
		// SCENE 2
		createBackground(2,"caveoutside 700x350.jpg");
		createObject(2,0,100,100,300,"blank100x100.png", "Look", "Talk", "Enter", "lookCave", "talkCave", "enterCave");
		createObject(2,355,250,50,50,"blank100x100.png", "Look", "Talk", "Search", "lookRoot", "talkRoot", "searchRoot");
		createArrowButton(2,650,150,50,50,"rightarrow 50x50.png","goScene1");
		bgPanel[2].add(bgLabel[2]);
		
		// SCENE 3
		createBackground(3,"cave 700x350.png");
		createArrowButton(3,650,150,50,50,"rightarrow 50x50.png","goScene2");
		bgPanel[3].add(bgLabel[3]);
	}
}



SceneChanger class



package Main;

public class SceneChanger {
	
	GameManager gm;

	public SceneChanger(GameManager gm) {
		
		this.gm = gm;
	}
	
	public void showSceen1() {
		
		gm.ui.bgPanel[1].setVisible(true);
		gm.ui.bgPanel[2].setVisible(false);	
		gm.ui.messageText.setText("Let's defeat the Demon Lord and save the world!");
		
		gm.stopMusic(gm.currentMusic);
		gm.currentMusic = gm.fieldMusic;
		gm.playMusic(gm.currentMusic);
	}
	public void showSceen2() {
		
		gm.ui.bgPanel[1].setVisible(false);
		gm.ui.bgPanel[2].setVisible(true);	
		gm.ui.bgPanel[3].setVisible(false);
		gm.ui.messageText.setText("");
		
		gm.stopMusic(gm.currentMusic);
		gm.currentMusic = gm.fieldMusic2;
		gm.playMusic(gm.currentMusic);
	}
	public void showSceen3() {
		
		gm.playSE(gm.enterSound);
		gm.ui.bgPanel[2].setVisible(false);
		gm.ui.bgPanel[3].setVisible(true);	
		gm.ui.messageText.setText("You enter the cave. What is waiting for you inside...\n\n"
				+ "*** This is the end of the demo. Thank you for playing!!! ***");
	}
	public void showGameOverScreen(int currentBgNum) {
		
		gm.ui.bgPanel[currentBgNum].setVisible(false);
		gm.ui.titleLabel.setVisible(true);
		gm.ui.titleLabel.setText("YOU DIED");
		gm.ui.restartButton.setVisible(true);
		gm.ui.restartButton.setText("Click here to restart");
		
		gm.stopMusic(gm.currentMusic);
		gm.playSE(gm.deathSound);
	}
	public void existGameOverScreen() {
		
		gm.ui.titleLabel.setVisible(false);
		gm.ui.restartButton.setVisible(false);
		gm.player.setPlayerDefaultStatus();
	}
}



ActionHandler class



package Main;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class ActionHandler implements ActionListener{
	
	GameManager gm;

	public ActionHandler(GameManager gm) {
		
		this.gm = gm;
	}
	
	
	@Override
	public void actionPerformed(ActionEvent e) {
		
		String yourChoice = e.getActionCommand();
		
		switch(yourChoice) {
		// SCENE 1
		case "lookHut": gm.ev1.lookHut(); break;
		case "talkHut": gm.ev1.talkHut(); break;
		case "restHut": gm.ev1.restHut(); break;
		case "lookGuard": gm.ev1.lookGuard(); break;
		case "talkGuard": gm.ev1.talkGuard(); break;
		case "attackGuard": gm.ev1.attackGuard(); break;
		case "lookChest": gm.ev1.lookChest(); break;
		case "talkChest": gm.ev1.talkChest(); break;
		case "openChest": gm.ev1.openChest(); break;
		// SCENE 2
		case "lookCave": gm.ev2.lookCave();break;
		case "talkCave": gm.ev2.talkCave();break;
		case "enterCave": gm.ev2.enterCave();break;
		case "lookRoot": gm.ev2.lookRoot();break;
		case "talkRoot": gm.ev2.talkRoot();break;
		case "searchRoot": gm.ev2.searchRoot();break;
 		// Change Scenes
		case "goScene1": gm.sChanger.showSceen1(); break;
		case "goScene2": gm.sChanger.showSceen2(); break;
		// OTHERS
		case "restart": gm.sChanger.existGameOverScreen(); gm.sChanger.showSceen1(); break;
		}
	}

}



Player class



package Main;

public class Player {
	
	GameManager gm;
	
	public int playerMaxLife;
	public int playerLife;
	
	public int hasSword;
	public int hasShield;
	public int hasLantern;
	
	public Player(GameManager gm) {
		
		this.gm = gm;
	}
	
	public void setPlayerDefaultStatus() {
		
		playerMaxLife = 5;
		playerLife = 3;
		hasSword = 0;
		hasShield = 0;
		hasLantern = 0;
		
		updatePlayerStatus();
	}
	public void updatePlayerStatus() {
		
		// REMOVE ALL LIFE ICON
		int i =1;
		while(i<6) {
			gm.ui.lifeLabel[i].setVisible(false);
			i++;
		}
		
		int lifeCount = playerLife;
		while(lifeCount!=0) {
			gm.ui.lifeLabel[lifeCount].setVisible(true);
			lifeCount--;
		}
		
		// CHECK PLAYER ITEMS
		if(hasSword==0) {
			gm.ui.swordLabel.setVisible(false);
		}
		if(hasSword==1) {
			gm.ui.swordLabel.setVisible(true);
		}
		if(hasShield==0) {
			gm.ui.shieldLabel.setVisible(false);
		}
		if(hasShield==1) {
			gm.ui.shieldLabel.setVisible(true);
		}
		if(hasLantern==0) {
			gm.ui.lanternLabel.setVisible(false);
		}
		if(hasLantern==1) {
			gm.ui.lanternLabel.setVisible(true);
		}
	}

}



SE class



package Main;

import java.net.URL;

import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;

public class SE {
	
	Clip clip;
	
	public void setFile(URL name) {
		
		try {
			AudioInputStream sound = AudioSystem.getAudioInputStream(name);
			clip = AudioSystem.getClip();
			clip.open(sound);
		}
		catch(Exception e) {
			
		}
	}
	
	public void play(URL name) {
		
		clip.setFramePosition(0);
		clip.start();
	}
	
	public void loop(URL name) {
		
		clip.loop(Clip.LOOP_CONTINUOUSLY);
	}
	public void stop(URL name) {
		
		clip.stop();
	}
}



Music



package Main;

import java.net.URL;

import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;

public class Music {

	Clip clip;
	
	public void setFile(URL name) {
		
		try {
			AudioInputStream sound = AudioSystem.getAudioInputStream(name);
			clip = AudioSystem.getClip();
			clip.open(sound);
		}
		catch(Exception e) {
			
		}
	}
	
	public void play(URL name) {
		
		clip.setFramePosition(0);
		clip.start();
	}
	
	public void loop(URL name) {
		
		clip.loop(Clip.LOOP_CONTINUOUSLY);
	}
	public void stop(URL name) {
		
		clip.stop();
	}
}



Event01



package Event;

import Main.GameManager;

public class Event01 {
	
	GameManager gm;
	
	public Event01(GameManager gm) {
		
		this.gm = gm;
	}
	
	public void lookHut() {
		gm.ui.messageText.setText("This is your house."); 
	}
	public void talkHut() {
		gm.ui.messageText.setText("Who are you talking to?");
	}
	public void restHut() {
		
		if(gm.player.playerLife != gm.player.playerMaxLife) {
			gm.ui.messageText.setText("You rest at the house.\n(Your life has recovered)");	
			gm.player.playerLife++;
			gm.player.updatePlayerStatus();
			gm.playSE(gm.healSound);
		}
		else {
			gm.ui.messageText.setText("Your life is full.");
		}
			
	}
	public void lookGuard() {
		gm.ui.messageText.setText("A guard is standing in front of you.");		
	}
	public void talkGuard() {
		gm.ui.messageText.setText("Guard: Don't go any further without a weapon!\nYou should check the chest over there!");	
		gm.playSE(gm.guard_01);
	}
	public void attackGuard() {
		if(gm.player.hasShield==0) {
			if(gm.player.hasSword==0) {
				if(gm.player.playerLife!=1) {
					gm.ui.messageText.setText("Guard: Hey, don't be stupid!\n(The guard hits you back and your life decreases by 1)");
					gm.player.playerLife--;
					
					gm.playSE(gm.guard_02);
					gm.playSE(gm.hitSound);
				}
				else if(gm.player.playerLife==1) {
					gm.ui.messageText.setText("Guard: What a fool.");
					gm.player.playerLife--;
					gm.sChanger.showGameOverScreen(1);
				}
			}
			else if(gm.player.hasSword==1) {
				gm.ui.messageText.setText("Guard: Oh, shit! \n(You have defeated the guard and gotten his shield!)");
				gm.player.hasShield=1;	
				
				gm.playSE(gm.guard_03);
				gm.playSE(gm.hitSound);
			}
			gm.player.updatePlayerStatus();
		}
		else {
			gm.ui.messageText.setText("Guard: Just leave me alone.");
			gm.playSE(gm.guard_04);
		}
			
	}
	public void lookChest() {
		gm.ui.messageText.setText("A chest is on the ground.");		
	}
	public void talkChest() {
		gm.ui.messageText.setText("You talk to the chest but it says nothing.");		
	}
	public void openChest() {
		if(gm.player.hasSword==0) {
			gm.ui.messageText.setText("You open the chest and find a sword!");	
			gm.player.hasSword=1;
			gm.player.updatePlayerStatus();
			gm.playSE(gm.itemSound);
		}
		else {
			gm.ui.messageText.setText("There's nothing inside...");	
		}
			
	}

}


Event02


package Event;

import Main.GameManager;

public class Event02 {

	public GameManager gm;
	
	public Event02(GameManager gm) {
		
		this.gm = gm;
	}
	
	public void lookCave() {
		gm.ui.messageText.setText("It's a cave!");
	}
	public void talkCave() {
		gm.ui.messageText.setText("You hear the echo of your voice.");
	}
	public void enterCave() {
		if(gm.player.hasLantern==0) {
			gm.ui.messageText.setText("It's too dark to enter.");
		}
		else {
			gm.sChanger.showSceen3();
		}		
	}
	public void lookRoot() {
		gm.ui.messageText.setText("This is a large tree.");
	}
	public void talkRoot() {
		gm.ui.messageText.setText("They say plant grows well if you talk to but this tree doesn't look like it needs encouragement.");
	}
	public void searchRoot() {
		if(gm.player.hasLantern==0) {
			gm.ui.messageText.setText("You find a lantern!");
			gm.player.hasLantern = 1;
			gm.player.updatePlayerStatus();
			gm.playSE(gm.itemSound);
		}
		else {
			gm.ui.messageText.setText("You didn't find anythng.");
		}
		
	}
}




No comments:

Post a Comment