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

2024/3/5

collision

HakimNait HakimNait

2024/3/5

#
I would like to create collisions in my games all in a super class: wall for any image that I enter there have collisions, but I don't know how to do it because I'm a beginner. can someone help?
danpost danpost

2024/3/6

#
HakimNait wrote...
I would like to create collisions in my games all in a super class: wall for any image that I enter there have collisions, but I don't know how to do it because I'm a beginner. can someone help?
Just keep a basic wall class, meaning no to little behavior and the basics as far as state is concerned (that is, only thing the subclasses of wall should do is set the appropriate image. In classes that can "hit" walls, use:
if (isTouching(wall.class))
HakimNait HakimNait

2024/3/6

#
How can I ensure that my character does not pass through walls? Here I used a hitWall method, but sometimes it's buggy and it passes through. public void act() { mover(); } public void mover() { animationTimer = animationTimer +1; if(Greenfoot.isKeyDown("d")) { setLocation(getX()+2,getY()); if(animationTimer % 8 == 0) animateRight(); if (hitWalls() == true) { setLocation(getX() - 3,getY()); } } if(Greenfoot.isKeyDown("a")) { setLocation(getX()-2,getY()); if(animationTimer % 8 == 0) animateLeft(); if (hitWalls() == true) { setLocation(getX() + 3,getY()); } } if(Greenfoot.isKeyDown("w")) { setLocation(getX(),getY()-2); if(animationTimer % 8 == 0) animateUp(); if (hitWalls() == true) { setLocation(getX(),getY() + 3); } } if(Greenfoot.isKeyDown("s")) { setLocation(getX(), getY()+2); if(animationTimer % 8 == 0) animateDown(); if (hitWalls() == true) { setLocation(getX(),getY() - 3); } } if(Greenfoot.isKeyDown("d") &&Greenfoot.isKeyDown("s")) { setLocation(getX(),getY()); if(animationTimer % 8 == 0) animateDownRight(); if (hitWalls() == true) { setLocation(getX() - 3,getY() - 3); } } if(Greenfoot.isKeyDown("a") &&Greenfoot.isKeyDown("s")) { setLocation(getX(),getY()); if(animationTimer % 8 == 0) animateDownLeft(); if (hitWalls() == true) { setLocation(getX() + 3,getY() - 3); } } if(Greenfoot.isKeyDown("a") &&Greenfoot.isKeyDown("w")) { setLocation(getX(),getY()); if(animationTimer % 8 == 0) animateUpLeft(); if (hitWalls() == true) { setLocation(getX() + 3,getY() + 3); } } if(Greenfoot.isKeyDown("d") &&Greenfoot.isKeyDown("w")) { setLocation(getX(),getY()); if(animationTimer % 8 == 0) animateUpRight(); if (hitWalls() == true) { setLocation(getX() - 3,getY() + 3); } } } public boolean hitWalls() { if (isTouching(Walls.class)) { return true; } else { return false; } }
danpost danpost

2024/3/9

#
HakimNait wrote...
How can I ensure that my character does not pass through walls? Here I used a hitWall method, but sometimes it's buggy and it passes through. << Code Omitted >>
The hitWall method is not the problem (although, it may be considered something not having at all). There are multiple possible reasons for the unwanted behavior you are getting from your character. The coding of the animating of the character, as well as the possible non-uniformity of the sizes of the images may also produce unwanted behavior (unprovided stuff) As far as what was given, the coding has many issues. It is haphazard, with an unnatural flow. It also has an abundance of repetition. The key checking is "loose", in that you are only checking for down keys. You really do not know which direction is being directed by the keys until all the keys are checked. I have found the best start at collecting key down information is by using the following:
int dx = 0, dy = 0; // to hold key down information for both horizontal and vertical directions
if (Greenfoot.isKeyDown("d")) dx++; // right (d) key down
if (Greenfoot.isKeyDown("a")) dx--; // left (a) key down
if (Greenfoot.isKeyDown("s")) dy++; // down (s) key down
if (Greenfoot.isKeyDown("w")) dy--; // up (w) key down
If either variable has a non-zero value, then a moving direction has been detected. A zero value can arise by neither key along its direction being down or both keys along its direction are down (cancelling each other out). Okay, now the values of the two variables are each either -1, 0, or 1, but you are allowing diagonal movement from your character as well as standard 4-way movement. There are 9 possible combination of values of the two variables, one where both are zero and no movement is to be taken, and the other 8 representing the 8 possible directions the character can go. The next line should therefore be:
if (dx == 0 && dy == 0) return;
Now, the character is ready to move -- or maybe not. Maybe the animation should run first, so the proper image is used during collision checking.
animate(dx, dy);
with animate method code of:
private void animate(int dx, int dy) {
    animationTimer = (1+animationTimer)%8;
    if (animationTimer%8 != 0) return;
    int dir = 0;
    if (dx == 0) dir = (2-dy)*2;
    else if (dy == 0) dir = (1-dx)*2;
    else dir = (2-dy)*2-dx*dy;
    switch (dir) {
        case 0:  animateRight(); break;
        case 1:  animateDownRight(); break;
        case 2:  animateDown(); break;
        case 3:  animateDownLeft(); break;
        case 4:  animateLeft(); break;
        case 5:  animateUpLeft(); break;
        case 6:  animateUp(); break;
        case 7:  animateUpRight(); break;
    }
}
Lines 4 thru 7 converts the two variable values into a single directional value where 45*dir is the true input direction. Now it moves.
setLocation(getX()+dx*3, getY()+dy*3);
and collision check:
if (isTouching(Walls.class)) setLocation(getX()-dx*3, getY()-dy*3);
If you are still running into issues with going through walls, try making the animation images all the same size.
HakimNait HakimNait

2024/3/10

#
thank you very much it works
You need to login to post a reply.