Animation question

Advice on general approaches or feasibility and discussions about game design

Animation question

Postby nicosilverx » Sun Feb 08, 2015 11:34 am

Hi, I have started to develop a "Tank" clone from NES, but I'm having some troubles...
I wrote a function for the shooting but when it's time to play the game doesn't render the bullet but a line, why?
(sorry for my english :lol: )
Code: Select all
#include <SPI.h>
#include <Gamebuino.h>
Gamebuino gb;

//game vars
int x=LCDWIDTH/2; //start position
int y=LCDHEIGHT/2;
int vx=1; //velocity
int vy=1;
int size=8; //size of the bitmap
byte rotation=NOROT; //start rotation
byte flip=NOFLIP;
static unsigned char PROGMEM tank[] = {
8,8,
B00010000,
B11010110,
B01111100,
B11010110,
B01010100,
B11000110,
B01111100,
B11111110,
}; //tank bitmap

void setup()
{
  gb.begin();
  gb.titleScreen(F("Tankduino"));
 
}

void loop()
{
  if(gb.update()){
   
    //move the ball using the buttons
    if(gb.buttons.repeat(BTN_RIGHT,2)){
      x = x + vx;
      rotation = ROTCW;
    }
    if(gb.buttons.repeat(BTN_LEFT,2)){
      x = x - vx;
      rotation = ROTCCW;
    }
    if(gb.buttons.repeat(BTN_DOWN,2)){
      y = y + vy;
      rotation = ROT180;
    }
    if(gb.buttons.repeat(BTN_UP,2)){
      y = y - vy;
      rotation = NOROT;
     
    }
   
    if(gb.buttons.pressed(BTN_A)){
      shoot(x,y,rotation);
    }
    if(gb.buttons.pressed(BTN_C)){
      gb.titleScreen(F("GameDuino"));
    }
    //frame
    if(x<0){
      x=0;
    }
    if((x+size)>LCDWIDTH){
      x=LCDWIDTH-size;
    }
    if(y<0){
      y=0;
    }
    if((y+size)>LCDHEIGHT){
      y=LCDHEIGHT-size;
    }
   
 //draw the tank and the frame
  gb.display.drawBitmap(x, y,tank,rotation,flip);
  gb.display.drawLine(0, 0, LCDWIDTH, 0);
  gb.display.drawLine(0, 0, 0, LCDHEIGHT);
  gb.display.drawLine(0, LCDHEIGHT-1, LCDWIDTH, LCDHEIGHT-1);
  gb.display.drawLine(LCDWIDTH-1, 0, LCDWIDTH-1, LCDHEIGHT);
}}
 
void shoot(int x, int y, int rot){
  int i=0;
  switch(rot){
   
    case NOROT:
      while(i<  LCDHEIGHT){
       
          gb.display.drawPixel(x+3,y-i);
          i++;
         
      }
    break;
   
    case ROTCW:
      while(i<LCDWIDTH){
          gb.display.drawPixel(x+i,y+3);
          i++;
      }
    break;
   
    case ROT180:
      while(i<LCDHEIGHT){
          gb.display.drawPixel(x+4,y+i);
          i++;
      }
    break;
   
    case ROTCCW:
    while(i<LCDWIDTH){
        gb.display.drawPixel(x-i,y+4);
        i++;
    }
    break;
 
 
  }
 

}
nicosilverx
 
Posts: 2
Joined: Sun Feb 08, 2015 11:29 am

Re: Animation question

Postby catsfolly » Sun Feb 08, 2015 3:38 pm

In the "shoot" command you are using while statements. I think these should be if statements.

For example:
Code: Select all
  while(i<LCDWIDTH){
          gb.display.drawPixel(x+i,y+3);
          i++;
      }


Should be

Code: Select all
  if(i<LCDWIDTH){
          gb.display.drawPixel(x+i,y+3);
          i++;
      }


The while statement will cause the drawpixel command to be repeated until the condition is true - in this case when the pixel reaches the edge of the screen. Using an if statement will cause the pixel to be drawn only if it hasn't reached the edge of the screen.

Does this make sense?
catsfolly
 
Posts: 5
Joined: Sun Feb 08, 2015 3:31 pm

Re: Animation question

Postby nicosilverx » Sun Feb 08, 2015 5:10 pm

But I want draw the bullet moving, not only the final destination
nicosilverx
 
Posts: 2
Joined: Sun Feb 08, 2015 11:29 am

Re: Animation question

Postby catsfolly » Mon Feb 09, 2015 6:42 am

The structure of main section of a Gamebuino program is a big loop:

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

// game code goes here.
}}


The "game code" part gets executed over and over (about 20 time a second).
So if we want something in the game to move, we move it a little bit each time the game code gets executed.

So I would suggest that the "shoot()" code should just CREATE the bullet, and another routine, for example "update_bullet()" should move the bullet a little bit each time the game code is executed.

Here is one way this could be done:

1. add this code to the game variables:

Code: Select all
// add to game vars
int bulletx;  // bullet x pos
int bullety;  // bullet y pos
byte bulletrot = ; // bullet dir
int bullet_active = 0; // non zero if bullet is moving


2. Then, in the loop part, add a call to update_bullet():

Code: Select all
 if(gb.buttons.pressed(BTN_A)){
          shoot(x,y,rotation);
        }
  update_bullet();  <--- add this line


3. Finally change the shoot routine and add an update_bullet routine:

Code: Select all
void shoot(int x, int y, int rot){
   bulletrot = rot;
   bullet_active = 1;
 switch(rot){
       
        case NOROT:
           bulletx = x+3;
      bullety = y;
             break;
       
        case ROTCW:
      bulletx = x;
      bullety = y+3;
                break;
       
        case ROT180:
           bulletx = x+4;
      bullety = y;
                  break;
       
        case ROTCCW:
                 bulletx = x;
      bullety = y+4;       
            break;
     
     
      }   
}

update_bullet(void) {
   if(bullet_active) {
   switch(bulletrot){
       
        case NOROT:
          if(bullety> 0){
              bullety -= 1;             
          }
     else bullet_active = 0;
        break;
       
        case ROTCW:
          if (bulletx<LCDWIDTH){
        bulletx += 1;
          }
          else bullet_active = 0;
        break;
       
        case ROT180:
          if(bullety < LCDHEIGHT){
      bullety += 1;
          }
          else bullet_active = 0;   
        break;
       
        case ROTCCW:
          if (bulletx> 0){
            bulletx -= 1;
          }
          else bullet_active = 0;         
       break;
      }
      if (bullet_active) gb.display.drawPixel(bulletx,bullety);
   }

}
catsfolly
 
Posts: 5
Joined: Sun Feb 08, 2015 3:31 pm


Return to Project Guidance & Game development

Who is online

Users browsing this forum: No registered users and 24 guests

cron