Despite I import the applet library, NetBeans cannot recognize and use getDocumentBase() in my code, I have my html file within my project and all other required files as well, here is a part of my code :
import java.awt.*;
import java.applet.*;
public class AirportCanvas extends Canvas
{
SingleLaneAirport controller;
Image redPlane;
Image bluePlane;
Image airport;
//AudioClip crashSound;
int[] redX,redY,blueX,blueY;
int maxCar = 2;
final static int initredX = 5;
final static int initredY = 55;
final static int initblueX = 410;
final static int initblueY = 130;
final static int bridgeY = 90;
boolean frozen = false;
int cycleTime = 20;
AirportCanvas(SingleLaneAirport controller)
{
super();
this.controller = controller;
// crashSound=controller.getAudioClip(controller.getDocumentBase(),"crash.au");
MediaTracker mt;
mt = new MediaTracker(this);
redPlane = controller.getImage(controller.getDocumentBase(), "redplane.png");
mt.addImage(redPlane, 0);
bluePlane = controller.getImage(controller.getDocumentBase(), "blueplane.png");
mt.addImage(bluePlane, 1);
airport = controller.getImage(controller.getDocumentBase(), "airport.png");
mt.addImage(airport, 2);
try
{
mt.waitForID(0);
mt.waitForID(1);
mt.waitForID(2);
}
catch (java.lang.InterruptedException e)
{
System.out.println("Couldn't load one of the images");
}
setSize(airport.getWidth(null),airport.getHeight(null));
init(1);
}
public final void init(int ncars)
{ //set number of cars
maxCar = ncars;
frozen = false;
redX = new int[maxCar];
redY = new int[maxCar];
blueX = new int[maxCar];
blueY = new int[maxCar];
for (int i = 0; i<maxCar ; i++)
{
redX[i] = initredX - i*85;
redY[i] = initredY;
blueX[i] =initblueX + i*85;
blueY[i] =initblueY;
}
repaint();
}
Image offscreen;
Dimension offscreensize;
Graphics offgraphics;
public void backdrop()
{
Dimension d = getSize();
if ((offscreen == null) || (d.width != offscreensize.width)
|| (d.height != offscreensize.height))
{
offscreen = createImage(d.width, d.height);
offscreensize = d;
offgraphics = offscreen.getGraphics();
offgraphics.setFont(new Font("Helvetica",Font.BOLD,36));
}
offgraphics.setColor(Color.lightGray);
offgraphics.drawImage(airport,0,0,this);
}
#Override
public void paint(Graphics g)
{
update(g);
}
#Override
public void update(Graphics g)
{
backdrop();
for (int i=0; i<maxCar; i++)
{
offgraphics.drawImage(redPlane,redX[i],redY[i],this);
offgraphics.drawImage(bluePlane,blueX[i],blueY[i],this);
}
if (blueY[0]==redY[0] && Math.abs(redX[0]+80 - blueX[0])<5)
{
offgraphics.setColor(Color.red);
offgraphics.drawString("Crunch!",200,100);
frozen=true;
// crashSound.play();
}
g.drawImage(offscreen, 0, 0, null);
}
//returns true for the period from just before until just after car on bridge
public boolean moveRed(int i) throws InterruptedException
{
int X = redX[i];
int Y = redY[i];
synchronized (this)
{
while (frozen )
wait();
if (i==0 || Math.abs(redX[i-1] - X) > 120)
{
X += 2;
if (X >=500)
{
X = -80; Y = initredY;
}
if (X >=60 && X < 290 && Y<bridgeY)
++Y;
if (X >=290 && Y>initredY)
--Y;
}
redX[i]=X;
redY[i]=Y;
repaint();
}
Thread.sleep(cycleTime);
return (X>25 && X<400);
}
//returns true for the period from just before until just after car on bridge
public boolean moveBlue(int i) throws InterruptedException
{
int X = blueX[i];
int Y = blueY[i];
synchronized (this)
{
while (frozen )
wait();
if (i==0 || Math.abs(blueX[i-1] - X) > 120)
{
X -= 2;
if (X <=-80)
{
X = 500; Y = initblueY;
}
if (X <=370 && X > 130 && Y>bridgeY)
--Y;
if (X <=130 && Y<initblueY)
++Y;
blueX[i]=X;
}
blueY[i]=Y;
repaint();
}
Thread.sleep(cycleTime);
repaint();
return (X>25 && X<400);
}
public synchronized void freeze()
{
frozen = true;
}
public synchronized void thaw()
{
frozen = false;
notifyAll();
}
}
Single Lane Airport Class :
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class SingleLaneAirport {
AirportCanvas display;
Button restart;
Button freeze;
Button onecar;
Button twocar;
Button threecar;
Checkbox fair;
Checkbox safe;
boolean fixed = false;
int maxCar = 1;
Thread red[];
Thread blue[];
#Override
public void init()
{
setLayout(new BorderLayout());
display = new AirportCanvas(this);
add("Center",display);
restart = new Button("Restart");
restart.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
display.thaw();
}
});
freeze = new Button("Freeze");
freeze.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
display.freeze();
}
});
onecar = new Button("One Car");
onecar.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
stop();
maxCar = 1;
start();
}
});
twocar = new Button("Two Cars");
twocar.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
stop();
maxCar = 2;
start();
}
});
threecar = new Button("Three Cars");
threecar.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
stop();
maxCar = 3;
start();
}
});
safe = new Checkbox("Safe",null,true);
safe.setBackground(Color.lightGray);
safe.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent e)
{
stop();
start();
}
});
fair = new Checkbox("Fair",null,false);
fair.setBackground(Color.lightGray);
fair.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent e)
{
stop();
start();
}
});
Panel p1 = new Panel();
p1.setLayout(new FlowLayout());
p1.add(freeze);
p1.add(restart);
p1.add(onecar);
p1.add(twocar);
p1.add(threecar);
p1.add(safe);
p1.add(fair);
add("South",p1);
setBackground(Color.lightGray);
}
#Override
public void start()
{
red = new Thread[maxCar];
blue = new Thread[maxCar];
display.init(maxCar);
Airport b;
if (fair.getState() && safe.getState())
b = new FairAirport();
else if ( safe.getState())
b = new SafeAirport();
else
b = new Airport();
for (int i = 0; i<maxCar; i++)
{
red[i] = new Thread(new RedPlane(b,display,i));
blue[i] = new Thread(new BluePlane(b,display,i));
}
for (int i = 0; i<maxCar; i++)
{
red[i].start();
blue[i].start();
}
}
#Override
public void stop()
{
for (int i = 0; i<maxCar; i++)
{
red[i].interrupt();
blue[i].interrupt();
}
}
}
Your class SingleLaneAirport should extend Applet class in order to use getDocumentBase() function.
Because getDocumentBase() is the function of Applet class and not the Object class
Related
noob here trying to make a simple snake game. followed along with tutorial on youtube and my code mayches the working code as best i can tell...snake not responding to commands, seems KeyListener not working. printed out requestFocusInWindow in jpanel constructor to make sure it was in focus and got back false, even though i entered setFocusable(true) asfirst arg in panel constructor.
please help me figure out why snake not responding to movement commands
package otherSnake;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JPanel;
public class Panel extends JPanel implements Runnable {
public static final int width = 800, height = 800;
private boolean running = false;
private Thread thread;
private Bodypart b;
private ArrayList<Bodypart> snake;
private Apple apple;
private ArrayList<Apple> apples;
private Random r;
private int size = 5;
private int x = 10, y = 10;
private boolean right = true, left = false, up = false, down = false;
private int ticks = 0;
private Key key;
public Panel() {
setFocusable(true);
key = new Key();
addKeyListener(key);
setPreferredSize(new Dimension(width, height));
r = new Random();
snake = new ArrayList<Bodypart>();
apples = new ArrayList<Apple>();
start();
}
public void tick() {
if (snake.size() == 0) {
b = new Bodypart(x, y, 10);
snake.add(b);
}
if (apples.size() == 0) {
int xCord = r.nextInt(79);
int yCord = r.nextInt(79);
apple = new Apple(xCord, yCord, 10);
apples.add(apple);
}
ticks++;
if (ticks > 250000) {
if (right)
x++;
if (left)
x--;
if (up)
y--;
if (down)
y++;
ticks = 0;
b = new Bodypart(x, y, 10);
snake.add(b);
if (snake.size() > size) {
snake.remove(0);
}
}
}
public void paint(Graphics g) {
g.clearRect(0, 0, width, height);
g.setColor(Color.BLACK);
for (int i = 0; i < width / 10; i++) {
g.drawLine(i * 10, 0, i * 10, height);
}
for (int i = 0; i < height / 10; i++) {
g.drawLine(0, i * 10, width, i * 10);
}
for (int i = 0; i < snake.size(); i++) {
snake.get(i).draw(g);
}
for (int i = 0; i < apples.size(); i++) {
apples.get(i).draw(g);
}
}
public void start() {
running = true;
thread = new Thread(this, "Game Loop");
thread.start();
}
public void stop() {
running = false;
try {
thread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void run() {
while (running) {
tick();
repaint();
}
}
private class Key implements KeyListener {
#Override
public void keyTyped(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_RIGHT ) {
up = false;
down = false;
right = true;
//left=false;
}
if (key == KeyEvent.VK_LEFT ) {
up = false;
down = false;
left = true;
//right=false;
}
if (key == KeyEvent.VK_UP ) {
up = true;
down = false;
left = false;
right = false;
}
if (key == KeyEvent.VK_DOWN ) {
up = false;
down = true;
left = false;
right = false;
}
}
#Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
}
}
In my code I have the following statements inside my Mouse Listener
class CustomMouseListener extends MouseAdapter {
Menu m;
MenuDesign mD;
SlideInLayout s;
public CustomMouseListener(Menu m, MenuDesign mD, SlideInLayout s) {
this.m = m;
this.mD = mD;
this.s = s;
}
public void mousePressed(MouseEvent mE) {
if(m != null && mD != null) {
if(mE.getSource() == mD) {
if(mD.getInOut()) {
mD.setFade(false);
Thread runSwap = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
s.show(m.getFirstPanel());
}
});
runSwap.start();
try {
runSwap.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
mD.setFade(true);
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
s.show(m.getOverlay());
}
}).start();
}
mD.fade();
m.getMainWindow().validate();
m.getMainWindow().repaint();
}
}
}
}
Ideally I would like my runnable animation to run at the same time as mD.fade(); so to do this I would write
Thread runSwap = new Thread(new Runnable() {
public void run() {
s.show(m.getFirstPanel());
}
});
instead of this.
Thread runSwap = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
s.show(m.getFirstPanel());
}
});
However this causes the end result of the animation to happen instantly. The other problem is that when I need to repaint the screen at the end as it ends up like the first frame in the picture below instead of the second frame however using the repaint() and validate() methods causes the animation in the runnable not to happen and the end result just appears again, even after a .join() is used with the thread.
I would appreciate any help in fixing the problem
Full Code if needed
package menutest;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
public class Menu {
JFrame myMainWindow = new JFrame("Menu Slide Test");
GridBagConstraints c;
MyFirstPanel fP;
MyOverlay oL;
MyMenuButton mB;
GridBagLayout baseLayout;
GridBagLayout overlayLayout;
SlideInLayout slideIn = new SlideInLayout();
JPanel tempHold = new JPanel(slideIn);
/* Height and Width */
int height = 600;
int width = 600;
private void runGUI(Menu m) {
myMainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myMainWindow.setLayout(new GridBagLayout());
setContraints();
createPanels(m);
myMainWindow.getContentPane().add(tempHold, c);
myMainWindow.getContentPane().add(mB, c, 0);
slideIn.show(fP);
myMainWindow.pack();
myMainWindow.setVisible(true);
myMainWindow.setLocationRelativeTo(null);
}
private void setContraints() {
c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
c.weightx = 1;
c.weighty = 1;
c.fill = GridBagConstraints.BOTH;
}
private void createPanels(Menu m) {
createFirstPanel(m);
createOverlay(m);
createMenuButton(m);
tempHold.add(fP);
tempHold.add(oL);
}
private void createFirstPanel(Menu m) {
baseLayout = new GridBagLayout();
fP = new MyFirstPanel(baseLayout, m);
}
private void createOverlay(Menu m) {
overlayLayout = new GridBagLayout();
oL = new MyOverlay(overlayLayout, m);
}
private void createMenuButton(Menu m) {
mB = new MyMenuButton(m);
}
public static void main(String[] args) {
Menu menu = new Menu();
menu.runGUI(menu);
}
/* Getters and Setters */
public JPanel getFirstPanel() {
return fP;
}
public JPanel getOverlay() {
return oL;
}
public JFrame getMainWindow() {
return myMainWindow;
}
public int myGetHeight() {
return height;
}
public int myGetWidth() {
return width;
}
public SlideInLayout getSlide() {
return slideIn;
}
}
class MyFirstPanel extends JPanel {
/**
*
*/
private static final long serialVersionUID = 2897488186622284953L;
MyFirstPanel(GridBagLayout layout, Menu mM) {
setLayout(layout);
setBackground(Color.RED);
setPreferredSize(new Dimension(mM.myGetWidth(), mM.myGetHeight()));
}
}
class MyOverlay extends JPanel {
/**
*
*/
private static final long serialVersionUID = 4595122972358754430L;
MyOverlay(GridBagLayout layout, Menu mM) {
setLayout(layout);
setBackground(Color.GREEN);
setPreferredSize(new Dimension(mM.myGetWidth(), mM.myGetHeight()));
}
}
class MyMenuButton extends JPanel {
/**
*
*/
private static final long serialVersionUID = -4986432081497113479L;
MyMenuButton(Menu mM) {
setLayout(null);
setBackground(new Color(0, 0, 0, 0));
setPreferredSize(new Dimension(mM.myGetWidth(), mM.myGetHeight()));
add(new MenuDesign(15, 15, mM, mM.myGetWidth()));
}
}
class MenuDesign extends JLabel {
/**
*
*/
private static final long serialVersionUID = 2255075501909089222L;
boolean inOut = false; //true for fade out, false for fade in
//starts on false because it changes to true on first click on label
float alpha = 1F;
Timer timer;
//Start Points
double[] r1Points = {0, 6.67766953};
double[] r2Points = {0, 16.67766953};
double[] r3Points = {0, 26.67766953};
//Current Points
double[] curR1Points = {r1Points[0], r1Points[1]};
double[] curR3Points = {r3Points[0], r3Points[1]};
//End Points
double[] endR1Points = {2.828427125, 0};
double[] endR3Points = {0, 35.35533906};
//Angles
double ang1 = 0;
double ang2 = 0;
//Height and width of component to make it as efficient as possible
int width = 50;
int height = 40;
MenuDesign(int x, int y, Menu m, int width) {
setBounds(x, y, this.width, height);
setCursor(new Cursor(Cursor.HAND_CURSOR));
addMouseListener(new CustomMouseListener(m, this, m.getSlide()));
timer = new Timer(5, new CustomActionListener(m, this, r1Points, r3Points, endR1Points, endR3Points, x, width - 60));
}
public void fade() {
timer.start();
System.out.println("Start");
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setColor(Color.WHITE);
Rectangle2D r1 = new Rectangle2D.Double(curR1Points[0], curR1Points[1], width, 4);
Rectangle2D r2 = new Rectangle2D.Double(r2Points[0], r2Points[1], width, 4);
Rectangle2D r3 = new Rectangle2D.Double(curR3Points[0], curR3Points[1], width, 4);
//r1
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1F));
g2d.rotate(Math.toRadians(ang1), endR1Points[0], endR1Points[1]);
g2d.fill(r1);
//r3
g2d.rotate(Math.toRadians(-ang1), endR1Points[0], endR1Points[1]);
g2d.rotate(Math.toRadians(-ang2), endR3Points[0], endR3Points[1]);
g2d.fill(r3);
//r2
g2d.rotate(Math.toRadians(ang2), endR3Points[0], endR3Points[1]);
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
g2d.fill(r2);
}
public Timer getTimer() {
return timer;
}
public float getAlpha() {
return alpha;
}
public void setAplha(float a) {
this.alpha = a;
if(a < 0) {
setAplha(0F);
}
if(a > 1) {
setAplha(1F);
}
validate();
repaint();
}
public boolean getInOut() {
return inOut;
}
public void setFade(boolean b) {
this.inOut = b;
}
public double[] getTransR1() {
return curR1Points;
}
public double[] getTransR3() {
return curR3Points;
}
public void setTransR1(double[] d) {
this.curR1Points = d;
}
public void setTransR3(double[] d) {
this.curR3Points = d;
}
public void setAng1(double d) {
this.ang1 = d;
}
public void setAng2(double d) {
this.ang2 = d;
}
public void stopTheTimer(int i) {
if(i == 101) {
timer.stop();
System.out.println("stop");
}
}
}
class CustomActionListener implements ActionListener {
Menu m;
MenuDesign mD;
MyFirstPanel mFP;
double[] a, b, c, d;
double incrementX1;
double incrementY1;
double incrementX2;
double incrementY2;
double incrementX3;
double incrementY3;
double incrementX4;
double incrementY4;
double angInc = 45.0 / 100.0;
double moveInc;
int i = 0;
int startPoint;
public CustomActionListener(Menu m, MyFirstPanel mFP) {
this.m = m;
this.mFP = mFP;
}
public CustomActionListener(Menu m, MenuDesign mD, double[] a, double[] b, double[] c, double[] d, int startPoint, int endPoint) {
this.m = m;
this.mD = mD;
this.a = a;
this.b = b;
this.c = c;
this.d = d;
this.startPoint = startPoint;
//Increments
int incTot = 100;
//r1 increments
incrementX1 = (c[0] - a[0]) / incTot;
incrementY1 = (c[1] - a[1]) / incTot;
incrementX2 = (a[0] - c[0]) / incTot;
incrementY2 = (a[1] - c[1]) / incTot;
//r2 increments
incrementX3 = (d[0] - b[0]) / incTot;
incrementY3 = (d[1] - b[1]) / incTot;
incrementX4 = (b[0] - d[0]) / incTot;
incrementY4 = (b[1] - d[1]) / incTot;
//Movement
moveInc = (endPoint - startPoint) / incTot;
}
public void actionPerformed(ActionEvent e) {
if(m != null && mD != null) {
if(e.getSource() == mD.getTimer()) {
if(mD.getInOut()) { //Start of transform into x
//r1
mD.setTransR1(new double[] {a[0] + (i * incrementX1), a[1] + (i * incrementY1)});
mD.setAng1(i * angInc);
//r2
mD.setAplha(mD.getAlpha() - 0.02F);
//r3
mD.setTransR3(new double[] {b[0] + (i * incrementX3), b[1] + (i * incrementY3)});
mD.setAng2(i * angInc);
//Location
mD.setLocation((int) (startPoint + (i * moveInc)), startPoint);
i++;
} else { //Start of transform into three lines
//r1
mD.setTransR1(new double[] {c[0] + (i * incrementX2), c[1] + (i * incrementY2)});
mD.setAng1((100 - i) * angInc);
//r2
if(i >= 50) {
mD.setAplha(mD.getAlpha() + 0.02F);
}
//r3
mD.setTransR3(new double[] {d[0] + (i * incrementX4), d[1] + (i * incrementY4)});
mD.setAng2((100 - i) * angInc);
//Location
mD.setLocation((int) (540 + (i * -moveInc)), 15);
i++;
}
if(i == 101) {
mD.stopTheTimer(i);
i = 0;
}
m.getMainWindow().validate();
m.getMainWindow().repaint();
}
}
}
}
class CustomMouseListener extends MouseAdapter {
Menu m;
MenuDesign mD;
SlideInLayout s;
public CustomMouseListener(Menu m, MenuDesign mD, SlideInLayout s) {
this.m = m;
this.mD = mD;
this.s = s;
}
public void mousePressed(MouseEvent mE) {
if(m != null && mD != null) {
if(mE.getSource() == mD) {
if(mD.getInOut()) {
mD.setFade(false);
Thread runSwap = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
s.show(m.getFirstPanel());
}
});
runSwap.start();
try {
runSwap.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
mD.setFade(true);
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
s.show(m.getOverlay());
}
}).start();
}
mD.fade();
m.getMainWindow().validate();
m.getMainWindow().repaint();
}
}
}
}
/////////////// Below here is not my code
class SlideInLayout implements LayoutManager {
private Component focusedComponent;
#Override
public void addLayoutComponent(String name, Component comp) {}
#Override
public void removeLayoutComponent(Component comp) {}
#Override
public void layoutContainer(Container parent) {
setSizes(parent);
if (hasFocusedComponent()) {
focusedComponent.setVisible(true);
}
}
private void setSizes(Container parent) {
Insets insets = parent.getInsets();
int maxWidth = parent.getWidth() - (insets.left + insets.right);
int maxHeight = parent.getHeight() - (insets.top + insets.bottom);
for (Component component : parent.getComponents()) {
component.setBounds(0, 0, maxWidth, maxHeight);
}
}
#Override
public Dimension minimumLayoutSize(Container parent) {
return new Dimension(0, 0);
}
#Override
public Dimension preferredLayoutSize(Container parent) {
Dimension preferredSize = new Dimension(0, 0);
if (hasFocusedComponent()) {
preferredSize = focusedComponent.getPreferredSize();
}
else if (parent.getComponentCount() > 0) {
int maxWidth = 0;
int maxHeight = 0;
for (Component component : parent.getComponents()) {
Dimension componentSize = component.getPreferredSize();
maxWidth = Math.max(maxWidth, componentSize.width);
maxHeight = Math.max(maxHeight, componentSize.height);
}
preferredSize = new Dimension(maxWidth, maxHeight);
}
return preferredSize;
}
private boolean hasFocusedComponent() {
return focusedComponent != null;
}
public void show(Component component) {
if (hasFocusedComponent())
swap(focusedComponent, component);
focusedComponent = component;
}
private void swap(Component transitionOut, Component transitionIn) {
new SwapTimerAction(transitionOut, transitionIn).start();
}
private class SwapTimerAction implements ActionListener {
private Timer timer;
private Component transitionOut;
private Component transitionIn;
private static final int tick = 16; //16ms
private static final int speed = 50;
public SwapTimerAction(Component transitionOut, Component transitionIn) {
this.transitionOut = transitionOut;
this.transitionIn = transitionIn;
}
public void start() {
Container container = transitionOut.getParent();
container.setComponentZOrder(transitionOut, 1);
container.setComponentZOrder(transitionIn, 0);
transitionIn.setBounds(-transitionOut.getWidth(), 0, transitionOut.getWidth(), transitionOut.getHeight());
timer = new Timer(tick, this);
timer.start();
}
#Override
public void actionPerformed(ActionEvent e) {
int newX = Math.min(transitionIn.getX() + speed, transitionOut.getX());
transitionIn.setLocation(newX, 0);
if (newX == transitionOut.getX()) {
timer.stop();
}
}
}
}
I have 3 classes. One class is my mainframe, another class is my JInternalFrame and also my Observer and the third class does a simulation with a field ob buttons and that one is also my observable class.
Basically I made a button in my observer that copies itself. That includes the add to the desktoppane and the addObserver function of my observable class.
The clone of my observer should also observer the very same observable. So if I interact with the one JInternalFrame, it also changes stuff for the other InternalFrame. It should act like a mirror. (Actually the copy should have like diffrent color buttons and a diffrent orientation but I think that should not be a problem to implement, as soon as I successfully could mirror my Observer)
So since I am using the Observable pattern, I also have to implement the "update" function in my Observer class. I did that and I works like a charm. But when I copy my JInternalFrame, the new InternalFrame observes the Observable(Simulation), but my original JInternalFrame loses the observable connection. It does not show buttons anymore etc.
What I tried: I created a second Observer/JInternalFrame class that extends my first Observer class. That did not work as well. I don't know if thats even a possibility to achieve what I want to.
Sorry for my non perfect english. Sorry for some german words that you might find in the code and sorry that I post so much code. But I am really uncertain right now where my mistake is since I tried to find the error for ours so far.
So here are 2 pictures for you:
First picture shows how my JInternalFrame looks like when I create it. Here everything works perfectly.
Second picture shows what it looks like when I click on the New View button. As already described. The original JInternalFrame does not show the simulation anymore. Although they are both observing the same Observable.
And here are my 3 imporant classes:
MainFrame:
public class LangtonsAmeise extends JFrame implements ActionListener {
JDesktopPane desk;
JPanel panelButtons;
JMenuBar jmb;
JMenu file, modus;
JMenuItem load, save, exit, mSetzen, mMalen, mLaufen;
JSlider slider;
static int xInt, yInt, xKindFrame = 450, yKindFrame = 450, xLocation,
yLocation, xMainFrame = 1000, yMainFrame = 900;
static boolean bSetzen = false, bMalen = false, running = true;
static JFileChooser fc;
Random randomGenerator = new Random();
JLabel xLabel, yLabel, speed, statusText, status;
JButton start, stop, addAnt;
JTextField xField, yField;
public LangtonsAmeise() {
// Desktop
desk = new JDesktopPane();
getContentPane().add(desk, BorderLayout.CENTER);
// File Chooser
fc = new JFileChooser(System.getProperty("user.dir"));
speed = new JLabel("Geschwindigkeit");
xLabel = new JLabel("x:");
yLabel = new JLabel("y:");
xLabel.setHorizontalAlignment(JLabel.RIGHT);
yLabel.setHorizontalAlignment(JLabel.RIGHT);
xLabel.setOpaque(true);
yLabel.setOpaque(true);
xField = new JTextField();
yField = new JTextField();
start = new JButton("Fenster erstellen");
stop = new JButton("Pause/Fortsetzen");
start.setMargin(new Insets(0, 0, 0, 0));
stop.setMargin(new Insets(0, 0, 0, 0));
// Buttons
panelButtons = new JPanel();
panelButtons.setLayout(new GridLayout());
panelButtons.add(start);
panelButtons.add(xLabel);
panelButtons.add(xField);
panelButtons.add(yLabel);
panelButtons.add(yField);
panelButtons.add(speed);
panelButtons.add(new Panel());
panelButtons.add(stop);
start.addActionListener(this);
stop.addActionListener(this);
add(panelButtons, BorderLayout.NORTH);
statusText = new JLabel("Status:");
status = new JLabel("Stopp");
// JMenuBar
jmb = new JMenuBar();
setJMenuBar(jmb);
file = new JMenu("File");
modus = new JMenu("Mode");
mLaufen = new JMenuItem("Laufen");
mMalen = new JMenuItem("Malen");
mSetzen = new JMenuItem("Setzen");
load = new JMenuItem("Simulation laden");
//save = new JMenuItem("Simulation speichern");
mSetzen.addActionListener(this);
mMalen.addActionListener(this);
mLaufen.addActionListener(this);
exit = new JMenuItem("Exit");
file.add(load);
file.addSeparator();
file.add(exit);
load.addActionListener(this);
modus.add(mLaufen);
modus.add(mSetzen);
modus.add(mMalen);
jmb.add(file);
jmb.add(modus);
for (int i = 0; i < 20; i++) {
jmb.add(new JLabel(" "));
}
jmb.add(statusText);
jmb.add(status);
setSize(new Dimension(xMainFrame, yMainFrame));
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
this.setLocation(dim.width / 2 - this.getSize().width / 2, dim.height
/ 2 - this.getSize().height / 2);
xField.setText("5");
yField.setText("5");
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("Fenster erstellen")) {
if (xField.getText().equals("") || yField.getText().equals("")) {
} else {
xInt = Integer.parseInt(xField.getText());
yInt = Integer.parseInt(yField.getText());
state s = new state();
kindFenster k = new kindFenster(s, this);
s.addObserver(k);
addChild(k);
s.startSimulation();
}
}
if (e.getActionCommand().equals("Pause/Fortsetzen")) {
running = !running;
System.out.println(running);
status.setText("Stopp");
}
if (e.getActionCommand().equals("Setzen")) {
status.setText("Setzen");
running = false;
bSetzen = true;
bMalen = false;
}
if (e.getActionCommand().equals("Laufen")) {
status.setText("Laufen");
running = true;
bSetzen = false;
bMalen = false;
}
if (e.getActionCommand().equals("Malen")) {
status.setText("Malen");
running = false;
bSetzen = false;
bMalen = true;
}
if (e.getActionCommand().equals("Simulation laden")) {
LangtonsAmeise.running = false;
InputStream fis = null;
try {
fc.showOpenDialog(null);
fis = new FileInputStream(fc.getSelectedFile().getPath());
ObjectInputStream ois = new ObjectInputStream(fis);
state s = (state) ois.readObject();
kindFenster k = new kindFenster(s, this);
s.addObserver(k);
addChild(k);
s.startSimulation();
} catch (IOException | ClassNotFoundException
| NullPointerException e1) {
LangtonsAmeise.running = true;
} finally {
try {
fis.close();
} catch (NullPointerException | IOException e1) {
LangtonsAmeise.running = true;
}
}
LangtonsAmeise.running = true;
}
}
public void addChild(JInternalFrame kind) {
xLocation = randomGenerator.nextInt(xMainFrame - xKindFrame);
yLocation = randomGenerator.nextInt(yMainFrame - yKindFrame - 100);
kind.setSize(370, 370);
kind.setLocation(xLocation, yLocation);
desk.add(kind);
kind.setVisible(true);
}
public static void main(String[] args) {
LangtonsAmeise hauptFenster = new LangtonsAmeise();
}
}
JInternalFrame:
public class kindFenster extends JInternalFrame implements ActionListener,
Serializable,Observer,Cloneable {
/**
*
*/
private static final long serialVersionUID = 8939449766068226519L;
static int nr = 0;
static int x,y,xScale,yScale,xFrame,yFrame;
state s;
ArrayList<ImageIcon> ameisen = new ArrayList<ImageIcon>();
JFileChooser fc;
LangtonsAmeise la;
Color alteFarbe, neueFarbe;
JButton save, addAnt, newView;
JPanel panelButtonsKind;
JSlider sliderKind;
public JPanel panelSpielfeld,panelSpielfeldKopie;
JButton[] jbArrayy;
static SetzenActionListener sal = new SetzenActionListener();
static MouseMotionActionListener mmal = new MouseMotionActionListener();
public kindFenster(state s,LangtonsAmeise la) {
super("Kind " + (++nr), true, true, true, true);
setLayout(new BorderLayout());
this.s=s;
jbArrayy=new JButton[s.jbArrayy.length];
for (int b = 1; b<s.jbArrayy.length;b++) {
this.jbArrayy[b] = s.jbArrayy[b];
}
this.la=la;
setSize(new Dimension(xFrame, yFrame));
this.addInternalFrameListener(listener);
this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
panelSpielfeld = new JPanel();
panelSpielfeld.setLayout(new GridLayout(s.y, s.x));
panelButtonsKind = new JPanel();
panelButtonsKind.setLayout(new GridLayout(1, 3));
save = new JButton("<html>Save<br>simulation</html>");
addAnt = new JButton("<html>Add<br>ant</html>");
newView = new JButton("<html>New<br>View</html>");
save.setActionCommand("save");
addAnt.setActionCommand("addAnt");
newView.setActionCommand("newView");
save.setMargin(new Insets(0, 0, 0, 0));
addAnt.setMargin(new Insets(0, 0, 0, 0));
addAnt.addActionListener(this);
save.addActionListener(this);
newView.addActionListener(this);
sliderKind = new JSlider(JSlider.HORIZONTAL, 1, 9, 5);
sliderKind.setSnapToTicks(true);
sliderKind.setPaintTicks(true);
sliderKind.setPaintTrack(true);
sliderKind.setMajorTickSpacing(1);
sliderKind.setPaintLabels(true);
sliderKind.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
JSlider source = (JSlider) e.getSource();
if (!source.getValueIsAdjusting()) {
int speed = source.getValue();
state.sleeptime = 1000 / speed;
}
}
});
panelButtonsKind.add(save);
panelButtonsKind.add(newView);
panelButtonsKind.add(sliderKind);
panelButtonsKind.add(addAnt);
add(panelButtonsKind, BorderLayout.NORTH);
add(panelSpielfeld, BorderLayout.CENTER);
this.addComponentListener(new MyComponentAdapter());
for (int i = 1 ; i<jbArrayy.length;i++) {
panelSpielfeld.add(jbArrayy[i]);
}
}
// I have been trying around to change the orientation of the buttons in the copy of the frame
public void secondViewFrameSettings() {
int temp;
for (int i = 1; i<=x;i++) {
for (int k = 0; k<y;k++) {
temp = i+(k*x);
panelSpielfeldKopie.add(s.jbArrayy[temp]);
}
}
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("addAnt")) {
s.addAnt();
}
if (e.getActionCommand().equals("newView")){
kindFenster kk = new kindFenster(s,la);
s.addObserver(kk);
la.addChild(kk);
}
if (e.getActionCommand().equals("save")) {
OutputStream fos = null;
try {
LangtonsAmeise.running=false;
try {
fc = new JFileChooser(System.getProperty("user.dir"));
fc.showSaveDialog(null);
LangtonsAmeise.fc.setCurrentDirectory(fc.getSelectedFile());
fos = new FileOutputStream(fc.getSelectedFile());
ObjectOutputStream o = new ObjectOutputStream(fos);
o.writeObject(s);
} catch (NullPointerException e2) {
System.out.println("Fehler beim Auswählen der Datei. Wenden Sie sich an den Entwickler.");
}
} catch (IOException e1) {
LangtonsAmeise.running=true;
System.err.println(e1);
} finally {
try {
fos.close();
} catch (NullPointerException | IOException e1) {
LangtonsAmeise.running=true;
}
LangtonsAmeise.running=true;
}
LangtonsAmeise.running=true;
}
}
InternalFrameListener listener = new InternalFrameAdapter() {
public void internalFrameClosing(InternalFrameEvent e) {
e.getInternalFrame().dispose();
s.simulation.suspend();
}
};
class MyComponentAdapter extends ComponentAdapter {
public void componentResized(ComponentEvent e) {
//Ameisenbilder an die Buttongrößen anpassen
xScale=s.jbArrayy[1].getSize().width;
yScale=s.jbArrayy[1].getSize().height;
s.ameisen.clear();
s.ameisen.add(new ImageIcon(new ImageIcon("ameise.gif")
.getImage().getScaledInstance(xScale, yScale,
Image.SCALE_SMOOTH)));
s.ameisen.add(new ImageIcon(new ImageIcon("ameise90.gif")
.getImage().getScaledInstance(xScale, yScale,
Image.SCALE_SMOOTH)));
s.ameisen.add(new ImageIcon(new ImageIcon("ameise180.gif")
.getImage().getScaledInstance(xScale, yScale,
Image.SCALE_SMOOTH)));
s.ameisen.add(new ImageIcon(new ImageIcon("ameise270.gif")
.getImage().getScaledInstance(xScale, yScale,
Image.SCALE_SMOOTH)));
}
}
public void update(Observable o, Object arg) {
if (o == s) {
for (int i = 1;i<s.jbArrayy.length;i++) {
jbArrayy[i].setBackground(s.jbArrayy[i].getBackground());
}
}
}
}
class SetzenActionListener implements ActionListener,Serializable {
JButton source;
#Override
public void actionPerformed(ActionEvent e) {
source = (JButton) e.getSource();
if (LangtonsAmeise.bSetzen == true) {
if (source.getBackground().equals(Color.GREEN)) {
source.setBackground(Color.WHITE);
} else {
source.setBackground(Color.GREEN);
}
}
}
}
class MouseMotionActionListener extends MouseInputAdapter implements Serializable {
boolean dragged = false;
JButton tempJButton = new JButton();
public void mouseEntered(MouseEvent e) {
if (LangtonsAmeise.bMalen == true && dragged == true) {
((JButton) e.getSource()).setBackground(Color.GREEN);
}
}
public void mouseDragged(MouseEvent e) {
dragged = true;
}
public void mouseReleased(MouseEvent e) {
dragged = false;
}
}
Observable class:
public class state extends Observable implements Serializable {
/**
*
*/
private static final long serialVersionUID = 450773214079105589L;
int[] obRand, reRand, unRand, liRand;
int x, y, temp;
static int sleeptime = 200;
Color background;
int posAmeise, aktuellesIcon = 1, altePosAmeise, xScale, yScale;
Color alteFarbe, neueFarbe, color1, color2;
ArrayList<JButton> jbSer = new ArrayList<JButton>();
private List<Ant> ants = new ArrayList<Ant>();
ArrayList<ImageIcon> ameisen = new ArrayList<>();
JButton[] jbArrayy;
transient Thread simulation;
public state() {
this.x = LangtonsAmeise.xInt;
this.y = LangtonsAmeise.yInt;
color1 = Color.WHITE;
color2 = Color.GREEN;
jbArrayy = new JButton[x * y + 1];
initializeBorders();
initializeAntsImages();
initializeSimulationButtons();
xScale = jbArrayy[1].getSize().width;
yScale = jbArrayy[1].getSize().height;
// Startpunkt für die Ameise festlegen
posAmeise = (((x / 2) * y) - y / 2);
background = jbArrayy[posAmeise].getBackground();
ants.add(new Ant(this));
}
public void initializeAntsImages() {
ameisen.add(new ImageIcon(new ImageIcon("ameise.gif").getImage()
.getScaledInstance(LangtonsAmeise.xKindFrame / x,
LangtonsAmeise.yKindFrame / y, Image.SCALE_SMOOTH)));
ameisen.add(new ImageIcon(new ImageIcon("ameise90.gif").getImage()
.getScaledInstance(LangtonsAmeise.xKindFrame / x,
LangtonsAmeise.yKindFrame / y, Image.SCALE_SMOOTH)));
ameisen.add(new ImageIcon(new ImageIcon("ameise180.gif").getImage()
.getScaledInstance(LangtonsAmeise.xKindFrame / x,
LangtonsAmeise.yKindFrame / y, Image.SCALE_SMOOTH)));
ameisen.add(new ImageIcon(new ImageIcon("ameise270.gif").getImage()
.getScaledInstance(LangtonsAmeise.xKindFrame / x,
LangtonsAmeise.yKindFrame / y, Image.SCALE_SMOOTH)));
}
// Alle Buttons für das Simulationsfeld werden erstellt
public void initializeSimulationButtons() {
jbArrayy[0] = new JButton();
for (int i = 1; i < jbArrayy.length; i++) {
jbArrayy[i] = new JButton();
jbArrayy[i].setBackground(color1);
jbArrayy[i].addActionListener(kindFenster.sal);
jbArrayy[i].addMouseListener(kindFenster.mmal);
jbArrayy[i].addMouseMotionListener(kindFenster.mmal);
}
}
// Ränderindex in Array schreiben
public void initializeBorders() {
reRand = new int[y];
liRand = new int[y];
obRand = new int[x];
unRand = new int[x];
for (int i = 0; i < x; i++) {
obRand[i] = i + 1;
unRand[i] = (x * y - x) + i + 1;
}
for (int i = 1; i <= y; i++) {
reRand[i - 1] = i * x;
liRand[i - 1] = i * x - (x - 1);
}
}
public void initializeSimulation() {
if (simulation != null && simulation.isAlive()) {
simulation.stop();
}
simulation = new Thread() {
#Override
public void run() {
super.run();
while (true) {
try {
sleep(300);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
while (LangtonsAmeise.running && countObservers() > 0) {
try {
Thread.sleep(sleeptime);
for (Ant a : ants) {
move(a);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
};
}
public void startSimulation() {
initializeSimulation();
simulation.start();
}
public void changeColor(int altePos, Color c) {
jbArrayy[altePos].setBackground(c);
}
public void addAnt() {
ants.add(new Ant(this));
}
public void changeIcon(boolean k, Ant a) {
int g = (k == true) ? 1 : -1;
if (a.aktuellesIcon + g < 0) {
a.aktuellesIcon = 3;
} else if (a.aktuellesIcon + g > 3) {
a.aktuellesIcon = 0;
} else {
a.aktuellesIcon += g;
}
jbArrayy[a.posAmeise].setIcon(ameisen.get(a.aktuellesIcon));
setChanged();
notifyObservers();
}
public void rightCheck(Ant a) {
if (checkInArray(a.posAmeise, reRand)) {
a.posAmeise -= x - 1;
} else {
a.posAmeise += 1;
}
}
public void leftCheck(Ant a) {
if (checkInArray(a.posAmeise, liRand)) {
a.posAmeise += x - 1;
} else {
a.posAmeise -= 1;
}
}
public void upCheck(Ant a) {
if (checkInArray(a.posAmeise, obRand)) {
a.posAmeise += (y - 1) * x;
} else {
a.posAmeise -= x;
}
}
public void downCheck(Ant a) {
if (checkInArray(a.posAmeise, unRand)) {
a.posAmeise -= (y - 1) * x;
} else {
a.posAmeise += x;
}
}
public void checkAmeisenSize(Ant a) {
while (!(ameisen.size() == 4)) {
}
;
}
public static boolean checkInArray(int currentState, int[] myArray) {
int i = 0;
for (; i < myArray.length; i++) {
if (myArray[i] == currentState)
break;
}
return i != myArray.length;
}
public ImageIcon getAntImage() {
return ameisen.get(aktuellesIcon);
}
public void move(Ant a) throws InterruptedException {
try {
a.altePosAmeise = a.posAmeise;
a.alteFarbe = jbArrayy[a.posAmeise].getBackground();
if (a.alteFarbe.equals(Color.GREEN) && ameisen.size() == 4) {
if (a.aktuellesIcon == 0) {
checkAmeisenSize(a);
rightCheck(a);
} else if (a.aktuellesIcon == 1) {
checkAmeisenSize(a);
downCheck(a);
} else if (a.aktuellesIcon == 2) {
checkAmeisenSize(a);
leftCheck(a);
} else if (a.aktuellesIcon == 3) {
checkAmeisenSize(a);
upCheck(a);
}
changeIcon(true, a);
changeColor(a.altePosAmeise, Color.WHITE);
} else if (a.alteFarbe.equals(Color.WHITE) && ameisen.size() == 4) {
if (a.aktuellesIcon == 0) {
checkAmeisenSize(a);
leftCheck(a);
} else if (a.aktuellesIcon == 1) {
checkAmeisenSize(a);
upCheck(a);
} else if (a.aktuellesIcon == 2) {
checkAmeisenSize(a);
rightCheck(a);
} else if (a.aktuellesIcon == 3) {
checkAmeisenSize(a);
downCheck(a);
}
changeIcon(false, a);
changeColor(a.altePosAmeise, Color.GREEN);
setChanged();
notifyObservers();
}
jbArrayy[a.altePosAmeise].setIcon(new ImageIcon());
} catch (IndexOutOfBoundsException e) {
move(a);
}
}
}
Edit: Ant Class
import java.awt.Color;
import java.awt.Image;
import java.io.Serializable;
import java.util.ArrayList;
import javax.swing.ImageIcon;
public class Ant implements Serializable {
int posAmeise, aktuellesIcon = 1, altePosAmeise;
Color alteFarbe, neueFarbe;
ArrayList<ImageIcon> ameisen = new ArrayList<>();
public Ant(state s) {
this.posAmeise = s.posAmeise;
s.jbArrayy[posAmeise].setIcon(s.ameisen.get(aktuellesIcon));
}
}
How do I make the player and the world scroll at the same time?
because no matter what i do it always has a small delay...
My point is this: my game is a 2d sidescroller (terraria/minecraft/rpg) game and I need to be able to move the terrain together with the world...
Player.java
package game.test.src;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import javax.swing.ImageIcon;
public class Player {
static final int MOVE_UP = 0, MOVE_DOWN = 1, MOVE_LEFT= 2, MOVE_RIGHT = 3;
private World world;
private Rectangle playerRect;
private Image playerImg;
//Block Variables
private int hoverX, hoverY;
private boolean hovering = false;
protected static int xDirection;
protected static int yDirection;
private Weapon weapon;
public Player(World world){
this.world = world;
playerImg = new ImageIcon("H:/2D game test/Game test 2/src/game/test/src/images/Character.png").getImage();
playerRect = new Rectangle(50, 0, 10, 36);
weapon = new Weapon(weapon.PICKAXE);
}
private static void setXDirection(int d){
xDirection = d;
}
private static void setYDirection(int d){
yDirection = d;
}
public void update()
{
move();
checkForCollision();
}
private void checkForCollision() {
}
private void move()
{
playerRect.x += xDirection;
playerRect.y += yDirection;
gravity();
}
private void gravity()
{
for(int i=0;i<world.arrayNum; i++)
{
if(!world.isSolid[i])
{
setYDirection(1);
}
else if(world.isSolid[i] && playerRect.intersects(world.blocks[i]))
{
setYDirection(0);
}
}
}
//MotionEvents
public void mousePressed(MouseEvent e)
{
}
public void mouseReleased(MouseEvent e)
{
}
public void mouseClicked(MouseEvent e)
{
}
public void mouseMoved(MouseEvent e)
{
int x = e.getX();
int y = e.getY();
int px = playerRect.x;
int py = playerRect.y;
for(int i = 0; i < world.arrayNum; i++)
{
if(weapon.isEquipped(Weapon.PICKAXE) &&
x > world.blocks[i].x && x < world.blocks[i].x + world.blocks[i].width &&
y > world.blocks[i].x && y < world.blocks[i].y + world.blocks[i].height && world.isSolid[i] &&
(world.blocks[i].x + (world.blocks[i].width / 2) ) <= (px + playerRect.width/2) + weapon.WEAPON_RADIUS &&
(world.blocks[i].x + (world.blocks[i].width / 2) ) >= (px + playerRect.width/2) - weapon.WEAPON_RADIUS &&
(world.blocks[i].y + (world.blocks[i].height / 2) ) <= (py + playerRect.height/2) + weapon.WEAPON_RADIUS &&
(world.blocks[i].y + (world.blocks[i].height / 2) ) >= (py + playerRect.height/2) - weapon.WEAPON_RADIUS)
{
hovering = true;
hoverX = world.blocks[i].x;
hoverY = world.blocks[i].y;
break;
}
else
hovering = false;
}
}
public void mouseDragged(MouseEvent e)
{
}
public void mouseEntered(MouseEvent e)
{
}
public void mouseExited(MouseEvent e)
{
}
//Drawing Methods
public void draw(Graphics g)
{
g.drawImage(playerImg, playerRect.x, playerRect.y, null);
if(hovering)
drawBlockOutline(g);
}
private void drawBlockOutline(Graphics g)
{
g.setColor(Color.black);
g.drawRect(hoverX, hoverY, world.blocks[0].width,world.blocks[0].height);
}
private class Weapon
{
public static final int UNARMED = 0;
public static final int PICKAXE = 1;
public static final int GUN = 2;
public int CURRENT_WEAPON;
public int WEAPON_RADIUS;
public Weapon(int w)
{
switch(w)
{
default:
System.out.println("No weapon selected");
break;
case UNARMED:
CURRENT_WEAPON = UNARMED;
WEAPON_RADIUS = 100;
break;
case PICKAXE:
CURRENT_WEAPON = PICKAXE;
WEAPON_RADIUS = 100;
break;
case GUN:
CURRENT_WEAPON = GUN;
WEAPON_RADIUS = 100;
break;
}
}
public void selectWeapon(int w)
{
switch(w)
{
default:
System.out.println("No weapon selected");
break;
case UNARMED:
CURRENT_WEAPON = UNARMED;
WEAPON_RADIUS = 100;
break;
case PICKAXE:
CURRENT_WEAPON = PICKAXE;
WEAPON_RADIUS = 100;
break;
case GUN:
CURRENT_WEAPON = GUN;
WEAPON_RADIUS = 100;
break;
}
}
public boolean isEquipped(int w)
{
if(w == CURRENT_WEAPON)
{
return true;
}
else
return false;
}
}
public void moveMap(){
for(Rectangle r : world.blocks){
r.x += xDirection;
r.y += yDirection;
}
}
public static void stopMoveMap(){
setXDirection(0);
setYDirection(0);
}
private static void setXDirection1(int dir){
xDirection = dir;
}
private static void setYDirection1(int dir){
yDirection = dir;
}
public static void navigatePlayer(int nav){
switch(nav){
default:
System.out.println("default case entered... Doing nothing.");
break;
case MOVE_UP:
setYDirection1(-1);
break;
case MOVE_DOWN:
setYDirection1(1);
break;
case MOVE_LEFT:
setXDirection1(-1);
break;
case MOVE_RIGHT:
setXDirection1(1);
break;
}
}
}
World.java
package game.test.src;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import javax.swing.ImageIcon;
public class World {
public Rectangle[] blocks;
public boolean[] isSolid;
public Image[] blockImg;
public final int arrayNum = 500;
//Block Images
public Image BLOCK_GRASS, BLOCK_DIRT, BLOCK_STONE, BLOCK_SKY;
private int x, y, xDirection, yDirection;;
//map navigation
static final int PAN_UP = 0, PAN_DOWN = 1, PAN_LEFT= 2, PAN_RIGHT = 3;
public World(){
BLOCK_GRASS = new ImageIcon("H:/2D game test/Game test 2/src/game/test/src/images/tile_grass.png").getImage();
BLOCK_DIRT = new ImageIcon("H:/2D game test/Game test 2/src/game/test/src/images/tile_dirt.png").getImage();
BLOCK_STONE = new ImageIcon("H:/2D game test/Game test 2/src/game/test/src/images/tile_stone.png").getImage();
BLOCK_SKY = new ImageIcon("H:/2D game test/Game test 2/src/game/test/src/images/tile_sky.png").getImage();
blocks = new Rectangle[500];
blockImg = new Image[500];
isSolid = new boolean[arrayNum];
loadArrays();
}
private void loadArrays(){
for(int i = 0; i < arrayNum; i++){
if(x >= 500){
x = 0;
y += 20;
}
if(i >= 0 && i < 100){
blockImg[i] = BLOCK_SKY;
isSolid[i] = false;
blocks[i] = new Rectangle(x, y, 20, 20);
}
if(i >= 100 && i < 125){
blockImg[i] = BLOCK_GRASS;
isSolid[i] = true;
blocks[i] = new Rectangle(x, y, 20, 20);
}
if(i >= 125 && i < 225){
blockImg[i] = BLOCK_DIRT;
isSolid[i] = true;
blocks[i] = new Rectangle(x, y, 20, 20);
}
if(i >= 225 && i < 500){
blockImg[i] = BLOCK_STONE;
isSolid[i] = true;
blocks[i] = new Rectangle(x, y, 20, 20);
}
x += 20;
}
}
public void draw(Graphics g){
for(int i = 0; i < arrayNum; i++){
g.drawImage(blockImg[i], blocks[i].x, blocks[i].y, null);
}
}
public void moveMap(){
for(Rectangle r : blocks){
r.x += xDirection;
r.y += yDirection;
}
}
public void stopMoveMap(){
setXDirection(0);
setYDirection(0);
}
private void setXDirection(int dir){
xDirection = dir;
}
private void setYDirection(int dir){
yDirection = dir;
}
public void navigateMap(int nav){
switch(nav){
default:
System.out.println("default case entered... Doing nothing.");
break;
case PAN_UP:
setYDirection(-1);
break;
case PAN_DOWN:
setYDirection(1);
break;
case PAN_LEFT:
setXDirection(-1);
break;
case PAN_RIGHT:
setXDirection(1);
break;
}
}
}
GamePanel.java
package game.test.src;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JPanel;
public class GamePanel extends JPanel implements Runnable {
//Double buffering
private Image dbImage;
private Graphics dbg;
//JPanel variables
static final int GWIDTH = 500, GHEIGHT = 400;
static final Dimension gameDim = new Dimension(GWIDTH, GHEIGHT);
//Game variables
private static final int DELAYS_BEFORE_YIELD = 10;
private Thread game;
private volatile boolean running = false;
private long period = 6*1000000; //ms -> nano
//Game Objects
World world;
Player p1;
public GamePanel(){
world = new World();
p1 = new Player(world);
setPreferredSize(gameDim);
setBackground(Color.WHITE);
setFocusable(true);
requestFocus();
//Handle all key inputs from user
addKeyListener(new KeyAdapter(){
#Override
public void keyPressed(KeyEvent e){
if(e.getKeyCode() == KeyEvent.VK_LEFT){
Player.navigatePlayer(Player.MOVE_LEFT);
world.navigateMap(World.PAN_LEFT);
}
if(e.getKeyCode() == KeyEvent.VK_RIGHT){
Player.navigatePlayer(Player.MOVE_RIGHT);
world.navigateMap(World.PAN_RIGHT);
}
if(e.getKeyCode() == KeyEvent.VK_UP){
Player.navigatePlayer(Player.MOVE_UP);
world.navigateMap(World.PAN_UP);
}
if(e.getKeyCode() == KeyEvent.VK_DOWN){
Player.navigatePlayer(Player.MOVE_DOWN);
world.navigateMap(World.PAN_DOWN);
}
}
#Override
public void keyReleased(KeyEvent e){
Player.stopMoveMap();
world.stopMoveMap();
}
#Override
public void keyTyped(KeyEvent e){
}
});
addMouseListener(new MouseAdapter()
{
#Override
public void mousePressed(MouseEvent e)
{
}
#Override
public void mouseReleased(MouseEvent e)
{
}
#Override
public void mouseClicked(MouseEvent e)
{
}
});
addMouseMotionListener(new MouseAdapter()
{
public void mouseMoved(MouseEvent e)
{
p1.mouseMoved(e);
}
public void mouseDragged(MouseEvent e)
{
}
public void mouseEntered(MouseEvent e)
{
}
public void mouseExited(MouseEvent e)
{
}
});
}
public void run(){
long beforeTime, afterTime, diff, sleepTime, overSleepTime = 0;
int delays = 0;
while(running){
beforeTime = System.nanoTime();
gameUpdate();
gameRender();
paintScreen();
afterTime = System.nanoTime();
diff = afterTime - beforeTime;
sleepTime = (period - diff) - overSleepTime;
//if sleepTime is between peiod and 0, then sleep
if(sleepTime < period && sleepTime > 0)
{
try{
Thread.sleep(sleepTime/1000000L);
overSleepTime = 0;
}catch(InterruptedException ex){
Logger.getLogger(GamePanel.class.getName()).log(Level.SEVERE, "EXCEPTION");
}
}
//the diff was greater than the period
else if(diff > period)
{
overSleepTime = diff - period;
}
else if(++delays >= DELAYS_BEFORE_YIELD)
{
Thread.yield();
delays = 0;
overSleepTime = 0;
}
//the loop took less time than expected
else
{
overSleepTime = 0;
}
}
}
private void gameUpdate(){
if(running && game != null){
world.moveMap();
p1.update();
}
}
private void gameRender(){
if(dbImage == null){ // Create the buffer
dbImage = createImage(GWIDTH, GHEIGHT);
if(dbImage == null){
System.err.println("dbImage is still null!");
return;
}else{
dbg = dbImage.getGraphics();
}
}
//Clear the screen
dbg.setColor(Color.WHITE);
dbg.fillRect(0, 0, GWIDTH, GHEIGHT);
//Draw Game elements
draw(dbg);
}
/* Draw all game content in this method */
public void draw(Graphics g){
world.draw(g);
p1.draw(g);
}
private void paintScreen(){
Graphics g;
try{
g = this.getGraphics();
if(dbImage != null && g != null){
g.drawImage(dbImage, 0, 0, null);
}
Toolkit.getDefaultToolkit().sync(); //For some operating systems
g.dispose();
}catch(Exception e){
System.err.println(e);
}
}
public void addNotify(){
super.addNotify();
startGame();
}
private void startGame(){
if(game == null || !running){
game = new Thread(this);
game.start();
running = true;
}
}
public void stopGame(){
if(running){
running = false;
}
}
private void log(String s){
System.out.println(s);
}
}
thanks for the help!
I'm working on a Java implementation of Conway's game of life as a personal project for myself. So far it works but the rules are coming out wrong. The expected patterns aren't showing up as well as it should. Is there something wrong with my code?
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Cell extends JComponent implements MouseListener {
private int row, col;
private boolean isLiving;
public Cell(int r, int c) {
this.row = r;
this.col = c;
this.addMouseListener(this);
}
public void isAlive(int neighbors) {
if (this.isLiving) {
if (neighbors < 2) {
this.isLiving = false;
} else if (neighbors == 2 || neighbors == 3) {
this.isLiving = true;
} else if (neighbors > 3) {
this.isLiving = false;
}
} else {
if (neighbors == 3) {
this.isLiving = true;
}
}
}
public boolean isLiving() {
return this.isLiving;
}
public void paintComponent(Graphics g) {
if (this.isLiving) {
g.fillRect(0, 0, 10, 10);
} else {
g.drawRect(0, 0, 10, 10);
}
}
public void mouseClicked(MouseEvent e) {
this.isLiving = !this.isLiving;
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
}
I suspect1 the problem with your code is that it is setting the cells to living or dead as soon as the neighbors are checked. That caused my early variants of this code to fail. That change of state has to be delayed until the entire grid (biosphere) has been checked.
This example shows typical Game of Life behavior.
Note that "suspicions ain't answers", so it is best to post an SSCCE.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Random;
public class GameOfLife extends JPanel {
private final int row, col;
private boolean isLiving;
public static Random random = new Random();
public GameOfLife(int r, int c) {
this.row = r;
this.col = c;
MouseListener listener = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
isLiving = !isLiving;
repaint();
}
};
this.addMouseListener(listener);
isLiving = random.nextBoolean();
}
public boolean isAlive(int neighbors) {
boolean alive = false;
if (this.isLiving) {
if (neighbors < 2) {
alive = false;
} else if (neighbors == 2 || neighbors == 3) {
alive = true;
} else if (neighbors > 3) {
alive = false;
}
} else {
if (neighbors == 3) {
alive = true;
}
}
return alive;
}
public void setAlive(boolean alive) {
isLiving = alive;
}
public boolean isLiving() {
return this.isLiving;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (this.isLiving) {
g.fillRect(0, 0, getWidth() - 1, getHeight() - 1);
} else {
g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
}
}
public static void main(String[] args) {
final int s = 40;
final GameOfLife[][] biosphere = new GameOfLife[s][s];
final JPanel gui = new JPanel(new GridLayout(s, s, 2, 2));
for (int ii = 0; ii < s; ii++) {
for (int jj = 0; jj < s; jj++) {
GameOfLife cell = new GameOfLife(ii, jj);
cell.setPreferredSize(new Dimension(10, 10));
gui.add(cell);
biosphere[ii][jj] = cell;
}
}
ActionListener al = (ActionEvent ae) -> {
boolean[][] living = new boolean[s][s];
for (int ii = 0; ii < s; ii++) {
for (int jj = 0; jj < s; jj++) {
int top = (jj > 0 ? jj - 1 : s - 1);
int btm = (jj < s - 1 ? jj + 1 : 0);
int lft = (ii > 0 ? ii - 1 : s - 1);
int rgt = (ii < s - 1 ? ii + 1 : 0);
int neighbors = 0;
if (biosphere[ii][top].isLiving()) {
neighbors++;
}
if (biosphere[ii][btm].isLiving()) {
neighbors++;
}
if (biosphere[lft][top].isLiving()) {
neighbors++;
}
if (biosphere[lft][btm].isLiving()) {
neighbors++;
}
if (biosphere[lft][jj].isLiving()) {
neighbors++;
}
if (biosphere[rgt][jj].isLiving()) {
neighbors++;
}
if (biosphere[rgt][top].isLiving()) {
neighbors++;
}
if (biosphere[rgt][btm].isLiving()) {
neighbors++;
}
living[ii][jj] = biosphere[ii][jj].isAlive(neighbors);
}
}
for (int ii = 0; ii < s; ii++) {
for (int jj = 0; jj < s; jj++) {
biosphere[ii][jj].setAlive(living[ii][jj]);
}
}
gui.repaint();
};
Timer timer = new Timer(50, al);
timer.start();
JOptionPane.showMessageDialog(null, gui);
timer.stop();
}
}