Reputation: 49
I am trying to make a Mario game. Right now I am trying to create the basic framework. My main Game class :
package com.arjav.jumper;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
import com.arjav.jumper.creatures.Player;
import com.arjav.jumper.input.KeyManager;
public class Game implements Runnable{
Thread thread = new Thread(this);
JFrame frame ;
Handler handler = new Handler() ;
int frames = 0;
Canvas canvas ;
KeyManager km = new KeyManager();
Graphics g ;
Player player = new Player(50 , 50 , 32 , 32 , this);
BufferStrategy bs ;
public KeyManager getKeyManager() {
return km;
}
public Game(String title , int width , int height) {
frame = new JFrame(title);
frame.setSize(width , height);
frame.setVisible(true);
frame.setDefaultCloseOperation(3);
frame.setResizable(false);
canvas = new Canvas();
canvas.setMaximumSize(new Dimension(width , height));
canvas.setMinimumSize(new Dimension(width , height));
canvas.setPreferredSize(new Dimension(width , height));
canvas.setFocusable(false);
frame.addKeyListener(km);
System.out.println("Key Manager added");
handler.addCreature(new Player(50 , 50 , 50 , 50 , this));
frame.add(canvas);
frame.pack();
}
public static void main(String[] args) {
Game game = new Game("Mario" , 720 , 360);
game.thread.start();
System.out.println("Started running");
}
public void run() {
while(true) {
tick();
render();
frames++ ;
if(frames == 60) {
System.out.println(frames + " FPS");
frames = 0 ;
}
try {
Thread.sleep(1000/60);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void tick() {
handler.tickCreature();
km.tick();
}
public Player getPlayer() {
return player;
}
public void render() {
if(bs == null) canvas.createBufferStrategy(3);
bs = canvas.getBufferStrategy();
g = bs.getDrawGraphics();
g.setColor(Color.RED);
handler.renderCreature(g);
g.setColor(Color.BLACK);
g.fillRect(0, 0, 720, 360);
bs.show();
g.dispose();
}
}
My Creature class :
package com.arjav.jumper.creatures;
import java.awt.Graphics;
public abstract class Creature {
public abstract void render(Graphics g);
public abstract void tick();
int x , y , width , height ;
public Creature(int x , int y , int width , int height) {
this.x = x ;
this.y = y ;
this.width = width ;
this.height = height ;
}
}
Player :
package com.arjav.jumper.creatures;
import java.awt.Color;
import java.awt.Graphics;
import com.arjav.jumper.Game;
public class Player extends Creature{
int x , y , width , height , velX = 0 , velY = 0 ;
Game game ;
public Player(int x , int y , int width , int height , Game game) {
super(x , y , width , height);
this.game = game ;
}
@Override
public void render(Graphics g) {
g.setColor(Color.RED);
g.fillRect(x , y , width , height);
System.out.println("Player rendered");
}
public void tick() {
if(game.getKeyManager().left) x -= 3 ;
if(game.getKeyManager().right) x += 3;
System.out.println("Player ticked");
System.out.println(x);
}
public void setVelX(int velX) {
this.velX = velX;
}
public void setVelY(int velY) {
this.velY = velY;
}
}
It does print player rendered and ticked and also it's x increases and decreases. So the only thing wrong with this is that a red box is not rendering.
Handler class :
package com.arjav.jumper;
import java.awt.Graphics;
import java.util.LinkedList ;
import com.arjav.jumper.creatures.Creature;
public class Handler {
public LinkedList<Creature> creature = new LinkedList<Creature>();
public void addCreature(Creature c) {
creature.add(c);
}
public void removeCreature(Creature c) {
creature.remove(c);
}
public void tickCreature() {
for(int i = 0 ; i < creature.size() ; i ++) {
Creature c = creature.get(i);
c.tick();
}
}
public void renderCreature(Graphics g) {
for(int i = 0 ; i < creature.size() ; i ++) {
Creature c = creature.get(i);
c.render(g);
}
}
}
Upvotes: 1
Views: 65
Reputation: 373
The problem here was that a subclass has variables with the same name as its parent class. Namely:
int x, y, width, height
When the player is created, the constructor of player delegates the x,y,width,height
to the parent creature class. This creature constructor saves these values to the class members, as required.
However, the player class contains variables with names
x, y, width, height
But these are essentially different variables, just with the same name. So now, when you reference any of these variable names in the player, you get the variables of the player (which are uninitialized, so 0), but you intend to get the variables from the creature.
To fix this, simply ensure that you don't have any duplicate variable names between subclasses and parents, since they effectively "hide" the parent variables. Java does not consider this an error, but it can cause a lot of confusion.
For more info, see hiding variables
Upvotes: 1