Java图形不显示
我一直在尝试为我的游戏显示图形,但面板上没有显示任何图形 下面是我的代码。main类调用其他两个类的paint方法Java图形不显示,java,graphics,graphics2d,Java,Graphics,Graphics2d,我一直在尝试为我的游戏显示图形,但面板上没有显示任何图形 下面是我的代码。main类调用其他两个类的paint方法 import java.awt.Color; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; imp
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Simulator extends JFrame implements KeyListener, Runnable, ActionListener {
private final int WIDTH, HEIGHT;
private Boolean right;
private int xMotion;
public Salt salt;
public Player playR;
Boolean running = false;
private Thread thread;
public static int score, highScore;
private int saltSpeed;
public Simulator(int width, int height) {
JPanel panel = new JPanel();
JFrame frame = new JFrame();
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(width, height);
panel.setBackground(Color.BLACK);
frame.add(panel);
playR = new Player();
this.HEIGHT = height;
this.WIDTH = width;
int xCordSalt = (int) (Math.random() * 631);
saltSpeed = 1;
salt = new Salt(saltSpeed);
right = true;
running = true;
}
public static void main(String[] args) {
Simulator game = new Simulator(640, 480);
game.start();
}
public void paintComponent(Graphics g)
{
salt.paint(g);
playR.paint(g);
}
public void start() {
running = true;
thread = new Thread(this);
thread.start();
repaint();
tick();
run();
}
public void stop() {
running = false;
System.exit(0);
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_D) {
right = true;
} else if (e.getKeyCode() == KeyEvent.VK_A) {
right = false;
}
}
public void tick() {
salt.tick(this, playR);
playR.tick();
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_D)
{
playR.setDirection(true);
}
else if(e.getKeyCode() == KeyEvent.VK_A)
{
playR.setDirection(false);
}
}
@Override
public void run() {
while (running) {
tick();
repaint();
try {
thread.sleep(7);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void incrementScore() {
score++;
}
@Override
public void actionPerformed(ActionEvent e) {
repaint();
tick();
}
}
下面是salt方法的代码:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.ArrayList;
public class Salt extends Rectangle{
private final int WIDTH = 10;
private final int HEIGHT = 10;
public int xCordSalt, yCordSalt;
private int speed;
Rectangle boundBox;
public Salt(int speedx)
{
xCordSalt = (int)Math.random()*641;
yCordSalt = 0;
speed = speedx;
boundBox = new Rectangle(xCordSalt, yCordSalt, WIDTH, HEIGHT);
boundBox.setBounds(xCordSalt, yCordSalt, WIDTH, HEIGHT);
}
public void tick(Simulator sim, Player playR)
{
boundBox.setBounds(xCordSalt, yCordSalt, WIDTH, HEIGHT);
if(yCordSalt >= 480)
{
//sim.stop();
}
else if(checkCollision(playR))
{
sim.incrementScore();
speed++;
yCordSalt = -speed;
}
yCordSalt = yCordSalt + speed;
}
public boolean checkCollision(Player playR)
{
if(this.getBoundBox().intersects(playR.getBoundBox()))
{
return true;
}
return false;
}
public void paint(Graphics g) {
g.setColor(Color.WHITE);
g.fillRect(xCordSalt, yCordSalt, WIDTH, HEIGHT);
}
public Rectangle getBoundBox()
{
return boundBox;
}
public double getSpeed()
{
return speed;
}
}
最后是方法播放器,它使用imageIcon类显示图像:
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
public class Player extends JPanel {
private int xCord, yCord;
public Rectangle boundBox;
private static ImageIcon ryan;
boolean isRight;
public Player() {
ryan = new ImageIcon("E:\ryan.png");
xCord = 640/2;
yCord = 460;
boundBox = new Rectangle(xCord, yCord, 20, 20);
}
public static void main(String[] args) {
}
public void tick() {
}
public void setDirection(Boolean right)
{
if(right)
isRight = true;
else
isRight = false;
}
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
g2d.drawImage(ryan.getImage(), xCord, yCord, null);
}
public Rectangle getBoundBox()
{
return boundBox;
}
}
现在它有些不完整,但我不明白为什么它没有显示任何图形。运行时,仅显示黑色框架/面板。我在每个类的tick()方法、每个类的paint()方法和paintComponent()方法以及start()方法中添加了一些print语句。游戏将启动,运行每个类的tick方法,但paintComponent()或任何paint()方法都会被调用 首先,您创建了一个多余的框架-类本身就是一个框架,因此不需要更多:
setSize(width, height);
setVisible(true);
第二,你在上面加了一个面板:它会覆盖所有的东西
第三个JFrame没有paintComponent-而是使用paint()
第四,在通过调用start()启动线程时,将自动调用run()方法-无需调用run()
以下是我的工作构造函数和绘制方法:
public Simulator(int width, int height) {
setSize(width, height);
panel.setBackground(Color.BLACK);
setVisible(true);
try {
bim=ImageIO.read(new File(.....));
}
catch (Exception ex) { ex.printStackTrace(); }
this.HEIGHT = height;
this.WIDTH = width;
int xCordSalt = (int) (Math.random() * 631);
saltSpeed = 1;
right = true;
running = true;
}
public void paint(Graphics g)
{
g.setColor(Color.magenta);
g.fillRect(0, 0, 100, 100);
g.drawImage(bim, 100, 0, null);
}
让我们从显而易见的
public class Simulator extends JFrame ... {
//...
public void paintComponent(Graphics g) {
salt.paint(g);
playR.paint(g);
}
JFrame
没有名为paintComponent
的方法,因此您的paintComponent
将永远不会被调用,因此salt
和playR
将永远不会被绘制
您可以通过将@Override
添加到paintComponent
来测试这一点,paintComponent将为您执行编译时健全性检查
public class Simulator extends JFrame ... {
//...
@Override
public void paintComponent(Graphics g) {
salt.paint(g);
playR.paint(g);
}
这将无法编译
现在,您可以替代paint
,但是。。。我不推荐
退后一步。JFrame
真正负责什么?提供一个容器,您可以将gui添加到其中并将其显示在屏幕上。您并没有向JFrame
添加任何新功能,因此我不会将其用作“主”组件,而是创建一个实例,并添加您想要使用的组件
相反,我将从一个JPanel
开始,覆盖它的paintComponent
方法,并将所有自定义绘制都放在其中
然后,我将使用此组件作为核心逻辑和控制器的起点
您甚至可以创建几个组件作为菜单和选项视图,并使用CardLayout
或OverlayoutLayout
来显示它们
我还建议您在查看时不要查看
KeyListener
,这将回答您的下一个问题。您需要将“E:\ryan.png”
更改为“E:\\ryan.png”
。反斜杠(\)是转义字符;要在字符串中放置一个实际的反斜杠,您需要用另一个反斜杠来转义该反斜杠。@ursinusTheStrong噢,伙计,我怎么能忘记转义序列!谢谢你提醒我!JFrame没有paintComponent方法,因此永远不会调用它,这就是为什么应该使用@Override。创建从JPanel扩展的类,重写它的paintComponent方法并在那里执行自定义喘息,确保首先调用super.paintComponent。一个想法是创建一个实体,它描述游戏中的某些元素,high do“stuff”这些元素中的一个将是“可绘制”的,它有一些方法可以将图形引用传递给它并绘制它自己,这样,你所需要做的就是维护一个实体列表,更新,和油漆them@MadProgrammer/@Override给了我这个错误:那么你是说我应该创建一个单独的类来处理图形?我有点不明白你说我应该做什么。是的,我建议添加@Override的原因是,当你“认为”你正在重写一个方法时,它会给你一个编译器警告,而当你没有这样做时,这是一个很好的健全性检查。是的,我会为所有自定义绘制使用一个单独的类(我在本例中使用),然后在绘制方法中添加salt.paint(带参数)和playR.paint()?另外,非常感谢你的帮助!我和我的同事都很困惑为什么它不起作用。不要直接在JFrame上画画。使用添加到JFrame的JPanel的paintComponent方法进行绘制。这是一个。@GilbertLeBlanc这是我在程序中做的,为什么它不在屏幕上打印任何东西呢?在这里,如果我运行未经编辑的代码会发生什么:我还在paintComponent方法、salt和player类的paint方法中使用了一个print语句,这些方法都没有打印任何内容,这意味着它们不能被调用。投票失败的原因是什么?这是否回答了老年退休金计划的问题?在哪些方面可以改进?不是你的选民;我同意“Swing程序应该重写paintComponent()
,而不是重写paint()
”。