如何解决Java canvas根本不更新
我正在尝试制作打砖块游戏,其中最初在桨上的球(在下面的代码中称为BAR)以一定的速度(大约100)在某个随机方向上发射(如果击中了屏幕上的砖块消失了,球也相应地改变了方向。
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import java.awt.event.KeyEvent;
import java.awt.event.*;
public class Brick_Breaker extends Canvas implements KeyListener{
int BRICK_WIDTH=60,BRICK_HEIGHT=30,X=0,Y=0;
int BAR_X = 390,BAR_Y=560,BAR_WIDTH=120,BAR_HEIGHT=20,BAR_DX=10;
int BALL_X=440,BALL_Y=540,BALL_SIZE=20,BALL_DX=0,BALL_DY=0;
int LEFT_WALL=100,RIGHT_WALL=800,TOP_WALL=10;
boolean GAME_STATE=false;
int BAR_STATE=0;
static int[][] y = new int[10][5];
static int[][] x = new int[10][5];
static int[][] status = new int[10][5];
static Canvas canvas;
static JFrame frame;
@Override
public void keyReleased(KeyEvent ke){}
@Override
public void keyTyped(KeyEvent ke){}
public void STaRT(){
frame = new JFrame("My Drawing");
frame.addKeyListener(this);
canvas = new Brick_Breaker();
canvas.setSize(900,600);
frame.add(canvas);
frame.pack();
frame.setVisible(true);
}
@Override
public void update(Graphics g){
BALL_X += BALL_DX;
BALL_Y += BALL_DY;
for(int i=0;i<10;i++){
for(int j=0;j<5;j++){
if(BALL_X>x[i][j]&&BALL_X<(x[i][j]+BRICK_WIDTH)&&BALL_Y<=y[i][j]+BAR_HEIGHT+BALL_SIZE && BALL_Y>y[i][j]&&BALL_DY<0){
BALL_DY=-BALL_DY;
status[i][j]-=1;
}else if(BALL_X>x[i][j]&&BALL_X<(x[i][j]+BRICK_WIDTH)&&BALL_Y>=y[i][j]-BALL_SIZE && BALL_Y<y[i][j]+BAR_HEIGHT&&BALL_DY>0){
BALL_DY=-BALL_DY;
status[i][j]-=1;
}else if(BALL_X+BALL_SIZE>=x[i][j]&&BALL_X<(x[i][j]+BRICK_WIDTH)&&BALL_Y>=y[i][j] && BALL_Y<y[i][j]+BAR_HEIGHT&&BALL_DY<0){
BALL_DX=-BALL_DX;
status[i][j]-=1;
}else if(BALL_X>x[i][j]&&BALL_X-BALL_SIZE<=(x[i][j]+BRICK_WIDTH)&&BALL_Y>=y[i][j] && BALL_Y<y[i][j]+BAR_HEIGHT&&BALL_DY<0){
BALL_DX=-BALL_DX;
status[i][j]-=1;
}else if(BALL_X-BALL_SIZE<LEFT_WALL||BALL_X+BALL_SIZE>RIGHT_WALL){
BALL_DX=-BALL_DX;
}else if(BALL_Y-BALL_SIZE<TOP_WALL){
BALL_DY=-BALL_DY;
}
}
}
BAR_X = BAR_X +BAR_STATE*BAR_DX;
repaint();
}
public static void main(String[] args) {
Brick_Breaker bb = new Brick_Breaker();
bb.STaRT();
for(int i=0;i<10;i++){
for(int j=0;j<5;j++){
x[i][j] = 300+60*j;
y[i][j] = 50+30*i;
status[i][j] = 1;
}
}
}
@Override
public void keyPressed(KeyEvent ke){
if(!GAME_STATE){
BALL_DX = (int)(100*Math.random());
BALL_DY = (int)(Math.sqrt(100*100-BALL_DX*BALL_DX));
GAME_STATE = true;
}else if(ke.getKeyCode() == KeyEvent.VK_LEFT){
BAR_STATE=-1;
}else if(ke.getKeyCode()==KeyEvent.VK_RIGHT){
BAR_STATE=1;
}
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.white);
g.drawLine(LEFT_WALL,600,LEFT_WALL,TOP_WALL);
g.drawLine(RIGHT_WALL,RIGHT_WALL,TOP_WALL);
g.drawLine(LEFT_WALL,TOP_WALL,TOP_WALL);
g.fillRect(BAR_X,BAR_Y,BAR_WIDTH,BAR_HEIGHT);
g.setColor(Color.red);
g.fillOval(BALL_X,BALL_Y,BALL_SIZE,BALL_SIZE);
for(int i=0;i<10;i++){
for(int j=0;j<5;j++){
if(status[i][j]>0){
X = x[i][j];Y=y[i][j];
g.setColor(Color.white);
g.fillRect(X,Y,BRICK_WIDTH,BRICK_HEIGHT);
g.setColor(Color.red);
g.fillRect(X+3,Y+3,BRICK_WIDTH-6,BRICK_HEIGHT-6);
}
}
}
setBackground(Color.black);
}
}
这里,更新功能似乎根本没有更新。 我不确定该方法的工作原理。 任何帮助将不胜感激
解决方法
Canvas
是一个相当低级的组件,只有在需要使用BufferStrategy
时才考虑使用。
update
被称为绘制阶段的一部分,因为您没有调用super
实现就覆盖了它,所以您中断了绘制工作流程。
AWT和Swing通常使用被动渲染系统,这意味着更新仅在系统确定需要进行时才发生,因此以update
的方式覆盖您的做法并没有实际意义,也不会继续为您提供帮助。
一个更好的起点是JPanel
,主要原因是它具有双重缓冲,并且省去了试图消除闪烁的麻烦。
Performing Custom Painting和Painting in AWT and Swing是一个很好的起点,以便更好地了解绘画的工作方式(以及您应该如何使用它)。
KeyListener
也是输入监视的不佳选择,说真的,出于所有原因,只需对SO进行一些搜索即可。
一种更好且通常没有问题的方法是也使用key bindings。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
int BRICK_WIDTH = 60,BRICK_HEIGHT = 30,X = 0,Y = 0;
int BAR_X = 390,BAR_Y = 560,BAR_WIDTH = 120,BAR_HEIGHT = 20,BAR_DX = 1;
int BALL_X = 440,BALL_Y = 540,BALL_SIZE = 20,BALL_DX = 0,BALL_DY = 0;
int LEFT_WALL = 100,RIGHT_WALL = 800,TOP_WALL = 10;
boolean GAME_STATE = false;
int BAR_STATE = 0;
int[][] y = new int[10][5];
int[][] x = new int[10][5];
int[][] status = new int[10][5];
private Timer timer;
public TestPane() {
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 5; j++) {
x[i][j] = 300 + 60 * j;
y[i][j] = 50 + 30 * i;
status[i][j] = 1;
}
}
BALL_DX = 0; //(int) (100 * Math.random());
BALL_DY = -1;//(int) (Math.sqrt(100 * 100 - BALL_DX * BALL_DX));
setBackground(Color.BLACK);
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,0),"left");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,"right");
ActionMap am = getActionMap();
am.put("left",new KeyAction(this,-1));
am.put("right",1));
}
@Override
public void addNotify() {
super.addNotify(); //To change body of generated methods,choose Tools | Templates.
if (timer == null) {
timer = new Timer(5,new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
tick();
}
});
timer.start();
}
}
@Override
public void removeNotify() {
super.removeNotify();
if (timer != null) {
timer.stop();
timer = null;
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(900,600);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.white);
g2d.drawLine(LEFT_WALL,600,LEFT_WALL,TOP_WALL);
g2d.drawLine(RIGHT_WALL,RIGHT_WALL,TOP_WALL);
g2d.drawLine(LEFT_WALL,TOP_WALL,TOP_WALL);
g2d.fillRect(BAR_X,BAR_Y,BAR_WIDTH,BAR_HEIGHT);
g2d.setColor(Color.red);
g2d.fillOval(BALL_X,BALL_Y,BALL_SIZE,BALL_SIZE);
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 5; j++) {
if (status[i][j] > 0) {
X = x[i][j];
Y = y[i][j];
g2d.setColor(Color.white);
g2d.fillRect(X,Y,BRICK_WIDTH,BRICK_HEIGHT);
g2d.setColor(Color.red);
g2d.fillRect(X + 3,Y + 3,BRICK_WIDTH - 6,BRICK_HEIGHT - 6);
}
}
}
g2d.dispose();
}
protected void tick() {
BALL_X += BALL_DX;
BALL_Y += BALL_DY;
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 5; j++) {
if (BALL_X > x[i][j] && BALL_X < (x[i][j] + BRICK_WIDTH) && BALL_Y <= y[i][j] + BAR_HEIGHT + BALL_SIZE && BALL_Y > y[i][j] && BALL_DY < 0) {
BALL_DY = -BALL_DY;
status[i][j] -= 1;
} else if (BALL_X > x[i][j] && BALL_X < (x[i][j] + BRICK_WIDTH) && BALL_Y >= y[i][j] - BALL_SIZE && BALL_Y < y[i][j] + BAR_HEIGHT && BALL_DY > 0) {
BALL_DY = -BALL_DY;
status[i][j] -= 1;
} else if (BALL_X + BALL_SIZE >= x[i][j] && BALL_X < (x[i][j] + BRICK_WIDTH) && BALL_Y >= y[i][j] && BALL_Y < y[i][j] + BAR_HEIGHT && BALL_DY < 0) {
BALL_DX = -BALL_DX;
status[i][j] -= 1;
} else if (BALL_X > x[i][j] && BALL_X - BALL_SIZE <= (x[i][j] + BRICK_WIDTH) && BALL_Y >= y[i][j] && BALL_Y < y[i][j] + BAR_HEIGHT && BALL_DY < 0) {
BALL_DX = -BALL_DX;
status[i][j] -= 1;
} else if (BALL_X - BALL_SIZE < LEFT_WALL || BALL_X + BALL_SIZE > RIGHT_WALL) {
BALL_DX = -BALL_DX;
} else if (BALL_Y - BALL_SIZE < TOP_WALL) {
BALL_DY = -BALL_DY;
}
}
}
BAR_X = BAR_X + BAR_STATE * BAR_DX;
repaint();
}
class KeyAction extends AbstractAction {
private TestPane source;
private int delta;
public KeyAction(TestPane source,int delta) {
this.source = source;
this.delta = delta;
}
@Override
public void actionPerformed(ActionEvent e) {
source.BAR_STATE = delta;
}
}
}
}
我搞砸了增量值,因为球和杠很快就消失了
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。