Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
jerky space shooter problem
#1
ok partyppl, i hacked the following code yesterday to give xteraco a simple example of a game. the thing is it's so jerky it looks like an epileptic stroke, i have no idea why. can anybody see what's wrong in there?

Code:
option explicit


''
'' we need some defines that
'' controll some game and gfx relatedvalues
'' that is the width and height of a ship
'' the color of the players ship and the
'' enemy ships, same for the bullets
'' and the speed of the bullets and ships
''
#define SHIP_WIDTH          20
#define SHIP_HEIGHT         10
#define SHIP_SPEED          10

#define PLAYER_SHIP_COLOR   3
#define PLAYER_BULLET_COLOR 3
#define PLAYER_HEALTH       100
#define PLAYER_SHOOT_INTERVAL  600    '' this is the timeinterval between shots of the player in milliseconds

#define ENEMY_SHIP_COLOR    2
#define ENEMY_BULLET_COLOR  7
#define ENEMY_HEALTH        30

#define BULLET_RADIUS       2
#define BULLET_SPEED        30
#define BULLET_DAMAGE       10

#define GAME_TIME_UNIT      50        '' this is the timeunit of the game in milliseconds


''
'' some keycodes for multikey
''
#define SC_ESCAPE &h01
#define SC_SPACE  &h39
#define SC_UP     &h48
#define SC_LEFT   &h4B
#define SC_RIGHT  &h4D
#define SC_DOWN   &h50





''
'' ok first we want to define a user defined type
'' for our ships. this structure will hold the position
'' of the ship, direction vector of the ship,
'' health and color ( i won't go into loading graphics so
'' we simply have wireframe graphics here, that is usage of
'' the almighty line hehe )
''
type Ship

   '' coordinates of the ship
   x as single      
   y as single
  
   '' direction of the ship ( a vector )
   dirx as single
   diry as single

   '' guess...
   health as single

   '' last time bullet was shot ( in milliseconds )
   '' if 3 seconds have past since the last shot
   '' we shot a new bullet and set this to the
   '' current time
   last_shot_time as integer

   '' color
   col as integer
end type


''
'' of course we also need a structure for the
'' bullets the ships shot. they have nearly the
'' same properties as the ships, except that
'' instead of health they got damage
''
type Bullet
   is_used as integer
   x as single
   y as single
   dirx as single
   diry as single
   damage as integer
   col as integer  
end type


'' init module declaration
declare sub InitGame( )

'' gfx module declarations
declare sub DrawShip ( s as Ship )
declare sub DrawBullet ( b as Bullet )

'' artificial intelligence module declarations
declare sub MoveEnemies ( )
declare sub MoveEnemyBullets ( )
declare sub MovePlayerBullets ( )

'' user input module declarations
declare sub ProccessPlayerInput()


''
'' k now that we have the basic structures we
'' define a few arrays that will hold all the
'' enemies and bullets in our game. for now
'' we can only have 10 enemies at once and
'' 500 bullets. so if we have filled up one
'' of the arrays we can't have another bullet
'' or ship added. notice we make them shared
'' so we have access to them in our functions
'' later. also note that we have seperate
'' arrays for bullets the player shot and
'' bullets the enemies shot. you'll see
'' later why it's like that ( we could have
'' done it in another way of course..
''
#define NUM_ENEMIES 10
#define NUM_BULLETS 500
dim shared enemies(NUM_ENEMIES) as Ship
dim shared enemy_bullets(NUM_BULLETS) as Bullet
dim shared player as Ship
dim shared player_bullets(NUM_BULLETS) as Bullet
dim shared globaltime as integer
dim shared lastframetime as double







sub InitGame  ()
   ''
   '' k now we initialize the enemies and bullets
   '' the enemies are placed randomly on the screen
   '' and to the right side of the screen ( that is
   '' x coordinate > 320 ) we'll use a screen res
   '' of 320x200 pixels. the enemies are not allowed
   '' to get out of the screen vertically, that is
   '' their y coordinates are in the range 0 < y < 200
   '' but the enemies can be outside of the screen x
   '' wise. that's why we have y = rnd * 200 and
   '' x = 320 + rnd * 640
   ''
   dim i as integer
   for i = 0 to NUM_ENEMIES
      enemies(i).x = 320 + rnd*640
      enemies(i).y = rnd * 200
      enemies(i).dirx = SHIP_SPEED
      enemies(i).diry = rnd * SHIP_SPEED - rnd * SHIP_SPEED
      enemies(i).health = ENEMY_HEALTH
      enemies(i).col = ENEMY_SHIP_COLOR
   next i

   ''
   '' we also have to init the players ship of course
   ''
   player.x = 0
   player.y = 100
   player.dirx = 0
   player.diry = 0
   player.health = PLAYER_HEALTH
   player.last_shot_time = TIMER
   player.col = PLAYER_SHIP_COLOR

   ''
   '' the bullets are initialized to standard values
   '' for now all bullets have the same damage and
   '' the same direction ( that is they travel from
   '' right to left in a straigt manner ). the
   '' is_used memeber is used to check wheter the
   '' element in the enemy_bullets()/player_bullets()
   '' array is used or not. if it'S not used ( is_user = 0 )
   '' then we can take that element and fill it with
   '' the info for the bullet we or an enemy ship just
   '' shot. note that enemy bullets have color 7
   '' and player bullets have color 4
   ''
   ''
   for i = 0 to NUM_BULLETS
      enemy_bullets(i).is_used = 0
      enemy_bullets(i).dirx = -BULLET_SPEED
      enemy_bullets(i).diry = 0
      enemy_bullets(i).damage = BULLET_DAMAGE
      enemy_bullets(i).col = ENEMY_BULLET_COLOR
   next i

   for i = 0 to NUM_BULLETS
      player_bullets(i).is_used = 0
      player_bullets(i).dirx = -BULLET_SPEED
      player_bullets(i).diry = 0
      player_bullets(i).damage = BULLET_DAMAGE
      player_bullets(i).col = PLAYER_BULLET_COLOR
   next i
end sub



sub DrawShip ( s as Ship )

   ''
   '' here we draw a ship depending on which
   '' direction it looks ( dirx < or > 0?? )
   '' for now this is only an arrow, ow me lazy  

   '' draw the triangle pointing to the left side
   if( s.dirx < 0 ) then
      line( s.x, s.y + SHIP_HEIGHT / 2)-(s.x + SHIP_WIDTH, s.y ), s.col
      line( s.x, s.y + SHIP_HEIGHT / 2)-(s.x + SHIP_WIDTH, s.y + SHIP_HEIGHT ), s.col
      line( s.x + SHIP_WIDTH, s.y )-(s.x + SHIP_WIDTH, s.y + SHIP_HEIGHT), s.col
   elseif( s.dirx >= 0 ) then
      line( s.x + SHIP_WIDTH, s.y + SHIP_HEIGHT / 2)-(s.x, s.y ), s.col
      line( s.x + SHIP_WIDTH, s.y + SHIP_HEIGHT / 2)-(s.x, s.y + SHIP_HEIGHT ), s.col
      line( s.x, s.y )-(s.x, s.y + SHIP_HEIGHT), s.col
   end if

end sub

sub DrawBullet ( b as Bullet )

   circle( b.x, b.y ), BULLET_RADIUS, b.col

end sub


sub ProcessPlayerInput ( )

   dim i as integer

   ''
   '' player wants to move upwards/downwards?
   ''
   if( multikey(SC_UP) )then player.diry = -SHIP_SPEED
   if( multikey(SC_DOWN)) then player.diry = SHIP_SPEED
   if( not multikey(SC_UP) and not multikey(SC_DOWN) ) then player.diry = 0
  
   ''
   '' player wants to shoot? then check when he shot the last time
   '' do nothing if the interval is to small, else spawn a new bullet
   ''
   if( multikey(SC_SPACE) and (TIMER - player.last_shot_time ) * 1000 >= PLAYER_SHOOT_INTERVAL ) then
      for i = 0 to NUM_BULLETS  
         '' we found a free slot, let's use it
         if( player_bullets(i).is_used = 0 ) then  
            player_bullets(i).x = SHIP_WIDTH + BULLET_RADIUS + 2
            player_bullets(i).y = SHIP_HEIGHT / 2 + player.y
            player_bullets(i).dirx = BULLET_SPEED
            player_bullets(i).diry = 0
            player_bullets(i).is_used = -1
            player.last_shot_time = timer
            exit for
            
         end if
      next i      
   end if


   '' and last we move the player
   player.x += (lastFrameTime / GAME_TIME_UNIT ) * player.dirx
   player.y += (lastFrameTime / GAME_TIME_UNIT ) * player.diry


   '' check wheter we are still on screen
   if( player.y < 0 ) then
      player.y = 0
   end if
   if( player.y > 200 - SHIP_WIDTH ) then
      player.y = 200 - SHIP_WIDTH
   end if

end sub


sub MovePlayerBullets( )

   dim i as integer

   ''
   '' here we move the bullets timebased and check wheter they hit an enemy
   ''
   for i = 0 to NUM_BULLETS

      if( player_bullets(i).is_used) then
         '' first move the bullet timebased
         player_bullets(i).x += (lastFrameTime / GAME_TIME_UNIT ) * player_bullets(i).dirx
         player_bullets(i).y += (lastFrameTime / GAME_TIME_UNIT ) * player_bullets(i).diry

         if( player_bullets(i).x > 320 ) then player_bullets(i).is_used = 0
         for i = 0 to NUM_ENEMIES
            if( enemies(i).x <= player_bullets(i).x and enemies(i).y + SHIP_WIDTH >= player_bullets(i).x ) then
               if( enemies(i).y <= player_bullets(i).y and enemies(i).y + SHIP_HEIGHT >= player_bullets(i).y ) then            
                  enemies(i).x = 320 + rnd*640
                  enemies(i).y = rnd * 200
                  enemies(i).dirx = SHIP_SPEED
                  enemies(i).diry = rnd * SHIP_SPEED - rnd * SHIP_SPEED
                  player_bullets(i).is_used = 0
                  exit for
               end if
            end if
         next i
      end if

   next i

end sub


sub MoveEnemies


end sub

dim i as integer
dim framestart as double
dim frameend as double

screen 13,,2
screenset 0, 1

InitGame()

'' we want to make the game timedependant, so no
'' matter what cpu we are on movement is equally fast
lastFrameTime = 0

while( not multikey(SC_ESCAPE))

   cls
  
   framestart = timer
   ProcessPlayerInput()
   MovePlayerBullets()

   '' draw everything
   drawShip player
   for i = 0 to NUM_BULLETS
      if(player_bullets(i).is_used) then
         drawBullet( player_bullets(i) )
      end if
   next i
   frameend = timer

   lastframetime = (frameend - framestart) * 1000

   flip
wend

screen 0
print timer
quote="NecrosIhsan"]
[Image: yagl1.png]
[/quote]
Reply
#2
Try getting rid of the time-based movement stuff. Just use conventional timing to lock the framerate to 30 or 60 fps, like this:
Code:
' Get the timer
the_time = timer


'.....


while (timer=the_time) < 33.3333
I think that's right.
.14159265358979323846264338327950288419716939937510582709445
Glarplesnarkleflibbertygibbertygarbethparkentalelelangathaffendoinkadonkeydingdonkaspamahedron.
Reply
#3
that's exactly the thing i wanted to show so a nono on eating up cpu cycles. any other suggestions? that crap drives me insane. maybe i should go with high precision timers.
quote="NecrosIhsan"]
[Image: yagl1.png]
[/quote]
Reply
#4
wait &h3da, 8 anyone?
Jumping Jahoolipers!
Reply
#5
nm problem solved, besides i don't see a point in waiting for a vertical retrace... :p
quote="NecrosIhsan"]
[Image: yagl1.png]
[/quote]
Reply
#6
it oculd smooth out your movement... (slows down fps to your computers refresh rate)
Jumping Jahoolipers!
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)