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

2015/5/11

Adding same Objects that act seperatly

1
2
xWanna xWanna

2015/5/11

#
Hi, I want to addObjects to the world that are acting seperatly of each other. I have a class that checks if the enemy is in range and that the sight isn't blocked. The other class is the enemy class that reduces the health. When I add the first enemy it works fine, but when I add another enemy the second one only targets you if the first one targets you too. So how can I let them act for them selves? Do I have to add a subclass to the class that checks the line of sight? Line of Sight:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
public SichtS(){
        setImage(new GreenfootImage(1,1));
    }
 
    /**
     * Act - do whatever the SichtS wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act()
    {
        if(!Quest.pause){
            sehenSchwert1(-100, 100, -100, 100);
 
            //GameOver();
        }
    }  
 
    public static boolean SichtS = true;
    public void sehenSchwert1(int SYNe, int SYPo, int SXNe, int SXPo){
        //AYNe = Negativ Y-Value of max distance to Character
        //AYPo = Positive Y-Value of max distance to Character
        //AXNe = Negativ X-Value of max distance to Character
        //AXPo = Positive X-Value of max distance to Character
        W1 w1 =  (W1) getWorld();
        Schwert schwert = new Schwert();
        Charakter1 charakter1 = new Charakter1();
 
        Wände wände = (Wände) getOneIntersectingObject(Wände.class);
        int EntfX = CharX-SchwertX; //Calculation of distance on x axe
        int EntfY = CharY-SchwertY; //Calculation of distance on y axe
        boolean EntfX1 = false;
        if(SXNe <= EntfX && SXPo >= EntfX ){ //checks if x distance is ok
            EntfX1 = true;
        }else{
            EntfX1 = false;
        }
        boolean EntfY1 = true;
        if(SYNe <= EntfY && SYPo >= EntfY){ //checks if y distance is ok
            EntfY1 = true;
        }else{
            EntfY1 = false;
        }
        boolean EntfS = false;
        if(EntfY1 == true && EntfX1 == true){ //checks if y&x distance is ok
            EntfS = true;
        }else{
            EntfS = false;
        }
 
        if(wände !=null || !EntfS){ // checks if line of sight is blocked
            SichtS = false;
            SchwertX = schwert.X2;
            SchwertY = schwert.Y2;
            CharX = charakter1.X1;
            CharY = charakter1.Y1;
            int myX = (SchwertX + CharX) / 2; //calculates X coordinate
            int myY = (SchwertY + CharY) / 2; //calculates y coordinate
            setLocation(myX, myY);
            turnTowards(CharX, CharY); //turning to character
            int d = (int)Math.sqrt(Math.pow((SchwertX-CharX),2)+Math.pow((SchwertY-CharY),2)); //calculation of d for size of the line of sight
            if(d<=0){
                d = 1;
            }
            setImage(new GreenfootImage(d, 1));
 
            //ImgS = getImage();
          //  ImgS.setColor(Color.GREEN);
          //  ImgS.drawLine(0, 0, d,0);
             
        }else{
            SichtS = true;
            SchwertX = schwert.X2;
            SchwertY = schwert.Y2;
            CharX = charakter1.X1;
            CharY = charakter1.Y1;
            int myX = (SchwertX + CharX) / 2;
            int myY = (SchwertY + CharY) / 2;
            setLocation(myX, myY);
            turnTowards(CharX, CharY);
            int d = (int)Math.sqrt(Math.pow((SchwertX-CharX),2)+Math.pow((SchwertY-CharY),2));
            if(d<=0){
                d = 1;
            }
            setImage(new GreenfootImage(d, 1));
 
            //ImgS = getImage();
           // ImgS.setColor(Color.RED);
            //ImgS.drawLine(0, 0, d,0);
              
        }
    }
Enemy:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/**
     * Act - do whatever the Schwert wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act()
    {
        if(!Quest.pause){
            getX2();
            getY2();
            ausrichten();
            treffen(10, 1000);
            Rot();
            //bewegen();
            //GameOver();
        }
    }  
    public static int X2 = 0;
    public void getX2(){
        X2 = getX();
    }
    public static int Y2 = 0;
    public void getY2(){
        Y2 = getY();
    }
 
    /**
     * Ausrichtn in Richtung Charakter, wenn SichtS (wird in Klasse SichtA berechnet) eintrifft
     *
     */public void ausrichten(){
        if(SichtS.SichtS){
            //turnTowards(Charakter1.X1, Charakter1.Y1);
            bewegen();
        }
 
    }
 
    public void bewegen(){
        GreenfootImage img = getImage();
        int xChar = Charakter1.X1;
        int yChar = Charakter1.Y1;
        if(xChar < getX() && getOneObjectAtOffset(img.getWidth()/2, 0, Wände.class)==null && getOneObjectAtOffset(img.getWidth()/2, 0, Tor.class)==null && getOneObjectAtOffset(img.getWidth()/2, 0, Fenster.class)==null){
            setLocation(X2 - 1, Y2);
            setImage("G6/G6Links.png");
        }else if(xChar > getX() && getOneObjectAtOffset(img.getWidth()/-2, 0, Wände.class)==null && getOneObjectAtOffset(img.getWidth()/-2, 0, Tor.class)==null && getOneObjectAtOffset(img.getWidth()/-2, 0, Fenster.class)==null){
            setLocation(X2 + 1, Y2);
            setImage("G6/G6Rechts.png");
        }
        if(yChar < getY() && getOneObjectAtOffset(0, img.getHeight()/-2, Wände.class)==null && getOneObjectAtOffset(0, img.getHeight()/-2, Tor.class)==null && getOneObjectAtOffset(0, img.getHeight()/-2, Fenster.class)==null){
            setLocation(X2, Y2 - 1);
            setImage("G6/G6Hinten.png");
        }else if(yChar > getY() && getOneObjectAtOffset(0, img.getHeight()/2, Wände.class)==null && getOneObjectAtOffset(0, img.getHeight()/2, Tor.class)==null && getOneObjectAtOffset(0, img.getHeight()/2, Fenster.class)==null){
            setLocation(X2, Y2 + 1);
            setImage("G6/G6Front.png");
        }
 
    }
azazeel azazeel

2015/5/11

#
try to use constructor to differentiate actor
xWanna xWanna

2015/5/11

#
How would you do it?
danpost danpost

2015/5/11

#
I think your problems stem from using static fields. Try to code it without the use of 'static' fields. The 'static' keyword is reserved for fields that belong to the class as a whole; they do not belong to individual objects of the class.
danpost danpost

2015/5/11

#
As far as a line-of-sight actor, have each actor of the class create its own line-of-sight actor for it to use. When needed, set its location, rotation and length and have it move a distance of half its length; then call a method of the line-of-sight class to get any information required (like number of intersectors -- if only 2, the targeting and the targeted, then the line of sight is clear).
xWanna xWanna

2015/5/13

#
@ danpost I don't quite get it, should I add the Line of sight actor in the cunstructor? And I don't know how to do it without the static field, if i remove it I get an error : "non-static variable X2 cannot be referenced from a static context."
danpost danpost

2015/5/13

#
xWanna wrote...
@ danpost I don't quite get it, should I add the Line of sight actor in the cunstructor? And I don't know how to do it without the static field, if i remove it I get an error : "non-static variable X2 cannot be referenced from a static context."
It is quite difficult to help without seeing the code you are trying to use (the more code given -- the better the responses and the quicker the resolution to the issues, usually). You can create the line of sight actor in the constructor; but, you cannot add it into the world until it itself is added into a world. You will need to keep a reference to the line of sight object in the class (a field that holds a line of sight object assigned directly or from within the constructor.
danpost danpost

2015/5/13

#
First, you need to create an actor subclass for the line of sight object. What have you come up with, so far?
xWanna xWanna

2015/6/1

#
Sorry for my late respons, but I ha some problems. But now to the programming. Some explanations first for better understanding of the following. I have the enemy and it's using the "Line of Sight" actor for checking if the player is in range or if the sight is blocked.+ If the sight is free and the player in range the enemy will move towards the player. I managed to add the "Line of sight" actor with the enemy, but the problem I have now is, that when I add more than one enemy and line of sight actor, the enemy aren't using the right "line of sight". For example if I add the first enemy and line of sight, the enemy is using this line of sight, but if I add another enemy and line of sight the first enemy is using the second line of sight and the other way round. I tried it in different ways. Add them from the Sight class (super class of line of sight): I tried first Line of sight and then enemy and the other way round, but didn't changed anything.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public void test(){
       SichtS sichts = new SichtS(); //Line of sight
       Schwert schwert = new Schwert(); //Enemy
 
       if(Quest.Schwert){   //Interaction with KI, not necessary
           Quest.Schwert = false
           if(i<1){
               getWorld().addObject(sichts, 400, 300);
               Schwert = true;
               getWorld().addObject(schwert, 200, 300);
               getWorld().addObject(sichts, 400, 300);
               i++;
           }
       }
       if(Greenfoot.isKeyDown("z")){
           i = 0;
       }
   }
I tried adding them from Line of sight:
1
2
3
4
5
6
7
8
9
10
11
public void Schwert(){
        Schwert schwert = new Schwert();
        if(i<1 && super.Schwert){
            getWorld().addObject(schwert, 200, 300);
            super.Schwert = false;
            i++;
        }
        if(Greenfoot.isKeyDown("z")){
            i = 0;
        }
    }
And from the enemy:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void SichtS(){
        SichtS sichts = new SichtS();
         
         
            if(i<1){
                getWorld().addObject(sichts, 400, 300);
                 
                i++;
             
        }
        if(Greenfoot.isKeyDown("z")){
            i = 0;
        }
    }
Hope you can help me. xWanna
danpost danpost

2015/6/1

#
For simplification, you should never have more than one line of sight actor in the world at any time. There are two ways (at least) to go about this. One is to have just one line of sight actor ever created and have all actors that need it use the same one. The other is to have each actor that needs one create one for itself and have it always use the same one. There is a third way -- to have each actor create one each time one is needed; but that would be quite wasteful as memory blocks would constantly be assigned for the actors, utilized once and then immediately discarded. The line of sight actor(s) should only be in the world for an instant, when needed -- just long enough to determine whether an interruption in the line of sight is present or not. I still would like to see the code you have for the line of sight actor (preferably the entire class code starting from line 1) before proceeding to having your other actors using objects of that class. It would give a better idea of how it is to be used; when it should be added and tested; etc.
xWanna xWanna

2015/6/1

#
The problem is that I'll have more than one enemy in my world and the enemies should act separately, so they don't move all if I'm in sight of one of them, only the one who can see me should move. The class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.awt.event.*;
import java.awt.Font;
import java.awt.Color;
import java.awt.Graphics;
import java.lang.Math;
 
/**
 * Checks if enemy can see the player
 * He can see him if no wall blocks the view or if the player is in range
 *
 * @author (your name)
 * @version (a version number or a date)
 */
public class SichtS extends Sicht
{
    
    public SichtS(){
        setImage(new GreenfootImage(1,1));
        
    }
 
    /**
     * Act - do whatever the SichtS wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act()
    {
        if(!Quest.pause){
            Schwert();
            sehenSchwert1(-100, 100, -100, 100);
             
            //GameOver();
        }
    }  
    int i = 0;
    public void Schwert(){
        Schwert schwert = new Schwert();
        if(i<1 && super.Schwert){
            getWorld().addObject(schwert, 200, 300);
            super.Schwert = false;
            i++;
        }
        if(Greenfoot.isKeyDown("z")){
            i = 0;
        }
    }
     
    public static boolean SichtS = true;
    public void sehenSchwert1(int SYNe, int SYPo, int SXNe, int SXPo){
        //AYNe = negative value of distance on Y-Axe to keep sight true
        //AYPo = positive value of distance on Y-Axe to keep sight true
        //AXNe = negative value of distance on X-Axe to keep sight true
        //AXPo = positive value of distance on X-Axe to keep sight true
 
        W1 w1 =  (W1) getWorld();
        Schwert schwert = new Schwert();
        Charakter1 charakter1 = new Charakter1();
 
        Wände wände = (Wände) getOneIntersectingObject(Wände.class);
        int EntfX = CharX-SchwertX; //calculation distance of X coordinates
        int EntfY = CharY-SchwertY; //calculating distance of Y coordinates
        boolean EntfX1 = false;
        if(SXNe <= EntfX && SXPo >= EntfX ){ //checks if x distance is inside the range for the sigth
            EntfX1 = true;
        }else{
            EntfX1 = false;
        }
        boolean EntfY1 = true;
        if(SYNe <= EntfY && SYPo >= EntfY){ //checks if y distance is inside the range for the sigth
            EntfY1 = true;
        }else{
            EntfY1 = false;
        }
        boolean EntfS = false;
        if(EntfY1 == true && EntfX1 == true){ //checks if y&x distance is inside range of sigth
            EntfS = true;
        }else{
            EntfS = false;
        }
 
        if(wände !=null || !EntfS){ //checks if sight is blcoked
            SichtS = false;
            SchwertX = schwert.X2;
            SchwertY = schwert.Y2;
            CharX = charakter1.X1;
            CharY = charakter1.Y1;
            int myX = (SchwertX + CharX) / 2; //calculates x coordinate
            int myY = (SchwertY + CharY) / 2; //calculates x coordinate
            setLocation(myX, myY);
            turnTowards(CharX, CharY); //turning towards player
            int d = (int)Math.sqrt(Math.pow((SchwertX-CharX),2)+Math.pow((SchwertY-CharY),2)); //calculating the size of the line
            if(d<=0){
                d = 1;
            }
            setImage(new GreenfootImage(d, 1));
 
            ImgS = getImage();
            ImgS.setColor(Color.GREEN);
            ImgS.drawLine(0, 0, d,0);
              
        }else{
            SichtS = true;
            SchwertX = schwert.X2;
            SchwertY = schwert.Y2;
            CharX = charakter1.X1;
            CharY = charakter1.Y1;
            int myX = (SchwertX + CharX) / 2;
            int myY = (SchwertY + CharY) / 2;
            setLocation(myX, myY);
            turnTowards(CharX, CharY);
            int d = (int)Math.sqrt(Math.pow((SchwertX-CharX),2)+Math.pow((SchwertY-CharY),2));
            if(d<=0){
                d = 1;
            }
            setImage(new GreenfootImage(d, 1));
 
            ImgS = getImage();
            ImgS.setColor(Color.RED);
            ImgS.drawLine(0, 0, d,0);
            
        }
    }
 
}
danpost danpost

2015/6/1

#
xWanna wrote...
The problem is that I'll have more than one enemy in my world and the enemies should act separately, so they don't move all if I'm in sight of one of them, only the one who can see me should move.
The problem is your line of sight class (and the class it extends). Your use of 'static' fields is a major issue. I can see now that you wish to actually see these lines of sight within the running of the scenario. That means each actor will have to have its own line of sight object and any and all classes that produce types of objects that could block the line of sight must either be subclasses of an in-between superclass or checked individually to see if the line is not obstructed. The code for the line of sight actor really needs total re-writing. The two actors that the object are to bridge should be given to the object when used. Basically, the class would be something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class LineOfSight extends Actor
{
    public LineOfSight()
    {
        hide();
    }
 
    public boolean isClearBetween(Actor a, Actor b)
    {
        // set location and rotation
        // set image (line length)
        // get number of intersectors minus line of sight objects  (count)
        // set color of line based on value of 'count'
        // return (count == 2)
    }
 
    public void hide()
    {
        // set invisible
    }
}
In a class that uses a line of sight object -- something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private LineOfSight los = new LineOfSight();
 
protected void addedToWorld(World world)
{
    los.hide();
    world.addObject(los, 0, 0);
}
 
public void act()
{
    // ...
    // if player not in range, los.hide(); else
    //     get reference to player in range
    //     if (los.isClearBetween(this, player)), turn towards player
    // ...
}
Super_Hippo Super_Hippo

2015/6/1

#
I am pretty sure that you can remove line 5 of one of the class codes given. You don't have to hide it twice.
danpost danpost

2015/6/1

#
Super_Hippo wrote...
I am pretty sure that you can remove line 5 of one of the class codes given. You don't have to hide it twice.
Right. Totally unnecessary to do it twice
xWanna xWanna

2015/6/2

#
// get number of intersectors minus line of sight objects (count)
How to do it? I think with a list, but can you tell me?
There are more replies on the next page.
1
2