Personally I never delete sprite (or other media) during the game loop. I load everything the game or current level needs then just make sprites active and inactive, visible and invisible as required. From what I understand and have experience, loading media can cause slow down.
I wrote a simple side scrolling shooter that you might find helpful. It's not a tutorial but it might give you some pointers.
remstart
ROCKET BIKE WITH A MASSIVE LASER GUN
a 2D side scrolling shooter
By 29 Games (22 December 2016)
aim of game:
fly your rocket bike (the little green box) and shoot as many of the alien scum (the red squares) as possible
using your massive laser gun (the big green box)
controls and game play (there are no on screen instructions so pay attention):
Gamepad / joystick (uses virtual joystick commands):
joystick = move up and down
button 1 = speed boost
button 2 = quit
Keyboard (uses raw keyboard input):
up and down arrow keys = move up and down
spacebar = speed boost
esc = quit
Touchscreen (there are no on screen buttons):
touch / drag up and down anywhere on the left of the screen = move up and down
(the rocket bike follows where your finger/thumb is vertically on the screen)
touch and hold anywhere on the right of the screen = speed boost
back button = quit
the input method will be automatically detected
the rocket bike will only move up and down relative to the screen but not horizontally
the speed boost simply increases the scrolling speed of the map and enemies
shooting is automatic when enemies appear on the screen
the game will restart automatically if you are hit by an enemy (you have no lives)
the hud shows your current score, your previous score and your high score (this is not saved when you quit the game)
remend
gosub _general
gosub _create_map
gosub _create_player
gosub _create_bullets
gosub _create_enemies
gosub _create_messages
`main loop
do
gosub _staring_variables
game_over = 0
repeat
gosub _player_controls_and_movement
gosub _scroll_map
gosub _player_collision_with_map
gosub _player_shooting
gosub _enemy_action
gosub _bullet_action
gosub _update_hud
sync()
until game_over > 0
gosub _update_scores
loop
end
_staring_variables:
`game
score = 0
`bike (the player)
bike_xpos# = screen_width/4
bike_ypos# = screen_height/2
bike_xvel# = 0.0
bike_yvel# = 0.0
bike_xacc# = 0.0
bike_yacc# = 0.0
`gun (also the player)
gun_xpos# = bike_xpos# + bike_width
`bullets
for i = 1 to num_bullets
bullet[i].life = 0
bullet[i].xpos# = 0
bullet[i].ypos# = 0
bullet[i].xvel# = gun_width*0.75
next
`enemies (simple red blocks that the player has to shoot or avoid)
for i = 1 to num_enemies
enemy[i].life = _f_enemy_life_and_size(enemy[i].spr,enemy_max_life)
enemy[i].xpos# = _f_enemy_x_position(enemy[i].spr,screen_width)
enemy[i].ypos# = _f_enemy_y_position(enemy[i].spr,screen_height,block_height)
enemy[i].xvel# = _f_enemy_x_velocity(score)
enemy[i].yvel# = _f_enemy_y_velocity()
next i
return
_player_shooting:
`determine if any enemy is on screen and in front of the massive laser gun
enemy_on_screen = 0
for i = 1 to num_enemies
if enemy[i].life > 0
if enemy[i].xpos# < screen_width and enemy[i].xpos# > bike_xpos#
enemy_on_screen = 1
endif
endif
next i
`player shooting
dec delay
if delay < 0
delay = 0
endif
`determine if bullet is fired
`based on the gun's delay (i.e. rate of fire) and if there are any enemies on screen
if delay <= 0
if enemy_on_screen = 1
bullet_found = 0
for i = 1 to num_bullets
if bullet_found = 0
delay = gun_delay
if bullet[i].life = 0
bullet_found = 1
bullet[i].life = 1
bullet[i].xpos# = gun_xpos#+1
bullet[i].ypos# = gun_ypos#+1
setSpritePosition(bullet[i].spr,bullet[i].xpos#,bullet[i].ypos#)
setSpriteVisible(bullet[i].spr,1)
endif
endif
next i
endif
endif
return
_player_controls_and_movement:
select input_mode
`joystick
case 1
`button 2 to quit
if getButtonPressed(2) = 1
end
endif
`button 1 for speed boost
bike_xacc# = getButtonState(1)*bike_xthrust# - bike_xvel#*bike_xdrag#
`joystick to move up and down
bike_yacc# = getJoyStickY()*bike_ythrust# - bike_yvel#*bike_ydrag#
endcase
`keyboard
case 2
` esc to quit
if getRawKeyPressed(27) = 1
end
endif
`space bar for speed boost
bike_xacc# = getRawKeyState(32)*bike_xthrust# - bike_xvel#*bike_xdrag#
`up and down arrow keys to move up and down
bike_yacc# = (getRawKeyState(40)-getRawKeyState(38))*bike_ythrust# - bike_yvel#*bike_ydrag#
endcase
`touch screen
case 3
` back button to quit
if getRawKeyPressed(27) = 1
end
endif
`reset flags for movement / acceleration controls
move_x = 0
move_y = 0
`get touch events
touch_a = getRawFirstTouchEvent(1)
touch_b = getRawNextTouchEvent()
touch_a_x = getRawTouchCurrentX(touch_a)
touch_a_y = getRawTouchCurrentY(touch_a)
touch_b_x = getRawTouchCurrentX(touch_b)
touch_b_y = getRawTouchCurrentY(touch_b)
touch_a_time# = getRawTouchTime(touch_a)
touch_b_time# = getRawTouchTime(touch_b)
`response to first touch event
if touch_a_time# > 0
move_y = _f_move_y(touch_a_x,touch_a_y,bike_ypos#,screen_width)
move_x = _f_move_x(touch_a_x,touch_a_y,screen_width)
endif
`response to second touch event
if touch_b_time# > 0
if move_y = 0
move_y = _f_move_y(touch_b_x,touch_b_y,bike_ypos#,screen_width)
endif
if move_x = 0
move_x = _f_move_x(touch_a_x,touch_a_y,screen_width)
endif
endif
`pressed and hold right side of the screen for speed boost
bike_xacc# = move_x*bike_xthrust# - bike_xvel#*bike_xdrag#
`touch / drag left hand side of screen to move up and down
bike_yacc# = move_y*bike_ythrust# - bike_yvel#*bike_ydrag#
endcase
endselect
`calculate bike's x and y velocities
`the bike's x velocity is applied to the scrolling borders and the enemie's velocity
bike_xvel# = bike_xvel# + bike_xacc#
bike_yvel# = bike_yvel# + bike_yacc#
`calculate bike and massive laser gun's y position
`the bike only moves up and down and does not move horizontally relative to the screen
bike_ypos# = bike_ypos# + bike_yvel#
gun_ypos# = bike_ypos# + bike_height
`position bike and massive laser gun
setSpritePosition(bike_spr,bike_xpos#,bike_ypos#)
setSpritePosition(gun_spr,gun_xpos#,gun_ypos#)
return
_scroll_map:
`move map
for j = 1 to 2
for i = 1 to num_blocks
`update position of the block, apply the bike's x velocity
block[j,i].xpos# = block[j,i].xpos# - scroll_speed# - bike_xvel#
setSpritePosition(block[j,i].spr,block[j,i].xpos#,block[j,i].ypos#)
`if block goes off left hand side of the screen then reposition the block off to the right of the screen
if block[j,i].xpos# < block_width*-1
block[j,i].xpos# = block[j,i].xpos#+block_width*num_blocks
endif
next i
next j
return
_enemy_action:
for i = 1 to num_enemies
if enemy[i].life > 0
`update the enemy's position
enemy[i].xpos# = enemy[i].xpos# + enemy[i].xvel# - bike_xvel#
enemy[i].ypos# = enemy[i].ypos# + enemy[i].yvel#
`detect if enemy hits the upper boundary
if enemy[i].ypos# < block_height
enemy[i].ypos# = block_height
enemy[i].yvel# = enemy[i].yvel# * -1
endif
`detect if enemy hits the lower boundary
if enemy[i].ypos# > screen_height - block_height - getSpriteHeight(enemy[i].spr)
enemy[i].ypos# = screen_height - block_height - getSpriteHeight(enemy[i].spr)
enemy[i].yvel# = enemy[i].yvel# * -1
endif
`destroy the enemy if it goes off the left hand side of the screen
if enemy[i].xpos# < -1000
enemy[i].life = 0
endif
endif
`reset the enemy if it is killed
if enemy[i].life <= 0
enemy[i].life = _f_enemy_life_and_size(enemy[i].spr,enemy_max_life)
enemy[i].xpos# = _f_enemy_x_position(enemy[i].spr,screen_width)
enemy[i].ypos# = _f_enemy_y_position(enemy[i].spr,screen_height,block_height)
enemy[i].xvel# = _f_enemy_x_velocity(score)
enemy[i].yvel# = _f_enemy_y_velocity()
endif
`position enemy sprite
setSpritePosition(enemy[i].spr,enemy[i].xpos#,enemy[i].ypos#)
`if the enemy hit the bike or massive laser gun is hit then the game is over
if getSpriteCollision(bike_spr,enemy[i].spr) = 1
game_over = 1
endif
if getSpriteCollision(gun_spr,enemy[i].spr) = 1
game_over = 1
endif
next i
return
_bullet_action:
for i = 1 to num_bullets
if bullet[i].life > 0
`calculate bullet's position and position sprite
bullet[i].xpos# = bullet[i].xpos# + bullet[i].xvel#
setSpritePosition(bullet[i].spr, bullet[i].xpos#, bullet[i].ypos#)
`destroy bullet if it goes off the right side of the screen
if bullet[i].xpos# > screen_width
bullet[i].life = 0
endif
`check if bullet has hit enemy
for j = 1 to num_enemies
if getSpriteCollision(bullet[i].spr,enemy[j].spr) = 1
`score (based on the size of the block, smaller enemies equal more points)
score = score + 1 + enemy_max_life - enemy[j].life
`kill bullet
bullet[i].life = 0
`as the enemy loses life it will get smaller
`need to recalcute position relative to the center of the sprite,
`could've used setSpriteOffset to help with this but didn't
dec enemy[j].life
setSpriteSize(enemy[j].spr,enemy[j].life*50,enemy[j].life*50)
enemy[j].xpos# = enemy[j].xpos# + 25
enemy[j].ypos# = enemy[j].ypos# + 25
endif
next j
else
`if the bullet is dead set sprite invisible
setSpriteVisible(bullet[i].spr,0)
endif
next i
return
_update_hud:
`update the current score
setTextString(current_score_txt, "CURRENT SCORE : " + str(score))
return
_update_scores:
`save previous score and update hud
previous_score = score
setTextString(previous_score_txt,"PREVIOUS SCORE : " + str(previous_score))
`determine if high score is achieved, save and update as appropriate
if score > high_score
high_score = score
setTextString(high_score_txt, "HIGH SCORE : " + str(high_score))
endif
return
_player_collision_with_map:
`detect collision with map
` upper boundary
if bike_ypos# < block_height
`reposition bike and reverse vertical velocity and acceleration
bike_ypos# = block_height
bike_yvel# = bike_yvel#*-1
bike_yacc# = bike_yacc#*-1
`position bike and massive laser gun
setSpritePosition(bike_spr,bike_xpos#,bike_ypos#)
setSpritePosition(gun_spr,bike_xpos#+bike_width,bike_ypos#+bike_height)
endif
`lower boundary
if bike_ypos# > screen_height - block_height - bike_height - gun_height
`reposition bike and reverse vertical velocity and acceleration
bike_ypos# = screen_height - block_height - bike_height - gun_height
bike_yvel# = bike_yvel#*-1
bike_yacc# = bike_yacc#*-1
`position bike and massive laser gun
setSpritePosition(bike_spr,bike_xpos#,bike_ypos#)
setSpritePosition(gun_spr,bike_xpos#+bike_width,bike_ypos#+bike_height)
endif
return
_general:
`set screen dimensions and virtual resolution
screen_width = 800
screen_height = 480
setVirtualResolution(screen_width,screen_height)
SetWindowSize(screen_width,screen_height,0)
`detect input mode (1 = physical joystick, 2 = physical keyboard, 3 = touch screen)
input_mode = 0
if getJoyStickExists() = 1
input_mode = 1
else
if getKeyBoardExists() = 1
input_mode = 2
else
if getMultiTouchExists() = 1
input_mode = 3
endif
endif
endif
return
_create_map:
`map variables
num_blocks = 6
scroll_speed# = 3.0
block_width = (screen_width/(num_blocks-1))+10
block_height = 25
`floor/ceiling
type map
spr as integer
xpos# as float
ypos# as float
endtype
dim block[2,num_blocks] as map
`create sprites for the map
color_modifier = 30
for j = 1 to 2
for i = 1 to num_blocks
`create and color sprites
block[j,i].spr = createSprite(0)
setSpriteSize(block[j,i].spr,block_width,block_height)
color_modifier = color_modifier*-1
setSpriteColor(block[j,i].spr,30+color_modifier,30+color_modifier,225+color_modifier,255)
`set block positions
block[j,i].xpos# = (i-1)*block_width
if j = 1
block[j,i].ypos# = 0
else
block[j,i].ypos# = screen_height-block_height
endif
next i
next j
return
_create_player:
`bike variables
bike_xthrust# = 1.0
bike_ythrust# = 1.2
bike_xdrag# = 0.12
bike_ydrag# = 0.12
bike_width = 12
bike_height = 4
`gun variables
gun_delay = 6
gun_width = 30
gun_height = 10
`rocket bike sprite
bike_spr = createSprite(0)
setSpriteSize(bike_spr,bike_width,bike_height)
setSpriteColor(bike_spr,0,255,0,255)
`massive laser gun sprite
gun_spr = createSprite(0)
setSpriteSize(gun_spr,gun_width,gun_height)
setSpriteColor(gun_spr,50,255,50,255)
return
_create_bullets:
`bullet variables
num_bullets = 10
`bullet UDT
type bullet_stats
spr as integer
xpos# as float
ypos# as float
xvel# as float
yvel# as float
life as integer
endtype
dim bullet[num_bullets] as bullet_stats
`create bullet sprites
for i = 1 to num_bullets
bullet[i].spr = createSprite(0)
setspriteSize(bullet[i].spr,gun_width+10,gun_height-2)
setSpriteColor(bullet[i].spr,255,255,0,255)
setSpritePosition(bullet[i].spr,0,0)
next i
return
_create_enemies:
`enemy variables
num_enemies = 12
enemy_max_life = 4
`enemies (re-use the same UDT as the bullets)
dim enemy[num_enemies] as bullet_stats
`create enemy sprites
for i = 1 to num_enemies
enemy[i].spr = createSprite(0)
setSpriteColor(enemy[i].spr,255,0,0,255)
next i
return
_create_messages:
`create the text that will be used for to show the current, previous and high scores
current_score_txt = createText("")
setTextSize(current_score_txt,20)
setTextPosition(current_score_txt,5,3)
previous_score_txt = createText("PREVIOUS SCORE : 0")
setTextSize(previous_score_txt,20)
setTextAlignment(previous_score_txt,1)
setTextPosition(previous_score_txt,screen_width/2,3)
high_score_txt = createText("HIGH SCORE : 0")
setTextSize(high_score_txt,20)
setTextAlignment(high_score_txt,2)
setTextPosition(high_score_txt,screen_width-5,3)
return
_initiate_enemy:
`determine the alien's life and set sprite size based on life
enemy[i].life = random(1,enemy_max_life)
setSpriteSize(enemy[i].spr,enemy[i].life*50,enemy[i].life*50)
`randomly position the enemy off the right hand side of the screen
enemy[i].xpos# = screen_width + random(screen_width/2,screen_width)
enemy[i].ypos# = random(block_height,screen_height-block_height-getSpriteHeight(enemy[i].spr))
`determine the enemy's velocities
`for every full 100 points scored
speed_mod# = trunc(score*0.1)*0.1
enemy[i].xvel# = (random(1,4) + speed_mod#) * -1
enemy[i].yvel# = random(0,6) - 3
return
`+++++++++++++++++++++++++++++++++++
`functions for initializing enemies
`fairly self explanatory (I hope)
function _f_enemy_life_and_size(sprite,life)
life = random(1,life)
setSpriteSize(sprite,life*50,life*50)
endfunction life
function _f_enemy_x_position(sprite,screen_w)
xpos# = screen_w + random(100,screen_w*2)
endfunction xpos#
function _f_enemy_y_position(sprite,screen_h,block_h)
ypos# = random(block_h,screen_h-block_h-getSpriteHeight(sprite))
endfunction ypos#
function _f_enemy_x_velocity(score)
speed_mod# = trunc(score*0.1)*0.1
xvel# = (random(1,4) + speed_mod#) * -1
endfunction xvel#
function _f_enemy_y_velocity()
yvel# = random(0,6) - 3
endfunction yvel#
`+++++++++++++++++++++++++++++++++++
`functions for touch screen controls
function _f_move_x(touch_x,touch_y,screen_w)
move_x = 0
`if the touch is on the right side of the screen register x movement (ie speed boost)
if touch_x > screen_w*0.6
move_x = 1
endif
endfunction move_x
function _f_move_y(touch_x,touch_y,target_y#,screen_w)
move_y = 0
`if the touch is on the left hand side of the screen register y movement
if touch_x < screen_w*0.4
`if the touch is below the bike, move downward
if touch_y - target_y# < -5
move_y = -1
endif
`if the touch is above the bike, move upward
if touch_y - target_y# > 5
move_y = 1
endif
endif
endfunction move_y
I also wrote a simple
canon shooting game which you might also find useful.