Why does this list have an error? - java

I am following a tutorial on YouTube, making a Java game.
And I'm getting this error while following it, and I have no idea as to why.
The type List is not generic; it cannot be parameterized with arguments <Enemy>
Here's the list:
private List<Enemy> enemies = new ArrayList<Enemy>();
I have imported java.util.*; and java.awt.*; for List to, theoretically, work.
Here is my Enemy class
import java.awt.*;
public class Enemy extends Entity {
private Rectangle hitbox;
private int movementX, movementY;
private boolean dead = false;
private Main instance;
public Enemy(Main instance, int x, int y) {
super(x, y);
this.instance = instance;
hitbox = new Rectangle(x,y,32,32);
movementX = 0;
movementY = 1;
}
private void move(){
if(instance.getStage().isCollided(hitbox)){
movementY = 0;
dead = true;
}
hitbox.x += movementX;
hitbox.y += movementY;
}
public boolean isDead() { return dead; }
public void draw(Graphics g){
move();
g.setColor(Color.RED);
g.fillRect(hitbox.x, hitbox.y, hitbox.width, hitbox.height);
}
}

You have only imported java.awt.*, which has a different non-generic List. You must fully-qualify your reference to java.util.List because java.awt.List is imported.
private java.util.List<Enemy> enemies = new ArrayList<Enemy>();
Ensure that you have java.util.* imported so ArrayList is resolved also.

By importing java.awt.*, you are also importing java.awt.List. You probably wanted to use java.util.List instead of java.awt.List.
Replace the wildcard import from java.awt with separate import statements for all the classes you need from java.awt, and import java.util.List.

The problem is compiler is trying to treat this List object as java.awt.List not java.util.List. Replace the code with
private java.util.List<Enemy> enemies = new ArrayList<Enemy>();

Related

Java subclass with different method parameters

I am trying to make a simulation that simulates simple creatures and carnivorous creatures.
I have a class called creature and a subclass called carnCreature. I have a method in creature called eat, that takes in a one type of object, but I need the eat method in the carnCreature class to take in a list of creatures. I tried naming the method the same as it is named in the creature class, but when I try to call it, java doesn't accept the updated parameters.
package simulationObjects;
import java.awt.Color;
import java.util.List;
import java.util.Random;
import java.lang.Math.*;
public class Creature {
public int x;
public int y;
public int maxTilesX;
public int maxTilesY;
public Color color;
public float health = 50;
public int life = 0;
public Creature (int x, int y, Color color, int maxTilesX, int maxTilesY) {
this.x = x;
this.y = y;
this.color = color;
this.maxTilesX = maxTilesX;
this.maxTilesY = maxTilesY;
}
public void update(Tile tile) {
eat(tile);
life++;
health-=1;
}
public void eat(Tile currentTile) {
if (currentTile.color == this.color) {
health += 3;
currentTile.color = Color.GRAY;
}
}
public boolean isCarnivore() {
return false;
}
}
package simulationObjects;
import java.awt.Color;
import java.util.List;
public class CarnCreature extends Creature{
private static final boolean CANABOLIC = false;
public CarnCreature(int x, int y, Color color, int maxTilesX, int maxTilesY) {
super(x, y, color, maxTilesX, maxTilesY);
// TODO Auto-generated constructor stub
}
public void update(List<Creature> creatures) {
eat(creatures);
life++;
health-=1;
}
public void eat(List<Creature> creatures) {
for (Creature creature : creatures) {
if (CANABOLIC) {
if (creature.color == this.color) {
health += 3;
creature.health = 0;
}
} else {
if (creature.color == this.color && creature.isCarnivore() == false) {
health += 3;
creature.health = 0;
}
}
}
}
public boolean isCarnivore() {
return true;
}
}
The eat function is being called later like this:
for (Creature creature : creatures) {
if (creature.isCarnivore()) {
creature.upadte(creatures);
} else {
creature.update(tiles.get(creature.x).get(creature.y));
}
}
I am trying to store the creatures and the carnCreatures in the same list, "creatures." Is this the problem, and do I need to store them in separate lists?
Thanks
You have a two options:
Once you know if the creature is carnivore cast it and access the method
Create a method with the same "signature", that is, same name AND arguments.
The second option is the more elegant. Using the "magic" of polymorphism each class will have its method called and you won't need to check the class with the isCarnivore() method. But you will need to get the list of creatures from the tile.
The isCarnivore() test will not spare you to cast to the subclass type as you manipulate as declared type the Creature the base class :
for (Creature creature : creatures) {
if (creature.isCarnivore()) {
((CarnCreature)creature).update(creatures);
} else {
creature.update(tiles.get(creature.x).get(creature.y));
}
}
So the isCarnivore() appear helpless as if (instanceof CarnCreature) would have the same effect and consequences.
Is this the problem, and do I need to store them in separate lists?
It would be better as you don't want manipulate them in an uniform way.
Using the base class to group them in a unique List make your task harder.
But in fact you have a deeper issue. Here eat() is not a overrided method but an overloaded method in the subclass. Same thing for update().
It means that in both cases the two methods are defined in the subclass.
Such a design will not allow to benefit from a polymorphism feature because you want to invoke the first method on the base class instance and invoke the overloaded method on the subclass instance.
In terms of concept, a carnivore creature IS not a creature. Their type of behavior is very different : one consumes a thing (a tile) and the other consumes a very different thing (a list of creature).
To benefit from polymorphism you should re-design the base class and the subclass to override the methods and not overload them. But as you pass really different types in the parameters, you are stuck.
So in your case I think that I would not even create a inheritancy relation between theses classes.

A variable that could take different types in?

TLDR: I need a variable that can take in an object from either of 2 classes.
I'm working on a Java 2D game, still getting the basics to work and here I have a problem: in the class Actor, in the constructor, the actor generates its hitbox (4 XY coordinates object) and then adds that hitbox to a list of things that need to check for collisions.
But now that I got all this working, I made a new class, Platform, so that my character can walk on something else than the defiled corpses of it's enemies. But in the Rect constructor, I have a variable (Parent) that sets itself to the object that called the constructor (with itself in parameter) so I would get hitbox.parent() = player for example.
But since the Platform objects are from another class (that I don't really want to inherit from the Actor class) how can I make it so that Rect and give itself a parent of different type ?
Edit
The class as it is now
package misc;
import item.Platform;
import npc.Actor;
public class Rect {
int x,y,wdt,hgt;
public Rect(Actor a){
x = a.x;
y = a.y;
wdt = a.wdt;
hgt = a.hgt;
}
public Rect(Platform p){
parent = p;
x =p.x;
y =p.y;
wdt =p.wdt;
hgt =p.hgt;
}
}
And here is the place where I have trouble calling it
private static void collision(Rect r1,Rect r2){
if (r1.y -r2.y <= r2.hgt && r1.y -r2.y >= -r2.hgt){
r1.parent.yCol = true;
}else{
r1.parent.yCol = false;
}
if (r1.x -r2.x <= r2.wdt && r1.x -r2.x >= -r2.wdt){
r1.parent.xCol = true;
}else{
r1.parent.xCol = false;
}
}
In addition to inheritance, you could also use an interface based approach.
public interface GameRect {
int getX();
int getY();
int getHeight();
int getWidth();
}
public class Actor implements GameRect {
// implementation
}
public class Platform implements GameRect {
// implementation
}
public class Rect {
// implementation
private GameRect parent;
// constructor works for all classes that implement GameRect interface
public Rect(GameRect gr) {
parent = gr;
x = gr.getX();
y = gr.getY();
// etc
}
}
The problem with a solution like this is that you need to cast back to the original type (Actor, and Platform respectively) every time you want to call class methods on the parent objects that are not GameRect interface methods.
You need to use Inheritance, which is one of the most important aspects of Object Oriented Programming. You need to do some reading on it so you understand how it works and how to use it: https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html

Inherit subclass variable by super in Java

This title does not express what I mean quite well, I apologize, but it is difficult for me to express it better, because I don't quite understand what's going on due to lack of OOP knowledge and experience.
I am building a basic game, which is going to have the player run around a board with a 'hero' sprite, being chased by a 'badGuy' sprite. Because the two sprites share 5-6 methods, I decided to make a super class 'Sprite' and two classes 'Hero extends Sprite' and 'BadGuy extends Sprite'. Now for all those super methods, including stuff like:
getX(); getY(); getBounds(); render();
to work I need the super class to track the location of 'Hero' and 'badGuy'. So I implemented 'Sprite' like this:
package game.sprites;
import javafx.scene.shape.Rectangle;
import javax.swing.*;
import java.awt.*;
public class Sprite {
public static int x;
public static int y;
private int imageWidth;
private int imageHeight;
public Image image;
public Sprite(int x, int y) {
Sprite.x = x;
Sprite.y = y;
}
public static void render(Graphics g, Image image) {
g.drawImage(image, x, y, null);
}
public Image loadImage(String filePath) {...}
public void getImageDimensions() {...}
public Rectangle getBounds() {
return new Rectangle(x, y, imageWidth, imageHeight);
}
public Image getImage() {
return image;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
The problem kicks in when I want to give different starting coordinates to 'Hero' and 'BadGuy' objects. Currently if I set them different, the second call of 'Sprite' overrides the first and both start at the same spot (which would be very frustrating if your goal is to run from 'badGuy').
'Hero' and 'BadGuy' are currently initialized this way:
public class BadGuy extends Sprite {
public BadGuy() {
super(x, y);
initBadGuy();
}
public void initBadGuy() {
loadImage("resources/craft.gif");
getImageDimensions();
x = 860; // Hero x = 20;
y = 560; // Hero y = 20;
}
So what I tried to do is make the subclasses override Sprite's x and y. But I googled it and I understand that this is very bad idea and thus it is not possible. So my question is something like: How can I make 'Sprite' inherit subclass 'x' and 'y' variables and perform the necessary methods when the certain subclass is called.
Now that I look at it - both the constructor and init<>() are identical for the subclasses, so maybe they can be implemented in 'Sprite' instead? Just a thought, but I'm getting quite confused already, so no idea.
Thanks.
You are getting this problem because x and y are declared as static fields in your Sprite class.
From JLS 8.3.1.1. static Fields
If a field is declared static, there exists exactly one incarnation of the field, no matter how many instances (possibly zero) of the class may eventually be created. A static field, sometimes called a class variable, is incarnated when the class is initialized (ยง12.4).
Use following code:
Change your Sprite Class like below:
public class Sprite {
public int x;
public int y;
....
}
BadGuy class:
public class BadGuy extends Sprite {
public BadGuy(int x, int y) {
super(x, y);
...
}
....
}
Hero class:
public class Hero extends Sprite {
public Hero(int x, int y) {
super(x, y);
...
}
....
}
From Main class do following: //From where you want to create Object of both classes
public static void main(String[] args){
Hero hero = new Hero(20,20);
BadGuy badGuy= new BadGuy(860,560);
}

Generics comparing objects in an ArrayList

I'm trying to create a generic class that compares objects in an array list and returns the largest. My issue is that I'm not quite sure I understand completely how generics work.
Measurable:
import java.util.ArrayList;
/**
Describes any class whose objects can be measured.
*/
public abstract class Measurable<T>{
abstract double getMeasure();
public static <T extends Measurable<T>> T getLargest(ArrayList<T> objects){
T largest = objects.get(0);
for(int i = 0; i < objects.size(); i ++){
if(largest.getMeasure() == objects.get(i).getMeasure()){
largest = objects.get(i);
}
}
return largest;
}
}
Box:
import java.awt.Rectangle;
import java.util.ArrayList;
public class Box extends Measurable {
private Rectangle box;
private static ArrayList<Rectangle> rectangles;
public Box(){
box = new Rectangle();
rectangles = new ArrayList<Rectangle>();
}
public ArrayList<Rectangle> create(){
for(int i = 0; i < 10; i++){
box = new Rectangle((int) Math.random(), (int) Math.random());
rectangles.add(box);
}
return rectangles;
}
#Override
public double getMeasure() {
double area = 0;
for(int i = 0; i < rectangles.size(); i++){
area = rectangles.get(i).getWidth()*rectangles.get(i).getHeight();
}
return area;
}
public static void main(String[] args){
Box b = new Box();
b.getLargest(b.create());
}
}
I'm coming across an issue where it says "The method getLargest(ArrayList) in the type Measurable is not applicable for the arguments (ArrayList)" but shouldn't I be able to use any object for the getLargest class?
As you wrote it, getLargest expects the objects passed to it in the List to implement Measurable, but java.awt.Rectangle does not.
When you write
public static <T extends Measurable<T>> T getLargest(ArrayList<T> objects){
that declares a T that is different, but named the same, as the T in the Measurable class as a whole, which is likely to lead to total confusion.
If you actually replace T with Rectangle in your code, you can see that you're trying to call Rectangle.getMeasure(), which is a method that does not exist.
I am not really sure where generics come into play here. It seems like you want to make a bunch of shapes that are derived from a base class Measurable. You also want the abstract class to hold some code for working with Measurable subclasses. Basically you need to make a subclass that implements Measurable. I think what you want a Box class like the one below.
public class Box extends Measurable {
private double width;
private double height;
public Box(double width, double height){
this.width = width;
this.height = height;
}
public double getMeasure() {
double area = width*height;
return area;
}
}

Referring a class on a list newbie confusion

I was studying livewallpaper in this site. However something there is something that i dont understand.
Example in the code of the tutorial there a class named MyPoint
public class MyPoint {
String text;
private int x;
private int y;
public MyPoint(String text, int x, int y) {
this.text = text;
this.x = x;
this.y = y;
}
}
then after he created a MyWallpaperService class. Inside of that class there is a line of code like this
private List<MyPoint> circles;
private Paint paint = new Paint();
private int width;
int height;
private boolean visible = true;
private int maxNumber;
private boolean touchEnabled;
public MyWallpaperEngine() {
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(MyWallpaperService.this);
maxNumber = Integer
.valueOf(prefs.getString("numberOfCircles", "4"));
touchEnabled = prefs.getBoolean("touch", false);
circles = new ArrayList<MyPoint>();
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(10f);
handler.post(drawRunner);
}
You can see the part of code has
private List<MyPoint> circles;
This is the part that i dont understand? What is happening in here? What will List<MyPoint> pass in the circles? Anyone knows what to call this? is this list reffering to a class? Cause im not sure on my title. Thank you..
private List<MyPoint> circles;
States that circles is a List of type MyPoint, (ie. it will hold objects of type MyPoint).
circles = new ArrayList<MyPoint>();
Now in the above line you are assigning the ArrayList object of type MyPoint to the Object Reference Variable of type List.
This is called as Interface Polymorphism.
List is an Interface, where as ArrayList a Concrete Class which implements List.
Eg:
public class Dog{
private String dName;
priavet int dAge;
public Dog(String dName, String dAge){
this.dName = dName;
this.dAge = dAge;
}
public String getDName(){
return this.dName;
}
public String getDName(){
return this.dAge;
}
}
public class Test{
public static void main(String[] args){
List<Dog> dAList = new ArrayList<Dog>();
dAList.add(new Dog("Tommy",5));
dAList.add(new Dog("Stark",2));
for(Dog d : dAList){ // Iterating over the List of Dog objects
System.out.println(d.getDName());
System.out.println(d.getDAge());
}
}
}
The List<MyPoint> object is, as the name suggests, a list of MyPoint instances which, judging from the code, represent the centers of your circles. The private identifier simply indicates that it cannot be accessed from outside of the class in which it is defined.
Its creating a list of objects. A List of MyPoint type objects
MyPoints in your case refers to the (x,y) coordinates of the circle(as you referred)

Categories