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

2021/5/31

Player pushing Block Pushing Block

1
2
Total-Eclipse Total-Eclipse

2021/5/31

#
So in my Scenario I have a class called Block.class and a Player named Pengu.class. Now what I want to do is: when a Pengu is pushing a Block that is in contact with a Block, both Blocks get pushed and not overlayed. The code of pushing the Block should be in the Block.class if possible. Code of Block.class
import greenfoot.*;  // (World, Actor, GreenfootImage, and Greenfoot)


public class Block extends Mover
{
    /**
     * Act - tut, was auch immer Block tun will. Diese Methode wird aufgerufen, 
     * sobald der 'Act' oder 'Run' Button in der Umgebung angeklickt werden. 
     */
    public void act() 
    {
        checkFall();
        moveBlock();
    }
    public void checkFall()
    {
        if (onGround()) {
            setVSpeed(0);
        }
        else {
            setLocation ( getX(), getY() + vSpeed);
            vSpeed = vSpeed + acceleration;
        }
    }
    public boolean onGround()
    {
        Cloud under1 = (Cloud) getOneObjectAtOffset(0, getImage().getHeight()/2-6 , Cloud.class);
        Cliff under2 = (Cliff) getOneObjectAtOffset(0, getImage().getHeight()/2-6 , Cliff.class);
        Block under3 = (Block) getOneObjectAtOffset(0, getImage().getHeight()/2-6 , Block.class);
        Platform under4 = (Platform) getOneObjectAtOffset(0, getImage().getHeight()/2 , Platform.class);
        return (under1 != null)||(under2 != null)||(under3 != null)||(under4 != null);
    }
    public void moveBlock()
    {
        if(isTouching(Pengu.class)) {
            if (Greenfoot.isKeyDown("Shift") == false)
            {
                if (Greenfoot.isKeyDown("A") )
                    {
                        setLocation ( getX() - Mover.speed, getY());
                    }
                if (Greenfoot.isKeyDown("D") )
                    {
                        setLocation ( getX() + Mover.speed, getY());
                    }
            }
            if(isTouching(Block.class)) {
                if (Greenfoot.isKeyDown("Shift") == false)
                {
                    if (Greenfoot.isKeyDown("A") )
                    {   
                        setLocation ( getX() - Mover.speed, getY());
                    }
                    if (Greenfoot.isKeyDown("D") )
                    {
                        setLocation ( getX() + Mover.speed, getY());
                    }
                }   
            }
        }
        
    }
}
Total-Eclipse Total-Eclipse

2021/5/31

#
This might have been unclear: The Pengu moves Left when touching A Key and ticht when touching D Key. Shift is used to pass trough Blocks.
danpost danpost

2021/5/31

#
The initiation of a push starts with pengu. The behavior of the block is that it can be pushed. Program Pengu to push block and program behavior (via a method) of block to be pushed (and push other blocks). It would look something like this:
// in Pengu action code with dx being distance to move
Actor block = getOneObjectAtOffset(dx+getImage().getWidth()*Math.signum(dx)/2, 0, Block.class);
if (block == null || ((Block)block).isPushed(dx))) setLocation(getX()+dx, getY());

// in Block
public boolean isPushed(int dx)
{
    Actor block = getOneObjectAtOffset(dx+getImage().getWidth()*Math.signum(dx)/2, 0, Block.class);
    if (block == null || ((Block)block).isPushed(dx))
    {
        setLocation(getX()+dx, getY());
        return true;
    }
    return false;
}
This is only to show how the code can be set up. It does not include taking into account world boundaries or other type obstacles.
Total-Eclipse Total-Eclipse

2021/6/1

#
So when I tried putting this in the code I got following (incompatible types: possible lossy conversion from float to int) The Code is now like this... Pengu:
public static final int dx = 10;
    public void act() 
    {
        Actor block = getOneObjectAtOffset(dx + getImage().getWidth()*Math.signum(dx)/2, 0, Block.class);
        if (block == null || ((Block)block).isPushed(dx)) setLocation(getX()+dx, getY());
        
        checkKeys();    //For Moving of Pengu.class      
        checkFall();    //For Moving of Pengu.class
   }
Block:
public void moveBlock()
    {
        if(isTouching(Pengu.class)) {
            if (Greenfoot.isKeyDown("Shift") == false)
            {
                if (Greenfoot.isKeyDown("A") )
                    {
                        setLocation ( getX() - Mover.speed, getY());
                    }
                if (Greenfoot.isKeyDown("D") )
                    {
                        setLocation ( getX() + Mover.speed, getY());
                    }
            }
            if(isTouching(Block.class)) {
                if (Greenfoot.isKeyDown("Shift") == false)
                {
                    if (Greenfoot.isKeyDown("A") )
                    {   
                        setLocation ( getX() - Mover.speed, getY());
                    }
                    if (Greenfoot.isKeyDown("D") )
                    {
                        setLocation ( getX() + Mover.speed, getY());
                    }
                }
            }
        }
    }
 public boolean isPushed(int dx)
    {
        Actor block = getOneObjectAtOffset(dx + getImage().getWidth()*Math.signum(dx)/2, 0, Block.class);
        if (block == null || ((Block)block).isPushed(dx))
        {
            setLocation(getX()+dx, getY());
            return true;
        }
        return false;
    }
danpost danpost

2021/6/2

#
In Pengu, line 1 above, dx should not be final. In fact, it should be a variable that is local to the act method (or the checkKeys method). In Block, remove the moveBlock method. Add a line in isPushed to check the "shift" key.
Total-Eclipse Total-Eclipse

2021/6/2

#
Stil the same error in the term: + getImage().getWidth()*Math.signum(dx)/2 New Pengu code:
import greenfoot.*;  // (World, Actor, GreenfootImage, and Greenfoot)

/**
 * A little penguin that wants to get to the other side.
 */
public class Pengu extends Mover
{
    private static final int jumpStrength = 24;
    public void act() 
    {
        int dx = 10;
        Actor block = getOneObjectAtOffset(dx + getImage().getWidth()*Math.signum(dx)/2, 0, Block.class);
        if (block == null || ((Block)block).isPushed(dx)) setLocation(getX()+dx, getY());
        
        checkKeys();    //For Moving of Pengu.class      
        checkFall();    //For Moving of Pengu.class  
    }
New Block Code:
 public boolean isPushed(int dx)
    {
        Actor block = getOneObjectAtOffset(dx + getImage().getWidth()*Math.signum(dx)/2, 0, Block.class);
        if (block == null || ((Block)block).isPushed(dx))
        {
            setLocation(getX()+dx, getY());
            return true;
        }
        return false;
    }
danpost danpost

2021/6/2

#
Please show checkKeys method in Pengu class.
Total-Eclipse Total-Eclipse

2021/6/3

#
Code of checkKeys:
public void checkKeys()
    {
        if (Greenfoot.isKeyDown("A") )
        {
            setImage("pengu-left.png");
            moveLeft();
        }
        if (Greenfoot.isKeyDown("D") )
        {
            setImage("pengu-right.png");
            moveRight();
        }
        if (Greenfoot.isKeyDown("space") )
        {
            if (onGround())
                jump();
        }
        if (Greenfoot.isKeyDown("Z") )
        {
            if (Level1.class.isInstance(getWorld()))
             {
                Greenfoot.setWorld( new Level1());
             }
        }
    } 
A, D and Space are used to move. Z is used to reload the level.
danpost danpost

2021/6/3

#
Alright -- sorry. I think I know what it is now. Try this: +getImage().getWidth()*(int)Math.signum(dx)/2
Total-Eclipse Total-Eclipse

2021/6/3

#
Ok this fixed this error. The blocks no longer stack. The Pengu was moving right constatly. I fixed this by removing(in Pengu.class): (setLocation(getX() +dx, getY()); ^This So now it is: (setLocation(getX(), getY()); However now you can only push the block to the right and not to the left. How can I fix this? Code of Pengu:
private static final int jumpStrength = 24;
    public void act() 
    {
        int dx = 10;
        Actor block = getOneObjectAtOffset(dx + getImage().getWidth()*(int)Math.signum(dx)/2, 0, Block.class);
        if (block == null || ((Block)block).isPushed(dx)) setLocation(getX(), getY());
        
        checkKeys();    //For Moving of Pengu.class      
        checkFall();    //For Moving of Pengu.class  
    }
Code of Block:
public boolean isPushed(int dx)
    {
        Actor block = getOneObjectAtOffset(dx + getImage().getWidth()*(int)Math.signum(dx)/2, 0, Block.class);
        
        if (block == null || ((Block)block).isPushed(dx))
        {
            setLocation(getX()+dx, getY());
            return true;
        }
        return false;
    }  
Total-Eclipse Total-Eclipse

2021/6/3

#
I made some changes to push it to the right. Here is the new Code: Pengu:
private static final int jumpStrength = 24;
    public void act() 
    {
        int dx = 10;
        Actor block = getOneObjectAtOffset(dx + getImage().getWidth()*(int)Math.signum(dx)/2, 0, Block.class);
        Actor block2 = getOneObjectAtOffset(-(dx + getImage().getWidth()*(int)Math.signum(dx)/2), 0, Block.class);
        if ((block == null || ((Block)block).isPushed(dx)) && Greenfoot.isKeyDown("D")) setLocation(getX(), getY());
        if ((block2 == null || ((Block)block2).isPushed(dx)) && Greenfoot.isKeyDown("A")) setLocation(getX(), getY());
        
        checkKeys();    //For Moving of Pengu.class      
        checkFall();    //For Moving of Pengu.class  
    }
Block:
public boolean isPushed(int dx)
    {
        Actor block = getOneObjectAtOffset(dx + getImage().getWidth()*(int)Math.signum(dx)/2, 0, Block.class);
        Actor block2 = getOneObjectAtOffset(-(dx +getImage().getWidth()*(int)Math.signum(dx)/2) , 0, Block.class);
        if ((block == null || ((Block)block).isPushed(dx)) && Greenfoot.isKeyDown("D"))
        {
            setLocation(getX() + dx, getY());
            return true;
        }
        if ((block2 == null || ((Block)block2).isPushed(dx)) && Greenfoot.isKeyDown("A"))
        {
            setLocation(getX() - dx, getY());
            return true;
        }
        return false;
    }
However now my game gives a ton of error codes when I try to push 2 Blocks at once.
Total-Eclipse Total-Eclipse

2021/6/3

#
These Error Codes come up when I stop pushing the Blocks into one direction: java.lang.StackOverflowError at java.base/java.util.LinkedList.add(LinkedList.java:342) at greenfoot.collision.ibsp.IBSPColChecker.getOneIntersectingDown(IBSPColChecker.java:655) at greenfoot.collision.ibsp.IBSPColChecker.getOneObjectAt(IBSPColChecker.java:835) at greenfoot.collision.ColManager.getOneObjectAt(ColManager.java:193) at greenfoot.World.getOneObjectAt(World.java:800) at greenfoot.Actor.getOneObjectAtOffset(Actor.java:918) at Block.isPushed(Block.java:37) Actor block = getOneObjectAtOffset(dx + getImage().getWidth()*(int)Math.signum(dx)/2, 0, Block.class); at Block.isPushed(Block.java:39) if ((block == null || ((Block)block).isPushed(dx)) && Greenfoot.isKeyDown("D")) at Block.isPushed(Block.java:44) if ((block2 == null || ((Block)block2).isPushed(dx)) && Greenfoot.isKeyDown("A")) Notes on the right of the error log are inserted by me.
Total-Eclipse Total-Eclipse

2021/6/3

#
When I try pushing a Block into a Block from the right(so I am pushing the Block to the left) these Error appear too, however it sends these error messages instantly and not only when I change direction or stop pushing.
Super_Hippo Super_Hippo

2021/6/3

#
As far as I understand it, dx should be set based on the key you press. So for example like this:
int dx = 0;
if (Greenfoot.isKeyDown("A") dx -= 10;
if (Greenfoot.isKeyDown("D") dx += 10;
I don’t see a reason to push a block before checking for keys and moving.
danpost danpost

2021/6/4

#
Yes, Hippo's code to replace line 4 above (int dx = 10;). Only execute lines 5 thru 8 if dx is not zero. Remove "A"/"D" movement code from checkKeys method. Set image immediately after setLocation(getX()+dx, getY()); line.
There are more replies on the next page.
1
2