0

I'm trying to have a movable Mario sprite on a level, and I have I know the keyListener is working, bc I have debug output in the console, but only the LevelComponent() appears:

public class MarioLevel extends JFrame {

  MarioComponent mc = new MarioComponent();
  JLabel background;

  public MarioLevel(){
    background = new LevelComponent();
    background.setLayout(null);
    this.add(background,BorderLayout.CENTER);
    this.setSize(868,915);
    this.setFocusable(true);
    this.setVisible(true);
    KeyListener kl = new MoveListener();
    this.addKeyListener(kl);

    background.add(mc);
    mc.setBounds(mc.marioSprite.x, mc.marioSprite.y, mc.marioSprite.sprite.getWidth(), mc.marioSprite.sprite.getHeight());

    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

  }

  class MoveListener implements KeyListener{
    public void keyPressed(KeyEvent k){

      if((k.getKeyCode() == 39)){
        mc.moveMario();
        System.out.println(mc.marioSprite.getCoordinates());
      }
      if(k.getKeyCode() == 83){
        mc.jumpMario();
        System.out.println(mc.marioSprite.getCoordinates());
      }
    }
    public void keyReleased(KeyEvent k){
//      if(k.getKeyCode = 83){
//        mc.Mario
//      }
    }
    public void keyTyped(KeyEvent k){}    
  }



  public static void main(String[] args){
   MarioLevel m = new MarioLevel();
  }


}

my MarioComponent:

public class MarioComponent extends JComponent{

  protected Mario marioSprite;


  public MarioComponent(){
    marioSprite = new Mario();
  }

  public void paintComponent(Graphics g){
    //super.paintComponent(g);
    marioSprite.draw(g);
  }

    public void moveMario(){
    marioSprite.move();
    repaint();
  }

   public void jumpMario(){
    marioSprite.jump();
    repaint();

  }

   public void getCoordinates(){
     System.out.println(marioSprite.getCoordinates());
   }

  @Override
  public Dimension getPreferredSize() {
    return new Dimension(marioSprite.sprite.getWidth(), marioSprite.sprite.getHeight());
  }

}

my Mario class:

public class Mario{
//all numbers multiplied by 2 from OG game
  protected MarioState state;
  protected int x, y;
  protected BufferedImage sprite;


  public Mario(){
    this.state = MarioState.SMALL;
    this.x = 54;
    this.y = 806;
    URL spriteAtLoc = getClass().getResource("sprites/Mario/SmallStandFaceRight.bmp");

    try{
      sprite = ImageIO.read(spriteAtLoc);

    } catch(IOException e){
      System.out.println("sprite not found");
      e.printStackTrace();
    }
  }

  public Mario(MarioState s, int x, int y){
    this.state = s;
    this.x = x;
    this.y = y;
  }

  public void move(){
    this.x+=2;

  }

  public void move(char c, int px){
    if(c =='x'){
      this.x += px;
    }
    if(c == 'y'){
      this.y += px;
    }
  }

  public void jump(){
this.y -= 46;
  }


  public String getCoordinates(){
return "Mario coords: " + this.x + ", " + this.y + ".";
  }

  public void draw(Graphics g){

    g.drawImage(sprite, this.x, this.y, null);
  }




}

my LevelMap class:

public class LevelMap{

  BufferedImage bg;

  public LevelMap(){
    URL bgAtLoc = getClass().getResource("sprites/Mario/level.bmp");
    try{
      bg = ImageIO.read(bgAtLoc);
    }
    catch(IOException e){
      System.out.println("invalid level!");
    }

  }

    public void draw(Graphics g){
    g.drawImage(bg, 0, 0, null);
  }



  public static void main(String[] args){}

}    

my LevelComponent class:

public class LevelComponent extends JLabel{
  protected LevelMap levelSprite;

  public LevelComponent(){
    levelSprite = new LevelMap();
  }

  public void paintComponent(Graphics g){
    levelSprite.draw(g);
  }
  @Override
  public Dimension getPreferredSize() {
    return new Dimension(levelSprite.bg.getWidth(), levelSprite.bg.getHeight());
  }



}

Both MarioComponent and LevelComponent show up in their own JFrames. My format of adding a JLabel and then adding components worked in a previous project I did, but is not working here. What could this be?

Derry
  • 371
  • 1
  • 13
  • 3
    1) For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). 2) Didn't someone steer you towards 'custom painting' in a [recent question](https://stackoverflow.com/q/44990575/418556)? It's the best way to approach making a game. – Andrew Thompson Jul 09 '17 at 06:44
  • I used that exact template, and on this its not working. – Derry Jul 09 '17 at 06:45
  • oh I thought u meant my blackjack one. Yes as I said, I can get each of these to show up in their own JFrame, but I want them (and soon others) in the same frame, obviously with Mario ontop of a background with enemies there too. A Mario on a blank JFrame is useless. – Derry Jul 09 '17 at 06:59
  • I also thought of adding this: mc.marioSprite.draw(mc.getGraphics()); to the MarioLevel constructor, no dice. – Derry Jul 09 '17 at 07:43
  • 2
    You really should learn how to make an MCVE / SSCCE that others can easily work with. It involves trimming out the irrelevant dross, demoting all but the class with `main(..)` method to default access and pasting them into the end of the `public` class, hot linking to images (if the images are truly needed) or generating them in code. Having said that, you don't seem to be getting the basic point that a game should typically not be built from a bunch of components. Just have a single component, a `JPanel`, override the `paintComponent(Graphics)` method and paint whatever is needed. – Andrew Thompson Jul 09 '17 at 08:28
  • 2
    `My format of adding a JLabel and then adding components worked in a previous project I did, but is not working here. What could this be?` - well you have a bug in your code you need to solve. You know the concept works, so you need to compare you working code with this code to see what you are doing differently. This is what debugging is all about. – camickr Jul 09 '17 at 14:41
  • @AndrewThompson what should it be built from? Are you saying that all the images should simply loaded into the constructors of what I put into the JFrames? – Derry Jul 09 '17 at 15:40
  • @camickr I tried for hours but couldn't do it; that's why I came here, not for wiseguy comments. – Derry Jul 09 '17 at 16:33
  • @Derry, Again how have you tried to debug this? Did you add a regular JLabel to the LevelComponent? Did it work? If not the problem is your LevelComponent. If it did, then the problem is your MarioComponent. – camickr Jul 09 '17 at 17:13
  • yes I've spent hours before I came here trying to debug. What do you mean "add regular JLabel" to levelComponent? – Derry Jul 09 '17 at 17:26
  • @Derry I showed you in a previous question (https://stackoverflow.com/questions/44894905/when-i-use-an-paintcomponent-to-my-jframe-i-have-to-resize-my-window-to-get-it) how to use Swing components to have a background component and a child component which works no problem. So the concept here is the same except for some reason you are using custom components to display the images. So since if worked before and doesn't work now, the problem would be in your implementation of the custom components. So Which component is wrong? – camickr Jul 09 '17 at 17:32
  • Why are you even using custom components? There is no reason you can't use a JLabel with an image. Then you just invoke setLocation(...) when you want to move the label. – camickr Jul 09 '17 at 17:32
  • I'm using custom components because the Mario sprite is going to move, and can move with a KeyListener, and enemies are going to be in there too. – Derry Jul 09 '17 at 17:36
  • 1
    Again, as I already stated. There is no reason "Mario", can't just be a JLabel with an Image. Then you use setLocation(...) to move "Mario" around the background image. Or as Andrew has already suggested you just have single component to do all the painting. So first you paint the background. Then you paint "Mario" where ever you want. – camickr Jul 09 '17 at 19:22

0 Answers0