我搜索并发现了几个类似的问题,但没有任何适用于我的情况,所以我去了。
我试图制作一个不同级别的游戏,每个级别的游戏都完全不同。
最初,我的代码看起来像这样并且运行良好:
public class Life extends JPanel{
private Story story;
public Life(){
story = new Story(this);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
story.render(g)
public void terminate(){
story.terminate();
System.out.println("Terminated");
}
public static void main(String[] args){
final JFrame frame = new JFrame("Life");
final Life life = new Life();
frame.add(life);
}
}
public class Story {
private int phase;
private Life life;
public Story(Life life){
this.life = life;
phase = 0;
}
public void render(Graphics g){
if(phase == 0) levelOneRender(g);
if(phase == 1) levelTwoRender(g);
}
}
我很担心每次游戏时都会浪费时间来检查我所处的阶段。由于我计划有20多个阶段,因此代码会快速效率低下。
所以我有一个想法,就是简单地将JP对象中的Graphics对象从我的Life对象传递到我的Story对象,并将Jpanel绘制在每个阶段的不同类中,如下所示:
public class Life extends JPanel{
public Life(){
story = new Story(this);
}
public static void main(String[] args){
final JFrame frame = new JFrame("Life");
final Life life = new Life();
}
}
public class Story {
private int phase;
private Intro intro;
private Life life;
public Story(Life life){
this.life = life;
phase = 0;
intro = new Intro(this);
}
public void nextPhase(){
this.phase++;
}
public Life getLife() {
return this.life;
}
}
public class Intro {
private static final int DELAY = 100; // in milliseconds, so 10 ticks per second
private Timer timer;
private Story story;
private Graphics g;
private int counter;
public Intro(Story story) {
this.story = story;
this.g = story.getLife().getGraphics();
this.counter = 0;
timer = new Timer(DELAY, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
tick();
story.repaint();
}
});
timer.start();
}
public void tick(){
if(counter <= 40){
terminate();
}
counter++;
render();
}
public void render(){
story.getLife().paint(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.draw(new Rectangle(0,0,10,10));
}
public void terminate(){
timer.stop();
story.nextPhase();
}
}
不幸的是,这不起作用,如story.getLife()。paint(g);在类Intro中,当我运行它时抛出nullPointerException。而且我很确定这不是我尝试此问题的唯一问题。
有没有正确的方法去做我想要的事情?
非常感谢你的时间。任何见解都将不胜感激。
答案 0 :(得分:1)
public void render(Graphics g){
if(phase == 0) levelOneRender(g);
if(phase == 1) levelTwoRender(g);
}
这并不像你想象的那么大。你现在拥有的很好。但是可以避免这些检查(正如您所要求的那样)。
不是在单独的方法中处理每个级别的绘画,而是在单独的对象中处理它们:
public bstract class Level {
public abstract void paint(Graphics g);
}
public final class LevelOne extends Level {
public void paint(Graphics g) {
//...
}
}
public final class LevelTwo extends Level {
public void paint(Graphics g) {
//...
}
}
这样,您无需检查int
值以查看要绘制的渲染,而只需切换Level
值即可呈现新级别:
Level one = new LevelOne();
Level two = new LevelTwo();
Level currentLevel = one;
public void paintComponent(Graphics g) {
super.paintComponent(g);
currentLevel.paint(g);
}
只需切换level
的值即可呈现不同级别