Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
156 views
in Technique[技术] by (71.8m points)

java - Make circles randomly dis/appear & change color using Swing Timer

So I'm making a game where you jump on rocks and you must not jump on rock which is covered by water. I'm stuck at the part where rocks (circles) randomly disappear in water and randomly appear and around 1.5 seconds before they disappear make it change color. I think its best to use javax.swing.Timer.

Could you help me achieve that?

Here is my code so far:
Main class:

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Menu;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
 import java.awt.image.BufferStrategy;
import java.util.Random;

import javax.swing.Timer;

public class Game extends Canvas implements Runnable{

private static final long serialVersionUID = -7800496711589684767L;

public static final int WIDTH = 640, HEIGHT = WIDTH / 12 * 9;

private Thread thread;
private boolean running = false;
private Random r;

private Handler handler;
//private HUD hud;
private Menu menu;

public enum STATE {
    Menu,
    Help,
    Game
};

public STATE gameState = STATE.Menu;

public Game() {
    handler = new Handler();
    menu = new Menu(this, handler);
    this.addKeyListener(new KeyInput(handler));
    this.addMouseListener(menu);
    new Window(WIDTH, HEIGHT, "My game", this);

    //hud = new HUD();
    r = new Random();

    //if(gameState == STATE.Game) {
    if(gameState == STATE.Game) {   //handler.addObject(new Player(100, 200, ID.Player));

    }

    //handler.addObject(new Player(100, 200, ID.Player));
    //handler.addObject(new BasicEnemy(100, 200, ID.BasicEnemy));   

}

public synchronized void start() {
    thread = new Thread(this);
    thread.start();
    running = true;
}

public synchronized void stop() {
    try {
        thread.join();
        running = false;
    }catch(Exception ex) { ex.printStackTrace(); }
}

public void run()
{
    this.requestFocus();
    long lastTime = System.nanoTime();
    double amountOfTicks = 60.0;
    double ns = 1000000000 / amountOfTicks;
    double delta = 0;
    long timer = System.currentTimeMillis();
    int frames = 0;
    while(running)
    {
                long now = System.nanoTime();
                delta += (now - lastTime) / ns;
                lastTime = now;
                while(delta >=1)
                        {
                            tick();
                            delta--;
                        }
                        if(running)
                            render();
                        frames++;

                        if(System.currentTimeMillis() - timer > 1000)
                        {
                            timer += 1000;
                            //System.out.println("FPS: "+ frames);
                            frames = 0;
                        }
    }
            stop();
 }  

private void tick() {
    handler.tick();
    //hud.tick();
    if(gameState == STATE.Game) {
        Random r = new Random();
        long now = System.currentTimeMillis();
        int b = 0;
        //System.out.println(now);
        long extraSeconds = 500;

    }else if(gameState == STATE.Menu) {
        menu.tick();
    }
}

private void render() {
    BufferStrategy bs = this.getBufferStrategy();
    if(bs == null) {
        this.createBufferStrategy(3);
        return;
    }

    Graphics g = bs.getDrawGraphics();
    long now = System.currentTimeMillis();

    g.setColor(new Color(87, 124, 212));
    g.fillRect(0, 0, WIDTH, HEIGHT);
    if(gameState == STATE.Game) {
        g.setColor(new Color(209, 155, 29));
        for(int i = 0; i < 5; i++) {
            g.fillOval(80 + (100 * i), 325, 70, 20);
        }
        if(gameState == STATE.Game) {


    }else if(gameState == STATE.Menu || gameState == STATE.Help){
        menu.render(g);
    }

    handler.render(g);

    if(gameState == STATE.Game) {
    }
    //hud.render(g);

    g.dispose();
    bs.show();
}

public static int clamp(int var, int min, int max) {
    if(var >= max)
        return var = max;
    else if(var <= max)
        return var = min;
    else 
        return var;
}

public static void main(String[] args) {
    new Game();
}
}

GameObject class:

package com.pitcher654.main;

import java.awt.Graphics;

public abstract class GameObject {

protected static int x, y;
protected ID id;
protected int velX, velY;

public GameObject(int x, int y, ID id) {
    this.x = x;
    this.y = y;
    this.id = id;
}

public abstract void tick();
public abstract void render(Graphics g);

public void setX(int x) {
    this.x = x;
}
public void setY(int y) {
    this.y = y;
}
public int getX() {
    return x;
}
public int getY() {
    return y;
}
public void setID(ID id) {
    this.id = id;
}
public ID getID() {
    return id;
}
public void setVelX(int velX) {
    this.velX = velX;
}
public void setVelY(int velY) {
    this.velY = velY;
}
public int getVelX() {
    return velX;
}
public int getVelY() {
    return velY;
}
}

Handler class:

package com.pitcher654.main;

import java.awt.Graphics;
import java.util.LinkedList;

public class Handler {

LinkedList<GameObject> object = new LinkedList<GameObject>();

public void tick() {
    for(int i = 0; i < object.size(); i++) {
        GameObject tempObject = object.get( i );

        tempObject.tick();
    }
}
public void render(Graphics g) {
    for(int i = 0; i < object.size(); i++) {
        GameObject tempObject = object.get(i);

        tempObject.render(g);
    }
}

public void addObject(GameObject object) {
    this.object.add(object);
}

public void removeObject(GameObject object) {
    this.object.remove(object);
}

}

ID class:

package com.pitcher654.main;

public enum ID {
Player(),
Player2(),
BasicEnemy(),
Misc();
}

KeyInput class:

package com.pitcher654.main;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

public class KeyInput extends KeyAdapter{

private Handler handler;

public KeyInput(Handler handler) {
    this.handler = handler;
}

public void keyPressed(KeyEvent e) {
    int key = e.getKeyCode();

    for(int i = 0; i < handler.object.size(); i++) {
        GameObject tempObject = handler.object.get(i);
        if(tempObject.getID() == ID.Player) {
            //kez events for Player 1
            //GameObject object = new GameObject(0, 0, ID.Misc);
            //System.out.println(tempObject.getID());               
            if(GameObject.x != 500) {
                if(key == KeyEvent.VK_RIGHT) {
                    Player.currentStone++;
                    tempObject.setX(tempObject.getX() + 100);
                }
            }
            if(GameObject.x != 100){
                if(key == KeyEvent.VK_LEFT) {
                    Player.currentStone--;
                    tempObject.setX(tempObject.getX() - 100);
                }
            }
        }
    }
    if(key == KeyEvent.VK_ESCAPE) System.exit(1);
}

public void keyReleased(KeyEvent e) {
    int key = e.getKeyCode();
}

}

Menu class:

package com.pitcher654.main;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import com.pitcher654.main.Game.STATE;

public class Menu extends MouseAdapter{

private Game game;
private Handler handler;
private GameObject Player;

public Menu(Game game, Handler handler) {
    this.game = game;
    this.handler = handler;
}

public void mouseClicked(MouseEvent e) {
    int mx = e.getX();
    int my = e.getY();

    if(game.gameState == STATE.Menu) {
        //play 1 button
        if(mouseOver(mx, my, (Game.WIDTH - 250) / 2, 150, 250, 64)) {
            game.gameState = STATE.Game;
            handler.addObject(new Player(100, 200, ID.Player));
            //handler.addObject(new BasicEnemy(0, 0, ID.BasicEnemy));
        }
        //Instructions button
        if(mouseOver(mx, my, (Game.WIDTH - 250) / 2, 250, 250, 64)) {
            game.gameState = STATE.Help;
        }
        //Quit button
        if(mouseOver(mx, my, (Game.WIDTH - 250) / 2, 350, 250, 64)) {
            System.exit(1);
        }
    }
    //Bacl to menu in game button
    if(game.gameState == STATE.Help) {
        if(mouseOver(mx, my, 23, 395, 100, 32)) {
            game.gameState = STATE.Menu;
            //handler.object.remove(Player);

        }
    }
}

public void mouseReleased(MouseEvent e) {

}

private boolean mouseOver(int mx, int my, int x, int y, int width, int height) {
    if(mx > x && mx < x + width) {
        if(my > y && my < y + height) {
            return true;
        }else return false;
    }else return false;
}

public void tick() {

}

public void render(Graphics g) {
    if(game.gameState == STATE.Menu) {
        Font fnt = new Font("Trebuchet MS", 30, 15);

        g.setColor(new Color(87, 124, 212));
        g.fillRect(0, 0, game.WIDTH, game.HEIGHT);
        g.setColor(Color.white);
        g.setFont(new Font("Papyrus", 1, 50));
        g.drawString("Price iz davnine", (Game.WIDTH - 250) / 2 - 50, 70);
        g.drawRect((Game.WIDTH - 250) / 2, 150, 250, 64);
        g.drawRect((Game.WIDTH - 250) / 2, 250, 250, 64);
        g.drawRect((Game.WIDTH - 250) / 2, 350, 250, 64);
        g.setFont(new Font("Trebuchet MS", 5000, 20));
        g.drawString("Play", (Game.WIDTH - 250) / 2 + 110, 190);
        g.setFont(fnt);
        g.drawString("How to Play", (Game.WIDTH - 250) / 2 + 85, 290);
        g.drawString("Quit", (Game.WIDTH - 250) / 2 + 105, 390);
    }else if(game.gameState == STATE.Help) {
        g.setColor(Color.white);
        g.setFont(new Font("Papyrus", 1, 50));
        g.drawString("How to play", (Game.WIDTH - 250) / 2 - 50, 70);
        g.setFont(new Font("Trebuchetr MS", 30, 10));
        g.drawRect(23, 395, 100, 32);
        g.setColor(Color.black);
        g.drawString("Back to Menu", 33, 415);
    }

}

}

Player class:

package com.pitcher654.main;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.Timer;

import com.pitcher654.main.Game.STATE;

public class Player extends GameObject {

    Random r = new Random();
    public static int currentStone = 1;

public Player(int x, int y, ID id) {
    super(x, y, id);
    //velX = r.nextInt(5) + 1;
    //velY = r.nextInt(5);
}

public void tick() {
    x += velX;
    y += velY;
    //System.out.println(x);
    //if(x == 500) x = 500;
}

public void render(Graphics g) {
    if(id == ID.Player) g.setColor(Color.white);
    g.fillRect(x, y, 32, 32);
    g.drawLine(x + 15, y, x + 15, y + 100);
    g.drawLine(x + 15, y + 100, x, y + 135);
    g.drawLine(x + 15, y + 100, x + 33, y + 135);
    g.drawLine(x + 15, y + 70, x - 35, y + 30);
    g.drawLine(x + 15, y + 70, x + 65, y + 30);
    /*if(game.gameState == STATE.Menu) {
        g.setColor(new Color(87, 124, 212));
        g.fillRect(0, 0, Game.WIDTH, Game.HEIGHT);
    }*/
}


}

And window class:

package com.pitcher654.main;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;

import j

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Based on you code, a Swing Timer isn't what you want. You already have a "game/main" loop which should be updating the current state of the game on each cycle and rendering it, you simply need to devise a means by which you can create a "rock", with a given life span, each time it's rendered, it needs to check if it's life span is nearly over and have it removed when it dies.

The rock is really just another entity in your game, which can be updated and rendered.

Rocks be like...

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.event.ComponentAdapter;
import java.awt.image.BufferStrategy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class RockyRoad {

    public static void main(String[] args) {
        new RockyRoad();
    }

    public RockyRoad() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new Game());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public static class Game extends Canvas implements Runnable {

        private static final long serialVersionUID = -7800496711589684767L;

        public static final int WIDTH = 640, HEIGHT = WIDTH / 12 * 9;

        private Thread thread;
        private boolean running = false;
        private Random rnd;

        private List<Entity> entities = new ArrayList<>(25);

        public enum STATE {
            Menu,
            Help,
            Game
        };

        public STATE gameState = STATE.Game;

        public Game() {
            rnd = new Random();
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    start();
                }
            });
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(WIDTH, HEIGHT);
        }

        public synchronized void start() {
            thread = new Thread(this);
            thread.start();
            running = true;
        }

        public synchronized void stop() {
            try {
                thread.join();
                running = false;
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }

        public void run() {
            this.requestFocus();
            long lastTime = System.nanoTime();
            double amountOfTicks = 60.0;
            double ns = 1000000000 / amountOfTicks;
            double delta = 0;
            long timer = System.currentTimeMillis();
            int frames = 0;
            while (running) {
                long now = System.nanoTime();
                delta += (now - lastTime) / ns;
                lastTime = now;
                while (delta >= 1) {
                    tick();
                    delta--;
                }
                if (running) {
                    update();
                    render();
                }
                frames++;

                if (System.currentTimeMillis() - timer > 1000) {
                    timer += 1000;
                    //System.out.println("FPS: "+ frames);
                    frames = 0;
                }
            }
            stop();
        }

        private void tick() {
            //hud.tick();
        }

        protected void update() {
            if (gameState == STATE.Game) {
                if (rnd.nextBoolean()) {
                    System.out.println("New...");
                    int x = rnd.nextInt(getWidth() - Rock.SIZE);
                    int y = rnd.nextInt(getHeight() - Rock.SIZE);
                    int lifeSpan = 4000 + rnd.nextInt(6000);
                    entities.add(new Rock(lifeSpan, x, y));
                }
                List<Entity> toRemove = new ArrayList<>(entities.size());
                List<Entity> control = Collections.unmodifiableList(entities);
                for (Entity entity : entities) {
                    if (entity.update(control, this) == EntityAction.REMOVE) {
                        System.out.println("Die...");
                        toRemove.add(entity);
                    }
                }
                entities.removeAll(toRemove);
            }
        }

        private void render() {
            BufferStrategy bs = this.getBufferStrategy();
            if (bs == null) {
                this.createBufferStrategy(3);
                return;
            }

            Graphics2D g = (Graphics2D) bs.getDrawGraphics();
            long now = System.currentTimeMillis();

            g.setColor(new Color(87, 124, 212));
            g.fillRect(0, 0, WIDTH, HEIGHT);
            if (gameState == STATE.Game) {
                g.setColor(new Color(209, 155, 29));
                if (gameState == STATE.Game) {
                    for (Entity entity : entities) {
                        entity.render(g, this);
                    }
                }

                g.dispose();
                bs.show();
            }
        }

        public static int clamp(int var, int min, int max) {
            if (var >= max) {
                return var = max;
            } else if (var <= max) {
                return var = min;
            } else {
                return var;
            }
        }
    }

    public interface Renderable {

        public void render(Graphics2D g2d, Component parent);
    }

    public enum EntityAction {
        NONE,
        REMOVE;
    }

    public interface Entity extends Renderable {

        // In theory, you'd pass the game model which would determine
        // all the information the entity really needed 
        public EntityAction update(List<Entity> entities, Component parent);
    }

    public static class Rock implements Renderable, Entity {

        protected static final int SIZE = 20;

        private int lifeSpan;
        private long birthTime;

        private int x, y;

        public Rock(int lifeSpan, int x, int y) {
            if (lifeSpan <= 1500) {
                throw new IllegalArgumentException("Life span for a rock can not be less then or equal to 1.5 seconds");
            }
            this.lifeSpan = lifeSpan;
            birthTime = System.currentTimeMillis();
            this.x = x;
            this.y = y;
        }

        @Override
        public void render(Graphics2D g2d, Component parent) {
            long age = System.currentTimeMillis() - birthTime;
            if (age < lifeSpan) {
                if (age < lifeSpan - 1500) {
                    g2d.setColor(Color.BLUE);
                } else {
                    g2d.setColor(Color.RED);
                }
                g2d.fillOval(x, y, SIZE, SIZE);
            }
        }

        @Override
        public EntityAction update(List<Entity> entities, Component parent) {
            EntityAction action = EntityAction.NONE;
            long age = System.currentTimeMillis() - birthTime;
            System.out.println("Age = " + age + "; lifeSpan = " + lifeSpan);
            if (age >= lifeSpan) {
                action = EntityAction.REMOVE;
            }
            return action;
        }

    }

}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...