Allegro.cc - Online Community

Allegro.cc Forums » Allegro Development » Python port example game proposal

This thread is locked; no one can reply to it. rss feed Print
Python port example game proposal
J-Gamer
Member #12,491
January 2011
avatar

I played around with the Python port for a while, and decided to write a small game with it. Here's what I've come up with:

#SelectExpand
1""" 2 Allegro Python port game example 3 Author: Jeroen De Busser 4""" 5 6from allegro import * 7from random import randint 8import os 9 10 11class Pallet: 12 def __init__(self, x, y, h, w, speed, keyup, keydown, color): 13 self.x, self.y, self.h, self.w, self.speed, self.keyup, self.keydown, self.color = x, y, h, w, speed, keyup, keydown, color 14 self.moving = 0 15 16 def handle_event(self, ev): 17 if ev.type == ALLEGRO_EVENT_KEY_DOWN: 18 if ev.keyboard.keycode == self.keyup: 19 self.moving = -1 20 elif ev.keyboard.keycode == self.keydown: 21 self.moving = 1 22 elif ev.type == ALLEGRO_EVENT_KEY_UP: 23 if (ev.keyboard.keycode == self.keyup and self.moving == -1) or (ev.keyboard.keycode == self.keydown and self.moving == 1): 24 self.moving = 0 25 26 def update(self): 27 self.y += self.moving * self.speed 28 if self.y < 0: 29 self.y = 0 30 elif self.y > al_get_display_height(al_get_current_display()) - self.h: 31 self.y = al_get_display_height(al_get_current_display()) - self.h 32 33 def draw(self): 34 # Fill 35 al_draw_filled_rounded_rectangle(self.x, self.y, self.x + self.w, self.y + self.h, 6, 6, self.color) 36 # Highlight 37 al_draw_filled_rounded_rectangle(self.x+2, self.y+2, self.x + self.w/2, self.y + self.h-5, 4, 4, al_map_rgba_f(0.2,0.2,0.2,0.2)) 38 39 40class Ball: 41 def __init__(self, x, y, speed, size, pallets, color): 42 self.x, self.y, self.speed, self.size, self.pallets, self.color = x, y, speed, size, pallets, color 43 self.xdir = randint(0,1) 44 self.ydir = randint(0,1) 45 46 def update(self): 47 new_x = self.x + (self.xdir - int(self.xdir == 0)) * self.speed 48 new_y = self.y + (int(self.ydir == 0) - self.ydir) * self.speed 49 p = self.pallets[self.xdir] #The pallet this ball is flying to 50 if ((new_x <= p.x + p.w and self.xdir == 0) or (new_x + self.size >= p.x and self.xdir == 1)) and new_y + self.size >= p.y and new_y <= p.y + p.h: 51 #We hit the pallet 52 self.xdir = (self.xdir + 1) % 2 53 new_x = self.x #Reset the x value 54 self.speed += 0.1 #Increase the difficulty 55 if new_y < 0 or new_y + self.size > al_get_display_height(al_get_current_display()): 56 #We hit a wall 57 self.ydir = (self.ydir + 1) % 2 58 new_y = self.y #Reset the y value 59 self.x = new_x 60 self.y = new_y 61 62 def draw(self): 63 #Fill 64 al_draw_filled_circle(self.x + self.size/2, self.y + self.size/2, self.size/2, self.color) 65 #Highlight 66 al_draw_filled_circle(self.x + self.size/4, self.y + self.size/4, self.size/6, al_map_rgb_f(0.8,0.9,0.8)) 67 68 69def main(): 70 #Initialisation 71 al_install_system(ALLEGRO_VERSION_INT, None) 72 73 w, h = 800, 600 74 #Make lines draw smoother 75 al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST) 76 al_set_new_display_option(ALLEGRO_SAMPLES, 4, ALLEGRO_SUGGEST) 77 display = al_create_display(w, h) 78 79 al_init_primitives_addon() 80 al_install_keyboard() 81 al_init_image_addon() 82 al_init_font_addon() 83 84 font = al_load_font("fixed_font.tga",0,0) 85 86 finished = False 87 need_redraw = True 88 FPS = 60 89 pallet_w, pallet_h, pallet_speed = 20, 80, 5 90 ball_size, ball_speed = 30, 4 91 left_player = Pallet(0,h/2-pallet_h/2,pallet_h,pallet_w,pallet_speed,ALLEGRO_KEY_W,ALLEGRO_KEY_S,al_map_rgb_f(1.0,0.0,0.0)) 92 right_player = Pallet(w-pallet_w,h/2-pallet_h/2, pallet_h, pallet_w, pallet_speed, ALLEGRO_KEY_UP,ALLEGRO_KEY_DOWN,al_map_rgb_f(0.0,0.0,1.0)) 93 ball = Ball(w/2,h/2,ball_speed,ball_size,[left_player,right_player],al_map_rgb_f(0,1.0,0)) 94 95 timer = al_create_timer(1.0/FPS) 96 97 queue = al_create_event_queue() 98 al_register_event_source(queue, al_get_timer_event_source(timer)) 99 al_register_event_source(queue, al_get_keyboard_event_source()) 100 al_register_event_source(queue, al_get_display_event_source(display)) 101 102 al_start_timer(timer) 103 104 while True: 105 ev = ALLEGRO_EVENT() 106 107 if need_redraw and al_is_event_queue_empty(queue): 108 al_clear_to_color(al_map_rgb_f(0,0,0)) 109 left_player.draw() 110 right_player.draw() 111 ball.draw() 112 if not finished: 113 al_draw_text(font, al_map_rgb_f(1,1,1), w/2, 10, ALLEGRO_ALIGN_CENTRE, "Player 1: use W and S to move, Player 2: use the up and down arrow keys.") 114 else: 115 al_draw_text(font, al_map_rgb_f(1,1,1), w/2, 10, ALLEGRO_ALIGN_CENTRE, "Press R to reset, ESC to exit.") 116 al_flip_display() 117 redraw = False 118 119 al_wait_for_event(queue,byref(ev)) 120 121 if ev.type == ALLEGRO_EVENT_TIMER: 122 left_player.update() 123 right_player.update() 124 ball.update() 125 if ball.x + ball.size < 0 or ball.x > w: 126 finished = True 127 al_stop_timer(timer) 128 redraw = True 129 elif (ev.type == ALLEGRO_EVENT_KEY_DOWN and ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) or ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE: 130 break 131 elif ev.type == ALLEGRO_EVENT_KEY_DOWN and ev.keyboard.keycode == ALLEGRO_KEY_R: 132 ball.x = w/2 133 ball.y = h/2 134 ball.speed = ball_speed 135 al_start_timer(timer) 136 finished = False 137 else: 138 left_player.handle_event(ev) 139 right_player.handle_event(ev) 140 141 al_uninstall_system() 142 143 144if __name__ == '__main__': 145 #Only start the game when this file is executed directly. 146 al_main(main)

The only resource it uses is the fixed_font.tga, found in the examples/data folder. Which will also be the only line of code to be fixed if it would ever get in the examples.
Do with it what you want ^^

" There are plenty of wonderful ideas in The Bible, but God isn't one of them." - Derezo
"If your body was a business, thought would be like micro-management and emotions would be like macro-management. If you primarily live your life with emotions, then you are prone to error on the details. If you over-think things all the time you tend to lose scope of priorities." - Mark Oates

Elias
Member #358
May 2000

Screenshot? (Can't run it from here on my phone.)

--
"Either help out or stop whining" - Evert

J-Gamer
Member #12,491
January 2011
avatar

video

Sorry for the jerky quality.

EDIT: I'm currently putting some new stuff in: Upgrades and maybe an AI

" There are plenty of wonderful ideas in The Bible, but God isn't one of them." - Derezo
"If your body was a business, thought would be like micro-management and emotions would be like macro-management. If you primarily live your life with emotions, then you are prone to error on the details. If you over-think things all the time you tend to lose scope of priorities." - Mark Oates

kazzmir
Member #1,786
December 2001
avatar

I translated your code to a new language I'm developing. Well its less of a full language and more of a new syntax for an old language (scheme).

Theres nothing super exciting here, just wanted to say I did it and it works. Thanks for the code j-gamer!

#SelectExpand
1#lang honu 2 3require prefix allegro_ racket_allegro_5; 4 5class Pallet(x y height width speed keyup keydown color){ 6 var moving = 0 7 draw(){ 8 allegro_draw_filled_rounded_rectangle(x, y, x + width, y + height, 6, 6, color) 9 allegro_draw_filled_rounded_rectangle(x+2, y+2, x + width/2, y + height-5, 4, 4, allegro_map_rgba_f(0.2,0.2,0.2,0.2)) 10 } 11 12 update(){ 13 y := y + moving * speed 14 if y < 0 then { 15 y := 0 16 } else { 17 0 18 } 19 var max = allegro_get_display_height(allegro_get_current_display()) - height 20 if y > max then { 21 y := max 22 } else { 23 0 24 } 25 } 26 27 handle_event(event){ 28 match event with 29 (allegro_KeyboardEvent type source timestamp display keycode unicode modifiers repeat){ 30 if type = 'KeyDown then { 31 if keycode = keyup then { 32 moving := -1 33 } else { 34 0 35 } 36 if keycode = keydown then { 37 moving := 1 38 } else { 39 0 40 } 41 } else { 42 0 43 } 44 if type = 'KeyUp then { 45 if keycode = keyup or keycode = keydown then { 46 moving := 0 47 } else { 48 0 49 } 50 } else { 51 0 52 } 53 } 54 } 55} 56 57class Ball(x y speed size pallets color){ 58 var xdir = 1 59 var ydir = 1 60 draw(){ 61 allegro_draw_filled_circle(x + size/2, y + size/2, size/2, color) 62 allegro_draw_filled_circle(x + size/4, y + size/4, size/6, allegro_map_rgb_f(0.8,0.9,0.8)) 63 } 64 65 reverseDirection(){ 66 xdir := 1 - xdir 67 } 68 69 right(){ 70 if xdir = 0 then { 71 1 72 } else { 73 0 74 } 75 } 76 77 up(){ 78 if ydir = 0 then { 79 1 80 } else { 81 0 82 } 83 } 84 85 update(){ 86 var new_x = x + (xdir - right()) * speed 87 var new_y = y + (up() - ydir) * speed 88 var p = pallets[xdir] #The pallet this ball is flying to 89 0 90 91 // printf("p.x ~a p.width ~a new_x ~a xdir ~a new_y ~a size ~a p.y ~a p.height ~a\n", p.x, p.width, new_x, xdir, new_y, size, p.y, p.height) 92 // printf("p.width is ~a\n", p.width) 93 if ((new_x <= p.x + p.width and xdir = 0) or 94 (new_x + size >= p.x and xdir = 1)) and 95 new_y + size >= p.y and new_y <= p.y + p.height then { 96 97 0 98 #We hit the pallet 99 xdir := (xdir + 1) % 2 100 new_x := x #Reset the x value 101 speed := speed + 0.3 #Increase the difficulty 102 } else { 103 0 104 } 105 106 if new_y < 0 or new_y + size > allegro_get_display_height(allegro_get_current_display()) then { 107 #We hit a wall 108 ydir := (ydir + 1) % 2 109 new_y := y #Reset the y value 110 } else { 111 0 112 } 113 x := new_x 114 y := new_y 115 } 116 117 setX(what){ 118 x := what 119 } 120} 121 122run_main(){ 123 printf("Start main\n") 124 allegro_install_system() 125 126 var width = 800 127 var height = 600 128 129 # Make lines draw smoother 130 # al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST) 131 # al_set_new_display_option(ALLEGRO_SAMPLES, 4, ALLEGRO_SUGGEST) 132 var display = allegro_create_display(width, height) 133 134 allegro_init_primitives_addon() 135 allegro_install_keyboard() 136 allegro_init_image_addon() 137 allegro_init_font_addon() 138 allegro_init_ttf_addon() 139 140 # var font = al_load_font("fixed_font.tga") 141 var font = allegro_load_font("arial.ttf", 20, 0) 142 143 var finished = false 144 var need_redraw = true 145 var FPS = 30 146 var pallet_w = 20 147 var pallet_h = 80 148 var pallet_speed = 5 149 var ball_size = 30 150 var ball_speed = 4 151 var left_player = new Pallet(0, height/2-pallet_h/2, pallet_h, pallet_w, pallet_speed, 'W, 'S, allegro_map_rgb_f(1.0, 0.0, 0.0)) 152 var right_player = new Pallet(width-pallet_w, height/2-pallet_h/2, pallet_h, pallet_w, pallet_speed, 'Up, 'Down, allegro_map_rgb_f(0.0,0.0,1.0)) 153 var ball = new Ball(width/2, height/2, ball_speed, ball_size, [left_player, right_player], allegro_map_rgb_f(0,1.0,0)) 154 155 var timer = allegro_create_timer(1.0/FPS) 156 157 var queue = allegro_create_event_queue() 158 allegro_register_event_source(queue, allegro_get_timer_event_source(timer)) 159 allegro_register_event_source(queue, allegro_get_keyboard_event_source()) 160 allegro_register_event_source(queue, allegro_get_display_event_source(display)) 161 162 allegro_start_timer(timer) 163 164 printf("Running!\n") 165 166 var done = false 167 while not done { 168 // var now = currentMilliseconds() 169 // printf("top ~a\n", currentMilliseconds()) 170 171 if need_redraw and allegro_is_event_queue_empty(queue) then { 172 allegro_clear_to_color(allegro_map_rgb_f(0,0,0)) 173 left_player->draw() 174 right_player->draw() 175 ball->draw() 176 if not finished then { 177 allegro_draw_text(font, allegro_map_rgb_f(1,1,1), width/2, 10, 'AlignCenter, "Player 1: use W and S to move, Player 2: use the up and down arrow keys.") 178 } else { 179 allegro_draw_text(font, allegro_map_rgb_f(1,1,1), width/2, 10, 'AlignCenter, "Press R to reset, ESC to exit.") 180 } 181 allegro_flip_display() 182 need_redraw := false 183 } else { 184 5 185 } 186 187 // printf("before ~a\n", currentMilliseconds()) 188 var event = allegro_wait_for_event(queue) 189 // printf("after ~a\n", currentMilliseconds()) 190 191 match event with 192 (allegro_TimerEvent type source timestamp count error){ 193 left_player->update() 194 right_player->update() 195 ball->update() 196 if ball.x + ball.size < 0 or ball.x > width then { 197 ball->setX(width / 2) 198 ball->reverseDirection() 199 // finished := true 200 // allegro_stop_timer(timer) 201 } else { 202 0 203 } 204 need_redraw := true 205 } 206 (allegro_KeyboardEvent type source timestamp display keycode unicode modifiers repeat){ 207 // printf("Pressed ~a\n", keycode) 208 if type = 'KeyChar and keycode = 'Escape then { 209 done := true 210 } else { 211 left_player->handle_event(event) 212 right_player->handle_event(event) 213 } 214 } 215 216 /* 217 var later = currentMilliseconds() 218 printf("Took ~ams\n", later - now) 219 */ 220 } 221 222 allegro_uninstall_system() 223} 224 225run_main()

Elias
Member #358
May 2000

So do we want this in the official repository? Would it go into the examples or demos folder?

--
"Either help out or stop whining" - Evert

Mark Oates
Member #1,146
March 2001
avatar

How does that work?

Is it a compiled binary that Python can interface with?

--
Visit CLUBCATT.com for cat shirts, cat mugs, puzzles, art and more <-- coupon code ALLEGRO4LIFE at checkout and get $3 off any order of 3 or more items!

AllegroFlareAllegroFlare DocsAllegroFlare GitHub

Elias
Member #358
May 2000

We could also include the unnamed-new-language-by-kazzmir version and a C version I guess :)

How does that work? Is it a compiled binary that Python can interface with?

You mean how language bindings of Allegro work in general? Then yes.

--
"Either help out or stop whining" - Evert

J-Gamer
Member #12,491
January 2011
avatar

kazzmir said:

Thanks for the code j-gamer!

No problem. I'm adding an AI as well right now. Might come in handy.

EDIT: It might not be the best way to do this, nor is it compliant with many of the best practices, but this AI works :p

#SelectExpand
1""" 2 Allegro Python port game example 3 Author: Jeroen De Busser 4""" 5import os 6from allegro import * 7from random import randint,random 8 9 10class Pallet: 11 def __init__(self, x, y, w, h, speed, color): 12 self.__initials = (x, y, w, h, speed, color, 0) 13 self.reset() 14 15 def reset(self): 16 '''Resets this pallet to its starting values ''' 17 (self.x, self.y, self.w, self.h, self.speed, self.color, self.moving) = self.__initials 18 19 def update(self): 20 self.y += self.moving * self.speed 21 if self.y < 0: 22 self.y = 0 23 elif self.y > al_get_display_height(al_get_current_display()) - self.h: 24 self.y = al_get_display_height(al_get_current_display()) - self.h 25 26 def draw(self): 27 # Fill 28 al_draw_filled_rounded_rectangle(self.x, self.y, self.x + self.w, self.y + self.h, 6, 6, self.color) 29 # Highlight 30 al_draw_filled_rounded_rectangle(self.x+2, self.y+2, self.x + self.w/2, self.y + self.h-5, 4, 4, al_map_rgba_f(0.2,0.2,0.2,0.2)) 31 32 33class Player(Pallet): 34 def __init__(self, x, y, h, w, speed, keyup, keydown, color): 35 self.__initials = (x, y, h, w, speed, keyup, keydown, color) 36 Pallet.__init__(self, x, y, h, w, speed, color) 37 self.keyup, self.keydown = keyup, keydown 38 39 def handle_event(self, ev): 40 if ev.type == ALLEGRO_EVENT_KEY_DOWN: 41 if ev.keyboard.keycode == self.keyup: 42 self.moving = -1 43 elif ev.keyboard.keycode == self.keydown: 44 self.moving = 1 45 elif ev.type == ALLEGRO_EVENT_KEY_UP: 46 if (ev.keyboard.keycode == self.keyup and self.moving == -1) or (ev.keyboard.keycode == self.keydown and self.moving == 1): 47 self.moving = 0 48 49 50class AI(Pallet): 51 def __init__(self, x, y, w, h, speed, color, difficulty, ball): 52 Pallet.__init__(self, x, y, w, h, speed, color) 53 self.difficulty = difficulty 54 self.ball = ball 55 56 def handle_event(self, ev): 57 #Only fire on a timer event 58 if ev.type == ALLEGRO_EVENT_TIMER: 59 #Calculate the target y location according to the difficulty level 60 if self.difficulty == 1: 61 target_y = self.ball.y + self.ball.size/2 62 else: 63 #Higher difficulty, so we need to precalculate the position of the ball if it is closer than a certain treshold 64 if self.ball.xdir == -1 or abs(self.x - self.ball.x) > al_get_display_width(al_get_current_display())*(self.difficulty-1)/self.difficulty: 65 #If the ball is moving away, return to the center of the screen 66 target_y = al_get_display_height(al_get_current_display())/2 67 else: 68 #The ball is moving towards this pallet within its FOV. 69 #Calculate what the y location of the ball will be when it lands at this pallets x location 70 target_y = self.ball.y + (self.x - self.ball.x)*self.ball.ydir 71 if target_y < 0: 72 target_y = abs(target_y) 73 elif target_y > al_get_display_height(al_get_current_display()): 74 target_y = al_get_display_height(al_get_current_display()) - target_y % al_get_display_height(al_get_current_display()) 75 76 #Set the movement 77 if target_y > self.y + self.h*3/4: 78 self.moving = 1 79 elif target_y < self.y + self.h*1/4: 80 self.moving = -1 81 else: 82 self.moving = 0 83 84 85class Ball: 86 def __init__(self, x, y, speed, size, pallets, color): 87 self.x, self.y, self.speed, self.size, self.pallets, self.color = x, y, speed, size, pallets, color 88 self.xdir = randint(0,1) 89 self.xdir = self.xdir - (self.xdir==0) 90 self.ydir = randint(0,1) 91 self.ydir = self.ydir - (self.ydir==0) 92 93 def update(self): 94 new_x = self.x + self.xdir * self.speed 95 new_y = self.y + self.ydir * self.speed 96 p = self.pallets[(self.xdir==1)] #The pallet this ball is flying to 97 if ((new_x <= p.x + p.w and self.xdir == -1) or (new_x + self.size >= p.x and self.xdir == 1)) and new_y + self.size >= p.y and new_y <= p.y + p.h: 98 #We hit the pallet 99 self.xdir = -self.xdir 100 self.speed += 0.1 101 self.on_pallet_touch(p) 102 self.new_x = self.x 103 if self.x < 0 or self.x > al_get_display_width(al_get_current_display()): 104 self.on_screen_exit() 105 if new_y < 0 or new_y + self.size > al_get_display_height(al_get_current_display()): 106 #We hit a wall 107 self.ydir = -self.ydir 108 new_y = self.y #Reset the y value 109 self.x = new_x 110 self.y = new_y 111 112 def on_pallet_touch(self, pallet): 113 """This function should be called on hitting a pallet""" 114 pass 115 116 def on_screen_exit(self): 117 '''This function is called when this ball exits the screen''' 118 pass 119 120 def draw(self): 121 #Fill 122 al_draw_filled_circle(self.x + self.size/2, self.y + self.size/2, self.size/2, self.color) 123 #Highlight 124 al_draw_filled_circle(self.x + self.size/4, self.y + self.size/4, self.size/6, al_map_rgb_f(0.8,0.9,0.8)) 125 126 127class Upgrade(Ball): 128 def __init__(self, x, y, speed, pallets, color, effect_function): 129 Ball.__init__(self, x, y, speed, 10, pallets, color) 130 self.function = effect_function 131 self.touched = False 132 133 def on_pallet_touch(self, pallet): 134 self.touched = True 135 self.function(pallet) 136 137 def on_screen_exit(self): 138 self.touched = True 139 140 141def main(): 142 #Initialisation 143 difficulty = int(input("What difficulty do you want to play on? Input: 0 for two-player mode, 1-4 for AI difficulty setting.\n")) 144 al_install_system(ALLEGRO_VERSION_INT, None) 145 146 w, h = 800, 600 147 #Make lines draw smoother 148 al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST) 149 al_set_new_display_option(ALLEGRO_SAMPLES, 4, ALLEGRO_SUGGEST) 150 display = al_create_display(w, h) 151 152 al_init_primitives_addon() 153 al_install_keyboard() 154 al_init_image_addon() 155 al_init_font_addon() 156 157 font = al_load_font("fixed_font.tga",0,0) 158 159 finished = False 160 need_redraw = True 161 FPS = 60 162 pallet_w, pallet_h, pallet_speed = 20, 80, 5 163 ball_size, ball_speed = 30, 4.6 164 players = [] 165 players.append(Player(0,h/2-pallet_h/2,pallet_w,pallet_h,pallet_speed,ALLEGRO_KEY_W,ALLEGRO_KEY_S,al_map_rgb_f(1.0,0.0,0.0))) 166 ball = Ball(w/2,h/2,ball_speed,ball_size,players,al_map_rgb_f(0,1.0,0)) 167 if not difficulty: 168 players.append(Player(w-pallet_w,h/2-pallet_h/2, pallet_w, pallet_h, pallet_speed, ALLEGRO_KEY_UP,ALLEGRO_KEY_DOWN,al_map_rgb_f(0.0,0.0,1.0))) 169 else: 170 players.append(AI(w-pallet_w,h/2-pallet_h/2, pallet_w, pallet_h, pallet_speed,al_map_rgb_f(0.0,0.0,1.0),difficulty,ball)) 171 172 upgrade_types = [(al_map_rgb_f(0.0,1.0,0.0),lambda pallet:setattr(pallet,'h',pallet.h*1.25)),(al_map_rgb_f(1.0,0.0,0.0),lambda pallet:setattr(pallet,'h',pallet.h * 0.8)),(al_map_rgb_f(1.0,1.0,1.0),lambda pallet:setattr(pallet,'speed',pallet.speed * 1.5)),(al_map_rgb_f(0.3,0.3,0.3),lambda pallet:setattr(pallet,'speed',pallet.speed * 2/3))] 173 upgrade_probability = 0.005 174 175 timer = al_create_timer(1.0/FPS) 176 177 queue = al_create_event_queue() 178 al_register_event_source(queue, al_get_timer_event_source(timer)) 179 al_register_event_source(queue, al_get_keyboard_event_source()) 180 al_register_event_source(queue, al_get_display_event_source(display)) 181 182 al_start_timer(timer) 183 184 upgrades = [] 185 186 score = [0,0] 187 188 while True: 189 if need_redraw and al_is_event_queue_empty(queue): 190 al_clear_to_color(al_map_rgb_f(0,0,0)) 191 for player in players: 192 player.draw() 193 ball.draw() 194 for upgrade in upgrades: 195 upgrade.draw() 196 if not finished: 197 al_draw_text(font, al_map_rgb_f(1,1,1), w/2, 10, ALLEGRO_ALIGN_CENTRE, "Player 1: use W and S to move, Player 2: use the up and down arrow keys.") 198 else: 199 al_draw_text(font, al_map_rgb_f(1,1,1), w/2, 10, ALLEGRO_ALIGN_CENTRE, "Press R to reset, ESC to exit.") 200 al_draw_text(font, al_map_rgb_f(1,1,1), w/2, h - 20, ALLEGRO_ALIGN_CENTRE, "{0} - {1}".format(*score)) 201 al_flip_display() 202 redraw = False 203 204 ev = ALLEGRO_EVENT() 205 al_wait_for_event(queue,byref(ev)) 206 207 if ev.type == ALLEGRO_EVENT_TIMER: 208 for player in players: 209 player.update() 210 ball.update() 211 if ball.x + ball.size < 0 or ball.x > w: 212 finished = True 213 score[ball.x < 0] += 1 214 al_stop_timer(timer) 215 for upgrade in upgrades: 216 upgrade.update() 217 if upgrade.touched: 218 upgrades.remove(upgrade) 219 if random() < upgrade_probability: 220 i = randint(0,len(upgrade_types)-1) 221 upgrades.append(Upgrade(w/2,h/2,ball_speed,players,upgrade_types[i][0],upgrade_types[i][1])) 222 redraw = True 223 elif (ev.type == ALLEGRO_EVENT_KEY_DOWN and ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) or ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE: 224 break 225 elif ev.type == ALLEGRO_EVENT_KEY_DOWN and ev.keyboard.keycode == ALLEGRO_KEY_R: 226 ball.x = w/2 227 ball.y = h/2 228 ball.speed = ball_speed 229 upgrades = [] 230 for player in players: 231 player.reset() 232 al_start_timer(timer) 233 finished = False 234 235 for player in players: 236 player.handle_event(ev) 237 238 al_uninstall_system() 239 240 241if __name__ == '__main__': 242 #Only start the game when this file is executed directly. 243 al_main(main)

Warning: if you input difficulty level 4(or higher, it's possible), then the ball needs to go as fast as looking like multiple balls on your screen to slip past the AI.

" There are plenty of wonderful ideas in The Bible, but God isn't one of them." - Derezo
"If your body was a business, thought would be like micro-management and emotions would be like macro-management. If you primarily live your life with emotions, then you are prone to error on the details. If you over-think things all the time you tend to lose scope of priorities." - Mark Oates

Go to: