Historical allegrocreategames_robspage3, Revision 4
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
(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)
- diff to current revision, view current revision history, backlinks
- Last modified Oct 30, 2017 by ChrisB