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

2016/11/17

Bounded moving in tilebased world

katenech katenech

2016/11/17

#
Please, help me with this code:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Hero here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Hero extends Actor
{
        //скорость по оси х
    int speedX=0;
    int speedY=0;
    
        int[][] map = new int[][]{
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1},
{0,0,0,0,0,0,0,0,0,0,0,23,0,0,0,0,0,139,0,0},
{0,0,0,0,0,0,0,0,0,23,23,0,23,0,0,0,139,0,139,0},
{0,0,0,0,0,0,0,0,23,0,23,0,0,0,0,23,0,305,0,0},
{0,0,0,0,0,0,0,0,0,23,0,0,23,0,0,0,0,0,0,0},
{0,0,0,0,0,442,0,23,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,23,0,0,23,0,0,0,0,0,0},
{0,0,0,0,0,0,0,442,0,0,0,0,442,0,0,0,0,27,27,27},
{0,0,0,0,0,0,0,0,0,420,420,282,420,420,420,420,0,27,2,27},
{0,0,0,0,0,0,0,0,0,420,420,420,420,420,420,420,0,27,2,27},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,2,27},
{0,0,0,0,0,0,0,27,27,27,27,27,27,27,27,27,27,27,2,27},
{0,0,0,0,0,0,0,27,2,2,2,2,2,2,2,2,2,2,2,27},
{0,0,0,0,0,0,0,27,2,2,2,2,2,2,2,2,2,2,2,27},
{0,0,0,0,0,0,0,99,2,2,2,2,2,2,2,2,2,2,2,27},
{0,0,0,0,0,0,0,27,27,27,27,27,27,27,27,27,27,27,27,27},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	    };
	    
int i,j;
    
    public void act() 
    {
        keyboardControls();
        
    }    
    
    public void keyboardControls(){
        if(Greenfoot.isKeyDown("left")){
            speedX=-2;
            speedY=0;
            boundMove();
        }
        if(Greenfoot.isKeyDown("right")){
            speedX=2;
            speedY=0;
            boundMove();
        }
        if(Greenfoot.isKeyDown("up")){
            speedY=-2;
            speedX=0;
            boundMove();
        }
        if(Greenfoot.isKeyDown("down")){
            speedY=2;
            speedX=0;
            boundMove();
        }
        
    }
    
        public void boundMove(){
        i=Math.round((getX())/32);
        j=Math.round((getY())/32);
        System.out.println(i+ " "+j+" "+map[j][i]);
        if(map[j][i]==0){
            setLocation(getX()+speedX, getY()+speedY);
        }else
        setLocation(getX()-speedX, getY()-speedY);
        }
    }     

It works, but not correctly)
Super_Hippo Super_Hippo

2016/11/17

#
What happens? What should happen?
katenech katenech

2016/11/18

#
The hero must go trough tiles with number 0. Sometimes the hero is stuck on the map. Sometimes it pass off tiles with other number (not 0).
Super_Hippo Super_Hippo

2016/11/18

#
Right now you are doing this: -adjust speedX/speedY based on key input -check if the hero stands on a valid field right now -move or move in the opposite direction I think you should check if the field where the actor wants to move is valid. If it is, move there and if not, do nothing. What I don't understand so far is that you are using this /32 in lines 71+72, but you are moving 2 cells.
danpost danpost

2016/11/18

#
What is the 'super' line in your World subclass constructor?
katenech katenech

2016/11/19

#
What is the 'super' line in your World subclass constructor?
super(640, 640, 1);
What I don't understand so far is that you are using this /32 in lines 71+72, but you are moving 2 cells.
/32 to calculate rows and columns in matrix (32 pix - width and height of tile). 2 cells= 2 pix - step of hero, may be different.
danpost danpost

2016/11/19

#
Is your player supposed to move completely from one zero location to another before changing directions? or, can it move freely as long as all near locations are zero? With the first way you can check the location coordinates to see if actually AT a zero location or not (getX()%32 == 16 && getY()%32 == 16). If either is not true then movement along that direction is possible else check next location in direction of movement. With the other way, again if either is not zero, then allow movement along that direction. But, if either (not both) condition is true then check location in direction of moement before moving that way.
katenech katenech

2016/11/19

#
I've tried to check possibility of moving
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

public class Hero extends Actor
{
        //скорость по оси х
    int speedX=0;
    int speedY=0;
    
        int[][] map = new int[][]{
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1},
{0,0,0,0,0,0,0,0,0,0,0,23,0,0,0,0,0,139,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,23,0,0,0,139,0,139,0},
{0,0,0,0,0,0,0,0,23,0,23,0,0,0,0,23,0,305,0,0},
{0,0,0,0,0,0,0,0,0,23,0,0,23,0,0,0,0,0,0,0},
{0,0,0,0,0,442,0,23,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,23,0,0,23,0,0,0,0,0,0},
{0,0,0,0,0,0,0,442,0,0,0,0,442,0,0,0,0,27,27,27},
{0,0,0,0,0,0,0,0,0,420,420,282,420,420,420,420,0,27,2,27},
{0,0,0,0,0,0,0,0,0,420,420,420,420,420,420,420,0,27,2,27},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,2,27},
{0,0,0,0,0,0,0,27,27,27,27,27,27,27,27,27,27,27,2,27},
{0,0,0,0,0,0,0,27,2,2,2,2,2,2,2,2,2,2,2,27},
{0,0,0,0,0,0,0,27,2,2,2,2,2,2,2,2,2,2,2,27},
{0,0,0,0,0,0,0,99,2,2,2,2,2,2,2,2,2,2,2,27},
{0,0,0,0,0,0,0,27,27,27,27,27,27,27,27,27,27,27,27,27},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        };
        
int i,j;

int hW=this.getImage().getWidth();
int hH=this.getImage().getHeight();
    
    public void act() 
    {
        keyboardControls();
        
    }    
    
    public void keyboardControls(){
        if(Greenfoot.isKeyDown("left")){
            speedY=0;
            speedX=-2;
            if (detectForbiddenTile(getX(), getY()) && detectForbiddenTile(getX(), getY()+hH)) {
                    setLocation(getX()+speedX, getY()+speedY);
                }else
            setLocation(getX(), getY());
        }
        if(Greenfoot.isKeyDown("right")){
            speedY=0;
            speedX=2;
            if (detectForbiddenTile(getX()+hW/2, getY()) && detectForbiddenTile(getX()+hW/2, getY()+hH)) {
                    setLocation(getX()+speedX, getY()+speedY);
                }else
            setLocation(getX(), getY());
        }
        if(Greenfoot.isKeyDown("up")){
            speedY=-2;
            speedX=0;
            if (detectForbiddenTile(getX(), getY()) && detectForbiddenTile(getX()+hW, getY())) {
                    setLocation(getX()+speedX, getY()+speedY);
                }else
            setLocation(getX(), getY());
        }
        if(Greenfoot.isKeyDown("down")){
            speedY=2;
            speedX=0;
            if (detectForbiddenTile(getX(), getY()+hH/2) && detectForbiddenTile(getX()+hW, getY()+hH/2)) {
                    setLocation(getX()+speedX, getY()+speedY);
                }else
            setLocation(getX(), getY());
        }
        
    }
    
        public boolean detectForbiddenTile(int x_MyHero, int y_MyHero) {
        
        j = Math.round(x_MyHero / 32);
        i = Math.round(y_MyHero / 32);
        System.out.println(i+ " "+j+" "+map[i][j]);
        switch (map[i][j]) {
        case 0: // grass
            return true;
        case 27:// wall
            return false;
        case 442:// tree
            return false;
        case 23:// 
            return false;
        }
        return true;
    }
    }     

It's not work correctly.. My hero stuck in some places..
danpost danpost

2016/11/19

#
Well, I was thinking more like this (code shown for horizontal movement only (right and left keys):
int dx = 0;
if (Greenfoot.isKeyDown("right")) dx++;
if (Greenfoot.isKeyDown("left")) dx--;
if (dx != 0 && (getX()%32 != 16 || map[getY()/32][getX()/32+dx] == 0))
{
    setLocation(getX()+dx*2, getY());
}
A similar code can be used for vertical movement (up and down keys). Your edges will need to be checked for also.
katenech katenech

2016/11/20

#
For my shame.. I don't understand the sense of code getX()%32 != 16 Why 16?
danpost danpost

2016/11/20

#
A tile is 32 pix wide and high. The center point would be at (16, 16) in each tile.
katenech katenech

2016/11/24

#
Thank you for code and explanation. Now I'm doing scrolling world with big tilemap.
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)


public class Hero extends Actor
{
  
        int[][] map = new int[][]{
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

	    };
	    
int i,j;

    
    public void act() 
    {
        //keyboardControls();
        //scrollingMove();
        keyboard();
    }    
    
      //сдвиг карты при подходе персонажа к краю экрана
    public void scrollMove(int dx, int dy){
        MyWorld w=(MyWorld)getWorld();
        
        //если подошли к левому краю экрана
        if((getX()+dx)<=50){
            //то остановились
            setLocation(50, getY());
            //... а мир сдвинули направо
            w.toScrollWorld(-dx,0);
        }else
        //если подошли к правому краю экрана
        if(((getX()+dx)>=w.getWidth()-50)){
            //то остановились
            setLocation(w.getWidth()-50, getY());
            //... а мир сдвинули налево
            w.toScrollWorld(-dx,0);
        }else 
        ////иначе просто переместились по экрану 
        setLocation(getX()+dx, getY());
          
                //если подошли к верхнему краю экрана
        if((getY()+dy)<=50){
            //то остановились
            setLocation(getX(), 50);
            //... а мир сдвинули вниз
            w.toScrollWorld(0,-dy);
        }else
        //если подошли к нижнему краю экрана
        if(((getY()+dy)>=w.getHeight()-50)){
            //то остановились
            setLocation(getX(), w.getHeight()-50);
            //... а мир сдвинули вверх
            w.toScrollWorld(0,-dy);
        }else 
        ////иначе просто переместились по экрану
        setLocation(getX(), getY()+dy);
    }  
            
    public void keyboard(){        
        MyWorld w=(MyWorld)getWorld();
                int dx = 0;
if (Greenfoot.isKeyDown("right"))dx++;
if (Greenfoot.isKeyDown("left")) dx--;
if (dx != 0 && (map[getY()/32][getX()/32+dx] == 0))
{
    setLocation(getX()+dx, getY());
    System.out.println(getX());
    if(getX()<=50 || getX()>=(w.getWidth()-50)) scrollMove(dx,0);
}

                int dy = 0;
if (Greenfoot.isKeyDown("down")) dy++;
if (Greenfoot.isKeyDown("up")) dy--;
if (dy != 0 && (map[getY()/32+dy][getX()/32] == 0))
{
    setLocation(getX(), getY()+dy);
    if(getY()<=50 || getY()>=(w.getHeight()-50)) scrollMove(0,dy);
}
    }
}
The problem is scroll World despite condition (map == 0) or (map == 0)
You need to login to post a reply.