使圈子随机显示&出现&使用Swing Timer更改颜色

时间:2016-01-17 20:34:46

标签: java eclipse windows swing timer

所以,我正在制作一个你在岩石上跳跃的游戏,你不能跳到被水覆盖的岩石上。我被困在岩石(圆圈)随机消失在水中并随机出现的部分,并且在它们消失之前大约1.5秒使其变色。我认为最好使用javax.swing.Timer

你能帮我实现吗?

到目前为止,这是我的代码:
主要课程:

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类:

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;
}
}

处理程序类:

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类:

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();
}

}

菜单类:

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);
    }

}

}

玩家类:

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);
    }*/
}


}

窗口类:

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 javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Window extends Canvas{

private static final long serialVersionUID = 9086330915853125521L;

BufferedImage image = null;
URL url = null;

public Window(int width, int height, String title, Game game) {
    JFrame frame = new JFrame(title);
    try {

        image = ImageIO.read(new URL("https://static.wixstatic.com/media/95c249_b887de2536aa48cb962e2336919d2693.png/v1/fill/w_600,h_480,al_c,usm_0.66_1.00_0.01/95c249_b887de2536aa48cb962e2336919d2693.png"));
    } catch (IOException e) {
        e.printStackTrace();
    }

    frame.setPreferredSize(new Dimension(width, height));
    frame.setMaximumSize(new Dimension(width, height));
    frame.setMinimumSize(new Dimension(width, height));

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setResizable(false);
    frame.setLocationRelativeTo(null);
    frame.add(game);
    frame.setIconImage(image);
    //DrawingPanel panel = new DrawingPanel();
    //frame.getContentPane().add(panel);
    frame.setVisible(true);
    frame.requestFocus();
    game.start();
}

public class DrawingPanel extends JPanel {

    private static final long serialVersionUID = -7662876024842980779L;

    public void paintComponent(Graphics g) {
        g.setColor(new Color(209, 155, 29));
        g.fillOval(100, 100, 100, 100);
    }
}
}

1 个答案:

答案 0 :(得分:3)

根据您的代码,Swing Timer不是您想要的。你已经有了一个“游戏/主要”循环,应该在每个循环中更新游戏的当前状态并渲染它,你只需要设计一种方法,通过它你可以创建一个具有给定寿命的“摇滚”,每次渲染时,都需要检查它的寿命是否已接近,并在它死亡时将其移除。

摇滚乐实际上只是游戏中的另一个实体,可以更新和渲染。

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;
        }

    }

}