所以我一直在尝试制作基本的视频游戏,只是为了了解它们的工作原理。我已经制作了一个工作模型,但我试图简化它,并且更容易修改/添加组件。
以下是我的程序中的两个类:
package KernelGame;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.TimerTask;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class VGKernel extends JPanel implements KeyListener{
public static final Graphics g = null;
public static Rectangle screen;
static Ball[] ball = new Ball[5];
public static Rectangle bounds;
public static JFrame frame;
public static VGTimerTask vgTask;
public static Rectangle player;
public static int move;
public VGKernel(){
super();
screen = new Rectangle(0, 0, 800, 600);
makeBalls();
bounds = new Rectangle(0, 0, 800, 600);
frame = new JFrame("VGKernel");
vgTask = new VGTimerTask();
player = new Rectangle(0, 541, 30, 30);
frame.addKeyListener(this);
frame.requestFocus();
}
public static void makeBalls(){
ball[0] = new Ball(0, 0, 20, 20, true, true);
ball[1] = new Ball(25, 25, 20, 20, true, true);
ball[2] = new Ball(50, 50, 20, 20, true, true);
ball[3] = new Ball(75, 75, 20, 20, true, true);
ball[4] = new Ball(100, 100, 20, 20, true, true);
}
class VGTimerTask extends TimerTask{
public void run(){
Ball.moveBalls(Ball.ball[0]);
Ball.moveBalls(Ball.ball[1]);
Ball.moveBalls(Ball.ball[2]);
Ball.moveBalls(Ball.ball[3]);
Ball.moveBalls(Ball.ball[4]);
checkCollisions();
frame.repaint();
}
}
public void paintComponent(Graphics g){
bounds = g.getClipBounds();
g.clearRect(screen.x, screen.y, screen.width, screen.height);
g.setColor(Color.red);
g.fillRect(Ball.ball[0].x, Ball.ball[0].y, 20, 20);
g.fillRect(Ball.ball[1].x, Ball.ball[1].y, 20, 20);
g.fillRect(Ball.ball[2].x, Ball.ball[2].y, 20, 20);
g.fillRect(Ball.ball[3].x, Ball.ball[3].y, 20, 20);
g.fillRect(Ball.ball[4].x, Ball.ball[4].y, 20, 20);
g.setColor(Color.blue);
g.fillRoundRect(player.x, player.y, player.width, player.height, 30, 30);
}
public static void main(String arg[]){
java.util.Timer vgTimer = new java.util.Timer(); // Create a Timer.
VGKernel panel = new VGKernel(); // Create an instance of our kernel.
VGKernel.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
VGKernel.frame.setSize(VGKernel.screen.width, VGKernel.screen.height);
VGKernel.frame.setResizable(false);
VGKernel.frame.setLocation(275, 75);
VGKernel.frame.setContentPane(panel);
VGKernel.frame.setVisible(true);
VGKernel.frame.setFocusable(true);
vgTimer.schedule(VGKernel.vgTask, 0, 10);
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
player.x = player.x-5;
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
player.x = player.x+5;
}
if (e.getKeyCode() == KeyEvent.VK_UP) {
player.y = player.y-5;
}
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
player.y = player.y+5;
}
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
if (e.getKeyChar() == 27) {
System.exit(0);
}
}
public void checkCollisions(){
Rectangle r1 = player.getBounds();
Rectangle r2 = Ball.ball[0].getBounds();
Rectangle r3 = Ball.ball[1].getBounds();
Rectangle r4 = Ball.ball[2].getBounds();
Rectangle r5 = Ball.ball[3].getBounds();
Rectangle r6 = Ball.ball[4].getBounds();
if (r1.intersects(r2)) {
JOptionPane.showMessageDialog(null, "VGKernel", "Game Over", JOptionPane.ERROR_MESSAGE);
System.exit(0);
}
if (r1.intersects(r3)) {
JOptionPane.showMessageDialog(null, "Game Over", "VGKernel", JOptionPane.ERROR_MESSAGE);
System.exit(0);
}
if (r1.intersects(r4)) {
JOptionPane.showMessageDialog(null, "Game Over", "VGKernel", JOptionPane.ERROR_MESSAGE);
System.exit(0);
} if (r1.intersects(r5)) {
JOptionPane.showMessageDialog(null, "Game Over", "VGKernel", JOptionPane.ERROR_MESSAGE);
System.exit(0);
} if (r1.intersects(r6)) {
JOptionPane.showMessageDialog(null, "Game Over", "VGKernel", JOptionPane.ERROR_MESSAGE);
System.exit(0);
}
}
}
和子类
package KernelGame;
@SuppressWarnings("serial")
public class Ball extends VGKernel{
public int x, y, width, height;
private boolean right, down;
public Ball(int x, int y, int width, int height, boolean down, boolean right){
}
public static void moveBalls(Ball b){
// Ball should really be its own class with this as a method.
if (b.right) b.x+=b.width/8; // If right is true, move ball right,
else b.x-=b.width/8; // otherwise move left.
if (b.down) b.y+=b.height/8; // Same for up/down.
else b.y-=b.width/8;
if (b.x > (bounds.width - b.width)) // Detect edges and bounce.
{b.right = false; b.x = bounds.width - b.width; }
if (b.y > (bounds.height - b.height))
{ b.down = false; b.y = bounds.height - b.height;}
if (b.x <= 0) { b.right = true; b.x = 0; }
if (b.y <= 0) { b.down = true; b.y = 0; }
}
public int getX(){ return getX();}
public int getY(){ return getY();}
public int getWidth(){ return getWidth();}
public int getHeight(){ return getHeight();}
}
Eclipse没有显示任何错误,但是当我运行它时,我得到:
Exception in thread "main" java.lang.StackOverflowError
at java.util.HashMap.getEntry(Unknown Source)
at java.util.HashMap.get(Unknown Source)
at sun.awt.AppContext.get(Unknown Source)
at com.sun.java.swing.SwingUtilities3.getDelegateRepaintManager(Unknown Source)
at javax.swing.RepaintManager.getDelegate(Unknown Source)
at javax.swing.RepaintManager.addDirtyRegion(Unknown Source)
at javax.swing.JComponent.repaint(Unknown Source)
at java.awt.Component.repaint(Unknown Source)
at javax.swing.JComponent.setFont(Unknown Source)
at javax.swing.LookAndFeel.installColorsAndFont(Unknown Source)
at javax.swing.plaf.basic.BasicPanelUI.installDefaults(Unknown Source)
at javax.swing.plaf.basic.BasicPanelUI.installUI(Unknown Source)
at javax.swing.JComponent.setUI(Unknown Source)
at javax.swing.JPanel.setUI(Unknown Source)
at javax.swing.JPanel.updateUI(Unknown Source)
at javax.swing.JPanel.<init>(Unknown Source)
at javax.swing.JPanel.<init>(Unknown Source)
at javax.swing.JPanel.<init>(Unknown Source)
at KernelGame.VGKernel.<init>(VGKernel.java:30)
at KernelGame.Ball.<init>(Ball.java:11)
at KernelGame.VGKernel.makeBalls(VGKernel.java:43)
at KernelGame.VGKernel.<init>(VGKernel.java:32)
at KernelGame.Ball.<init>(Ball.java:11)
at KernelGame.VGKernel.makeBalls(VGKernel.java:43)
我不知道如何理解所有这些错误,所以非常感谢帮助。感谢:d
答案 0 :(得分:3)
A Ball
public class Ball extends VGKernel{
是VGKernel
public class VGKernel extends JPanel implements KeyListener{
当您创建Ball
时,您也正在创建VGKernel
部分,即您也在调用其构造函数和初始值设定项。这意味着每个VGKernel
都会调用
makeBalls();
创建了一堆Ball
个对象。这些对象也是VGKernel
,所以他们的创建也涉及调用
makeBalls();
会创建更多Ball
s,从而产生更多Ball
s,令人作呕。
基本上,您必须修复整个对象模型。
解决这些问题后,您还应该修复dognose标识的问题。你的getter也是无限递归的。
答案 1 :(得分:2)
public int getX(){ return getX();}
public int getY(){ return getY();}
public int getWidth(){ return getWidth();}
public int getHeight(){ return getHeight();}
您的方法再次调用相同的方法 - &gt;无限循环 - &gt; StackOverflow的。
你想:
public int getX(){ return this.x;}
等等。 (当使用getter / setter时,你可以使x,y,widht和height“私有”。