所以,我正在制作一个你在岩石上跳跃的游戏,你不能跳到被水覆盖的岩石上。我被困在岩石(圆圈)随机消失在水中并随机出现的部分,并且在它们消失之前大约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);
}
}
}
答案 0 :(得分:3)
根据您的代码,Swing Timer
不是您想要的。你已经有了一个“游戏/主要”循环,应该在每个循环中更新游戏的当前状态并渲染它,你只需要设计一种方法,通过它你可以创建一个具有给定寿命的“摇滚”,每次渲染时,都需要检查它的寿命是否已接近,并在它死亡时将其移除。
摇滚乐实际上只是游戏中的另一个实体,可以更新和渲染。
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;
}
}
}