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

2016/12/3

Wolfenstein 3D like image drawing

Tritos Tritos

2016/12/3

#
Hey I`m currently working on a "3D" game created with Greenfoot. It is based on the techniques Wolfenstein 3D used to create a 3D effect. That means that I basically use a top-down perspective. In every acting-cycle I look how far the wall in front of me is away from me. Then I calculate the height of the Wall and draw a rectangle with this height on my screen. This is the code I use for that (and it works)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public void drawSightF()
    {
        GreenfootImage drawerImg = getWorld().getObjects(Drawer.class).get(0).getImage();
        drawerImg.clear();
        int distance = 0;
        int xSave = getX();
        int ySave = getY();
 
        while(!isTouching(Wall.class))
        {
            distance = distance + 15;
            move(10);
        }
 
        int h1 = (int)(900.0*((1400.0-distance)/(1400.0)));
        drawerImg.fillRect(690, 450 - (h1/2), 10, h1);
        setLocation(xSave, ySave);
    }
Drawer.class is basically a canvas. The method is started in the act method. However I obviously also want to draw the walls that aren`t directly in front of me. I tried to use this code for doing that.
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
public void drawSight()
    {
        GreenfootImage drawerImg = getWorld().getObjects(Drawer.class).get(0).getImage();
        drawerImg.clear();
        int distance = 0;
        int xSave = getX();
        int ySave = getY();
 
        for(int n = 0; n <= 90; n = n + 10)
        {
            turn((int)(n));
            while(!isTouching(Wall.class))
            {
                distance = distance + 15;
                move(10);
            }
 
            int h1 = (int)(900.0*((1400.0-distance)/(1400.0)));
            drawerImg.fillRect(690 + n, 450 - (h1/2), 1, h1);
 
            distance = 0;
 
            setRotation(getRotation()-(n*2));
 
            while(!isTouching(Wall.class))
            {
                distance = distance + 15;
                move(10);
            }
 
            h1 = (int)(900.0*((1400.0-distance)/(1400.0)));
            drawerImg.fillRect(690 - n, 450 - (h1/2), 1, h1);
 
            distance = 0;
 
            setRotation(getRotation()+n);
        }
        setLocation(xSave, ySave);
    }
However now he always thinks he already is in a wall and the while-loop is never entered and therefore direction stays 0 and the rectangle get drawn at full height. I do not understand why the player thinks he is in a wall. Thanks for the help Tritos
Tritos Tritos

2016/12/3

#
Also I just found another problem: I can only walk in rotations devidable by 45(so up, down, left, right, between up and left....) I cant figure oput why tho this is my walking method(one of them)
1
2
3
4
5
6
7
8
9
10
11
12
public void moveFor()
    {
        for (int i=0; i<speed; i++)
        {
            move(1);
            if (isTouching(Wall.class))
            {
                move(-1);
                return;
            }
        
    }
and this is my turning method
1
2
3
4
public void turnLeft()
    {
        turn(-turnSpeed);
    }
turnSpeed is set to 1
danpost danpost

2016/12/3

#
Tritos wrote...
Also I just found another problem: I can only walk in rotations devidable by 45(so up, down, left, right, between up and left....) I cant figure oput why tho
When moving one pixel at a time, there are only eight neighboring pixels that can be landed on, each at some angle divisible by 45. Think of the actor in the middle of a tic-tac-toe grid, each grid-square being a pixel location your actor can be at. You should be able that see that you cannot move between pixel locations. There are several ways to correct the movement. One is using a class for smooth moving, like my QActor class, which can be downloaded from here or the SmoothMover class, which can simply be imported via the menubar ('Edit>Import class...'). Your class would extend the smooth moving class and implement its methods for moving. If your speed value is constant and large enough, you could avoid the extra class by something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void moveFor()
{
    int x = getX();
    int y = getY();
    for (int i=0; i<speed; i++)
    {
        setLocation(x, y);
        move(i+1);
        if (isTouching(Wall.class))
        {
            setLocation(x, y);
            move(i);
            return;
        }
    }
}
Tritos Tritos

2016/12/3

#
Thank you very much that works very well. Could you maybe also take a look at my other problem?
danpost danpost

2016/12/3

#
Tritos wrote...
Thank you very much that works very well. Could you maybe also take a look at my other problem?
I glanced it over, but nothing was immediately apparent. I currently do not have the time to get into it too deeply. Sorry.
Tritos Tritos

2016/12/3

#
Ok, thats fine. Thanks for your help anyway ;)
danpost danpost

2016/12/3

#
Tritos wrote...
Ok, thats fine. Thanks for your help anyway ;)
Around line 20 or 22, I think you might want to reset the actor back to its original location (xSave, ySave). This is just a guess and I could be totally off here.
You need to login to post a reply.