Skip to content

Commit 87cb434

Browse files
authored
Add TimePlanner Game
1 parent 9e85624 commit 87cb434

File tree

4 files changed

+368
-0
lines changed

4 files changed

+368
-0
lines changed

TimePlanner/TimePlanner.py

Lines changed: 336 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,336 @@
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()

TimePlanner/TimePlanner.webm

99.6 KB
Binary file not shown.

TimePlanner/arcade_description.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
TimePlanner v1.1 by N0P3
2+
3+
Use the D-Pad to control the placement position and press the A button to drop. The dashed line on the left represents the deadline. You need to ensure there are no gaps every time the deadline is reached. Any gaps will cost you one life point. The game ends when you run out of life points.
4+
5+
P.S. I know this might not be the most exciting game, but I really wanted to create something for this tiny device.

TimePlanner/events.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
Datasets=[
3+
[
4+
[1,1],
5+
[1,1],
6+
],
7+
[
8+
[1,1,1],
9+
],
10+
[
11+
[1,1,1,1],
12+
],
13+
[
14+
[1,1],
15+
],
16+
[
17+
[1],
18+
],
19+
[
20+
[1,1],
21+
[0,1],
22+
],
23+
[
24+
[1,1,1],
25+
[0,0,1],
26+
],
27+
]

0 commit comments

Comments
 (0)