I'm making simple 2D games. I have a game loop, and in the game loop i have an update
method. I make things move by adding 1 to xPos whenever it loops. This means that if you have a slow fps then everything goes in slow motion and if you have a high fps everything moves
really quick.
This is my code:
long fpsTimer;
int frames;
public void run(){
running = true;
fpsTimer = System.nanoTime();
while(running){
render();
update();
try{
Thread.sleep(6);
}catch(InterruptedException e){}
frames++;
if(System.nanoTime() >= fpsTimer+1000000000){
System.out.println(frames+" fps");
frames = 0;
fpsTimer = System.nanoTime();
}
}
}
All Code
import java.awt.*;
import java.awt.image.*;
import javax.swing.JFrame;
import java.awt.event.*;
public class Game extends Canvas implements Runnable{
public static final int WIDTH = 800;
public static final int HEIGHT = 300;
public JFrame f;
private String title = "Untitled Test";
private Image image;
private Sprite player;
public Game(){
player = new Sprite(100, 100);
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setMaximumSize(new Dimension(WIDTH, HEIGHT));
setMinimumSize(new Dimension(WIDTH, HEIGHT));
addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e){
player.keyPressed(e.getKeyCode());
}
public void keyReleased(KeyEvent e){
player.keyReleased(e.getKeyCode());
}
});
}
public static void main(String[] args){
Game g = new Game();
g.f = new JFrame(g.title);
g.f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
g.f.add(g);
g.f.setResizable(false);
g.f.pack();
g.f.setLocationRelativeTo(null);
Thread gameLoop = new Thread(g);
gameLoop.start();
g.f.setVisible(true);
}
private void render(){
BufferStrategy bs = getBufferStrategy();
if(bs==null){
createBufferStrategy(3);
return;
}
image = createImage(WIDTH, HEIGHT);
Graphics g = image.getGraphics();
player.draw(g);
g.dispose();
Graphics bsg = bs.getDrawGraphics();
bsg.drawImage(image, 0, 0, WIDTH, HEIGHT, null);
bsg.dispose();
bs.show();
}
private void update(){
player.move();
}
long fpsTime;
int frames;
public void run(){
fpsTime = System.nanoTime();
while(true){
render();
update();
try{
Thread.sleep(6);
}catch(InterruptedException e){}
frames++;
if(System.nanoTime() >= fpsTime+1000000000){
System.out.println(frames+" fps");
frames = 0;
fpsTime = System.nanoTime();
}
}
}
}
First of all you should not have a constant sleep time. Instead, the value should be dynamically computed. Maybe its easier to use Timer#scheduleAtFixedRate(...) cause this already takes care of that for you.
Then, 6 ms per iteration seems much too less. 60 frames per second is ideal (if you just have 30, its ok too i think), so 16 ms is enough (or about 32 for 30 fps). (Note that the refresh rate of your screen is the upper limit - it should be about 60 Hz - more doesn't make sense).
Thirdly think about dynamically computing the moves of your objects. Instead of having a constant delta that you add to the coordinates you should better have some kind of 'move function' that calculates the coordinates based on the current time.
Let's say you want to move an object along the x-axis with a constant speed of pps pixels per second. The function for the x coordinate of that object would then be:
x(t) := x0 + (t - t0) * pps / 1000
(t is the time that has passed since start in ms, x0 is the initial x coordinate of the object when it appeared first, t0 is the time at which the object appeared, pps is the number of pixels the object should move per second).
This makes your objects move with the same speed - no matter what framerate you've got.
Note that this approach gets more complex if your objects should react to user input or other events (like collisions etc.).
Related
I am currently working on a 3 cushion billiards game project. I have added two balls on the table so far. I am trying to move one of the balls but I am having a hard time doing that. Should I use a timer? If so then could you tell me an effective way to use the timer on my code so I can move my balls?
Your help would be much appreciated.
Thanks in advance.
Farhan Hasan
I have tried to create a move function for the class balls. But I am not sure what I should put inside the function, I have added the xSpeed and ySpeed. The xLocation and the yLocation changes depending on the xSpeed and ySpeed.
public class Balls
{
private Color ballFillColor;
private Color ballBorderColor;
private int ballX = 0;
private int ballY = 0;
private int xSpeed = 5;
private int ySpeed = 0;
private int ballWidth = 0;
private int ballHeight = 0;
Timer t;
public boolean fillBall = false;
private static Balls ballArray[]; //Required for drawMultipleBalls
Balls(){ //Constructor
ballBorderColor = Color.black;
}
Balls(int ballX, int ballY, int ballWidth, int ballHeight, Color ballBorderColor, JFrame window){ //Constructor
// X , Y , Width, Height, Border Colour, container
this.setBallBorderColor(ballBorderColor);
this.setBallWidth(ballWidth);
this.setBallHeight(ballHeight);
this.setBallX(ballX);
this.setBallY(ballY);
this.drawBall(window);
}
//Here is the move function. I am not really sure what to do here.
public void move()
{
if(this.ballX < 1000 - this.ballWidth)
{
this.ballX += this.xSpeed;
}
try
{
Thread.sleep(1);
}
catch(Exception e)
{
}
}
//GET AND SET FUNCTIONS HERE
//HERE ARE THE FUNCTIONS WHICH ARE RESPONSIBLE FOR DRAWING MY BALLS IN JFRAME
public void drawBall(JFrame frame)
{
frame.getContentPane().add(new MyComponent());
}
public void drawMultipleBalls(JFrame frame, Balls[] balls)
{
ballArray = balls;
frame.getContentPane().add(new MyComponent2());
}
private class MyComponent extends JComponent{
public void paintComponent(Graphics g){
if (fillBall) //Fill first, and then draw outline.
{
g.setColor(ballFillColor);
g.fillOval(getBallX(),getBallY(), getBallHeight(),getBallWidth());
}
g.setColor(getBallBorderColor());
g.drawOval(getBallX(),getBallY(), getBallHeight(),getBallWidth());
}
}
private class MyComponent2 extends JComponent{
public void paintComponent(Graphics g){
for (int i = 0; i < ballArray.length; i++)
{
if (ballArray[i].fillBall) //Fill first, and then draw outline.
{
g.setColor(ballArray[i].ballFillColor);
g.fillOval(ballArray[i].getBallX(),ballArray[i].getBallY(), ballArray[i].getBallHeight(),ballArray[i].getBallWidth());
}
g.setColor(ballArray[i].getBallBorderColor());
g.drawOval(ballArray[i].getBallX(),ballArray[i].getBallY(), ballArray[i].getBallHeight(),ballArray[i].getBallWidth());
}
}
}
Hopefully, I can have two movable balls for the game, the should bounce back as the hit the edge of the screen and they should be able to slow down over time. For that, I am thinking to use a damper (I will multiply the xSpeed and ySpeed with a number less than 1, eventually it will slow down the ball)
Here is a simple example I came up with to show a ball moving and bouncing off the edges.
The direction changes based on the boundary. Left and top edges just check for 0. Bottom and right edges need to include the diameter of the ball.
The x and y increments are independent. And these amounts in conjunction with the timer can change the movement. Notice however, that to have objects bounce off of each other (as in a pool game) is more complicated due to angle of trajectories, etc. And the distances bounced will vary and slow with time based on frictional values. Everything else is documented in the Java API.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MovementDemo extends JPanel implements ActionListener {
JFrame frame = new JFrame("Movement Demo");
int size = 500;
int x = 50;
int y = 200;
int diameter = 50;
int yinc = 2;
int xinc = 2;
int xdirection = 1;
int ydirection = 1;
public MovementDemo() {
setPreferredSize(new Dimension(size, size));
frame.add(this);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new MovementDemo().start());
}
public void start() {
Timer timer = new Timer(100, this);
timer.setDelay(5);
timer.start();
}
public void actionPerformed(ActionEvent ae) {
if (x < 0) {
xdirection = 1;
}
else if (x > size - diameter) {
xdirection = -1;
}
if (y < 0) {
ydirection = 1;
}
else if (y > size - diameter) {
ydirection = -1;
}
x = x + xdirection * xinc;
y = y + ydirection * yinc;
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.BLUE);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.fillOval(x, y, diameter, diameter);
}
}
It seems in general there are a few things you need to figure out:
has the ball collided with another ball
has the ball collided with a wall
otherwise just figure out what is the ball's new position based on its velocity
Below is some sample code that stubs some of this out. You can first compare the current ball's position to all others (not including the current ball of course). If there are any equal positions, process a collision with a ball. If the ball is at the window border i.e it hit a wall, process a collision with a wall. Otherwise just calculate its new position based on its current velocity.
The process collision part is just to apply physics mechanics to whatever degree of complexity you require. One general suggested change would be to update the velocity of the balls then apply it to the position after. The specific calculations for velocity changes you could apply as needed and as you can imagine it can get pretty involved which is why I suggest using a separate method and possibly a sub class for velocity instead of managing each part of the velocity vector in the ball itself. I used the wall as an object because of this. The composition, weights, velocities etc of the object's colliding can affect the resulting collision, but how complex you want that processing to be is up to you.
Sorry I'm no physics expert but I hope this sends you in the right direction in terms of code! Also this might help with the specific calculations you might want to use:
https://www.khanacademy.org/science/physics/one-dimensional-motion/displacement-velocity-time/v/calculating-average-velocity-or-speed
public void move()
{
// check if balls are on same position not including this ball
for(Ball b: ballArray){
if (this.position == b.position && this != b){
processCollision(this, b, null);
} else{
// if the ball hasn't collided with anything process its movement based on speed
// this assumes a 1000 x 1000 window for keeping objects inside it
if(this.ballX < 1000 - this.ballWidth && this.ballY < 1000 - this.ballHeight){
this.ballX += this.xSpeed;
this.ballY += this.ySpeed;
}else {
processCollision(this, null, new Wall());
}
}
}
try
{
Thread.sleep(1);
}
catch(Exception e)
{
}
}
public void processCollision(Ball b1, Ball b2, Wall w){
// if ball hasn't collided with a wall, process a ball - ball collision
if(w == null){
// apply physics mechanics according the complexity desired for ball collisions
b1.xSpeed -= b2.xSpeed;
b1.ySpeed -= b2.ySpeed;
// ball 2 would end up slowing down
b2.xSpeed -= b1.xSpeed;
b2.ySpeed -= b1.ySpeed;
}
// if ball hasn't collided with a ball, process a ball - wall collision
if(b2 == null){
// apply physics mechanics for hitting a wall
// e.g as below: just send ball in opposite direction
b1.xSpeed = b1.xSpeed * -1;
b1.ySpeed = b1.ySpeed * -1;
}
// either way, process ball's new position based on its new speed
b1.ballX += b1.xSpeed;
b1.ballY += b1.ySpeed;
b2.ballX += b2.xSpeed;
b2.ballY += b2.ySpeed;
}
i have to do an exercise of java swing.
draw a simple circle/ball (done)
move a circle (done)
from a starting point (half of jpanel(x),0(y)) move this circle/ball that follow an arch direction and bounce when the circle touch the end of screen side (in my case the window it's only x: 0-300 y: 0-300, it's a very little windows)
when the screen end (see picture that i have linked below) continue to bounce in arch movement following the sides of screen until ball return in initial position,no need to be exactly initial position but bounce must is infinite and continuosly(sorry for my english)
https://imgur.com/jNtxeld
what's the function that i need for doing an arch movement? i can't use graphic2d or existent class in java, i need function to apply for x,y for move this ball
i know arch formula from mathematic but i don't know how apply in java in this case, i think i need a function for get all points of a arch position and then i can apply to x and y for move the ball.
help
i have this code
public class Ani2 extends JPanel implements Runnable{
private final int DELAY =105;
public Ani2(){
JFrame jf = new JFrame();
jf.setSize(300,300);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.add(this);
jf.setVisible(true);
}
private Thread animator;
int x=150, y=150;
#Override
public void addNotify() {
super.addNotify();
animator = new Thread(this);
animator.start();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(red);
Graphics2D g2d = (Graphics2D)g;
g2d.fillOval(x,y, 20, 20);
g.dispose();
}
public static void main(String[] args) {
new Ani2();
}
#Override
public void run() {
long beforeTime, timeDiff, sleep;
beforeTime = System.currentTimeMillis();
while (true) {
x += 1;
y -= 1;
repaint();
timeDiff = System.currentTimeMillis() - beforeTime;
sleep = DELAY - timeDiff;
if (sleep < 0)
sleep = 2;
try {
Thread.sleep(sleep);
} catch (InterruptedException e) {
System.out.println("interrupted");
}
beforeTime = System.currentTimeMillis();
}
}
}
I'm guessing that "arch function" means physics.
Imagine your ball sitting at rest on a ledge at height h above a surface. The ball has mass m; gravity exerts a force on the ball equal to m*g in the down direction.
The equations of motion for the ball are:
F = m*a
This is a vector equation, because force, acceleration, velocity, and displacement are all vector quantities.
I can use calculus to solve for the distance the ball falls from the height after giving it a push in the positive x-direction (initial x-velocity).
The result will be a quadratic equation.
I am trying to create a fading/transitioning colors algorithm between two colors and a timer; the timer will determine how fast the colors swap between one another. The only problem is: the more fading transition objects I add in, the faster they all go. For example: If I add in one StandardFade (the class) object, it will run at the timer (alpha, in the code) I give it. However, if more objects that do 'fade' appear on the screen, the timer is no longer relevant, and they all go at the same rate, faster and faster with each object. Can anyone explain why?
//Test Game Class, Implements the StandardFades
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;
public class TestGame extends Canvas implements Runnable{
private static final long serialVersionUID = -7267473597604645224L;
private Thread thread;
private boolean running = false;
private boolean consoleFPS = true;
private boolean titleFPS = true;
private TestWindow window;
//Fade objects, two is for a really long timer to test to see if they would transition at different times
StandardFade one = new StandardFade(Color.RED,Color.BLUE,.005);
StandardFade two = new StandardFade(Color.RED,Color.GREEN,.00000000000000001);
StandardFade three = new StandardFade(Color.RED,Color.YELLOW,.000005);
private int currentFPS;
private int frames;
public int levelNum;
public TestGame(int width, int height, String title){
this.window = new TestWindow(width,height, title, this);
this.initFades();
this.start();
}
private synchronized void start(){
if(running)
return;
else{
this.thread = new Thread(this);
this.thread.start();
this.running = true;
}
}
private synchronized void stop(){
if(!this.running)
return;
else{
try{
this.thread.join();
}catch(InterruptedException e){
e.printStackTrace();
}
this.running = false;
System.exit(0);
}
}
/**
* This game loop was provided by online sources, though there are many examples
* of a game loop online.
*
* #author RealTutsGML
*/
public void run() {
requestFocus(); //Focuses the click/input on the frame/canvas.
long lastTime = System.nanoTime(); //The current system's nanotime.
double ns = 1000000000.0 / 60.0; //Retrieves how many nano-seconds are currently in one tick/update.
double delta = 0; //How many unprocessed nanoseconds have gone by so far.
long timer = System.currentTimeMillis();
int frames = 0; //The frames per second.
int updates = 0; //The updates per second.
while (running) {
boolean renderable = false; //Determines if the game should render the actual graphics.
long now = System.nanoTime();//At this point, the current system's nanotime once again.
delta += (now - lastTime) / ns;
lastTime = now;
//If the amount of unprocessed ticks is or goes above one...
//Also determines if the game should update or not/render. Approximately sixty frames per second.
while (delta >= 1) {
tick();
delta--;
updates++;
renderable = true;
}
if(renderable){
frames++;
render();
}
if (System.currentTimeMillis() - timer > 1000) {
timer += 1000;
System.out.println(frames);
updates = 0;
frames = 0;
}
}
this.stop();
}
/**
* This method should tick everything that needs to be updated via positioning,
* mouse input, etc.
*/
private void tick(){
/********************PUT ALL TICKABLE METHODS IN THIS METHOD; ALL CALCULATIONS, EVERYTHING*********************/
//this.stdFadeHandler.get(0).tick();
//this.stdFadeHandler.tick();
one.tick();
two.tick();
three.tick();
/**********************************END OF TICK METHOD INFORMATION AND METHODS******************************/
}
private void render(){
BufferStrategy bs = this.getBufferStrategy();
if(bs == null){
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.BLACK);
g2.fillRect(0, 0, window.getWidth(), window.getHeight());
/*******************PLACE ALL DRAWING INSTRUCTIONS WITHIN THIS SECTION OF THE RENDER METHOD*************************/
g2.setColor(one.getColor());
g2.fillRect(20, 20, 200, 200);
g2.setColor(two.getColor());
g2.fillRect(20, 300, 200, 200);
g2.setColor(three.getColor());
g2.fillRect(20, 540, 200, 200);
//this.stdFadeHandler
/*******************DO NOT PLACE ANY MORE DRAWING INSTRUCTIONS WITHIN THIS SECTION OF THE RENDER METHOD***************/
g.dispose();
g2.dispose();
bs.show();
}
private void initFades(){
}
public static void main(String[] args){
TestGame stdGame = new TestGame(800,800,"Test Standard Game");
}
Below is the actual class that MAKES the frames: StandardFade
import java.awt.Color;
import java.awt.Graphics2D;
public class StandardFade {
private static float time = 0;
private static boolean firstColor = true;
private Color color1;
private Color color2;
private double alpha;
private Color fadeColor;
/**
* Lines that implement the
* r,g and b values come from Princeton University; I will author
* them in at the bottom.
*
* Method takes two parameters and fades them into one another according to a
* timer/clock value: alpha.
* #param c1 First color to be used.
* #param c2 Second color to be used.
* #param alpha How fast colors should shift. 0 <= n <= 1.
* Closer value is to zero, the longer it will take to shift.
* ***Important note about alpha: for non-seizure inducing colors, alpha <= .0005***
*
* The issue that is occurring is that, no matter what I do, no matter if I make
* different StandardFade objects and assign them, they will always render at the
* same rate, and faster and faster, depending on how many objects are fading.
*
* #return new Color based on r, g, and b values calculated.
*
* #author (Only code utilized was lines 58-60):
* http://introcs.cs.princeton.edu/java/31datatype/Fade.java.html
*/
public StandardFade(Color c1, Color c2, double alpha){
this.color1 = c1;
this.color2 = c2;
this.alpha = alpha;
}
public void tick() {
if(time <= 1f && firstColor){
time += alpha;
}
else{
firstColor = false;
}
if(time >= 0f && !firstColor)
time -= alpha;
else{
firstColor = true;
}
//System.out.println(time);
short r = (short) (time * color2.getRed() + (1 - time) * color1.getRed());
short g = (short) (time * color2.getGreen() + (1 - time) * color1.getGreen());
short b = (short) (time * color2.getBlue() + (1 - time) * color1.getBlue());
if(r > 255) r = 255;
if(g > 255) g = 255;
if(b > 255) b = 255;
if(r < 0) r = 0;
if(g < 0) g = 0;
if(b < 0) b = 0;
this.fadeColor = new Color(r, g, b);
}
public Color getColor(){
return this.fadeColor;
}
The only problem is: the more fading transition objects I add in, the faster they all go
private static float time = 0;
You are using a static variable for the time. This variable is shared by all instances of the ColorFade class. So each fading objects updates the same variable.
Don't use a static variable (just get rid of the static keyword). Each fading object needs its own "time" variable.
private float time = 0;
I also question if the firstColor variable should be static.
That's quite a lot of code to go through (try to reduce your problem down as much as possible in future) but based on your description of the problem - it gets faster the more objects you have - I'm guessing your problem is this line:
private static float time = 0;
I assume you're aware that static fields are shared between class instances. They do not each store their own separate value.
This causes problems because each instance increments the time value every time the tick method is called. That's okay when there is only one instance, but problematic when there are more.
Simply remove the static keyword and it should work properly:
private float time = 0;
I'm making simple spaceship game on JavaFX. I have class SpaceShip and i want to make random objects from this class in my main game loop on random starting position(in interval of 5 seconds for example). I try to use Timer schedule() method for the task. The problem is that i can't get clear image of the spaceship, it disappears and show in other point because of the constantly looping. Can someone help me with advice how to handle with this.
My game loop:
new AnimationTimer() {
#Override
public void handle(long currentNanoTime) {
double t = (currentNanoTime - startNanoTime) / 1000000000.0;
double xMoving = ((100 * t) % (canvas.getWidth() + 100));
double x = 232 + 128 * Math.cos(t);
double y = 232 + 128 * Math.sin(t);
//background image clears canvas
gc.drawImage(space, 0, 0);
gc.drawImage(earth, x, y);
gc.drawImage(sun, 196, 196);
// draw UFO
gc.drawImage(ufo.getFrame(t), 100, 25);
//draw spaceShip
SpaceShip.generate(new SpaceShip(spaceShipImageArr, 0.100, gc, t, xMoving - 100, (randomNum + 150)));
//timer schedule
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
SpaceShip.generate(new SpaceShip(spaceShipImageArr, 0.100, gc, t, xMoving - 100, (randomNum + 230)));
}
}, 5000);
}
}.start();
And the SpaceShip class:
package objectClasses;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.image.Image;
public class SpaceShip{
private final GraphicsContext gc;
private final double frame;
private final double y;
private final double x;
private AnimatedImage object;
public SpaceShip(Image[] arr, double duration, GraphicsContext gc, double frame, double x, double y) {
object = new AnimatedImage();
this.object.frames = arr;
this.object.duration = duration;
this.gc = gc;
this.frame = frame;
this.y = y;
this.x = x;
}
private void drawShip() {
this.gc.drawImage(this.object.getFrame(frame), x, y);
}
public static void generate(SpaceShip spaceShip) {
spaceShip.drawShip();
}
}
This is the culprit.
SpaceShip.generate(new SpaceShip(spaceShipImageArr, 0.100, gc, t, xMoving - 100, (randomNum + 150)));
Basically, in each frame you create a new instance of SpaceShip. The blinking images are caused by space ships being created over and over again. That won't work.
You need to create these objects outside the game loop and store their references:
SpaceShip mySpaceShip = new SpaceShip(spaceShipImageArr, 0.100, gc, t, xMoving - 100, (randomNum + 150));
In the game loop you just update the position of your actors (that part is missing) and keep drawing them at new positions.
SpaceShip.generate(mySpaceShip);
Side note: you can remove the generate method altogether, make drawShip public, rename it to draw and simply call mySpaceShip.draw() - it will be more evident what's the role of your methods. It's perfectly acceptable for an object to draw itself.
EDIT: Problem solved, turns out I needed to call main.repaint() instead of frame.repaint()
I am using a class that extends Canvas and overrides the 'paint(Graphics graphics)' method. In a loop which activates 60 times a second (it works like it's supposed to), I have called frame.repaint() (the canvas is correctly added to the frame). The paint method gets called about 4 or 5 times, then stops getting called. My other method in the loop, does not stop however, proving that it's the frame.repaint() method.
To make the problem clear, the JFrame.repaint() method stops getting called after 4 or 5 attempts within a second.
To prove this, I've increased an integer every second in my update method (which is getting called 60 times per second) and I'm using that as the x cordanite as a rectangle in my frame, which should make the rectangle larger each second. The rectangle paint's for 2 seconds or so, then stops growing, however the integer is still increasing. One thing to keep in mind that the rectangle does draw for the first few times, indicating that it's some sort of issue with the frame.
Is there a better way to call the paint(Graphics graphics) method? Do
I have some flaw in my code?
Sorry if my explanation was confusing, but I attached the code below (and in a pastebin file that you can find here: http://pastebin.com/WNnK54gq)
I have been looking for the past few hour's, and haven't found any replacement for the frame.repant() method.
Thanks in advanced!
public class Main extends Canvas {
//Static Variables
public static Main main;
public static String name = "Game";
public static double version = 1.0;
public static int FPS;
//Object Variables
private JFrame frame;
private boolean running;
private int screenX;
private int screenY;
private int x = 0;
//Constructor
public Main() {
setSize(new Dimension(500, 500));
}
//Main Method
public static void main(String[] args) {
main = new Main();
main.init();
}
//Object Methods
private void init() {
frame = new JFrame(name);
frame.setSize(500, 500);
frame.setResizable(false);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(main);
loop();
}
public void loop() {
running = true;
int fps = 0;
long timer = System.currentTimeMillis();
long lastTime = System.nanoTime();
final double ns = 1000000000.0 / 60;
double delta = 0;
while (running) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while (delta >= 1) {
if (fps <= 60) {
fps++;
update();
frame.repaint();
delta--;
}
}
if (System.currentTimeMillis() - timer > 1000) {
timer += 1000;
log("Running at " + fps + " FPS and UPS");
FPS = fps;
fps = 0;
}
}
}
public void update() {
screenX = frame.getWidth();
screenY = frame.getHeight();
x++;
if (x >= 500) x = 0;
log("update");
//update gametstate
}
public void log(String string) {
System.out.println("[" + name + "] [" + version + "] " + string);
}
public void log() {
System.out.println("[" + name + "] [" + version + "]");
}
#Override
public void paint(Graphics graphics) {
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, screenX, screenY);
//update gamestate
graphics.setColor(Color.BLUE);
graphics.fillRect(0, 200, x, 300);
log("rendered");
}
while (delta >= 1) {
if (fps <= 60) {
fps++;
update();
frame.repaint();
delta--;
}
}
Once fps hits 61, it will stop rendering or updating, because you never set fps back to 0.
while (delta >= 1) {
if (fps <= 60) {
fps++;
update();
frame.repaint();
delta--;
if(fps == 60) fps = 0;
}
}
You need to set fps back to 0.