2021年4月6日星期二

Minigame Program gets stuck at beggining

So, for testing my skill i wanted to create a minigame, about tanks because "why not", the problem is that my program seems to get stuck when i run it, showing no errors during compilation, i only get a white screen with no tanks, but when i minimize the window, wait a while and reopen it, the tanks appear, and they weren't supposed to, they were supposed to already be in the screen when program starts running, also, even after reopening the window, KeyListener doesn't work either, i guess it's an error maybe on method startGame() or run() but i don't know.

If needed, here's the code, all of it.

//=============================================================================================================================================================|IMPORTS  import javax.swing.JFrame;  import javax.swing.JPanel;  import javax.swing.JOptionPane;    import javax.imageio.ImageIO;    import java.awt.Color;  import java.awt.Graphics;  import java.awt.Graphics2D;  import java.awt.RenderingHints;  import java.awt.Rectangle;    import java.awt.event.KeyEvent;  import java.awt.event.KeyListener;    import java.awt.image.BufferedImage;  import java.awt.image.AffineTransformOp;    import java.awt.geom.AffineTransform;    import java.lang.Math;    import java.util.ArrayList;    import java.io.IOException;    //=============================================================================================================================================================|CLASSES  public class MegaTank extends JPanel implements Runnable, KeyListener {      private static volatile boolean RUNNING = false;      private static Thread AuxThread1;        //Game physics constants:      //This three values are used on the tank classes, on the constructor and methods move() and accelerate(), scroll down to see them.      public static final int SCALE = 3;          //Scales tanks sizes by this factor.      public static final double BOUNCE = 5;      //Coefficient used to set elasticity of walls in a collision (Inversely proportional).      public static final double FRICTION = 0.5;  //Determines how fastly tanks naturally decelerate when they aren't already accelerating.        public SpriteRender TankRender = new SpriteRender();      public ArrayList<Tank> TankList = new ArrayList<Tank>();      public Hero Player1 = new Hero(this, 100, 300);        public MegaTank() {          addKeyListener(this);          setFocusable(true);          setBackground(Color.WHITE);          setDoubleBuffered(true);      }        @Override      public void keyTyped(KeyEvent e) {          if(e.getKeyCode() == KeyEvent.VK_G) {              TankList.add(new Goblin(Player1.Canvas, 0, 0));          }      }        @Override      public void keyPressed(KeyEvent e) {          Player1.keyPressed(e);      }        @Override      public void keyReleased(KeyEvent e) {          Player1.keyReleased(e);      }        private synchronized void startGame() {          RUNNING = true;            AuxThread1 = new Thread(this, "2DRenderer");          AuxThread1.start();            TankList.add(new Thunder(this, 600, 200));          TankList.add(new Thunder(this, 700, 100));          TankList.add(new Goblin(this, 300, 400));      }        private synchronized void stopGame() {          RUNNING = false;            try {              AuxThread1.join();          } catch(InterruptedException E) {              E.printStackTrace();          }      }        public void run() {          final long NPS = 1000000000;    //Nanoseconds in a second, by definition is 1000000000.          final byte UPS = 40;            //Number of objective updates per second.          final byte FPS = 40;            //Number of objective visual frames per second.          final double NPU = NPS / UPS;   //Nanoseconds per update.          final double NPF = NPS / FPS;   //Nanoseconds per frame.            long TicksTag = System.nanoTime();  //Timestamp used for updates and frames.            double TimerTag = 0;          double DeltaTag = 0;          double GammaTag = 0;            while(RUNNING) {              final long StartTag = System.nanoTime();                TimerTag = StartTag - TicksTag;              TicksTag = StartTag;              DeltaTag = DeltaTag + TimerTag / NPU;                while(DeltaTag >= 1) {                  DeltaTag--;                    refresh();                  repaint();              }          }      }        public void refresh() {          for(int I = 0; I < TankList.size(); I++) {              TankList.get(I).move();          }            Player1.move();      }        public void paint(Graphics G) {          super.paint(G);          Graphics2D G2D = (Graphics2D)(G);            for(int I = 0; I < TankList.size(); I++) {              TankList.get(I).paint(G2D);          }            Player1.paint(G2D);      }        public static void main(String[] args) {          GameForm Form1 = new GameForm(1300, 700, "MegaTank");          MegaTank Game1 = new MegaTank();          Form1.add(Game1);          Game1.startGame();      }  }    abstract class Tank {      //Interactions      protected MegaTank Canvas;        //Position      protected double X;      protected double Y;        //Velocity      protected double VX;      protected double VY;        //Acceleration      protected double AX;      protected double AY;        //Turret rotation      protected char Rotation = 'D';      //Symbolises turret rotation of the tank, uses WASD keys for identification.        //Game stats      protected int Health;           //Hitpoints of the unit. When 0, the unit dies.      protected int Damage;           //Hitpoints removed to striked targets per hit.      protected int MSpeed;           //Maximum movement speed of the unit in straight line.      protected int Pixels;           //Physical size in pixels of the unit (excluding scaling).        //Sprite      protected String SpriteName;        //File name of the sprite sheet for the tank model.      protected boolean Symmetric;        //Whether or not the tank model is aesthetically symmetric, without this, tank rendering can be inaccurate.      protected BufferedImage TankSprite; //Image used for rendering the object, is cut from the sprite sheet and can be replaced.        public Tank(MegaTank Canvas, int X, int Y) {          this.Canvas = Canvas;          this.X = X;          this.Y = Y;      }        public void accelerate() {          VX = VX + AX;          VY = VY + AY;            if(Math.abs(VX + AX) > MSpeed) {              VX = (Math.abs(VX) / VX) * MSpeed;          }            if(Math.abs(VY + AY) > MSpeed) {              VY = (Math.abs(VY) / VY) * MSpeed;          }            if(AX == 0) {              if(VX > 0) {                  VX = VX - Canvas.FRICTION;              }                if(VX < 0) {                  VX = VX + Canvas.FRICTION;              }          }            if(AY == 0) {              if(VY > 0) {                  VY = VY - Canvas.FRICTION;              }                if(VY < 0) {                  VY = VY + Canvas.FRICTION;              }          }      }        public void move() {          accelerate();          animate();            if(X + VX < 0) {              VX = -VX / Canvas.BOUNCE;          }            if(X + VX > Canvas.getWidth() - Pixels * Canvas.SCALE) {              VX = -VX / Canvas.BOUNCE;          }            if(Y + VY < 0) {              VY = -VY / Canvas.BOUNCE;          }            if(Y + VY > Canvas.getHeight() - Pixels * Canvas.SCALE) {              VY = -VY / Canvas.BOUNCE;          }            X = X + VX;          Y = Y + VY;      }        public void animate() {          if(Symmetric) {              if(AX > 0) {                  TankSprite = Canvas.TankRender.scaleSprite(Canvas.TankRender.cutSprite(SpriteName, 0, 0, Pixels), Canvas.SCALE);              }                if(AX < 0) {                  TankSprite = Canvas.TankRender.scaleSprite(Canvas.TankRender.cutSprite(SpriteName, 2, 0, Pixels), Canvas.SCALE);              }                if(AY > 0) {                  TankSprite = Canvas.TankRender.scaleSprite(Canvas.TankRender.cutSprite(SpriteName, 3, 2, Pixels), Canvas.SCALE);              }                if(AY < 0) {                  TankSprite = Canvas.TankRender.scaleSprite(Canvas.TankRender.cutSprite(SpriteName, 1, 2, Pixels), Canvas.SCALE);              }          } else {              if(AX > 0) {                  TankSprite = Canvas.TankRender.scaleSprite(Canvas.TankRender.cutSprite(SpriteName, 0, 0, Pixels), Canvas.SCALE);              }                if(AX < 0) {                  TankSprite = Canvas.TankRender.scaleSprite(Canvas.TankRender.cutSprite(SpriteName, 6, 0, Pixels), Canvas.SCALE);              }                if(AY > 0) {                  TankSprite = Canvas.TankRender.scaleSprite(Canvas.TankRender.cutSprite(SpriteName, 7, 2, Pixels), Canvas.SCALE);              }                if(AY < 0) {                  TankSprite = Canvas.TankRender.scaleSprite(Canvas.TankRender.cutSprite(SpriteName, 1, 2, Pixels), Canvas.SCALE);              }          }      }        public void paint(Graphics2D G2D) {          G2D.drawImage(TankSprite, (int)(X), (int)(Y), Canvas);      }  }    class Hero extends Tank {      public Hero(MegaTank Canvas, int X, int Y) {          super(Canvas, X, Y);            Health = 3;          Damage = 1;          MSpeed = 3;          Pixels = 20;            Symmetric = false;          SpriteName = "Hero.Bmp";          TankSprite = Canvas.TankRender.scaleSprite(Canvas.TankRender.cutSprite(SpriteName, 0, 0, Pixels), Canvas.SCALE);      }        public void keyTyped(KeyEvent e) {}        public void keyPressed(KeyEvent e) {          if(e.getKeyCode() == KeyEvent.VK_RIGHT) {              AX = 0.5;          }            if(e.getKeyCode() == KeyEvent.VK_LEFT) {              AX = -0.5;          }            if(e.getKeyCode() == KeyEvent.VK_DOWN) {              AY = 0.5;          }            if(e.getKeyCode() == KeyEvent.VK_UP) {              AY = -0.5;          }      }        public void keyReleased(KeyEvent e) {          if(e.getKeyCode() == KeyEvent.VK_RIGHT || e.getKeyCode() == KeyEvent.VK_LEFT) {              AX = 0;          }            if(e.getKeyCode() == KeyEvent.VK_DOWN || e.getKeyCode() == KeyEvent.VK_UP) {              AY = 0;          }      }  }    class Goblin extends Tank {      public Goblin(MegaTank Canvas, int X, int Y) {          super(Canvas, X, Y);            Health = 1;          Damage = 1;          MSpeed = 5;          Pixels = 10;            Symmetric = true;          SpriteName = "Goblin.Bmp";          TankSprite = Canvas.TankRender.scaleSprite(Canvas.TankRender.cutSprite(SpriteName, 0, 0, Pixels), Canvas.SCALE);            AX = 0.5; //FOR DEBUGGING      }  }    class Thunder extends Tank {      public Thunder(MegaTank Canvas, int X, int Y) {          super(Canvas, X , Y);            Health = 3;          Damage = 2;          MSpeed = 2;          Pixels = 20;            Symmetric = false;          SpriteName = "Thunder.Bmp";          TankSprite = Canvas.TankRender.scaleSprite(Canvas.TankRender.cutSprite(SpriteName, 0, 0, Pixels), Canvas.SCALE);            AY = 0.01; //FOR DEBUGGING      }  }  
https://stackoverflow.com/questions/66978647/minigame-program-gets-stuck-at-beggining April 07, 2021 at 10:06AM

没有评论:

发表评论