Hello!! Thanks for the responses!!
I realize there’s probably better ways to go about doing this, but I only know just Java and it’ll take too long to learn OpenGL or javaFX imo to just do a little project for class. It doesn’t even have to be a totally sound program since it’s not even really for a programming class.
I was trying to get away with posting my code since it’s probably a bit of a mess haha, but I’ve hit a wall. So here is the “Board” class for my game. I’ve been tweaking it but I’m still hitting problems.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Board extends JPanel implements ActionListener {
private Timer timer;
private GameCharacter craft;
private final int DELAY = 10;
private boolean ingame;
private boolean textDisplay = false;
private boolean boxDisplay = false;
private DialogueBox box;
private ArrayList<InteractObject> candy;
private ArrayList<String> messages;
private int invisibleCount = 0;
private final int ICRAFT_X = 40;
private final int ICRAFT_Y = 60;
private final int B_WIDTH = 400;
private final int B_HEIGHT = 300;
private final int BOX_X = 40;
private final int BOX_Y = 200;
private final int TEXT_OFFSET_X = 90;
private final int TEXT_OFFSET_Y = 50;
private int msgNum = 0;
private final int[][] pos =
{
{200,150}, {10,0}, {160,35}, {250,15},
{330,120}, {325, 210}
};
private final String[] msg =
{
"Candy gotten.", "Candy obtained.", "Candy recieved.",
"Candy from a baby.", "Sweet.", "Maybe I should lay off the candy.", " "
};
public Board()
{
initBoard();
System.out.println("Board has been initialized");
}
private void initBoard()
{
box = new DialogueBox(BOX_X,BOX_Y);
box.setVisible(false);
addKeyListener(new TAdapter());
setFocusable(true);
ingame = true;
setPreferredSize(new Dimension(B_WIDTH, B_HEIGHT));
craft = new GameCharacter(ICRAFT_X, ICRAFT_Y);
initObjects();
timer = new Timer(DELAY, this);
timer.start();
}
public void initObjects()
{
candy = new ArrayList<>();
for (int[] p : pos)
{
candy.add(new InteractObject(p[0], p[1]));
}
messages = new ArrayList<>();
for(int i=0; i<msg.length; i++)
{
messages.add(msg[i]);
}
}
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
if (ingame) {
drawObjects(g);
}
else {
drawGameOver(g);
}
Toolkit.getDefaultToolkit().sync();
}
private void drawObjects(Graphics g)
{
for (InteractObject a : candy) {
if (a.isVisible()) {
g.drawImage(a.getImage(), a.getX(), a.getY(), this);
}
}
if (craft.isVisible()) {
g.drawImage(craft.getImage(), craft.getX(), craft.getY(),
this);
}
if (box.isVisible())
{
g.drawImage(box.getImage(), box.getX(), box.getY(), this);
Font small = new Font("Microsoft Jheng Hei UI", Font.BOLD, 14);
FontMetrics fm = getFontMetrics(small);
g.setColor(Color.black);
g.setFont(small);
g.drawString(messages.get(msgNum-1), box.getX() + TEXT_OFFSET_X, box.getY() + TEXT_OFFSET_Y);
}
}
private void drawGameOver(Graphics g)
{
String msg = "Thanks for playing!";
Font small = new Font("Microsoft Jheng Hei UI", Font.PLAIN, 14);
FontMetrics fm = getFontMetrics(small);
g.setColor(Color.black);
g.setFont(small);
for(int i=0; i< msg.length(); i++)
{
String s = "";
s += msg.charAt(i);
g.drawString(msg, (B_WIDTH - fm.stringWidth(msg)) / 2,
B_HEIGHT / 2);
}
}
@Override
public void actionPerformed(ActionEvent e)
{
inGame();
updateCandy();
updateCraft();
updateDialog();
checkCollisions();
repaint();
}
private void inGame()
{
if (!ingame)
{
System.out.println("Not in game");
timer.stop();
}
}
private void updateCraft()
{
if (craft.isVisible())
{
craft.move();
}
}
private void updateCandy()
{
if (candy.isEmpty())
{
ingame = false;
return;
}
for (int i = 0; i < candy.size(); i++)
{
InteractObject a = candy.get(i);
if (!a.isVisible())
{
//msgNum = i;
candy.remove(i);
messages.remove(i);
}
}
}
private void updateDialog()
{
box.setVisible(boxDisplay);
if(!craft.isEnter())
{
boxDisplay = false;
}
}
public void checkCollisions()
{
Rectangle r3 = craft.getBounds();
for (InteractObject lolly : candy)
{
Rectangle r2 = lolly.getBounds();
if (r3.intersects(r2) && craft.isEnter())
{
boxDisplay = true;
lolly.setVisible(false);
msgNum = candy.indexOf(lolly);
}
}
}
private class TAdapter extends KeyAdapter
{
@Override
public void keyReleased(KeyEvent e)
{
craft.keyReleased(e);
//box.keyPressed(e);
}
@Override
public void keyPressed(KeyEvent e)
{
craft.keyPressed(e);
}
}
}
The above code, when it works, opens up a message box when an object of the InteractObject class registers a collision and an enter press with the craft object. The box remains open as long as the player only hits enter and nothing else (not ideal, but have no clue how to keep the box open only until enter is hit again).
Trouble is, most times I get an index out of bounds error when some of the objects register a collission, and no text box popup and I’m not sure why? The message ArrayList is populated at the same time the candy ArrayList is, and they’re updated at the same time. So why is it giving me errors that it can’t find the index?
Also, does anyone have any idea how to keep the message box open until enter is hit again? I feel like I need a while loop somewhere, but I have no idea where.