|
| 1 | +##### |
| 2 | +###. TimePlanner v1.1 |
| 3 | +###. Developed by N0P3 |
| 4 | + |
| 5 | +import thumby |
| 6 | +from sys import path |
| 7 | +import time |
| 8 | +import random |
| 9 | +path.append("/Games/TimePlanner") |
| 10 | +import events |
| 11 | + |
| 12 | + |
| 13 | +#Spr = thumby.Sprite(16, 16, "/sprite0.bin", 10, 3) |
| 14 | + |
| 15 | +# Increase this to make the flutter animation change frames faster |
| 16 | +thumby.display.setFPS(30) |
| 17 | + |
| 18 | +WHITE=1 |
| 19 | +BLACK=0 |
| 20 | + |
| 21 | +BOX_WIDTH=5 |
| 22 | +BOX_HEIGHT=5 |
| 23 | + |
| 24 | +# BITMAP: width: 8, height: 8 |
| 25 | +bitmap6 = bytearray([62,28,8,0,0,0,0,0]) |
| 26 | +# BITMAP: width: 8, height: 8 |
| 27 | +heart = bytearray([6,15,31,62,31,15,6,0]) |
| 28 | +# BITMAP: width: 8, height: 8 |
| 29 | +broken_heart = bytearray([6,9,17,34,17,9,6,0]) |
| 30 | + |
| 31 | +def draw_lives(x,y,n,total): |
| 32 | + for i in range(total): |
| 33 | + if n>0: |
| 34 | + thumby.display.blit(heart,x,y,7,6,0,0,0) |
| 35 | + n-=1 |
| 36 | + else: |
| 37 | + thumby.display.blit(broken_heart,x,y,7,6,0,0,0) |
| 38 | + x+=8 |
| 39 | + |
| 40 | + |
| 41 | + |
| 42 | +def draw_empty_box(x,y): |
| 43 | + thumby.display.drawFilledRectangle(x, y, BOX_WIDTH, BOX_HEIGHT, BLACK) |
| 44 | + |
| 45 | +def draw_box(x,y): |
| 46 | + thumby.display.drawRectangle(x, y, BOX_WIDTH, BOX_HEIGHT, WHITE) |
| 47 | + |
| 48 | +def draw_filled_box(x,y): |
| 49 | + thumby.display.drawFilledRectangle(x, y, BOX_WIDTH, BOX_HEIGHT, WHITE) |
| 50 | + |
| 51 | +def draw_chosen_box(x,y): |
| 52 | + draw_empty_box(x,y) |
| 53 | + draw_box(x,y) |
| 54 | + thumby.display.setPixel(x+int(BOX_WIDTH/2), y+int(BOX_HEIGHT/2), WHITE) |
| 55 | + |
| 56 | +def draw_vertical_dashed_line(x,y,length,dash_len,color=WHITE): |
| 57 | + if color == 1: |
| 58 | + black=0 |
| 59 | + white=1 |
| 60 | + else: |
| 61 | + white=0 |
| 62 | + black=1 |
| 63 | + |
| 64 | + final_y=y+length |
| 65 | + #thumby.display.drawLine(x,y,x,final_y,black) |
| 66 | + |
| 67 | + end_y=y |
| 68 | + for i in range(int(length/dash_len)): |
| 69 | + end_y+=dash_len |
| 70 | + if end_y>final_y: |
| 71 | + end_y=final_y |
| 72 | + |
| 73 | + thumby.display.drawLine(x,y+(i*dash_len),x,end_y,white) |
| 74 | + |
| 75 | + white,black=black,white |
| 76 | + |
| 77 | + |
| 78 | +class Timer: |
| 79 | + def __init__(self,action_interval): |
| 80 | + self.action_interval=action_interval |
| 81 | + self.last_action_time = time.ticks_ms() |
| 82 | + |
| 83 | + def reset(self): |
| 84 | + self.last_action_time = time.ticks_ms() |
| 85 | + |
| 86 | + def time_up(self): |
| 87 | + current_time = time.ticks_ms() |
| 88 | + return time.ticks_diff(current_time, self.last_action_time) >= self.action_interval |
| 89 | + |
| 90 | +BOX = 0 |
| 91 | +FILLED = 1 |
| 92 | +CHOSEN = 2 |
| 93 | + |
| 94 | +class Event: |
| 95 | + def __init__(self,dataset): |
| 96 | + self.dataset=dataset |
| 97 | + |
| 98 | + def height(self): |
| 99 | + return len(self.dataset) |
| 100 | + |
| 101 | + def draw(self,x,y,mode): |
| 102 | + self.draw_with_scale(x,y,mode,BOX_WIDTH,BOX_HEIGHT) |
| 103 | + |
| 104 | + def draw_with_scale(self,x,y,mode,width,height): |
| 105 | + i=0 |
| 106 | + for line in self.dataset: |
| 107 | + j=0 |
| 108 | + for box in line: |
| 109 | + final_x=x+j*width |
| 110 | + final_y=y+i*(height) |
| 111 | + if box == 1: |
| 112 | + if mode == BOX: |
| 113 | + draw_box(final_x,final_y) |
| 114 | + elif mode == FILLED: |
| 115 | + draw_filled_box(final_x,final_y) |
| 116 | + elif mode == CHOSEN: |
| 117 | + draw_chosen_box(final_x,final_y) |
| 118 | + else: |
| 119 | + print("Unknown Box Mode '",mode,"'") |
| 120 | + j+=1 |
| 121 | + |
| 122 | + i+=1 |
| 123 | + |
| 124 | + def get_event_positions(self): |
| 125 | + positions={} |
| 126 | + y=0 |
| 127 | + for line in self.dataset: |
| 128 | + x=0 |
| 129 | + for item in line: |
| 130 | + if item == 1: |
| 131 | + if y in positions: |
| 132 | + positions[y].append(x) |
| 133 | + else: |
| 134 | + positions[y]=[x] |
| 135 | + x+=1 |
| 136 | + y+=1 |
| 137 | + return positions |
| 138 | + |
| 139 | +class Calendar: |
| 140 | + def __init__(self,line_nums,line_length,preload=5): |
| 141 | + |
| 142 | + self.line_nums=line_nums |
| 143 | + self.deadline=1 |
| 144 | + self.item_nums=14 |
| 145 | + |
| 146 | + self.current_px=self.deadline+preload |
| 147 | + self.current_py=0 |
| 148 | + self.current_index=0 |
| 149 | + |
| 150 | + #init road |
| 151 | + self.road=[] |
| 152 | + for i in range(self.line_nums): |
| 153 | + line=[] |
| 154 | + current_preload=preload |
| 155 | + for j in range(line_length): |
| 156 | + if current_preload>0: |
| 157 | + line.append(1) |
| 158 | + current_preload-=1 |
| 159 | + else: |
| 160 | + line.append(0) |
| 161 | + self.road.append(line) |
| 162 | + |
| 163 | + |
| 164 | + |
| 165 | + |
| 166 | + def move_on(self): |
| 167 | + c.current_index+=1 |
| 168 | + ok=True |
| 169 | + for line in self.road: |
| 170 | + if line[c.current_index]==0: |
| 171 | + ok=False |
| 172 | + break |
| 173 | + return ok |
| 174 | + |
| 175 | + |
| 176 | + def plan_event(self,event: Event): |
| 177 | + positions=event.get_event_positions() |
| 178 | + |
| 179 | + ok=True |
| 180 | + for y in positions: |
| 181 | + for x in positions[y]: |
| 182 | + final_x,final_y=self.current_index+self.current_px+x,self.current_py+y |
| 183 | + if self.road[final_y][final_x]!=0: |
| 184 | + ok=False |
| 185 | + |
| 186 | + if ok: |
| 187 | + for y in positions: |
| 188 | + for x in positions[y]: |
| 189 | + final_x,final_y=self.current_index+self.current_px+x,self.current_py+y |
| 190 | + print("(",x,",",y,") -> ","(",final_x,",",final_y,")") |
| 191 | + self.road[final_y][final_x]=1 |
| 192 | + |
| 193 | + return ok |
| 194 | + |
| 195 | + def draw(self,x,y,chosen_event: Event): |
| 196 | + |
| 197 | + calendar_x=x |
| 198 | + calendar_y=y+BOX_HEIGHT |
| 199 | + |
| 200 | + thumby.display.drawRectangle( |
| 201 | + calendar_x, |
| 202 | + calendar_y, |
| 203 | + calendar_x+self.item_nums*BOX_WIDTH, |
| 204 | + self.line_nums*BOX_HEIGHT, |
| 205 | + WHITE) |
| 206 | + |
| 207 | + dataset=[] |
| 208 | + for l in self.road: |
| 209 | + line=l[self.current_index:self.current_index+self.item_nums] |
| 210 | + dataset.append(line) |
| 211 | + e=Event(dataset) |
| 212 | + chosen_event.draw(x+self.current_px*BOX_WIDTH,calendar_y+self.current_py*BOX_HEIGHT,CHOSEN) |
| 213 | + e.draw(calendar_x,calendar_y,FILLED) |
| 214 | + draw_vertical_dashed_line(x+self.deadline*BOX_WIDTH,y,y+(self.line_nums+2)*BOX_HEIGHT,1) |
| 215 | + |
| 216 | + |
| 217 | + |
| 218 | + |
| 219 | + |
| 220 | +def random_event(datasets): |
| 221 | + return Event(random.choice(events.Datasets)) |
| 222 | + |
| 223 | + |
| 224 | + |
| 225 | + |
| 226 | +preload=4 |
| 227 | +interval=3000 |
| 228 | +c=Calendar(3,50,preload) |
| 229 | +t=Timer(interval) |
| 230 | +e=random_event(events.Datasets) |
| 231 | +next_event=random_event(events.Datasets) |
| 232 | +score=0 |
| 233 | +lives=3 |
| 234 | +win=False |
| 235 | +game_over=False |
| 236 | +exit_timer=Timer(3000) |
| 237 | +thumby.display.setFont("/lib/font3x5.bin",3,5,WHITE) |
| 238 | +def game_update(): |
| 239 | + global score |
| 240 | + global game_over |
| 241 | + global preload |
| 242 | + global interval |
| 243 | + global t |
| 244 | + global e |
| 245 | + global next_event |
| 246 | + global lives |
| 247 | + global win |
| 248 | + c.draw(1,2,e) |
| 249 | + e.draw_with_scale(4,31,CHOSEN,4,4) |
| 250 | + #thumby.display.blit(bitmap6,0,30,3,6,0,0,0) |
| 251 | + thumby.display.drawText("next:",30,33,WHITE) |
| 252 | + next_event.draw_with_scale(50,31,CHOSEN,4,4) |
| 253 | + thumby.display.drawText("Score:"+str(score),35,1,WHITE) |
| 254 | + draw_lives(47,23,lives,3) |
| 255 | + #thumby.display.fill(1) |
| 256 | + #thumby.display.drawSprite(Spr) |
| 257 | + #Spr.setFrame(Spr.currentFrame+1) |
| 258 | + |
| 259 | + #e=Event(events.CubeEvent) |
| 260 | + # e.draw(0,0,EMPTY) |
| 261 | + if t.time_up(): |
| 262 | + if not c.move_on(): |
| 263 | + print("Oops!") |
| 264 | + lives-=1 |
| 265 | + if lives<=0: |
| 266 | + game_over=True |
| 267 | + exit_timer.reset() |
| 268 | + else: |
| 269 | + preload-=1 |
| 270 | + if preload<=0: |
| 271 | + score+=1 |
| 272 | + interval-=0 |
| 273 | + t=Timer(interval) |
| 274 | + print("Score:",score) |
| 275 | + if c.current_index==35: |
| 276 | + game_over=True |
| 277 | + win=True |
| 278 | + exit_timer.reset() |
| 279 | + t.reset() |
| 280 | + |
| 281 | + if thumby.buttonR.justPressed(): |
| 282 | + print("right") |
| 283 | + c.current_px+=1 |
| 284 | + |
| 285 | + if thumby.buttonL.justPressed(): |
| 286 | + print("left") |
| 287 | + c.current_px-=1 |
| 288 | + if c.current_px<c.deadline: |
| 289 | + c.current_px=c.deadline |
| 290 | + |
| 291 | + if thumby.buttonU.justPressed(): |
| 292 | + print("up") |
| 293 | + c.current_py-=1 |
| 294 | + if c.current_py<0: |
| 295 | + c.current_py=0 |
| 296 | + |
| 297 | + if thumby.buttonD.justPressed(): |
| 298 | + print("down") |
| 299 | + c.current_py+=1 |
| 300 | + |
| 301 | + |
| 302 | + if thumby.buttonA.justPressed(): |
| 303 | + print("A") |
| 304 | + if c.plan_event(e): |
| 305 | + e=next_event |
| 306 | + next_event=random_event(events.Datasets) |
| 307 | + else: |
| 308 | + print("Can't place event here") |
| 309 | + |
| 310 | + if c.current_py+e.height()>c.line_nums: |
| 311 | + c.current_py-=1 |
| 312 | + |
| 313 | +while(True): |
| 314 | + thumby.display.fill(0) |
| 315 | + if game_over: |
| 316 | + thumby.display.fill(0) |
| 317 | + thumby.display.setFont("/lib/font5x7.bin",5,7,WHITE) |
| 318 | + if win: |
| 319 | + thumby.display.drawText("YOU WIN",14,10,1) |
| 320 | + thumby.display.setFont("/lib/font3x5.bin",3,5,WHITE) |
| 321 | + thumby.display.drawText("Thanks for playing my game and reading my code.",1,22,1) |
| 322 | + else: |
| 323 | + thumby.display.drawText("Game Over",10,10,1) |
| 324 | + thumby.display.setFont("/lib/font3x5.bin",3,5,WHITE) |
| 325 | + thumby.display.drawText("Your Score:"+str(score),11,20,WHITE) |
| 326 | + |
| 327 | + if exit_timer.time_up(): |
| 328 | + if thumby.buttonA.justPressed() or thumby.buttonB.justPressed(): |
| 329 | + print("Exit") |
| 330 | + break |
| 331 | + else: |
| 332 | + game_update() |
| 333 | + # draw_box(thumby.display.width-20,thumby.display.height-6) |
| 334 | + # draw_filled_box(thumby.display.width-13,thumby.display.height-6) |
| 335 | + # draw_chosen_box(thumby.display.width-6,thumby.display.height-6) |
| 336 | + thumby.display.update() |
0 commit comments