- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以我正在制作一个游戏,我有 EnemyAI
以及 player
,它们都扩展了 JPanel
。世界有一个 null
布局,所以我正在使用 setBounds();
来“移动”(我实际上只是移动世界图像)entities
(player
和 AI
)并正确放置它们。但是当我添加(看起来,我测试了尽可能小的数字)5 时,它会完全自行调用 repaint()
。这会导致玩家在视觉上原地行走。我添加的实体越多,间隔越快(即 5 个实体调用 repaint()
比 500 个慢很多)。
注意:下面类中的window
只是一个JFrame
。
主类:
public class Game(){
public static boolean fighting = false;
public static void startGame(){
WorldPanel game = new WorldPanel();
game.setPreferredSize(new Dimension(window.getWidth(), window.getHeight()));
PlayerPane player = new PlayerPane(32,32, "Player 1");
game.addKeyListener(new KeyListener(){
public void keyPressed(KeyEvent arg0) {
if(fighting == false){
move(player, game, arg0.isShiftDown(), arg0.getKeyCode());
} else {
System.out.println("Fighting = " + fighting);
}
}
@Override
public void keyReleased(KeyEvent arg0) {
gameTimer.stop();
player.setIndex(0);
game.repaint();
}
@Override
public void keyTyped(KeyEvent arg0) {
}
});
window.add(game);
game.setLayout(null);
game.requestFocus();
setImages(player, PLAYER_DOWN);
player.setDrawY(349);
player.setDrawX(493);
player.updateBounds();
game.add(player);
entities.add(player);
addEntities(game);
redoWindow();
}
public static void updateEntityBounds(){
PlayerPane player = null;
EnemyAI enemy = null;
for(int i = 0; i < entities.size(); i++){
if(i == 0){
player = (PlayerPane) entities.get(i);
} else {
enemy = (EnemyAI) entities.get(i);
if(enemy.getBounds().intersects(player.getBounds())){
startFight(i);
}
}
if(player != null){
player.updateBounds();
}
if(enemy != null){
enemy.updateBounds();
}
}
}
public static void addEntities(WorldPanel game){
EnemyAI enemies[] = new EnemyAI[5];
for(int i = 0; i < enemies.length; i++){
if(i%6 == 0){
try{
enemies[i] = new EnemyAI(32,32, ImageIO.read(new File("H:\\Java\\Game\\src\\res\\SlimeLv3Still.png")));
enemies[i].start();
}catch(IOException e){
e.printStackTrace();
}
}else if (i % 2 == 0){
try{
enemies[i] = new EnemyAI(32,32, ImageIO.read(new File("H:\\Java\\Game\\src\\res\\SlimeLv2Still.png")));
enemies[i].setEnX(enemies[i].getRandomX());
enemies[i].setEnY(enemies[i].getRandomY());
enemies[i].start();
}catch(IOException e){
e.printStackTrace();
}
} else {
try{
enemies[i] = new EnemyAI(32,32, ImageIO.read(new File("H:\\Java\\Game\\src\\res\\SlimeLv1Still.png")));
enemies[i].setEnX(enemies[i].getRandomX());
enemies[i].setEnY(enemies[i].getRandomY());
enemies[i].start();
}catch(IOException e){
e.printStackTrace();
}
}
game.add(enemies[i]);
entities.add(enemies[i]);
}
}
public static void move(PlayerPane player, WorldPanel game, boolean shiftDown, int keyPressed){
gameTimer = new Timer(50, new ActionListener(){
public void actionPerformed(ActionEvent e){
updateEntityBounds();
redoWindow();
gameTimer.stop();
}
});
if(gameTimer.isRepeats()){
gameTimer.setRepeats(false);
}
if(shiftDown){
if(keyPressed == KeyEvent.VK_W && ((game.getImageY() == 0 && player.getDrawY() > 10) || player.getDrawY() >= 349)){
player.setDrawY(player.getDrawY() - 2);
setImages(player, PLAYER_UP);
gameTimer.start();
} else
if(keyPressed == KeyEvent.VK_S && ((game.getImageY() == -3868 && player.getDrawY() < 681) || player.getDrawY() <= 349)){
player.setDrawY(player.getDrawY() + 2);
setImages(player, PLAYER_DOWN);
gameTimer.start();
} else
if(keyPressed == KeyEvent.VK_A && ((game.getImageX() == 0 && player.getDrawX() > 10) || player.getDrawX() > 493 )){
player.setDrawX(player.getDrawX() - 2);
setImages(player, PLAYER_LEFT);
gameTimer.start();
} else
if(keyPressed == KeyEvent.VK_D && ((game.getImageX() == -5126 && player.getDrawX() < player.getHeight() - 10) || player.getDrawX() < 493 )){
player.setDrawX(player.getDrawX() + 2);
setImages(player, PLAYER_RIGHT);
gameTimer.start();
} else
if(keyPressed == KeyEvent.VK_W && game.getImageY() < 0){
if(game.getImageY() == -1){
game.setImageY(game.getImageY() + 1);
} else {
game.setImageY(game.getImageY() + 2);
}
for(int i = 1; i < entities.size(); i++){
EnemyAI enemy = (EnemyAI)entities.get(i);
enemy.setEnY(enemy.getEnY() + 2);
}
setImages(player, PLAYER_UP);
gameTimer.start();
} else
if(keyPressed == KeyEvent.VK_A && game.getImageX() < 0){
if(game.getImageX() == -1){
game.setImageX(game.getImageX() + 1);
} else {
game.setImageX(game.getImageX() + 2);
}
for(int i = 1; i < entities.size(); i++){
EnemyAI enemy = (EnemyAI)entities.get(i);
enemy.setEnX(enemy.getEnX() + 2);
}
setImages(player, PLAYER_LEFT);
gameTimer.start();
} else
if(keyPressed == KeyEvent.VK_S && game.getImageY() > -3868){
if(game.getImageY() == -3867){
game.setImageY(game.getImageY() - 1);
} else {
game.setImageY(game.getImageY() - 2);
}
for(int i = 1; i < entities.size(); i++){
EnemyAI enemy = (EnemyAI)entities.get(i);
enemy.setEnY(enemy.getEnY() - 2);
}
setImages(player, PLAYER_DOWN);
gameTimer.start();
} else
if(keyPressed == KeyEvent.VK_D && game.getImageX() > -5126){
if(game.getImageX() == -5125){
game.setImageX(game.getImageX() - 1);
} else {
game.setImageX(game.getImageX() - 2);
}
for(int i = 1; i < entities.size(); i++){
EnemyAI enemy = (EnemyAI)entities.get(i);
enemy.setEnX(enemy.getEnX() - 2);
}
setImages(player, PLAYER_RIGHT);
gameTimer.start();
}
} else {
if(keyPressed == KeyEvent.VK_W && ((game.getImageY() == 0 && player.getDrawY() > 10) || player.getDrawY() > 349)){
player.setDrawY(player.getDrawY() - 1);
setImages(player, PLAYER_UP);
gameTimer.start();
} else
if(keyPressed == KeyEvent.VK_S && ((game.getImageY() == -3868 && player.getDrawY() < 681) || player.getDrawY() < 349)){
player.setDrawY(player.getDrawY() + 1);
setImages(player, PLAYER_DOWN);
gameTimer.start();
} else
if(keyPressed == KeyEvent.VK_A && ((game.getImageX() == 0 && player.getDrawX() > 10) || player.getDrawX() > 493 )){
player.setDrawX(player.getDrawX() - 1);
setImages(player, PLAYER_LEFT);
gameTimer.start();
} else
if(keyPressed == KeyEvent.VK_D && ((game.getImageX() == -5126 && player.getDrawX() < player.getHeight() - 10) || player.getDrawX() < 493 )){
player.setDrawX(player.getDrawX() + 1);
setImages(player, PLAYER_RIGHT);
gameTimer.start();
} else
if(keyPressed == KeyEvent.VK_W && game.getImageY() < 0){
game.setImageY(game.getImageY() + 1);
setImages(player, PLAYER_UP);
for(int i = 1; i < entities.size(); i++){
EnemyAI enemy = (EnemyAI)entities.get(i);
enemy.setEnY(enemy.getEnY() + 1);
}
gameTimer.start();
} else
if(keyPressed == KeyEvent.VK_A && game.getImageX() < 0){
game.setImageX(game.getImageX() + 1);
setImages(player, PLAYER_LEFT);
for(int i = 1; i < entities.size(); i++){
EnemyAI enemy = (EnemyAI)entities.get(i);
enemy.setEnX(enemy.getEnX() + 1);
}
gameTimer.start();
} else
if(keyPressed == KeyEvent.VK_S && game.getImageY() > -3868){
game.setImageY(game.getImageY() - 1);
setImages(player, PLAYER_DOWN);
for(int i = 1; i < entities.size(); i++){
EnemyAI enemy = (EnemyAI)entities.get(i);
enemy.setEnY(enemy.getEnY() - 1);
}
gameTimer.start();
} else
if(keyPressed == KeyEvent.VK_D && game.getImageX() > -5126){
game.setImageX(game.getImageX() - 1);
setImages(player, PLAYER_RIGHT);
for(int i = 1; i < entities.size(); i++){
EnemyAI enemy = (EnemyAI)entities.get(i);
enemy.setEnX(enemy.getEnX() - 1);
}
gameTimer.start();
}
}
}
}
玩家:
public class PlayerPane extends JPanel{
private static final long serialVersionUID = 8946273935579723365L;
private ImageIcon images[] = new ImageIcon[9];
public static final int PLAYER_FRAMES = 9;
private String name;
private int index;
private int imageX, imageY;
private int HP = 100;
public PlayerPane(int width, int height, String playerName) {
setPreferredSize(new Dimension(width, height));
imageX = imageY = 0;
name = playerName;
// Border border = BorderFactory.createBevelBorder(BevelBorder.RAISED);
// PlayerPane.this.setBorder(border);
}
public String getName(){
return name;
}
public void paintComponent(Graphics g){
try {
g.drawImage(ImageIO.read(new File("H:\\Java\\Game\\src\\res\\TransparentImg.png")),0,0,getWidth(),getHeight(), null);
} catch (IOException e) {
e.printStackTrace();
}
g.drawImage(images[index].getImage(), 0,0, null);
if(index == images.length-1){
index = 0;
} else {
index++;
}
}
public void setIndex(int index){
this.index = index;
}
public void stop(){
index = 0;
}
public void addImage(ImageIcon image, int x){
images[x] = image;
}
public void setDrawX(int x){
imageX = x;
}
public void setDrawY(int y){
imageY = y;
}
public int getDrawY(){
return imageY;
}
public int getDrawX(){
return imageX;
}
public void updateBounds(){
setBounds(imageX, imageY, 32,32);
}
public int getHP(){
return HP;
}
public void setHP(int hp){
HP = hp;
}
}
EnemyAI 类:
public class EnemyAI extends AI{
private static final long serialVersionUID = -2417438750134536982L;
private Rectangle rect;
private BufferedImage backgroundImg;
private int HP = 1;
private int damage = 15;
public EnemyAI(int width, int height, BufferedImage backgroundImg){
super();
rect = new Rectangle(width, height);
this.backgroundImg = backgroundImg;
}
@Override
public void paintComponent(Graphics g) {
try{
g.drawImage(ImageIO.read(new File("H:\\Java\\Game\\src\\res\\TransparentImg.png")), 0,0,null);
}catch(IOException e){
e.printStackTrace();
}
g.drawImage(backgroundImg, 0, 0, null);
}
public boolean intersects(Rectangle r){
return rect.intersects(r);
}
public int getRandomX(){
Random ran = new Random();
int rand = ran.nextInt(6144);
return rand;
}
public int getRandomY(){
Random ran = new Random();
int rand = ran.nextInt(4608);
return rand;
}
public int getHP(){
return HP;
}
public void setHP(int hp){
HP = hp;
}
public int getDamage(){
return damage;
}
}
上述类扩展的AI类:
public abstract class AI extends JPanel implements Runnable{
private static final long serialVersionUID = 283692586329054555L;
private boolean running = false;
private Thread moveThread;
private int x = 0, y = 0;
public AI(){
moveThread = new Thread(this);
}
public void start(){
running = true;
moveThread.start();
}
public void stop(){
running = false;
}
public boolean isRunning(){
return running;
}
public void run(){
while(running){
if(Game.fighting == false){
Random direction = new Random();
int dir = direction.nextInt(4);
switch(dir){
case 1:
if(this.getX() < Game.getWindowWidth()){
this.setEnX(this.getX() + 1);
}
break;
case 2:
if(this.getX() > 0){
this.setEnX(this.getX() - 1);
}
break;
case 3:
if(this.getX() < Game.getWindowHeight()){
this.setEnY(this.getY() + 1);
}
break;
case 4:
if(this.getX() < 0){
this.setEnY(this.getY() - 1);
}
break;
}
updateBounds();
try{
Thread.sleep(200);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
public void setEnX(int x){
this.x = x;
}
public void setEnY(int y){
this.y = y;
}
public int getEnX(){
return x;
}
public int getEnY(){
return y;
}
public void updateBounds(){
setBounds(x, y, 32,32);
}
public abstract void paintComponent(Graphics g);
}
我知道我只是向你们扔了很多代码。我试着不这样做,但回过头来看我试图提供一个运行的例子。如果我遗漏了任何代码,请告诉我,我会添加它。
无论如何,我需要知道的是如何让 setBounds()
停止调用 repaint()
(除了使用少于 5 个 实体
)。此外,我在添加 entities
时删除了 EnemyAI.start()
并且确实阻止了它。所以我有理由相信问题出在AI
类的run()
方法中。这几乎只是调用 setBounds()
。
最佳答案
这是正常行为,这就是为什么您不能在 paintComponent
中修改状态的原因。我们无法控制重绘何时发生:系统有时会自行完成。
这是我的意思的一个例子,你不应该这样做:
public class PlayerPane extends JPanel{
...
public void paintComponent(Graphics g){
...
// modifying index
if(index == images.length-1){
index = 0;
} else {
index++;
}
}
}
您需要遍历所有代码,查找您在 paintComponent
中修改过这样的变量的每个地方,并将其移出到其他地方。
作为旁注,您还应该移动您的 ImageIO.read
调用,使它们不在 paintComponent
中。程序启动时将图像加载到 static
变量或类似变量中。
作为一般提示,您应该通过绘画来研究动画,而不是尝试为组件设置动画。从长远来看,这对您的游戏大有裨益。
总结一下:
paintComponent
无状态。paintComponent
中绘制这些图像。这是一个最小的例子,它通过动画形状从窗口落下来演示这一点:
import java.net.*;
import javax.swing.*;
import javax.imageio.*;
import java.awt.image.*;
import java.awt.event.*;
import java.awt.Dimension;
import java.awt.Color;
import java.awt.Graphics;
import java.util.List;
import java.util.ArrayList;
import java.util.Random;
class FallingShapes implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new FallingShapes());
}
@Override
public void run() {
List<Entity> entities = new ArrayList<Entity>();
int w = 0;
int h = 0;
for (BufferedImage img : Resources.images) {
entities.add(new Entity(img));
w += img.getWidth();
h += img.getHeight();
}
PaintPanel p = new PaintPanel(entities);
p.setPreferredSize(new Dimension(w, (2 * h)));
JFrame f = new JFrame();
f.setContentPane(p);
f.pack();
f.setLocationRelativeTo(null);
f.setResizable(false);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
new Animator((1000 / 60), p, entities).start();
}
static class Animator implements ActionListener {
int period;
JPanel context;
int height;
List<Entity> entities;
Animator(int period, JPanel context, List<Entity> entities) {
this.context = context;
this.height = context.getHeight();
this.period = period;
this.entities = entities;
}
@Override
public void actionPerformed(ActionEvent a) {
for (Entity e : entities) {
double dist =
(period / 1000.0) * (height * e.rate);
e.y += dist;
e.y %= height;
}
context.repaint();
}
void start() {
Random r = new Random();
int x = 0;
for (Entity e : entities) {
e.x = x;
e.y = r.nextInt(height);
e.rate = (0.25 + (0.75 * r.nextDouble()));
x += e.width;
}
new Timer(period, this).start();
}
}
static class Entity {
BufferedImage img;
double x, y, rate;
int width, height;
Entity(BufferedImage img) {
this.img = img;
this.width = img.getWidth();
this.height = img.getHeight();
}
void paint(Graphics g, JPanel context) {
int x = (int) Math.round(this.x);
int y = (int) Math.round(this.y);
g.drawImage(img, x, y, null);
int cHeight = context.getHeight();
if ((y + height) > cHeight) {
g.drawImage(img, x, y - cHeight, null);
}
}
}
static class PaintPanel extends JPanel {
List<Entity> entities;
PaintPanel(List<Entity> entities) {
this.entities = entities;
setBackground(Color.white);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Entity e : entities) {
e.paint(g, this);
}
}
}
static class Resources {
static final String[] paths = {
"http://i.stack.imgur.com/wCF8S.png",
"http://i.stack.imgur.com/5v2TX.png",
"http://i.stack.imgur.com/F0JHK.png",
"http://i.stack.imgur.com/4EVv1.png",
"http://i.stack.imgur.com/xj49g.png",
};
static final List<BufferedImage> images =
new ArrayList<BufferedImage>();
static {
for (String path : paths) {
try {
images.add(ImageIO.read(new URL(path)));
} catch (Exception e) {
throw new AssertionError(e);
}
}
}
}
}
(图片来自 here .)
其他有用的动画和绘画示例:
关于java - Component.setBounds 调用 Component.repaint?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30175533/
有没有可能,当我们使用Java的setBounds(x,y,width,height)方法时,如果我们改变机器(不同尺寸的显示器或任何其他设备),组件就会从一个地方改变到另一个地方?多种尺寸显示设备)
我想制作 3 个面板,一个在西侧,一个在东侧,一个在南侧。当我执行此操作时,它会给我一个框架,其颜色全部在另一个之上,并且不会给我按钮。 frame = new JFrame(); frame.set
是否可以将一个值放入 setBounds 中以将宽度设置为所需的最小值? JLabel title = new JLabel("Title Text"); title.setBounds(50, 20
如何使用 setBounds 示例获得自动值: myJPanel.setBounds(0, 0, [auto], 300); 我正在使用框布局,并希望自动计算宽度,就像我不调用 setBounds 时
我在将 .setBounds 应用于 JLabel 时遇到问题。它与我之前定义的 JLabel 一起使用,但完全忽略了我的第二个边界定义。我稍微修改了宽度和高度,看看它是否会影响 JLabel,但事实
这是我继承自 JFrame 的一个小类的构造函数: public ToolView(Controller controller) { super("Tools"); setLayout
我正在 Java Swing 中制作一个类似国际象棋的游戏(我知道 Swing 不是正确的方法,但我仍然想尝试一下)我在使棋子以适当的速度显示在显示屏上时遇到问题。由于棋子物理位置的性质,我无法使用布
我正在用java做一个小Gui。我正在使用 setBounds 方法在我的 JFrame 上设置按钮等的位置,但问题是,当我将它与 JPanel 一起使用时,按钮在 JFrame 上不可见,而没有 J
我想在按下按钮时显示标签的移动一段时间。请帮忙。只需告诉我如何在更改 setBounds 期间暂停进程一段时间,在本例中 sleep 方法暂停进程,但仅执行最后一个 setBound 语句: void
您好,我正在使用 setBounds 方法打开一个特定大小的窗口。但是我在参数中传递的大小是窗口的大小,包括框架的条。如何仅为内容设置尺寸? 最佳答案 设置内容的大小,然后在 JFrame 上调用 p
我在包含 2 个 JPanel 的 JFrame 中遇到了一个奇怪的问题。我有一个名为“SlotCheck”的类,它扩展了 JFrame。我有一个名为“Slot”的类,它扩展了 JPanel。在 Sl
是否在事件调度线程上调用了像 JPanel 这样的 Component 的 setBounds() 方法?我问这个问题是因为我正在编写一个程序来绘制平台并使用 Swing Timer 将它们向上移动。
我正在用 Java 做一个小的 Gui。我正在使用 setBounds 方法在我的 JFrame 上设置按钮等的位置,但问题是当我将它与 JPanel 一起使用时,按钮在 JFrame 上不可见,并且
我在 setBounds 上找不到任何内容、它的用途或它的实际功能。有人可以澄清我吗?非常感谢! 最佳答案 如果您将 layout 设置为 null,您可以使用 setBounds(x, y, wid
您好,我正在处理项目中基于 swing 的 gui 部分,我需要将 setBounds JFrame 的方法与 setResizable 调用同步,所以我这样做: setResizable(t
我正在开发一个 Eclipse 插件,其中我想显示一个标签和一个进度条。但不幸的是我无法更改它们的大小。无论我在标签和进度条的 setBounds 属性中提到什么大小,都会给我坐标:矩形 { 3, 3
我得到的 setbounds 值是魔数(Magic Number)。有没有办法将所有值分配给一个变量,而不是为每个值分配一个变量? setBounds(10,0,30,200); 提前致谢。 最佳答案
我读到使用 setBounds() 命令创建 GUI 是不好的。 我知道如何使用布局管理器,但我不得不说它们也有其缺点。 我现在正在编写游戏,有时我需要将组件堆叠在一起。我发现没有办法使用布局管理器来
我正在尝试创建一个包含 3 个文本字段的 JPanel。除了 textArea3 之外,包括按钮在内的其他所有内容都已就位。最后的面板是这样的。正如您在图片中看到的,textArea3 使用整个 JF
getFrame().setBounds(200, 200, 200, 200) 在 netbeans 中不起作用,原因是什么?我也使用了 getFrame().setTitle() 并且它可以工作,
我是一名优秀的程序员,十分优秀!