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

2019/3/25

Having some problems with my jumping code

CarolK CarolK

2019/3/25

#
Ok so, I'm trying right now to make a general code for jumping, because my game will have many heroes. I'm having some problems here, and I don't quite understand why. Whenever the "up" is triggered, the Actor won't jump and I don't know if it's because of this part of code or smth else. I'm new to Greenfoot, so any advice would be highly appreciated ^_^.
private int velocity=0;
    
    public void jump(int jumpStrength)
    {
        velocity++;
        setLocation(getX(), getY()+velocity);
        if(velocity>jumpStrength)
        {
            velocity=-jumpStrength;
        }
    }
    
    public void movement(int x, int y, int speed, int jumpStrength)
    {
        if(Greenfoot.isKeyDown("up") && !atTopEdge(getY()) && onGround())
        {
            velocity=0;
            jump(jumpStrength);
        }
        if(Greenfoot.isKeyDown("left") && !atLeftEdge(x))
        {
            setLocation(x-speed,y);
        }
        if(Greenfoot.isKeyDown("right") && !atRightEdge(x))
        {
            setLocation(x+speed,y);
        }
    }
And also, here's the onGround() :
 public boolean onGround()
    {
        //x(ground & floating rocks) 482 370 310 235 106
        switch(getX()+getImage().getHeight()/2+5)
        {
            case 482: return true;
            case 370: return true;
            case 310: return true;
            case 235: return true;
            case 106: return true;
            default: return false;
        }
    }
The "Ground" is divided in some rocks floating and I didn't find any other way to see if it's on the ground itself or on the rocks. I'm thinking that I should separate every rock but will it be truly useful? What can I do to make it simpler? Thanks in advance!! :D Edit: It'll be a pixel game, that's why I'm using very precise numbers
danpost danpost

2019/3/25

#
One of the main problems is with your onGround method code. As it is, there are only 5 x-locations where a jump can be initiated (at one of the 5 case values minus 5 minus half the image width). At any other location, which there are world width minus 5 of, no jumping would be possible. Another issue is in the use of your velocity value. You zero it before calling jump, where it is then incremented to one, then you compare its value to jumpStrengh. The result of the comparison will always be the same (that is, unless you call jump from somewhere else). The logic in the jump code does not seem sound, however. Any vertical movement would require the "up" key be pressed. Once the key is released, the actor would seem to end up floating at whatever height it was at. Maybe my Jump and Run Demo w/Moving Platform scenario can give you some pointers.
CarolK CarolK

2019/3/29

#
First of all, I want to thank you for the example, it was a HUUGE help :D I nailed the jumping part and it looks fine to me, but I'm facing another problem now. I want my Hero to be able to jump on different platform-like rocks of different hights, which isn't a problem anymore, but how can I make it STAND on it? For some reasons, the Hero won't stay every time on the rock and sometimes will get in it, which is weird. Also, I have this 'special' rock... If the Hero jumps on it multiple times, then it will fall through it(and I don't want this to happen!!), which is even weirder. I think at least one of these problems might be related to the horizontal movement... I tried to take your example(the while) on moveHorizontically method and apply it to my code, but it only made my Hero go back to the place it stood before trying to jump on the rock... which is worse. And I can't find a solution to that. Like, do I need to check the coordinates at every rock-jump and apply that while only when the Hero hits the rock on the edges? It seems logic, but it would take some space and I think there might be better and easier solutions. There are the movement methods for the Hero:
 public int gravity=2;
    public int vSpeed=0;
    public int hSpeed=0;
    
    public void movementV(int jumpStrength)
    {
        boolean onGround=false;
        int actorHeight=getImage().getHeight();
        vSpeed+=gravity;
        setLocation(getX(),getY()+vSpeed);
        if(getY()>482-actorHeight/2) //my ground level
        {
            setLocation(getX(),482-actorHeight/2);
            onGround=true;
            vSpeed=0;
        }
        int dy=(int)Math.signum(vSpeed);//dir
        //cheking if a hero is standing on a rock and NOT IN IT WDGDHSJVX
        //huh
        //doesn't help
        Actor rock = getOneIntersectingObject(Rock1.class);
        boolean onRock= getObjectsInRange(2,Rock1.class).size()>0; //many different rocks
        
        if(onRock && rock.getY()-rock.getImage().getHeight()/2 <= getY()+actorHeight/2-1)
        {
            setLocation(getX(),getY()-2*dy);
        }
        
        if(getOneIntersectingObject(null)!=null)
        {
            setLocation(getX(),getY()-2*dy);
            if(dy>0) onGround=true; //ON GROUND not rock!!!
            vSpeed=0;
        }
        if((onGround || onRock) && Greenfoot.isKeyDown("up")) 
            vSpeed=-jumpStrength; //depending on the hero
    }
    
    public void movementH(int speed)
    {
        int actorWidth=getImage().getWidth();
        int dx=0;
        if(Greenfoot.isKeyDown("left") && !atLeftEdge(getX()))
            dx--;
        if(Greenfoot.isKeyDown("right") && !atRightEdge(getX()))
            dx++;
        setLocation(getX()+dx*speed,getY());
    }
and also, the rock itself:
// SIZE : width = 110 ; height = 24
    
    
    public void act() 
    {
        setLocation(getX(), getY() - 1);
        Actor Heroes = getOneIntersectingObject(Heroes.class);
        setLocation(getX(), getY() + 1);
        if(Heroes!=null && Heroes.getY()+Heroes.getImage().getHeight()/2 <= getY()-getImage().getHeight()/2)
        {
            Heroes.setLocation(Heroes.getX(), Heroes.getY() - Heroes.getImage().getHeight()/2);
        }
        if(Heroes!=null && Heroes.getY()+Heroes.getImage().getHeight()/2 >= getY() +getImage().getHeight()/2)
        {
            Heroes.setLocation(Heroes.getX(), Heroes.getY() + Heroes.getImage().getHeight()/2-2);
        }
    } 
Your Jump and Run Demo really helped a lot. I'm sorry if I took way too many elements & ideas from it, but I thought it was sooo well done and it was the only example that made me realize what was wrong with my code and what I'm supposed to do for this kind of game. ^_^
danpost danpost

2019/3/30

#
CarolK wrote...
Your Jump and Run Demo really helped a lot. I'm sorry if I took way too many elements & ideas from it, but I thought it was sooo well done and it was the only example that made me realize what was wrong with my code and what I'm supposed to do for this kind of game. ^_^
Not a problem.
I want my Hero to be able to jump on different platform-like rocks of different hights, which isn't a problem anymore, but how can I make it STAND on it? For some reasons, the Hero won't stay every time on the rock and sometimes will get in it
My use of the onGround boolean field was really just, in a general sense, a standing indicator, only to determine if jumping was allowable or not. You seem to have a lot going on between lines 22 and 34. What was insufficient with the code I used in my demo (for your case)?
Also, I have this 'special' rock... If the Hero jumps on it multiple times, then it will fall through it(and I don't want this to happen!!), ... I think at least one of these problems might be related to the horizontal movement... I tried to take your example(the while) on moveHorizontically method and apply it to my code, but it only made my Hero go back to the place it stood before trying to jump on the rock... which is worse. And I can't find a solution to that. Like, do I need to check the coordinates at every rock-jump and apply that while only when the Hero hits the rock on the edges? It seems logic, but it would take some space and I think there might be better and easier solutions.
It appears you have no collision detection (yet) for horizontal movement.
CarolK CarolK

2019/4/6

#
danpost wrote...
My use of the onGround boolean field was really just, in a general sense, a standing indicator, only to determine if jumping was allowable or not. You seem to have a lot going on between lines 22 and 34. What was insufficient with the code I used in my demo (for your case)?
I have a total of 4 rocks(platforms) in my game and I want the jumps triggered on them to be different than the one triggered on the ground. Every rock is on a different level, with different coordinates. Also, I'm using actors for them. I don't understand why the Hero will fall through the rock/get in it and move normally(horizontally). Like, I was expecting many kinds of bugs and logical errors but this just doesn't make any sense. Let's say, I'm jumping straight in the middle of a rock and land normally. Okay, everything works fine, but when I get to jump on another one, it just melts in it or falls through it. Another thing that I noticed was that if my Hero would jump so high that it would touch the top of the World and then fall, it would fall through everything and hit the ground. How can I repair that?
It appears you have no collision detection (yet) for horizontal movement.
How can I do that? I'm using actors for rocks and I can't use any method related to actors because the Hero has to stand on it after a jump and would be moved back to the edge of the rock instantly. What can I do?
danpost danpost

2019/4/6

#
CarolK wrote...
when I get to jump on another one, it just melts in it or falls through it. Another thing that I noticed was that if my Hero would jump so high that it would touch the top of the World and then fall, it would fall through everything and hit the ground. How can I repair that?
Well, there are some things with your code that do not make sense. Line 22 in the Hero code above uses such a small range, for one. However, I am not exactly sure why you assign a value to onRock in that way. Better might be:
boolean onRock = rock != null && vSpeed > 0;
-- although, you will probably have a better place to do that later in your code. Another issue are how lines 26 and 31 perform. They, upon collision, move the actor upward regardless of the initial movement direction along the vertical. Also, the moving is based on the location of the hero, not on the object collided with. Both these are problems.
danpost wrote...
It appears you have no collision detection (yet) for horizontal movement.
How can I do that? I'm using actors for rocks and I can't use any method related to actors because the Hero has to stand on it after a jump and would be moved back to the edge of the rock instantly. What can I do?
If the hero is moved vertically, and re-positioned to not touch and actor if needed, then any horizontal movement that causes a collision will not be because the hero is standing on it.
You need to login to post a reply.