This site requires JavaScript, please enable it in your browser!
Greenfoot back
vertrook13noel
vertrook13noel wrote ...

2015/7/18

1 class shared by many world constructors = impossible?

vertrook13noel vertrook13noel

2015/7/18

#
Sorry for this being long, I can't figure out how to explain the problem more briefly (this is my first post). I usually try to solve things myself; but after 2 days, this one has me stumped and I could really use help. I'm new to Greenfoot, but not to programming. I have multiple world subclasses representing different floors in a dungeon. The constructor of each of these classes creates a Viewport object (representing the part of the screen where you view the level), which keeps track of the state of the level, its map, and so on — so that when the player goes up a floor he goes to another level; and when he goes down a floor, he returns (I'm using Greenfoot.setWorld(). Each floor is receiving/passing references to and from each other). The crux of the problem is that each Viewport object cannot cast the world it gets from the getWorld() method, to the appropriate type. For example, let's say that the Level01 constructor tries to create a new Viewport(). This sets up a map, and where a player and the monsters are on it, etc. This new Viewport object needs to access the variables of the world that it resides in. And so it runs getWorld(). But now it must cast the world to a Level01 type in order to use it. I can't write "Level01 world = (Level01)getWorld()" in the Viewport class or else the class can't be used by a Level02 object. So in short: how do I write a class that gets shared by objects of each world subclass, and that can access the world it resides in, cast to the appropriate type? It seems to be either unsharable, or sharable — but can't retrieve the world that it's a part of. I tried generics, but that failed — but maybe I'm doing it wrong. Or, maybe I'm not allowed to extend a non-generic class (Actor) with a generic class (Viewport). Here's the code of that attempt In the Level01 constructor: public class Level01 extends World { public Player player; public Level01() { Viewport<Level01> viewport = new Viewport<Level01>(); } } ...and in the Viewport class: public class Viewport<T> extends Actor { public void initializeMap() { T world = (T)getWorld(); int health = world.player.health; // Generates error: cannot find symbol - variable player world.addObject(new Wall(), 10, 10); // Generates error: cannot find symbol - method addObject(Wall, int, int) } } It appears to be finding the world, converting it to a Level01 (it doesn't seem to error there), but not finding any of its variables or methods — whether inherited (addObject) or explicitly stated (player). — Oh, and the Player class definitely has the "public int health;" in it, with an initialized value in its constructor. And all of this is in an attempt to create multiple worlds in an object oriented manner. Thank you!
davmac davmac

2015/7/18

#
I don't think you need Viewport to be a generic class. Instead, you should abstract out the shared functionality of the worlds that you need to access from Viewport into a single class (which extends World), and have all your levels extend this class rather than extending World directly.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class AbstractLevel extends World
{
    public Player player;
}
 
public class Level01 extends AbstractLevel
{
    public Level01()
    {
        Viewport<Level01> viewport = new Viewport<Level01>();
    }
}
 
public class Viewport extends Actor
{
    public void initializeMap()
    {
        AbstractLevel world = (AbstractLevel) getWorld();
         
        int health = world.player.health;
        world.addObject(new Wall(), 10, 10);
    }
}
vertrook13noel vertrook13noel

2015/7/18

#
Whoa, that's BRILLIANT! That solves everything simply and elegantly and I definitely wouldn't have thought of that. Plus, it teaches me how to get around generics. Thank you so much; now I can make a huge game and reuse the same classes for each level. <cackles with glee>
You need to login to post a reply.