Just one block following collision

Understanding the language, error messages, etc.

Just one block following collision

Postby elGuillemola » Fri Jul 31, 2015 6:01 pm

Hello :lol: ,
I have been having troubles creating several blocks with the same "Physics" :?: . The idea is to make the player able to push the boxes and that they follow the same "gravity, friction and collision" that the one the player have.

With one block works but whenever I try to create more, these blocks are just drawn in the display and don't move.

This is how it looks in the emulator:
Photo = http://postimg.org/image/tsz837p83/
PS= The blocks in the left side don't follow the gravity

This is the main code:
Code: Select all
#include <EEPROM.h>
#include <avr/pgmspace.h>
#include <SPI.h>
#include <Gamebuino.h>
Gamebuino gb;

byte i;

typedef struct {
  byte w;
  byte x;
  byte h;
  byte y;
} Box;

typedef struct {
  byte w;
  float x;
  float vx;
  byte h;
  float y;
  float vy;
} Block;

typedef struct {
  byte w;
  float x;
  float xv;
  byte h;
  float y;
  float yv;
} MovingBox;

const byte BK[] PROGMEM = {8,8,
B00111100,
B01111110,
B11011011,
B11111111,
B11111111,
B11111111,
B11111111,
B11000011,
};

const byte JumpingBoxCrouching[] PROGMEM = {8,4,
B00111100,
B01111110,
B11011011,
B11111111,
};

const byte JumpingBoxMovingLeft[] PROGMEM = {8,8,
B00011110,
B00111111,
B01101111,
B01111111,
B00011111,
B01111111,
B01111111,
B11010110,
};

const byte JumpingBoxMovingLeft2[] PROGMEM = {8,8,
B00011110,
B00111111,
B01101111,
B01111111,
B01111111,
B01111111,
B01111111,
B01101011,
};

const byte JumpingBoxMovingRight[] PROGMEM = {8,8,
B01111000,
B11111100,
B11110110,
B11111110,
B11111000,
B11111110,
B11111110,
B01101011,
};

const byte JumpingBoxMovingRight2[] PROGMEM = {8,8,
B01111000,
B11111100,
B11110110,
B11111110,
B11111110,
B11111110,
B11111110,
B11010110,
};

const byte Block1[] PROGMEM = {8,8,
B11111111,
B10000001,
B10111101,
B10110101,
B10101101,
B10111101,
B10000001,
B11111111,
};

const byte Obstacle[] PROGMEM = {88,4,
B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11110000,
B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00010000,
B11010101,B01010101,B01010101,B01010101,B01010101,B01010101,B01010101,B01010101,B01010101,B01010101,B01010000,
B01111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11100000,
};

const byte Column[] PROGMEM = {8,24,
B11111111,
B11111111,
B01111110,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B11111111,
};



void setup()
{
  gb.begin();
  initGame();
}

void loop(){
  if(gb.update()){

    if(gb.buttons.pressed(BTN_C))
    {
      initGame();
    }

    if(gb.buttons.pressed(BTN_UP))
    {
     initObstacles();
     initPlayer();
     InitBlock ();
    }
   
    updatePlayer();
    updateObstacles();
    updateBlock ();
   
    drawObstacles();
    drawPlayer();
    drawBlock();

  }
}

void initGame()
{
  gb.titleScreen(F("      THE PITCH "));
  gb.battery.show = false;
  gb.pickRandomSeed();
 
  initObstacles();
  initPlayer();
  InitBlock ();
}



This is the block code:
Code: Select all

#define NumberBlocks 3
Block movingblock [NumberBlocks];

void InitBlock ()
{
  movingblock[0].h = 8;
  movingblock[0].w = 8;
  movingblock[0].x = LCDWIDTH/2-4;
  movingblock[0].y = 35;
 
  movingblock[1].h = 8;
  movingblock[1].w = 8;
  movingblock[1].x = LCDWIDTH/2-4;
  movingblock[1].y = 10;

  movingblock[2].h = 8;
  movingblock[2].w = 8;
  movingblock[2].x = LCDWIDTH/10;
  movingblock[2].y = 10;
}

void updateBlock()
{
  movingblock[i].vx *= 0.5;
  movingblock[i].x += movingblock[i].vx;

  if(movingblockCollision())
  {
    movingblock[i].x -= movingblock[i].vx;
    movingblock[i].vx *= -0.5;
  }
 
  movingblock[i].vy += 0.8;
  movingblock[i].vy *= 0.8;
  movingblock[i].y += movingblock[i].vy;

  if(movingblockCollision())
  {
    movingblock[i].y -= movingblock[i].vy;
    movingblock[i].vy *= -0.5;
  }
}

void drawBlock ()
{
  //DRAW BOXES
  for (byte i = 0; i < NumberBlocks; i++)
  {
    gb.display.drawBitmap(movingblock[i].x, movingblock[i].y, Block1);
  }
}


This is the "wall" code:
Code: Select all
#define NUM_OBSTACLES 7
#define NumberFloor 4
#define NumberColumns 6
#define NumberPlatform 7

Box obstacles[NUM_OBSTACLES];

void initObstacles(){

  //SET OBSTACLES
  obstacles[0].w = LCDWIDTH;
  obstacles[0].h = 0;
  obstacles[0].x = 0;
  obstacles[0].y = 0;

  obstacles[1].w = 0;
  obstacles[1].h = LCDHEIGHT;
  obstacles[1].x = 0;
  obstacles[1].y = 0;

  obstacles[2].w = 0;
  obstacles[2].h = LCDHEIGHT;
  obstacles[2].x = LCDWIDTH;
  obstacles[2].y = 0;

  obstacles[3].w = 84;
  obstacles[3].h = 4;
  obstacles[3].x = 0;
  obstacles[3].y = 44;

  obstacles[4].w = 8;
  obstacles[4].h = 24;
  obstacles[4].x = LCDWIDTH/4-4;
  obstacles[4].y = 16;

  obstacles[5].w = 8;
  obstacles[5].h = 24;
  obstacles[5].x = LCDWIDTH-LCDWIDTH/4-4;
  obstacles[5].y = 16;

  obstacles[6].w = 8;
  obstacles[6].h = 2;
  obstacles[6].x = LCDWIDTH/2-4;
  obstacles[6].y = LCDHEIGHT/2;
}

void updateObstacles()
{
 
}

void drawObstacles(){
  //DRAW OBSTACLES
  for(byte f=0; f<NumberFloor; f++){
    gb.display.drawBitmap(obstacles[f].x, obstacles[f].y, Obstacle, obstacles[f].w, obstacles[f].h);
  }
  for(byte f=4; f<NumberColumns; f++){
    gb.display.drawBitmap(obstacles[f].x, obstacles[f].y, Column, obstacles[f].w, obstacles[f].h);
  }
  for(byte f=6; f<NumberPlatform; f++){
    gb.display.fillRect(obstacles[f].x, obstacles[f].y, obstacles[f].w, obstacles[f].h);
  }
}


This is the player code:
Code: Select all
MovingBox player;


void initPlayer(){
  player.w = 8;
  player.h = 8;
  player.x = 5;
  player.y = 30;
}

void updatePlayer(){
  //CROUCHING
  if(gb.buttons.pressed(BTN_DOWN)){
    player.h = 4;
    player.y += 4;
    gb.sound.playTick();
  }
  if(gb.buttons.timeHeld(BTN_DOWN))
  {
    gb.display.drawBitmap(player.x, player.y, JumpingBoxCrouching);
  }

  //STAND UP AFTER CROUCHING
  if(! gb.buttons.timeHeld(BTN_DOWN)){
    if(player.h ==4){
      player.h = 8;
      player.y -= 4;
      if(playerCollision()){
        player.h = 4;
        player.y += 4;
      }
    }
  }

  //PLAYER BASIC SETUP AND OBSTACLES
  player.xv *= 0.5;
  if(gb.buttons.repeat(BTN_RIGHT,1))
  {
    player.xv += 0.85;
  }
  if(gb.buttons.repeat(BTN_RIGHT,1) && !gb.buttons.timeHeld (BTN_DOWN)){
    gb.display.drawBitmap (player.x, player.y, JumpingBoxMovingRight);
  }
  if(gb.buttons.repeat(BTN_LEFT,1)
  ){
    player.xv -= 0.85;
  }
  if(gb.buttons.repeat(BTN_LEFT,1) && !gb.buttons.timeHeld (BTN_DOWN)){
    gb.display.drawBitmap (player.x, player.y, JumpingBoxMovingLeft);
  }
 
  player.x += player.xv;

  if(playerCollision()){
    player.x -= player.xv;
    player.xv *= -0.5;
  }
 
  player.yv += 0.8;
  player.yv *= 0.8;
 
  if(gb.buttons.timeHeld(BTN_A) > 0 & gb.buttons.timeHeld(BTN_A) < 2 )
  {
    player.yv -= 6;
    gb.sound.playOK();
  }

  player.y += player.yv;

  if(playerCollision()){
    player.y -= player.yv;
    player.yv *= -0.5;
  }

  //PLAYER AND BOX
  if (movingblockmoving()){
    player.x -= player.xv;
    player.xv *= -0.5;
  if (gb.buttons.timeHeld (BTN_B))
   {
    if(gb.buttons.repeat(BTN_RIGHT,1))
    {
     movingblock[i].vx += 1.25;
     player.xv += 1;
    }
    if(gb.buttons.repeat(BTN_LEFT,1))
    {
     movingblock[i].vx -= 1.25;
     player.xv -= 1;
    }
   }
  }
 
  if(movingblockmoving())
  {
    player.y -= player.yv;
    player.yv *= -0.5;
  }


  if(! gb.buttons.timeHeld(BTN_DOWN) && ! gb.buttons.timeHeld(BTN_LEFT) && ! gb.buttons.timeHeld(BTN_RIGHT))
   { 
    gb.display.drawBitmap(player.x, player.y, BK);
   }
}

void drawPlayer()
{
}

boolean playerCollision(){
  //PLAYER AND OBSTACLES
  for(byte f=0; f<NUM_OBSTACLES; f++)
  {
    if(gb.collideRectRect((int)player.x, (int)player.y, player.w, player.h, obstacles[f].x, obstacles[f].y, obstacles[f].w, obstacles[f].h)){
      return true;
    }
  }
  return false;
}


boolean movingblockCollision(){
  for(byte f=0; f<NUM_OBSTACLES; f++)
  {
    if(gb.collideRectRect((int)movingblock[i].x, (int)movingblock[i].y, movingblock[i].w, movingblock[i].h, obstacles[f].x, obstacles[f].y, obstacles[f].w, obstacles[f].h)){
      return true;
    }
  }
  return false;
}

boolean movingblockmoving()
{
  //PLAYER MOVING BOX
    for (byte i=0; i<NumberBlocks; i = i++)
  {
    if(gb.collideRectRect((int)movingblock[i].x, (int)movingblock[i].y, movingblock[i].w, movingblock[i].h, (int)player.x, (int)player.y, player.w, player.h))
    {
      return true;
    }
     return false;
}
}


Thanks in advance.
elGuillemola
 
Posts: 3
Joined: Fri Jul 31, 2015 5:42 pm

Re: Just one block following collision

Postby Sorunome » Sun Aug 02, 2015 10:46 pm

I see the following issue:
inside of your loop you do a normal call to updateBlock(); without any loop or so, and in your function updateBlock() you use i as if you would iter through all the blocks but you don't. You might want to look into that.
User avatar
Sorunome
 
Posts: 629
Joined: Sun Mar 01, 2015 1:58 pm

Re: Just one block following collision

Postby elGuillemola » Fri Aug 14, 2015 6:13 pm

Hello again,
After fixing the problems commented above, I still having some issues. Blocks follow gravity laws and collide with the walls and columns... But they do not interact with the player. Just the block "number 0" is able to be pushed while the other aren't. I believe I know the issue: in the boolean loop called "movingblockmoving" the collision is detected but it doesn't send back what "number i" block are we having contact. Therefore, is there a way that the "number i" pushed block can be returned from that loop and "send" to the movingblock[r].vx in the 61 line and 65 line in the 4th tabbed code?

I tried adding "return i" in that loop but it didn't work and honestly I don't know (let's say) where it sent it.

Here is the code:
Main code:
Code: Select all
#include <EEPROM.h>
#include <avr/pgmspace.h>
#include <SPI.h>
#include <Gamebuino.h>
Gamebuino gb;

byte r;

typedef struct {
  byte w;
  byte x;
  byte h;
  byte y;
} Box;

typedef struct {
  byte w;
  float x;
  float vx;
  byte h;
  float y;
  float vy;
} Block;

typedef struct {
  byte w;
  float x;
  float xv;
  byte h;
  float y;
  float yv;
} MovingBox;

const byte BK[] PROGMEM = {8,8,
B00111100,
B01111110,
B11011011,
B11111111,
B11111111,
B11111111,
B11111111,
B11000011,
};

const byte JumpingBoxCrouching[] PROGMEM = {8,4,
B00111100,
B01111110,
B11011011,
B11111111,
};

const byte JumpingBoxMovingLeft[] PROGMEM = {8,8,
B00011110,
B00111111,
B01101111,
B01111111,
B00011111,
B01111111,
B01111111,
B11010110,
};

const byte JumpingBoxMovingLeft2[] PROGMEM = {8,8,
B00011110,
B00111111,
B01101111,
B01111111,
B01111111,
B01111111,
B01111111,
B01101011,
};

const byte JumpingBoxMovingRight[] PROGMEM = {8,8,
B01111000,
B11111100,
B11110110,
B11111110,
B11111000,
B11111110,
B11111110,
B01101011,
};

const byte JumpingBoxMovingRight2[] PROGMEM = {8,8,
B01111000,
B11111100,
B11110110,
B11111110,
B11111110,
B11111110,
B11111110,
B11010110,
};

const byte Block1[] PROGMEM = {8,8,
B11111111,
B10000001,
B10111101,
B10110101,
B10101101,
B10111101,
B10000001,
B11111111,
};

const byte Obstacle[] PROGMEM = {88,4,
B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11110000,
B11000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00010000,
B11010101,B01010101,B01010101,B01010101,B01010101,B01010101,B01010101,B01010101,B01010101,B01010101,B01010000,
B01111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11100000,
};

const byte Column[] PROGMEM = {8,24,
B11111111,
B11111111,
B01111110,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B01000010,
B11111111,
};



void setup()
{
  gb.begin();
  initGame();
}

void loop(){
  if(gb.update()){

    if(gb.buttons.pressed(BTN_C))
    {
      initGame();
    }

    if(gb.buttons.pressed(BTN_UP))
    {
     initObstacles();
     initPlayer();
     InitBlock ();
    }
   
    updatePlayer();
    updateObstacles();
    updateBlock ();
   
    drawObstacles();
    drawPlayer();
    drawBlock();

  }
}

void initGame()
{
  gb.titleScreen(F("      THE PITCH "));
  gb.battery.show = false;
  gb.pickRandomSeed();
 
  initObstacles();
  initPlayer();
  InitBlock ();
}


Block code:
Code: Select all
#define NumberBlocks 3
Block movingblock [NumberBlocks];

void InitBlock ()
{
  movingblock[0].h = 8;
  movingblock[0].w = 8;
  movingblock[0].x = LCDWIDTH/2-4;
  movingblock[0].y = 35;
 
  movingblock[1].h = 8;
  movingblock[1].w = 8;
  movingblock[1].x = LCDWIDTH/2-4;
  movingblock[1].y = 10;

  movingblock[2].h = 8;
  movingblock[2].w = 8;
  movingblock[2].x = LCDWIDTH/10;
  movingblock[2].y = 10;
}

void updateBlock()
{
  for (byte i = 0; i<NumberBlocks; i++)
  {
  movingblock[i].vx *= 0.5;
  movingblock[i].x += movingblock[i].vx;

  if(movingblockCollision())
  {
    movingblock[i].x -= movingblock[i].vx;
    movingblock[i].vx *= -0.5;
  }
 
  movingblock[i].vy += 0.8;
  movingblock[i].vy *= 0.8;
  movingblock[i].y += movingblock[i].vy;

  if(movingblockCollision())
  {
    movingblock[i].y -= movingblock[i].vy;
    movingblock[i].vy *= -0.5;
  }
}
}

void drawBlock ()
{
  //DRAW BOXES
  for (byte i = 0; i < NumberBlocks; i++)
  {
    gb.display.drawBitmap(movingblock[i].x, movingblock[i].y, Block1);
  }
}


Obtacles code:
Code: Select all
#define NUM_OBSTACLES 7
#define NumberFloor 4
#define NumberColumns 6
#define NumberPlatform 7

Box obstacles[NUM_OBSTACLES];

void initObstacles(){

  //SET OBSTACLES
  obstacles[0].w = LCDWIDTH;
  obstacles[0].h = 0;
  obstacles[0].x = 0;
  obstacles[0].y = 0;

  obstacles[1].w = 0;
  obstacles[1].h = LCDHEIGHT;
  obstacles[1].x = 0;
  obstacles[1].y = 0;

  obstacles[2].w = 0;
  obstacles[2].h = LCDHEIGHT;
  obstacles[2].x = LCDWIDTH;
  obstacles[2].y = 0;

  obstacles[3].w = 84;
  obstacles[3].h = 4;
  obstacles[3].x = 0;
  obstacles[3].y = 44;

  obstacles[4].w = 8;
  obstacles[4].h = 24;
  obstacles[4].x = LCDWIDTH/4-4;
  obstacles[4].y = 16;

  obstacles[5].w = 8;
  obstacles[5].h = 24;
  obstacles[5].x = LCDWIDTH-LCDWIDTH/4-4;
  obstacles[5].y = 16;

  obstacles[6].w = 8;
  obstacles[6].h = 2;
  obstacles[6].x = LCDWIDTH/2-4;
  obstacles[6].y = LCDHEIGHT/2;
}

void updateObstacles()
{
 
}

void drawObstacles(){
  //DRAW OBSTACLES
  for(byte f=0; f<NumberFloor; f++){
    gb.display.drawBitmap(obstacles[f].x, obstacles[f].y, Obstacle, obstacles[f].w, obstacles[f].h);
  }
  for(byte f=4; f<NumberColumns; f++){
    gb.display.drawBitmap(obstacles[f].x, obstacles[f].y, Column, obstacles[f].w, obstacles[f].h);
  }
  for(byte f=6; f<NumberPlatform; f++){
    gb.display.fillRect(obstacles[f].x, obstacles[f].y, obstacles[f].w, obstacles[f].h);
  }
}


Player code (here I have the problems):
Code: Select all
MovingBox player;


void initPlayer(){
  player.w = 8;
  player.h = 8;
  player.x = 5;
  player.y = 30;
}

void updatePlayer(){
  //CROUCHING
  if(gb.buttons.pressed(BTN_DOWN)){
    player.h = 4;
    player.y += 4;
    gb.sound.playTick();
  }

  //STAND UP AFTER CROUCHING
  if(! gb.buttons.timeHeld(BTN_DOWN)){
    if(player.h ==4){
      player.h = 8;
      player.y -= 4;
      if(playerCollision()){
        player.h = 4;
        player.y -= 4;
        gb.sound.playTick();
      }
    }
  }

  //PLAYER BASIC SETUP AND OBSTACLES
  player.xv *= 0.01;
  if(gb.buttons.repeat(BTN_RIGHT,1))
  {
    player.xv += 1.4;
  }
  if(gb.buttons.repeat(BTN_LEFT,1)
  ){
    player.xv -= 1.4;
  }
 
  player.x += player.xv;

  if(playerCollision())
  {
    player.x -= player.xv;
    player.xv *= -0.5;
  }
 
  if(movingblockmoving() && !gb.buttons.timeHeld (BTN_B))
  {
    player.x -= player.xv;
    player.xv *= -0.5;
  }

  if(movingblockmoving() && gb.buttons.timeHeld (BTN_B))
  {
    if (gb.buttons.repeat (BTN_RIGHT,1))
    {
      movingblock[r].vx += 3;
    }
    if (gb.buttons.repeat (BTN_LEFT,1))
    {
      movingblock[r].vx -= 3;
    }
   
    player.x -= player.xv;
    player.xv *= -0.5;
  }
 
  player.yv += 0.8;
  player.yv *= 0.8;
 
  if(gb.buttons.timeHeld(BTN_A) > 0 && gb.buttons.timeHeld(BTN_A) < 2)
  {
    player.yv -= 6;
    gb.sound.playOK();
  }

  player.y += player.yv;

  if(playerCollision())
  {
    player.y -= player.yv;
    player.yv *= -0.5;
  }

  if(movingblockmoving() && !gb.buttons.timeHeld (BTN_B) || movingblockmoving() && gb.buttons.timeHeld (BTN_B))
  {
    player.y -= player.yv;
    player.yv *= -0.5;
  }
}

void drawPlayer()
{
  if(player.h == 4)
  {
    gb.display.drawBitmap(player.x, player.y, JumpingBoxCrouching);
  }
 
  if(! gb.buttons.timeHeld(BTN_DOWN) && ! gb.buttons.timeHeld(BTN_LEFT) && ! gb.buttons.timeHeld(BTN_RIGHT))
  { 
   gb.display.drawBitmap(player.x, player.y, BK);
  }

  if(gb.buttons.repeat(BTN_RIGHT,1) && !gb.buttons.timeHeld (BTN_DOWN))
  {
    gb.display.drawBitmap (player.x, player.y, JumpingBoxMovingRight);
  }

  if(gb.buttons.repeat(BTN_LEFT,1) && !gb.buttons.timeHeld (BTN_DOWN))
  {
    gb.display.drawBitmap (player.x, player.y, JumpingBoxMovingLeft);
  }
}

boolean playerCollision(){
  //PLAYER AND OBSTACLES
  for(byte f=0; f<NUM_OBSTACLES; f++)
  {
    if(gb.collideRectRect((int)player.x, (int)player.y, player.w, player.h, obstacles[f].x, obstacles[f].y, obstacles[f].w, obstacles[f].h)){
      return true;
    }
  }
  return false;
}

boolean movingblockCollision(){
  for (byte i=0; i<NumberBlocks; i++)
  {
  for(byte f=0; f<NUM_OBSTACLES; f++)
  {
    if(gb.collideRectRect((int)movingblock[i].x, (int)movingblock[i].y, movingblock[i].w, movingblock[i].h, obstacles[f].x, obstacles[f].y, obstacles[f].w, obstacles[f].h)){
      return true;
    }
  }
  }
  return false;
}

boolean movingblockmoving()
{
  //PLAYER MOVING BOX
    for (byte i=0; i<NumberBlocks; i = i++)
  {
    if(gb.collideRectRect((int)movingblock[i].x, (int)movingblock[i].y, movingblock[i].w, movingblock[i].h, (int)player.x, (int)player.y, player.w, player.h))
    {
      return true;
    }
     return false;
}
}


By the way, how can I make my character have an animation... I mean, for instance, make the character rise and step the foot in the floor as a sucesion of bytes. Is there an example somewhere?
And make move the camera around the player?

Thanks in advance!
Last edited by elGuillemola on Thu Aug 20, 2015 4:27 pm, edited 1 time in total.
elGuillemola
 
Posts: 3
Joined: Fri Jul 31, 2015 5:42 pm

Re: Just one block following collision

Postby Sorunome » Fri Aug 14, 2015 6:48 pm

you could make it return int8_t and instead of return false you do return -1 and instead of return true you do return f (or whatever the iterator is), and then you check if it is !=-1 and still have the number of the block
User avatar
Sorunome
 
Posts: 629
Joined: Sun Mar 01, 2015 1:58 pm

Re: Just one block following collision

Postby elGuillemola » Thu Aug 20, 2015 4:21 pm

That doesn't work. The character remains stuck as it was colliding with a box and if you try to push it will move although the character and the block aren't close.
elGuillemola
 
Posts: 3
Joined: Fri Jul 31, 2015 5:42 pm


Return to Programming Questions

Who is online

Users browsing this forum: No registered users and 59 guests