0

I know there are a lot of answers for this but they don't seem to work. I don't know whether I am somehow using a different version of Java or the code for applet's is different but here's my code:

Snippet from HUD class:

public void paint (Graphics g)
{

    if(g instanceof Graphics2D)
    {
        Graphics2D g2d = (Graphics2D)g;
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        g2d.drawString("This is gona be awesome", 200, 200);
    }

Main Class:

import java.applet.Applet; (more, they just glitched with the code block)


public class Main extends Applet implements Runnable, KeyListener {

static ArrayList<Block> all_blocks = new ArrayList<Block>();
Player player;
HUD hud;
static int amount = 0;

public void init(){

    setSize(700, 500);
    addKeyListener(this);

}

public void start(){

    player = new Player(100, 100);
    HUD hud = new HUD();

    for (int i = 0; i < 75; i++){

        new Grass(i*30, 400);

    }
    new Spikes(250, 370);


    Thread thread = new Thread(this);
    thread.start();

}

@Override
public void run() {

    while (true){

        player.update();

        repaint();
        camera_scroll(this.amount);

        try {
            Thread.sleep(17);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

}

public void stop(){

}

public void camera_scroll(int amount){
    int new_amount;

    if (amount > 30){
        new_amount = 30;
        this.amount -= 30;

    } else {
        new_amount = amount;
        this.amount = 0;
    }
    for (Block b: all_blocks){
        b.x += new_amount;
        b.update();
    }
    player.x += new_amount;
}

public void paint(Graphics g){
    for (Block block: all_blocks){
        block.paint(g);
    }
    hud.paint(g);
    player.paint(g);

}

@Override
public void keyPressed(KeyEvent e) {
    switch(e.getKeyCode()){

    case KeyEvent.VK_LEFT:
    case KeyEvent.VK_A:
        player.moveLeft();
        break;

    case KeyEvent.VK_RIGHT:
    case KeyEvent.VK_D:
        player.moveRight();
        break;

    case KeyEvent.VK_UP:
    case KeyEvent.VK_W:
        player.moveUp();
        break;



    }

}

@Override
public void keyReleased(KeyEvent e) {
    switch(e.getKeyCode()){

    case KeyEvent.VK_LEFT:
    case KeyEvent.VK_A:
        player.stopLeft();
        break;

    case KeyEvent.VK_RIGHT:
    case KeyEvent.VK_D:
        player.stopRight();
        break;

    case KeyEvent.VK_UP:
    case KeyEvent.VK_W:
        player.stopUp();
        break;


    }
}

@Override
public void keyTyped(KeyEvent e) {
    // TODO Auto-generated method stub

}



}

Drawing of the player and blocks work fine and their paint method is identical to HUD's but they draw images instead. Let me know if you need anything else. Thanks!

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Andy
  • 263
  • 1
  • 11
  • `if(g instanceof Graphics2D)` will never be true. – BitNinja Aug 04 '14 at 23:36
  • @BitNinja Actually, since 1.4 (I think) it will always be true... – MadProgrammer Aug 05 '14 at 00:19
  • Consider providing a [runnable example](https://stackoverflow.com/help/mcve) which demonstrates your problem. This will result in less confusion and better responses – MadProgrammer Aug 05 '14 at 00:21
  • 1
    1) Why code an applet? If it is due to spec by your instructor, please refer them to [Why CS teachers should **stop** teaching Java applets](http://programmers.blogoverflow.com/2013/05/why-cs-teachers-should-stop-teaching-java-applets/). 2) Why use AWT components rather than Swing? See [this answer](http://stackoverflow.com/a/6255978/418556) for many good reasons to abandon AWT. 3) A single blank line of white space is *always* enough. Blank lines after `{` or before `}` are also typically redundant. – Andrew Thompson Aug 06 '14 at 02:45

1 Answers1

2

The Problem...

There are two main issues...

One...

You are creating instance of objects within the start method, when they should be created in your init method.

start can be called multiple times (normally after stop is called) to get the applet to continue. This is not a good place to try and initialize the state of your underlying applet, instead, it would be better used to restart the Thread (assuming you also stop it when stop is called)...

So, instead of...

public void init(){

    setSize(700, 500);
    addKeyListener(this);

}

public void start(){

    player = new Player(100, 100);
    HUD hud = new HUD();

    for (int i = 0; i < 75; i++){

        new Grass(i*30, 400);

    }
    new Spikes(250, 370);


    Thread thread = new Thread(this);
    thread.start();

}

you should be using something like...

public void init(){

    setSize(700, 500);
    addKeyListener(this);

    player = new Player(100, 100);
    HUD hud = new HUD();

    for (int i = 0; i < 75; i++){

        new Grass(i*30, 400);

    }
    new Spikes(250, 370);

}

public void start(){

    Thread thread = new Thread(this);
    thread.start();

}

Two...

You are creating a local instance of your objects, shadowing your instance fields, which is causing a NullPointerException (for me it was in paint...

So instead of

public void init(){

    setSize(700, 500);
    addKeyListener(this);

    player = new Player(100, 100);
    HUD hud = new HUD();

    for (int i = 0; i < 75; i++){

        new Grass(i*30, 400);

    }
    new Spikes(250, 370);

}

You should be using...

public void init(){

    setSize(700, 500);
    addKeyListener(this);

    player = new Player(100, 100);
    hud = new HUD();
    // Notice that HUD has not been re-declared...

    for (int i = 0; i < 75; i++){

        new Grass(i*30, 400);

    }
    new Spikes(250, 370);

}

Side Notes

  • AWT was replaced by Swing some 15+ years ago, the API is no longer, generally, used. It would recomended to use JApplet instead...
  • Applets are notoriously difficult to develop and typically run within a very restrictive security sandbox. Unless you have a very particular need to use them, I'd recommend avoiding them for the time been and use a JFrame as you core, top level container.
  • It's generally a bad idea to paint directly to a top level container like an applet or frame, instead, it is generally encouraged that you move your core logic to something like a JPanel and override it's paintComponent method to perform custom painting. This is recommended for a number of reasons, including the fact that painting is actually quite involved and complicated and it is very easy to break the paint chain and top level containers aren't double buffered, which will cause flickering. Swing components (apart from there top level counterparts) are double buffered by default. Take a look at Painting in AWT and Swing and Performing Custom Painting for more details
  • KeyListeners are notorious for having issues related to focus. If you move to the Swing API, it is best to use the Key Bindings API
  • Also, Swing is not thread safe, just beware ;)
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Wow, I can't thank you enough. That helps a lot thanks. Thanks heaps though, gonna go again with a take 2 and try JApplet. Thanks sooo much! – Andy Aug 05 '14 at 00:51