Sry guys for asking, but my game has a slow startup and I want create a loading screen to keep the person busy until the game starts up. So does anyone know how to do this or find a faster way to startup the program. My dad said to optimise the programming code and I don’t know what he means by that.
we need some code
What is being slow? Like Cero said, show us the code! And “optimizing” means to make something run faster by using a better algorithm or something like that.
Here is some code I have alot so sorry…
MainWindow.java
import javax.swing.*;
import java.awt.*;
public class MainWindow extends JFrame{
private static final long serialVersionUID = 1L;
MainGamePanel MGP = new MainGamePanel();
public MainWindow(){
this.setTitle("Mind Maze");
this.setSize(1300,700);
this.add(MGP);
this.setResizable(false);
this.setVisible(true);
this.setLocationRelativeTo(null);
this.toFront();
}
public static void main(String[] args){
MainWindow MW = new MainWindow();
}
}
MainGamePanel.java
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
public class MainGamePanel extends JPanel{
private static final long serialVersionUID = 1L;
SinglePlayer SP = new SinglePlayer();
Thread SinglePlay = new Thread(SP);
private boolean Start = false;
public MainGamePanel(){
this.add(SP);
this.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
int x = e.getX();
int y = e.getY();
if(x > 325 && x < 325 + 70 &&
y > 235 && y < 235 + 70 && !Start){
StartGame();
}
}
public void mouseReleased(MouseEvent e){}
public void mouseClicked(MouseEvent e){}
});
}
public void StartGame(){
Start = true;
SP.running = true;
SinglePlay.start();
}
public void paint(Graphics g){
if(!Start){
g.setColor(Color.GREEN);
g.fillRect(325,235,70,30);
g.setColor(Color.BLACK);
g.drawRect(325,235,70,30);
g.drawString("Play",325+23,235+20);
repaint();
}else{
SP.paintComponent(g);
repaint();
}
}
}
SinglePlayer.java
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
public class SinglePlayer extends JPanel implements Runnable{
private static final long serialVersionUID = 1L;
private Image dbImage;
private Graphics dbg;
MapDirector MD = new MapDirector();
public boolean running = false;
public SinglePlayer(){
this.setFocusable(true);
this.requestFocus();
this.addKeyListener(new KeyListener(){
public void keyPressed(KeyEvent e){MD.prey.keyPressed(e);}
public void keyReleased(KeyEvent e){MD.prey.keyReleased(e);}
public void keyTyped(KeyEvent e){MD.prey.keyTyped(e);}
});
}
public void paint(Graphics g){
dbImage = createImage(getWidth(),getHeight());
dbg = dbImage.getGraphics();
paintComponent(dbg);
g.drawImage(dbImage,0,0,this);
}
public void paintComponent(Graphics g){
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.WHITE);
g2d.fillRect(0,0,1300,700);
MD.paint(g,g2d);
g2d.setColor(Color.BLACK);
}
public void run(){
while(running){
MD.prey.Movement();
for(int i = 0;i < MD.wallT.size();i++){
MD.WallCollision(MD.wallT.get(i));
}
repaint();
try{
Thread.sleep(20);
}catch(Exception e){System.out.println("!!!ERROR!!!");}
}
}
}
MapDirector.java
import java.util.*;
import java.awt.*;
public class MapDirector{
Maps M = new Maps();
Prey prey;
private int random;
ArrayList<Floor> floor = new ArrayList<Floor>();
ArrayList<Wall> wall = new ArrayList<Wall>();
ArrayList<Wall> wallT = new ArrayList<Wall>();
private int Maze1[][] = M.Maze1;
public MapDirector(){
prey = new Prey(50,50,500,270);
random = 0;
random++;
for(int y = 0;y < Maze1.length;y++){
for(int x = 0;x < Maze1[y].length;x++){
if(random == 1||random == 5||random == 9||random == 13){
if(Maze1[y][x] == 2){Maze1[y][x] = 0;}
if(Maze1[y][x] == 3){Maze1[y][x] = 1;}
if(Maze1[y][x] == 4){Maze1[y][x] = 0;}
if(Maze1[y][x] == 5){Maze1[y][x] = 1;}
}
else if(random == 2||random == 6||random == 10||random == 14){
if(Maze1[y][x] == 2){Maze1[y][x] = 1;}
if(Maze1[y][x] == 3){Maze1[y][x] = 0;}
if(Maze1[y][x] == 4){Maze1[y][x] = 1;}
if(Maze1[y][x] == 5){Maze1[y][x] = 0;}
}
else if(random == 3||random == 7||random == 11||random == 15){
if(Maze1[y][x] == 2){Maze1[y][x] = 1;}
if(Maze1[y][x] == 3){Maze1[y][x] = 1;}
if(Maze1[y][x] == 4){Maze1[y][x] = 1;}
if(Maze1[y][x] == 5){Maze1[y][x] = 0;}
}
else if(random == 4||random == 8||random == 12||random == 16){
if(Maze1[y][x] == 2){Maze1[y][x] = 0;}
if(Maze1[y][x] == 3){Maze1[y][x] = 1;}
if(Maze1[y][x] == 4){Maze1[y][x] = 1;}
if(Maze1[y][x] == 5){Maze1[y][x] = 1;}
}
if(Maze1[y][x] == 0){floor.add(new Floor(x*50,y*46));}
if(Maze1[y][x] == 1){wall.add(new Wall(x*50,y*46,0));wall.add(new Wall(x*50,y*46-4,0));
wall.add(new Wall(x*50,y*46-8,0));wallT.add(new Wall(x*50,y*46-12,1));}
}
}
}
public void WallCollision(Wall w){
Rectangle wall = new Rectangle(w.x,w.y,50,50);
Rectangle U = new Rectangle(prey.x + 20,prey.y + 10,13,5);
Rectangle D = new Rectangle(prey.x + 20,prey.y + 20,13,5);
Rectangle L = new Rectangle(prey.x + 12,prey.y + 20,5,5);
Rectangle R = new Rectangle(prey.x + 35,prey.y + 20,5,5);
if(U.intersects(wall)){prey.y += 2;prey.gy -= 2;}
else if(D.intersects(wall)){prey.y -= 2;prey.gy += 2;}
else if(L.intersects(wall)){prey.x += 2;prey.gx -= 2;}
else if(R.intersects(wall)){prey.x -= 2;prey.gx += 2;}
}
public void paint(Graphics g,Graphics2D g2d){
g2d = (Graphics2D) g;
g2d.translate(prey.gx,prey.gy);
for(Floor f : floor){f.paint(g,g2d);}
for(Wall w : wall){w.paint(g,g2d);}
prey.paint(g,g2d);
for(Wall w : wallT){w.paint(g,g2d);}
}
}
Maps.java
import java.util.*;
import java.io.*;
public class Maps{
Scanner s;
public int Maze1[][] = new int[23][33];
public Maps(){
Maze1();
}
public void Maze1(){
try{
s = new Scanner(new File("C:/Users/LordBerzerker97/Desktop/Games/MindMaze/CodeMM/src/MapHolder/Maze1.txt")).useDelimiter(",");
}catch(Exception e) {System.out.println(e + "ERROR");}
for(int y = 0;y < Maze1.length;y++){
for(int x = 0;x < Maze1[y].length;x++){
if(s.hasNextInt()){
Maze1[y][x] = s.nextInt();
}
}
if(s.hasNextLine()){
s.nextLine();
}
}
}
}
Prey.java
import java.awt.event.*;
import java.awt.image.*;
import java.awt.*;
import java.io.*;
public class Prey implements KeyListener{
SpriteLoader SL = new SpriteLoader();
BufferedImage preySheet = null;
BufferedImage preyL,preyR,preyU,preyD;
public int vx,vy,x,y,gx,gy;
public Prey(int x,int y,int gx,int gy){
this.x = x;
this.y = y;
this.gx = gx;
this.gy = gy;
try {
preySheet = SL.LoadImage("Images/Prey.png");
} catch (IOException e) {
e.printStackTrace();
}
SpriteSheetHolder SSH = new SpriteSheetHolder(preySheet);
preyD = SSH.GrabSprite(0,0,50,50);
}
public void paint(Graphics g,Graphics2D g2d){
g2d = (Graphics2D) g;
g2d.drawImage(preyD,x,y,50,50,null);
}
public void Movement(){
x += vx;
y += vy;
gx -= vx;
gy -= vy;
}
public void VelocityX(int vx){this.vx = vx;}
public void VelocityY(int vy){this.vy = vy;}
public void keyPressed(KeyEvent e){
int KeyCode = e.getKeyCode();
if(KeyCode == KeyEvent.VK_A){VelocityX(-2);}
else if(KeyCode == KeyEvent.VK_W){VelocityY(-2);}
else if(KeyCode == KeyEvent.VK_S){VelocityY(+2);}
else if(KeyCode == KeyEvent.VK_D){VelocityX(+2);}
}
public void keyReleased(KeyEvent e){
int KeyCode = e.getKeyCode();
if(KeyCode == KeyEvent.VK_A){VelocityX(0);}
else if(KeyCode == KeyEvent.VK_W){VelocityY(0);}
else if(KeyCode == KeyEvent.VK_S){VelocityY(0);}
else if(KeyCode == KeyEvent.VK_D){VelocityX(0);}
}
public void keyTyped(KeyEvent e){}
}
SpriteLoader.java
import java.awt.image.*;
import javax.imageio.*;
import java.net.*;
import java.io.*;
public class SpriteLoader{
public BufferedImage LoadImage(String ImagePath) throws IOException{
URL url = this.getClass().getResource(ImagePath);
BufferedImage img = ImageIO.read(url);
return img;
}
}
SpriteSheetHolder.java
import java.awt.image.*;
public class SpriteSheetHolder{
public BufferedImage SpriteSheetHold;
public SpriteSheetHolder(BufferedImage SSH){
this.SpriteSheetHold = SSH;
}
public BufferedImage GrabSprite(int x,int y,int width,int height){
BufferedImage sprite = SpriteSheetHold.getSubimage(x,y,width,height);
return sprite;
}
}
Wall.java
import java.awt.image.*;
import java.awt.*;
import java.io.*;
public class Wall{
SpriteLoader SL = new SpriteLoader();
BufferedImage WallSheet = null;
BufferedImage wall;
public int x,y,Direction;
public Wall(int x,int y,int Direction){
this.x = x;
this.y = y;
this.Direction = Direction;
try {
WallSheet = SL.LoadImage("Images/Wall.png");
} catch (IOException e) {
e.printStackTrace();
}
SpriteSheetHolder SSH = new SpriteSheetHolder(WallSheet);
if(Direction == 0){wall = SSH.GrabSprite(0,0,50,50);}
else if(Direction == 1){wall = SSH.GrabSprite(50,0,50,50);}
}
public void paint(Graphics g,Graphics2D g2d){
g2d = (Graphics2D) g;
g2d.drawImage(wall,x,y,50,50,null);
}
}
Floor.java
import java.awt.image.*;
import java.awt.*;
import java.io.*;
public class Floor{
SpriteLoader SL = new SpriteLoader();
BufferedImage FloorSheet = null;
BufferedImage Floor;
int x,y;
public Floor(int x,int y){
this.x = x;
this.y = y;
try {
FloorSheet = SL.LoadImage("Images/Floor.png");
} catch (IOException e) {
e.printStackTrace();
}
SpriteSheetHolder SSH = new SpriteSheetHolder(FloorSheet);
Floor = SSH.GrabSprite(0,0,50,50);
}
public void paint(Graphics g,Graphics2D g2d){
g2d = (Graphics2D) g;
g2d.drawImage(Floor,x,y,50,50,null);
}
}
Sorry for the lots of code. I tried creating a splash screen once but it didn’t work either so I removed it.
Have you tried profiling your code? A profiler like VisualVM is excellent. It is included in the JDK at PATH_TO_JDK\bin\jvisualvm.exe
How about your assets? to put it honest maybe you amde it too mess. I look multiple class extending JPanel so you end up having multiple Graphics object instances. There’s also more than one KeyListener too.
So then should I lessen the amount of graphics objects in the game? Should I also remove the keyListener in prey.java? Also what happens if I add more than one run method, is it good or bad?
well first of what is exactly is slow ?
do some system.outs and find out what is the slow part, and then by slow, how slow are we talking ?
Well I mean when I double click on the jar it takes some time for it to startup. Like right when I double click on the jar it takes a few seconds then the window pops up.
yes but what part in the code
How can you use System.outs to find the parts that are slow? Is it like System.out.println("ERROR "+e); inside a try and catch block? Or does it have to be something else other than an Exception.
Obviously the problem is in code that runs before the game window is displayed.
That’s an awful lot of code you posted. That said, just think about what your program is doing before it ever displays its window. For example, it looks to create lots of “stuff” (you instantiate member variables outside of constructor or method bodies, which causes them to be run early on). Chances are something here is slowing you down. Without digging too deep, I’d be suspicious of the stuff done in the MapDirector class.
For example, in each iteration in your double-nested for-loop in MapDirector, you create a minimum of 2, and a maximum of 4, combination of Wall and Floor instances. This is an average of (23333) = 2277 Walls/Floors, depending on what’s in your map data file. Now, each Wall and Floor create their own Image to paint themselves; however, there’s no need for each Wall instance (for example) to have a separate copy of the wall image. The same goes for the floors. What you should be doing is create each of these two images once, then have all Floors reference the same floor BufferedImage, and all Walls reference the same wall BufferedImage. This will save ~ 2275 image loads on your game’s startup.
Another thing to keep in mind is you might want to follow standard Java code conventions, in particular those for variable names. Usually, variable and method names start with lower-case letters. Following these conventions will make your code much easier for fellow Java programmers to read, and they’re pretty much universally followed.
So what I should do then in the mapDirector class is not to use g.drawImage in the Wall and Floor class themselves, but instead draw them in the mapDirector class?
Usually you would want to create some kind of Art/Asset manager but here you should be safe making a static Image variable in Wall and Floor that all instances share.
I understand what static means, but what will changing the bufferedImages static going to do? Sorry for questioning just curious.
Ok so I changed some code in the wall class, the floor class, and the MapDirector class.
MapDirector.java
import java.util.*;
import java.awt.*;
public class MapDirector{
Maps M = new Maps();
Prey prey;
ArrayList<Floor> floor = new ArrayList<Floor>();
ArrayList<Wall> wall = new ArrayList<Wall>();
ArrayList<Wall> wallT = new ArrayList<Wall>();
private int Maze1[][] = M.Maze1;
public MapDirector(){
prey = new Prey(50,50,500,270);
for(int y = 0;y < Maze1.length;y++){
for(int x = 0;x < Maze1[y].length;x++){
if(Maze1[y][x] == 0){floor.add(new Floor(x*50,y*46));}
if(Maze1[y][x] == 1){wall.add(new Wall(x*50,y*46,1));wall.add(new Wall(x*50,y*46-4,1));
wall.add(new Wall(x*50,y*46-8,1));wallT.add(new Wall(x*50,y*46-12,1));}
}
}
}
public void WallCollision(Wall w){
Rectangle wall = new Rectangle(w.x,w.y,50,50);
Rectangle U = new Rectangle(Prey.x + 20,Prey.y + 10,13,5);
Rectangle D = new Rectangle(Prey.x + 20,Prey.y + 20,13,5);
Rectangle L = new Rectangle(Prey.x + 17,Prey.y + 20,5,5);
Rectangle R = new Rectangle(Prey.x + 30,Prey.y + 20,5,5);
if(U.intersects(wall)){Prey.y += 2;Prey.gy -= 2;}
else if(D.intersects(wall)){Prey.y -= 2;Prey.gy += 2;}
else if(L.intersects(wall)){Prey.x += 2;Prey.gx -= 2;}
else if(R.intersects(wall)){Prey.x -= 2;Prey.gx += 2;}
}
public void paint(Graphics g,Graphics2D g2d){
g2d = (Graphics2D) g;
g2d.translate(Prey.gx,Prey.gy);
for(Floor f : floor){g2d.drawImage(Floor.floor,f.x,f.y,50,50,null);}
for(Wall w : wall){g2d.drawImage(Wall.wall,w.x,w.y,50,50,null);}
prey.paint(g,g2d);
for(Wall w : wallT){g2d.drawImage(Wall.wall,w.x,w.y,50,50,null);}
}
}
Floor.java
import java.awt.image.*;
import java.io.*;
public class Floor{
SpriteLoader SL = new SpriteLoader();
BufferedImage FloorSheet = null;
static BufferedImage floor;
public int x,y;
public Floor(int x,int y){
this.x = x;
this.y = y;
try {
FloorSheet = SL.LoadImage("Images/Floor.png");
} catch (IOException e) {
e.printStackTrace();
}
SpriteSheetHolder SSH = new SpriteSheetHolder(FloorSheet);
floor = SSH.GrabSprite(0,0,50,50);
}
}
Wall.java
import java.awt.image.*;
import java.io.*;
public class Wall{
SpriteLoader SL = new SpriteLoader();
BufferedImage WallSheet = null;
static BufferedImage wall;
public int x,y,Direction;
public Wall(int x,int y,int Direction){
this.x = x;
this.y = y;
this.Direction = Direction;
try {
WallSheet = SL.LoadImage("Images/Wall.png");
} catch (IOException e) {
e.printStackTrace();
}
SpriteSheetHolder SSH = new SpriteSheetHolder(WallSheet);
if(Direction == 0){wall = SSH.GrabSprite(0,0,50,50);}
else if(Direction == 1){wall = SSH.GrabSprite(50,0,50,50);}
}
}
No you’re still loading the image in the constructor, which means it will reload with every single instance. Load the image in a static block:
public class Wall {
....
static BufferedImage wall;
static {
try{
wall = SL.LoadImage("Images/Wall.png");
}
catch(Exception exc) {}
}
...
}
Ok so now it runs a bit faster. Thanks for the help guys:D
Try making your constructor in MapDirector like this:
public MapDirector(){
BufferedImage FloorSheet = SL.LoadImage("Images/Floor.png");
BufferedImage WallSheet = SL.LoadImage("Images/Wall.png");
prey = new Prey(50,50,500,270);
for(int y = 0;y < Maze1.length;y++){
for(int x = 0;x < Maze1[y].length;x++){
if(Maze1[y][x] == 0){floor.add(new Floor(x*50,y*46, FloorSheet));}
if(Maze1[y][x] == 1){wall.add(new Wall(x*50,y*46,1, WallSheet));wall.add(new Wall(x*50,y*46-4,1, WallSheet));
wall.add(new Wall(x*50,y*46-8,1, WallSheet));wallT.add(new Wall(x*50,y*46-12,1, WallSheet));}
}
}
}
This way you load the images only once, and all your classes use the same images.
In other word, let an entity hold pointer to image object somewhere not the image itself.