Historical allegrocreategames_robspage3, Revision 5

Robots revenge main gameplay loop

As ever in the process of game making, the player and robot entities have been added to (and will no doubt be subject to further changes, so what we have now is

--Robot attributes 
constant R_X = 1,                                   --x posn 
         R_Y = 2,                                   --y posn 
         R_TYPE = 3, 
         R_SPEED = 4,                               --speed at which robot can move 
         R_BMP_NUM = 5,                             --which bitmap are we displaying 
         R_BMP = 6,                                 --the actual bitmap handle 
         R_DIRECTION = 7,                           --the direction the robot travels in, use 'L' and 'R' 
         NUM_ROBOT_ATTRIBUTES = 7,                      --adjust this if you change the number of attributes 
         
--player attributes 
         P_X = 1, 
         P_Y = 2, 
         P_LIFE = 3, 
         P_LEVEL = 4, 
         P_SHIELD = 5, 
         P_BMP_NUM = 6, 
         P_BMP = 7, 
         P_SPEED = 8, 
         P_DIRECTION = 9,                           --use 'L' and 'R' 
         NUM_PLAYER_ATTRIBUTES = 9, 
 
--wall attributes 
         W_X = 1, 
         W_Y = 2, 
         W_BMP = 3, 
         W_DESTROYABLE = 4,  
         NUM_WALL_ATTRIBUTES = 4     
 

That's right, we have also forward planned for walls!

The player and movement loop boils down to this - detect the input (in this case keys), update the player position, update the robot position, check for capture, update the arena, and update the screen.

This is encapsulated in the begin game procedure

--------------------------------------------------------------- 
procedure begin_game() 
--start background music 
--create arena 
--populate with robots 
--place exit 
--place teleport if level requires it 
--------------------------------------------------------------- 
integer fn, cn 
atom arena_bmp 
sequence robot_list = {}, current_robot 
integer robots_per_level, num_bots, overlaid_flag = 0 
sequence exit_location = {0,0} 
sequence player 
atom NRx, NRy                                       --new robot position 
integer player_caught = 0, at_player 
atom L                                              --distance to robot to player 
                                                        --also Length of the hypotenuse 
atom Pdist                                              --the dist proportion that the robot can move                                                        
                                                         
current_robot = repeat(0, NUM_ROBOT_ATTRIBUTES)  
player = repeat(0, NUM_PLAYER_ATTRIBUTES)                
 
Level = 1                                   --may change later 
robots_per_level = 3 
num_bots = Level * robots_per_level 
 
--load intro music 
fn = FMUSIC_LoadSong("action.it") 
cn = FMUSIC_PlaySong(fn) 
VOID = FMUSIC_SetMasterVolume(fn, 10) 
 
arena_bmp = create_bitmap(640,480)          --create a bitmap for the arena 
clear_bitmap(arena_bmp)                     --clear the arena 
 
--create a robot list 
--Number of robots to create depends on level, for now just start with 10 
robot_list = repeat(current_robot, num_bots) 
for i = 1 to num_bots do 
    while 1  do 
        --robot creation incorporating anti overlaying technology 
        overlaid_flag = 0    
        robot_list[i][R_X] = rand(32) * 20          --the images are 20*20, screen size is 640 * 480, 640/20 = 32 
        robot_list[i][R_Y] = rand(24) * 20 
 
        for j = 1 to num_bots do                    --check overlays 
            if j = i then continue end if 
            if robot_list[j][R_X] = 0 then 
                exit 
            end if 
            if abs(robot_list[j][R_X] + 10 - robot_list[i][R_X] + 10) <= 20 or 
               abs(robot_list[j][R_Y] + 10 - robot_list[i][R_Y] + 10) <= 20 then 
                    overlaid_flag = 1 
                    exit 
                    --try again!     
            end if           
        end for 
 
        if overlaid_flag = 0 then 
            exit 
        end if 
    end while    
     
    robot_list[i][R_SPEED] = 5 
    robot_list[i][R_TYPE] = 1 
    robot_list[i][R_BMP_NUM] = rand(2) 
    if robot_list[i][R_BMP_NUM] = 1 then 
        robot_list[i][R_BMP] = r1_bmp       --pointers to the location of the robot bitmap 
    else 
        robot_list[i][R_BMP] = r2_bmp 
    end if 
    robot_list[i][R_DIRECTION] = 'L'         
end for 
 
--put the exit somewhere on there 
while 1 do 
    exit_location = {rand(620), rand(460)} 
    overlaid_flag = 0 
    for i = 1 to num_bots do 
        if abs(robot_list[i][R_X] + 10 - exit_location[1]+10) <= 20 or 
           abs(robot_list[i][R_Y] + 10 - exit_location[2]+10) <= 20 then 
                overlaid_flag = 1 
                exit 
                --try again!     
        end if   
    end for 
    if overlaid_flag = 0 then 
        exit 
    end if 
end while 
 
--set up the player 
while 1 do 
    player[P_X] = rand(620) 
    player[P_Y] = rand(480) 
    player[P_SPEED] = 7 
    overlaid_flag = 0 
    for i = 1 to num_bots do 
        if abs(robot_list[i][R_X] + 10 - player[P_X]+10) <= 20 or 
           abs(robot_list[i][R_Y] + 10 - player[P_Y]+10) <= 20 then 
                overlaid_flag = 1 
                exit 
                --try again!     
        end if   
    end for 
    if overlaid_flag = 0 then 
        exit 
    end if 
end while 
player[P_LIFE] = 3 
player[P_LEVEL] = Level 
player[P_SHIELD] = 0 
player[P_BMP_NUM] = 1 
if player[P_BMP_NUM] = 1 then 
    player[P_BMP] = p1_bmp 
else 
    player[P_BMP] = p2_bmp 
end if 
player[P_DIRECTION] = 'L' 
 
--that's the robots, the exit and the player set up 
--lets blit them onto the arena bitmap, then blit that to the screen. 
 
for i = 1 to num_bots do 
    blit(robot_list[i][R_BMP], arena_bmp,                       --src_bmp, dest_bmp 
            0,0,                                                --src start coords 
            robot_list[i][R_X],robot_list[i][R_Y],              --dest coords 
            20,20)                                              --size of src to blit 
end for 
 
--blit the exit somewhere on there 
blit(exit_bmp, arena_bmp, 
        0,0, 
        exit_location[1], exit_location[2], 
        20,20) 
         
--blit the player on to the arena 
blit(player[P_BMP], arena_bmp, 
        0,0, 
        player[P_X], player[P_Y], 
        20,20) 
 
blit(arena_bmp, screen,  0, 0, 0, 0, SCREEN_W, SCREEN_H) 
 
--player and robot movement loop 
while 1 do 
    --wait for a cursor key to be pressed 
    --while keypressed() = 0 do end while 
    clear_keybuf() 
    VOID = readkey() 
 
    if key(KEY_UP) then 
        player[P_Y] -= player[P_SPEED] 
        if player[P_Y] < 0 then  
            player[P_Y] = 1 
        end if 
    elsif key(KEY_DOWN) then 
        player[P_Y] += player[P_SPEED] 
            if player[P_Y] >  SCREEN_H - 20 then 
                player[P_Y] = SCREEN_H -  20 
            end if 
    elsif key(KEY_LEFT) then 
        player[P_X] -= player[P_SPEED] 
        if player[P_X] < 0 then  
            player[P_X] = 1 
        end if 
        player[P_DIRECTION] = 'L' 
    elsif key(KEY_RIGHT) then 
        player[P_X] += player[P_SPEED] 
            if player[P_X] >  SCREEN_W - 20 then 
                player[P_X] = SCREEN_W -  20 
            end if 
        player[P_DIRECTION] = 'R' 
    elsif key(KEY_Q) or key(KEY_ESC) then 
        exit 
    end if 
 
 
    --animate the player 
    player[P_BMP_NUM] = player[P_BMP_NUM] * -1 + 1 
    if player[P_BMP_NUM] = 1 then 
        player[P_BMP] = p1_bmp 
    else 
        player[P_BMP] = p2_bmp 
    end if 
     
 
    --update the arena bmp 
 
    clear_bitmap(arena_bmp)                                         --this is just one way of doing this 
                                                                    --could clear each of the old bitmaps,  
                                                                    --and write the new ones 
/* 
    for i = 1 to num_bots do 
        blit(robot_list[i][R_BMP], arena_bmp,                       --src_bmp, dest_bmp 
                0,0,                                                --src start coords 
                robot_list[i][R_X],robot_list[i][R_Y],              --dest coords 
                20,20)                                              --size of src to blit 
    end for 
*/ 
    --blit the exit somewhere on there 
    blit(exit_bmp, arena_bmp, 
            0,0, 
            exit_location[1], exit_location[2], 
            20,20) 
         
    --blit the player on to the arena 
    --note using draw sprite here, so we can flip the bmp 
    if player[P_DIRECTION] = 'L' then 
        draw_sprite(arena_bmp, player[P_BMP],                       --destination, src 
                    player[P_X], player[P_Y])                       --position 
    else 
        draw_sprite_h_flip(arena_bmp, player[P_BMP],                        --destination, src 
                    player[P_X], player[P_Y])                       --position 
    end if 
     
     
    --blit(player[P_BMP], arena_bmp, 
    --      0,0, 
    --      player[P_X], player[P_Y], 
    --      20,20) 
     
 
    --move and animate each of the bots 
    for i = 1 to num_bots do 
        at_player = 0 
        L = sqrt(power(robot_list[i][R_X] - player[P_X], 2) + power(robot_list[i][R_Y] - player[P_Y], 2))    
             --L = the length of the hypotenuse 
        Pdist = robot_list[i][R_SPEED] / L 
        if Pdist > 1 then 
            player_caught = 1 
            at_player = 1 
        end if 
        NRx = robot_list[i][R_X] - (robot_list[i][R_X] - player[P_X]) * Pdist 
        NRy = robot_list[i][R_Y] - (robot_list[i][R_Y] - player[P_Y]) * Pdist 
        if at_player = 1 then 
            NRx = player[P_X] 
            NRy = player[P_Y] 
        end if 
 
        --animate the robot 
        if robot_list[i][R_BMP_NUM] = 1 then 
            robot_list[i][R_BMP_NUM] = 0 
            robot_list[i][R_BMP] = r1_bmp       --pointers to the location of the robot bitmap 
        else 
            robot_list[i][R_BMP_NUM] = 1 
            robot_list[i][R_BMP] = r2_bmp 
        end if 
        if NRx < robot_list[i][R_X] then 
            robot_list[i][R_DIRECTION] = 'L' 
        else 
            robot_list[i][R_DIRECTION] = 'R' 
        end if 
 
        --update the robot position 
        robot_list[i][R_X] = floor(NRx) 
        robot_list[i][R_Y] = floor(NRy) 
         
        --draw the robot sprites to the arena 
        if robot_list[i][R_DIRECTION] = 'L' then 
            draw_sprite(arena_bmp, robot_list[i][R_BMP],                        --destination, src 
                    robot_list[i][R_X], robot_list[i][R_Y])                     --position 
        else 
            draw_sprite_h_flip(arena_bmp, robot_list[i][R_BMP],                     --destination, src 
                    robot_list[i][R_X], robot_list[i][R_Y])                     --position 
        end if 
    end for 
 
    blit(arena_bmp, screen,  0, 0, 0, 0, SCREEN_W, SCREEN_H) 
 
    rest(100) 
 
end while 
 
 
VOID = FMUSIC_StopSong(fn) 
VOID = FMUSIC_FreeSong(fn) 
 
 
end procedure 
 

The code is well commented, so there isn't much point in me adding much here.

The 'which direction should the robot move in' section is interesting, in that this introduces some vector maths. I had to work this out for myself again, so it was an interesting excercise for me too.

The allegro screen starts in the top left at pixel 1,1, x goes along the top of the screen from left to right up to 640 (or chosen resolution), and from top to bottom to 480 (or chosen resolution).

I wanted to move the robot towards the player at it's attributed speed. so the first thing to do was to calculate the length of the vector, or line, between the player and the robot.

The player is at coordinates Px and Py, and the robot at coordinates Rx and Ry. This actually forms a right angled triangle which we use to calculate the length of the hypoteneuse, that looks like this

https://drive.google.com/file/d/0B_FlaOPLFXdTTC1yZ1BXczdrSDA/view?usp=sharing

(Can't get this to embed yet)
Once we have the length of the hypotenuse, we can work out the proportion of that the robot will travel towards the player in it's speed allocation - Length / speed. Note, if this is greater than one then the robot has overtaken the player.

Next we use this proportion to update the x and y coordinates of the robot, as a proportion along the x and y axis differences between the robot position and the player position. (see NRx and NRy in the code)

We also introduce draw_sprite() and draw_sprite_h_flip() - these are simpler ways of putting the robot bitmap onto the arena (treating the bitmap as a sprite). As the backgrounds of the sprite is the same colour as the arena, we don't need to worry about sprite colour transparency, just yet, but look what happens when the bitmaps overlay each other.

Player capsture is covered - we just need an end animation. Player exit isn't detected, and next levels aren't done yet. I'm going to make this a bit tidier for the next iteration, but for now you can download the program from https://app.box.com/s/c8w99wcdknep0bwh27lxneg2cscc40fc (Its RobotsR02.exw - just run this in the same folder as all the other media)
Home
Page 4 - clash detection

Search



Quick Links

User menu

Not signed in.

Misc Menu