03-07-2005, 03:36 PM
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