gravity update
This commit is contained in:
parent
e73538c4f7
commit
2a1e9a14cd
|
@ -1 +1,2 @@
|
||||||
.idea
|
|
||||||
|
|
||||||
|
|
71
test.py
71
test.py
|
@ -1,68 +1,5 @@
|
||||||
def speed_and_lines_for_levels(level):
|
def curve(lvl):
|
||||||
if level == 0:
|
return 1/(0.8-((lvl-1)*0.007))**(lvl-1)*0.016666
|
||||||
return 48, 10
|
|
||||||
elif level == 1:
|
|
||||||
return 43, 20
|
|
||||||
elif level == 2:
|
|
||||||
return 38, 30
|
|
||||||
elif level == 3:
|
|
||||||
return 33, 40
|
|
||||||
elif level == 4:
|
|
||||||
return 28, 50
|
|
||||||
elif level == 5:
|
|
||||||
return 23, 60
|
|
||||||
elif level == 6:
|
|
||||||
return 18, 70
|
|
||||||
elif level == 7:
|
|
||||||
return 13, 80
|
|
||||||
elif level == 8:
|
|
||||||
return 8, 90
|
|
||||||
elif level == 9:
|
|
||||||
return 6, 100
|
|
||||||
elif 10 <= level <= 12:
|
|
||||||
return 5, 100
|
|
||||||
elif level == 11:
|
|
||||||
return 5, 100
|
|
||||||
elif level == 12:
|
|
||||||
return 5, 100
|
|
||||||
elif level == 13:
|
|
||||||
return 43, 100
|
|
||||||
elif level == 14:
|
|
||||||
return 43, 100
|
|
||||||
elif level == 15:
|
|
||||||
return 43, 100
|
|
||||||
elif level == 16:
|
|
||||||
return 43, 110
|
|
||||||
elif level == 17:
|
|
||||||
return 43, 120
|
|
||||||
elif level == 18:
|
|
||||||
return 43, 130
|
|
||||||
elif level == 19:
|
|
||||||
return 43, 140
|
|
||||||
elif level == 20:
|
|
||||||
return 43, 150
|
|
||||||
elif level == 21:
|
|
||||||
return 43, 160
|
|
||||||
elif level == 22:
|
|
||||||
return 43, 170
|
|
||||||
elif level == 23:
|
|
||||||
return 43, 180
|
|
||||||
elif level == 24:
|
|
||||||
return 43, 190
|
|
||||||
elif level == 25:
|
|
||||||
return 43, 200
|
|
||||||
elif level == 26:
|
|
||||||
return 43, 200
|
|
||||||
elif level == 27:
|
|
||||||
return 43, 200
|
|
||||||
elif level == 28:
|
|
||||||
return 1, 200
|
|
||||||
else:
|
|
||||||
return 1, 200
|
|
||||||
|
|
||||||
|
for i in range(0, 30):
|
||||||
print(speed_and_lines_for_levels(9))
|
print(i, curve(i))
|
||||||
print(speed_and_lines_for_levels(10))
|
|
||||||
print(speed_and_lines_for_levels(11))
|
|
||||||
print(speed_and_lines_for_levels(12))
|
|
||||||
print(speed_and_lines_for_levels(13))
|
|
436
tetris-main.py
436
tetris-main.py
|
@ -6,7 +6,7 @@ from string import Template
|
||||||
BLOCK_SIZE = 30
|
BLOCK_SIZE = 30
|
||||||
FIELD_SIZE_X = 10
|
FIELD_SIZE_X = 10
|
||||||
FIELD_SIZE_Y = 20
|
FIELD_SIZE_Y = 20
|
||||||
GUIDELINES = ["NES like", "Current"]
|
GUIDELINES = ["Current", "NES like"]
|
||||||
|
|
||||||
|
|
||||||
class Block:
|
class Block:
|
||||||
|
@ -195,6 +195,7 @@ TETROMINOS = [
|
||||||
class DeltaTemplate(Template):
|
class DeltaTemplate(Template):
|
||||||
delimiter = "%"
|
delimiter = "%"
|
||||||
|
|
||||||
|
|
||||||
def strfdelta(tdelta, fmt):
|
def strfdelta(tdelta, fmt):
|
||||||
d = {"D": tdelta.days}
|
d = {"D": tdelta.days}
|
||||||
hours, rem = divmod(tdelta.seconds, 3600)
|
hours, rem = divmod(tdelta.seconds, 3600)
|
||||||
|
@ -211,55 +212,6 @@ def strfdelta(tdelta, fmt):
|
||||||
return t.substitute(**d)
|
return t.substitute(**d)
|
||||||
|
|
||||||
|
|
||||||
def speed_and_lines_for_levels(level):
|
|
||||||
if level == 0:
|
|
||||||
return 48, 10
|
|
||||||
elif level == 1:
|
|
||||||
return 43, 20
|
|
||||||
elif level == 2:
|
|
||||||
return 38, 30
|
|
||||||
elif level == 3:
|
|
||||||
return 33, 40
|
|
||||||
elif level == 4:
|
|
||||||
return 28, 50
|
|
||||||
elif level == 5:
|
|
||||||
return 23, 60
|
|
||||||
elif level == 6:
|
|
||||||
return 18, 70
|
|
||||||
elif level == 7:
|
|
||||||
return 13, 80
|
|
||||||
elif level == 8:
|
|
||||||
return 8, 90
|
|
||||||
elif level == 9:
|
|
||||||
return 6, 100
|
|
||||||
elif 10 <= level <= 12:
|
|
||||||
return 5, 100
|
|
||||||
elif 13 <= level <= 15:
|
|
||||||
return 4, 100
|
|
||||||
elif level == 16:
|
|
||||||
return 3, 110
|
|
||||||
elif level == 17:
|
|
||||||
return 3, 120
|
|
||||||
elif level == 18:
|
|
||||||
return 3, 130
|
|
||||||
elif level == 19:
|
|
||||||
return 2, 140
|
|
||||||
elif level == 20:
|
|
||||||
return 2, 150
|
|
||||||
elif level == 21:
|
|
||||||
return 2, 160
|
|
||||||
elif level == 22:
|
|
||||||
return 2, 170
|
|
||||||
elif level == 23:
|
|
||||||
return 2, 180
|
|
||||||
elif level == 24:
|
|
||||||
return 2, 190
|
|
||||||
elif 25 <= level <= 28:
|
|
||||||
return 2, 200
|
|
||||||
else:
|
|
||||||
return 1, 200
|
|
||||||
|
|
||||||
|
|
||||||
class TetrisGameplay:
|
class TetrisGameplay:
|
||||||
def __init__(self, size_x=FIELD_SIZE_X, size_y=FIELD_SIZE_Y, level=0, buffer_zone=20, srs=True, lock_delay=True, seven_bag=True, ghost_piece=True, hold=True, hard_drop=True, handling=(167, 33), nes_mechanics=False, next_len=3):
|
def __init__(self, size_x=FIELD_SIZE_X, size_y=FIELD_SIZE_Y, level=0, buffer_zone=20, srs=True, lock_delay=True, seven_bag=True, ghost_piece=True, hold=True, hard_drop=True, handling=(167, 33), nes_mechanics=False, next_len=3):
|
||||||
self.buffer_y = buffer_zone
|
self.buffer_y = buffer_zone
|
||||||
|
@ -335,9 +287,9 @@ class TetrisGameplay:
|
||||||
self.pieces[self.current_id] += 1
|
self.pieces[self.current_id] += 1
|
||||||
self.lock_delay_run = False
|
self.lock_delay_run = False
|
||||||
self.lock_delay_frames = 30
|
self.lock_delay_frames = 30
|
||||||
self.lines_for_level_up = speed_and_lines_for_levels(level)[1]
|
|
||||||
self.start_level = level
|
|
||||||
self.level = level
|
self.level = level
|
||||||
|
self.lines_for_level_up = self.gravity_and_lines_table()[1]
|
||||||
|
self.start_level = level
|
||||||
self.game_over = False
|
self.game_over = False
|
||||||
|
|
||||||
def spawn_tetromino(self):
|
def spawn_tetromino(self):
|
||||||
|
@ -378,6 +330,9 @@ class TetrisGameplay:
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"size_x={len(self.FIELD[0])}, size_y={len(self.FIELD)}, buffer_y: {self.buffer_y}"
|
return f"size_x={len(self.FIELD[0])}, size_y={len(self.FIELD)}, buffer_y: {self.buffer_y}"
|
||||||
|
|
||||||
|
def gravity_and_lines_table(self):
|
||||||
|
return 1 / (0.8 - ((self.level - 1) * 0.007)) ** (self.level - 1) * 0.016666, self.level * 10 + 10
|
||||||
|
|
||||||
def clear_lines(self):
|
def clear_lines(self):
|
||||||
cleared = 0
|
cleared = 0
|
||||||
frames_delay = 0
|
frames_delay = 0
|
||||||
|
@ -699,7 +654,7 @@ class TetrisGameplay:
|
||||||
self.lock_delay_frames = 30
|
self.lock_delay_frames = 30
|
||||||
self.lock_delay_run = False
|
self.lock_delay_run = False
|
||||||
|
|
||||||
def move_down(self, by_player=False, instant=False):
|
def move_down(self, instant=False):
|
||||||
if not self.collision(self.current_posx, self.current_posy + 1, self.current_id, self.current_spin_id):
|
if not self.collision(self.current_posx, self.current_posy + 1, self.current_id, self.current_spin_id):
|
||||||
if instant:
|
if instant:
|
||||||
add_to_score = 0
|
add_to_score = 0
|
||||||
|
@ -712,8 +667,6 @@ class TetrisGameplay:
|
||||||
else:
|
else:
|
||||||
self.current_posy += 1
|
self.current_posy += 1
|
||||||
self.spin_is_last_move = False
|
self.spin_is_last_move = False
|
||||||
if by_player:
|
|
||||||
self.score[0] += 1
|
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
@ -798,6 +751,265 @@ class TetrisGameplay:
|
||||||
win.blit(FONT.render("LINES", 1, (255, 255, 255)),
|
win.blit(FONT.render("LINES", 1, (255, 255, 255)),
|
||||||
(5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1, 90 + BLOCK_SIZE * 7))
|
(5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1, 90 + BLOCK_SIZE * 7))
|
||||||
total_lines = sum(self.cleared_lines)
|
total_lines = sum(self.cleared_lines)
|
||||||
|
win.blit(FONT.render(f"{total_lines:03d}", 1, (255, 255, 255)),
|
||||||
|
(5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1, 115 + BLOCK_SIZE * 7))
|
||||||
|
win.blit(FONT.render("LV", 1, (255, 255, 255)),
|
||||||
|
(5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1, 155 + BLOCK_SIZE * 7))
|
||||||
|
win.blit(FONT.render(f"{self.level:02d}", 1, (255, 255, 255)),
|
||||||
|
(5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1, 180 + BLOCK_SIZE * 7))
|
||||||
|
try:
|
||||||
|
pps = sum(self.pieces) / self.game_time
|
||||||
|
except ZeroDivisionError:
|
||||||
|
pps = 0
|
||||||
|
win.blit(FONT.render("PPS", 1, (255, 255, 255)),
|
||||||
|
(5 + BLOCK_SIZE * FIELD_SIZE_X + 120 + BLOCK_SIZE * k1, 155 + BLOCK_SIZE * 7))
|
||||||
|
if pps >= 1:
|
||||||
|
win.blit(FONT.render(f"{pps:1.1f}", 1, (255, 255, 255)),
|
||||||
|
(5 + BLOCK_SIZE * FIELD_SIZE_X + 120 + BLOCK_SIZE * k1, 180 + BLOCK_SIZE * 7))
|
||||||
|
else:
|
||||||
|
win.blit(FONT.render(f".{int(pps*100):02d}", 1, (255, 255, 255)),
|
||||||
|
(5 + BLOCK_SIZE * FIELD_SIZE_X + 120 + BLOCK_SIZE * k1, 180 + BLOCK_SIZE * 7))
|
||||||
|
win.blit(FONT.render("TIME", 1, (255, 255, 255)),
|
||||||
|
(5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1, 220 + BLOCK_SIZE * 7))
|
||||||
|
if self.game_time < 10:
|
||||||
|
win.blit(FONT.render(strfdelta(datetime.timedelta(seconds=self.game_time), '%s.%Z'), 1, (255, 255, 255)),
|
||||||
|
(5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1, 245 + BLOCK_SIZE * 7))
|
||||||
|
elif self.game_time < 60:
|
||||||
|
win.blit(FONT.render(strfdelta(datetime.timedelta(seconds=self.game_time), '%S.%z'), 1, (255, 255, 255)),
|
||||||
|
(5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1, 245 + BLOCK_SIZE * 7))
|
||||||
|
elif self.game_time < 3600:
|
||||||
|
win.blit(FONT.render(strfdelta(datetime.timedelta(seconds=self.game_time), '%m:%S'), 1, (255, 255, 255)),
|
||||||
|
(5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1, 245 + BLOCK_SIZE * 7))
|
||||||
|
else:
|
||||||
|
win.blit(FONT.render(strfdelta(datetime.timedelta(seconds=self.game_time), '%H:%M:%S'), 1, (255, 255, 255)),
|
||||||
|
(5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1, 245 + BLOCK_SIZE * 7))
|
||||||
|
if self.game_over:
|
||||||
|
text_size_x = FONT.size("GAME")[0]
|
||||||
|
pygame.draw.rect(win, (0, 0, 0), (
|
||||||
|
BLOCK_SIZE * (FIELD_SIZE_X / 2) - text_size_x, BLOCK_SIZE * FIELD_SIZE_Y / 2, text_size_x * 2 + 10, 60))
|
||||||
|
win.blit(FONT.render("GAME", 1, (255, 255, 255)),
|
||||||
|
(5 + BLOCK_SIZE * FIELD_SIZE_X / 2 - text_size_x / 2, 5 + BLOCK_SIZE * FIELD_SIZE_Y / 2))
|
||||||
|
win.blit(FONT.render("OVER", 1, (255, 255, 255)),
|
||||||
|
(5 + BLOCK_SIZE * FIELD_SIZE_X / 2 - text_size_x / 2, 5 + BLOCK_SIZE * FIELD_SIZE_Y / 2 + 25))
|
||||||
|
pygame.display.update()
|
||||||
|
|
||||||
|
def draw_game_stats(self, on_pause):
|
||||||
|
win.fill((25, 25, 25))
|
||||||
|
if on_pause:
|
||||||
|
win.blit(FONT.render("GAME PAUSED", 1, (255, 255, 255)), (25, 25))
|
||||||
|
else:
|
||||||
|
win.blit(FONT.render("STATISTIC", 1, (255, 255, 255)), (25, 25))
|
||||||
|
total_score = sum(self.score)
|
||||||
|
win.blit(FONT.render(f"SCORE {total_score:16d}", 1, (255, 255, 255)), (25, 100))
|
||||||
|
total_pieces = sum(self.pieces)
|
||||||
|
win.blit(FONT.render(f"PIECES {total_pieces:15d}", 1, (255, 255, 255)), (25, 130))
|
||||||
|
total_lines = sum(self.cleared_lines)
|
||||||
|
win.blit(FONT.render(f"LINES {total_lines:16d}", 1, (255, 255, 255)), (25, 160))
|
||||||
|
try:
|
||||||
|
pps = total_pieces / self.game_time
|
||||||
|
except ZeroDivisionError:
|
||||||
|
pps = 0
|
||||||
|
win.blit(FONT.render(f"PIECES PER SECOND {pps:0.2f}", 1, (255, 255, 255)), (25, 190))
|
||||||
|
win.blit(FONT.render(f"LEVELS {self.start_level:02d}-{self.level:02d}", 1, (255, 255, 255)), (25, 220))
|
||||||
|
win.blit(
|
||||||
|
FONT.render(f"TIME {strfdelta(datetime.timedelta(seconds=self.game_time), '%H:%M:%S.%Z'):>17s}", 1, (255, 255, 255)),
|
||||||
|
(25, 250))
|
||||||
|
win.blit(SMALL_FONT.render(f"BURNED TIMES LINES PIECES TABLE", 1, (255, 255, 255)), (25, 290))
|
||||||
|
win.blit(
|
||||||
|
SMALL_FONT.render(f"SINGLE {self.cleared_lines[0]:5d} {self.cleared_lines[0]:5d} L {self.pieces[0]:<4d} J {self.pieces[1]:<4d}", 1, (255, 255, 255)),
|
||||||
|
(25, 310))
|
||||||
|
double_times = int(self.cleared_lines[1] / 2)
|
||||||
|
win.blit(SMALL_FONT.render(f"DOUBLE {double_times:5d} {self.cleared_lines[1]:5d} S {self.pieces[2]:<4d} Z {self.pieces[3]:<4d}", 1, (255, 255, 255)),
|
||||||
|
(25, 325))
|
||||||
|
triple_times = int(self.cleared_lines[2] / 3)
|
||||||
|
win.blit(SMALL_FONT.render(f"TRIPLE {triple_times:5d} {self.cleared_lines[2]:5d} T {self.pieces[4]:<4d} O {self.pieces[6]:<4d}", 1, (255, 255, 255)),
|
||||||
|
(25, 340))
|
||||||
|
tetris_times = int(self.cleared_lines[3] / 4)
|
||||||
|
win.blit(SMALL_FONT.render(f"TETRIS {tetris_times:5d} {self.cleared_lines[3]:5d} I {self.pieces[5]:<10d}", 1, (255, 255, 255)),
|
||||||
|
(25, 355))
|
||||||
|
win.blit(SMALL_FONT.render(f"SCORE TABLE", 1, (255, 255, 255)), (25, 380))
|
||||||
|
win.blit(SMALL_FONT.render(f"SOFT DROPS {self.score[0]:14d}", 1, (255, 255, 255)), (25, 400))
|
||||||
|
win.blit(SMALL_FONT.render(f"HARD DROPS {self.score[1]:14d}", 1, (255, 255, 255)), (25, 415))
|
||||||
|
win.blit(SMALL_FONT.render(f"SINGLE {self.score[2]:18d}", 1, (255, 255, 255)), (25, 430))
|
||||||
|
win.blit(SMALL_FONT.render(f"DOUBLE {self.score[3]:18d}", 1, (255, 255, 255)), (25, 445))
|
||||||
|
win.blit(SMALL_FONT.render(f"TRIPLE {self.score[4]:18d}", 1, (255, 255, 255)), (25, 460))
|
||||||
|
win.blit(SMALL_FONT.render(f"TETRIS {self.score[5]:18d}", 1, (255, 255, 255)), (25, 475))
|
||||||
|
win.blit(SMALL_FONT.render(f"T-SPIN MINI NO L. {self.score[6]:7d}", 1, (255, 255, 255)), (25, 490))
|
||||||
|
win.blit(SMALL_FONT.render(f"T-SPIN MINI SINGLE {self.score[7]:6d}", 1, (255, 255, 255)), (25, 505))
|
||||||
|
win.blit(SMALL_FONT.render(f"T-SPIN MINI DOUBLE {self.score[8]:6d}", 1, (255, 255, 255)), (25, 520))
|
||||||
|
win.blit(SMALL_FONT.render(f"T-SPIN NO LINES {self.score[9]:9d}", 1, (255, 255, 255)), (25, 535))
|
||||||
|
win.blit(SMALL_FONT.render(f"T-SPIN SINGLE {self.score[10]:11d}", 1, (255, 255, 255)), (25, 550))
|
||||||
|
win.blit(SMALL_FONT.render(f"T-SPIN DOUBLE {self.score[11]:11d}", 1, (255, 255, 255)), (25, 565))
|
||||||
|
win.blit(SMALL_FONT.render(f"T-SPIN TRIPLE {self.score[12]:11d}", 1, (255, 255, 255)), (25, 580))
|
||||||
|
win.blit(SMALL_FONT.render(f"COMBO BONUS {self.score[13]:13d}", 1, (255, 255, 255)), (25, 595))
|
||||||
|
win.blit(SMALL_FONT.render(f"BACK-TO-BACK BONUS {self.score[14]:6d}", 1, (255, 255, 255)), (25, 610))
|
||||||
|
pygame.display.update()
|
||||||
|
|
||||||
|
|
||||||
|
class NesLikeTetris(TetrisGameplay):
|
||||||
|
def __init__(self, size_x=FIELD_SIZE_X, size_y=FIELD_SIZE_Y, level=0):
|
||||||
|
super().__init__(size_x, size_y, level, 2, False, False, False, False, False, False, (267, 100), True, 1)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
ans = f"size_x={len(self.FIELD[0])}, size_y={len(self.FIELD)}, Field:"
|
||||||
|
for i in self.FIELD:
|
||||||
|
ans += f"\n{i}"
|
||||||
|
return ans
|
||||||
|
|
||||||
|
def gravity_and_lines_table(self):
|
||||||
|
if self.level == 0:
|
||||||
|
return 1/48, 10
|
||||||
|
elif self.level == 1:
|
||||||
|
return 1/43, 20
|
||||||
|
elif self.level == 2:
|
||||||
|
return 1/38, 30
|
||||||
|
elif self.level == 3:
|
||||||
|
return 1/33, 40
|
||||||
|
elif self.level == 4:
|
||||||
|
return 1/28, 50
|
||||||
|
elif self.level == 5:
|
||||||
|
return 1/23, 60
|
||||||
|
elif self.level == 6:
|
||||||
|
return 1/18, 70
|
||||||
|
elif self.level == 7:
|
||||||
|
return 1/13, 80
|
||||||
|
elif self.level == 8:
|
||||||
|
return 1/8, 90
|
||||||
|
elif self.level == 9:
|
||||||
|
return 1/6, 100
|
||||||
|
elif 10 <= self.level <= 12:
|
||||||
|
return 1/5, 100
|
||||||
|
elif 13 <= self.level <= 15:
|
||||||
|
return 1/4, 100
|
||||||
|
elif self.level == 16:
|
||||||
|
return 1/3, 110
|
||||||
|
elif self.level == 17:
|
||||||
|
return 1/3, 120
|
||||||
|
elif self.level == 18:
|
||||||
|
return 1/3, 130
|
||||||
|
elif self.level == 19:
|
||||||
|
return 1/2, 140
|
||||||
|
elif self.level == 20:
|
||||||
|
return 1/2, 150
|
||||||
|
elif self.level == 21:
|
||||||
|
return 1/2, 160
|
||||||
|
elif self.level == 22:
|
||||||
|
return 1/2, 170
|
||||||
|
elif self.level == 23:
|
||||||
|
return 1/2, 180
|
||||||
|
elif self.level == 24:
|
||||||
|
return 1/2, 190
|
||||||
|
elif 25 <= self.level <= 28:
|
||||||
|
return 1/2, 200
|
||||||
|
else:
|
||||||
|
return 1, 200
|
||||||
|
|
||||||
|
def clear_lines(self):
|
||||||
|
cleared = 0
|
||||||
|
frames_delay = 0
|
||||||
|
height = None
|
||||||
|
y = len(self.FIELD)
|
||||||
|
for i in self.FIELD:
|
||||||
|
ic = 0
|
||||||
|
for k in i:
|
||||||
|
if k is not None:
|
||||||
|
ic += 1
|
||||||
|
if ic == FIELD_SIZE_X:
|
||||||
|
cleared += 1
|
||||||
|
self.FIELD.remove(i)
|
||||||
|
new = list(range(FIELD_SIZE_X))
|
||||||
|
x = 0
|
||||||
|
while x != FIELD_SIZE_X:
|
||||||
|
new[x] = None
|
||||||
|
x += 1
|
||||||
|
self.FIELD.insert(0, new)
|
||||||
|
y -= 1
|
||||||
|
if ic > 0 and height is None:
|
||||||
|
height = y
|
||||||
|
frames_delay += 10 + (2 * int(height / 4))
|
||||||
|
|
||||||
|
if cleared >= 0:
|
||||||
|
self.cleared_lines[cleared - 1] += cleared
|
||||||
|
frames_delay += 18
|
||||||
|
if cleared == 1:
|
||||||
|
self.score[2] += 40 * (min(self.level, 29) + 1)
|
||||||
|
elif cleared == 2:
|
||||||
|
self.score[3] += 100 * (min(self.level, 29) + 1)
|
||||||
|
elif cleared == 3:
|
||||||
|
self.score[4] += 300 * (min(self.level, 29) + 1)
|
||||||
|
elif cleared == 4:
|
||||||
|
self.score[5] += 1200 * (min(self.level, 29) + 1)
|
||||||
|
if sum(self.cleared_lines) >= self.lines_for_level_up:
|
||||||
|
self.level += 1
|
||||||
|
self.lines_for_level_up += 10
|
||||||
|
return frames_delay
|
||||||
|
|
||||||
|
def draw_game(self):
|
||||||
|
win.fill((25, 25, 25))
|
||||||
|
pygame.draw.rect(win, (0, 0, 0),
|
||||||
|
(5, (BLOCK_SIZE * 2 + 5), BLOCK_SIZE * FIELD_SIZE_X, BLOCK_SIZE * FIELD_SIZE_Y))
|
||||||
|
x = 0
|
||||||
|
y = -self.buffer_y
|
||||||
|
for i in self.FIELD:
|
||||||
|
for k in i:
|
||||||
|
window_x = 5 + BLOCK_SIZE * x
|
||||||
|
window_y = (BLOCK_SIZE * 2 + 5) + BLOCK_SIZE * y
|
||||||
|
if k is not None:
|
||||||
|
pygame.draw.rect(win, k.color, (window_x, window_y, BLOCK_SIZE, BLOCK_SIZE))
|
||||||
|
pygame.draw.rect(win, (0, 0, 0), (window_x, window_y, BLOCK_SIZE, BLOCK_SIZE), width=2)
|
||||||
|
x += 1
|
||||||
|
x = 0
|
||||||
|
y += 1
|
||||||
|
i1 = self.current_posy - self.buffer_y
|
||||||
|
k1 = self.current_posx
|
||||||
|
if self.current_id is not None:
|
||||||
|
for i in TETROMINOS[self.current_id][self.current_spin_id]:
|
||||||
|
for k in i:
|
||||||
|
if k is not None:
|
||||||
|
window_x = 5 + BLOCK_SIZE * k1
|
||||||
|
window_y = (BLOCK_SIZE * 2 + 5) + BLOCK_SIZE * i1
|
||||||
|
pygame.draw.rect(win, (int(k.color[0]*self.lock_delay_frames/30), int(k.color[1]*self.lock_delay_frames/30), int(k.color[2]*self.lock_delay_frames/30)), (window_x, window_y, BLOCK_SIZE, BLOCK_SIZE))
|
||||||
|
pygame.draw.rect(win, (0, 0, 0), (window_x, window_y, BLOCK_SIZE, BLOCK_SIZE), width=2)
|
||||||
|
k1 += 1
|
||||||
|
k1 = self.current_posx
|
||||||
|
i1 += 1
|
||||||
|
x_offset = 0
|
||||||
|
for q in range(0, self.next_length):
|
||||||
|
i1 = 0
|
||||||
|
k1 = 0
|
||||||
|
for i in TETROMINOS[self.next_queue[q]][0]:
|
||||||
|
for k in i:
|
||||||
|
if k is not None:
|
||||||
|
window_x = 5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1 + x_offset
|
||||||
|
window_y = (BLOCK_SIZE * 2 + 30) + BLOCK_SIZE * i1
|
||||||
|
pygame.draw.rect(win, k.color, (window_x, window_y, BLOCK_SIZE, BLOCK_SIZE))
|
||||||
|
pygame.draw.rect(win, (0, 0, 0), (window_x, window_y, BLOCK_SIZE, BLOCK_SIZE), width=1)
|
||||||
|
k1 += 1
|
||||||
|
k1 = 0
|
||||||
|
i1 += 1
|
||||||
|
x_offset += 45
|
||||||
|
if self.support_hold:
|
||||||
|
if self.hold_id is not None:
|
||||||
|
i1 = 0
|
||||||
|
k1 = 0
|
||||||
|
for i in TETROMINOS[self.hold_id][0]:
|
||||||
|
for k in i:
|
||||||
|
if k is not None:
|
||||||
|
window_x = 5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + 10 * k1
|
||||||
|
window_y = (BLOCK_SIZE * 2 + 75) + 10 * i1
|
||||||
|
pygame.draw.rect(win, k.color, (window_x, window_y, 10, 10))
|
||||||
|
pygame.draw.rect(win, (0, 0, 0), (window_x, window_y, 10, 10), width=1)
|
||||||
|
k1 += 1
|
||||||
|
k1 = 0
|
||||||
|
i1 += 1
|
||||||
|
win.blit(FONT.render("SCORE", 1, (255, 255, 255)),
|
||||||
|
(5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1, 25 + BLOCK_SIZE * 7))
|
||||||
|
total_score = sum(self.score)
|
||||||
|
win.blit(FONT.render(f"{total_score:06d}", 1, (255, 255, 255)),
|
||||||
|
(5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1, 50 + BLOCK_SIZE * 7))
|
||||||
|
win.blit(FONT.render("LINES", 1, (255, 255, 255)),
|
||||||
|
(5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1, 90 + BLOCK_SIZE * 7))
|
||||||
|
total_lines = sum(self.cleared_lines)
|
||||||
win.blit(FONT.render(f"{total_lines:03d}", 1, (255, 255, 255)),
|
win.blit(FONT.render(f"{total_lines:03d}", 1, (255, 255, 255)),
|
||||||
(5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1, 115 + BLOCK_SIZE * 7))
|
(5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1, 115 + BLOCK_SIZE * 7))
|
||||||
win.blit(FONT.render("LV", 1, (255, 255, 255)),
|
win.blit(FONT.render("LV", 1, (255, 255, 255)),
|
||||||
|
@ -875,76 +1087,14 @@ class TetrisGameplay:
|
||||||
win.blit(SMALL_FONT.render(f"TETRIS {tetris_times:5d} {self.cleared_lines[3]:5d} I {self.pieces[5]:<10d}", 1, (255, 255, 255)),
|
win.blit(SMALL_FONT.render(f"TETRIS {tetris_times:5d} {self.cleared_lines[3]:5d} I {self.pieces[5]:<10d}", 1, (255, 255, 255)),
|
||||||
(25, 355))
|
(25, 355))
|
||||||
win.blit(SMALL_FONT.render(f"SCORE TABLE", 1, (255, 255, 255)), (25, 380))
|
win.blit(SMALL_FONT.render(f"SCORE TABLE", 1, (255, 255, 255)), (25, 380))
|
||||||
win.blit(SMALL_FONT.render(f"SOFT DROPS {self.score[0]:14d}", 1, (255, 255, 255)), (25, 400))
|
win.blit(SMALL_FONT.render(f"DROPS {self.score[0]:7d}", 1, (255, 255, 255)), (25, 400))
|
||||||
win.blit(SMALL_FONT.render(f"HARD DROPS {self.score[1]:14d}", 1, (255, 255, 255)), (25, 415))
|
win.blit(SMALL_FONT.render(f"SINGLE {self.score[2]:6d}", 1, (255, 255, 255)), (25, 415))
|
||||||
win.blit(SMALL_FONT.render(f"SINGLE {self.score[2]:18d}", 1, (255, 255, 255)), (25, 430))
|
win.blit(SMALL_FONT.render(f"DOUBLE {self.score[3]:6d}", 1, (255, 255, 255)), (25, 430))
|
||||||
win.blit(SMALL_FONT.render(f"DOUBLE {self.score[3]:18d}", 1, (255, 255, 255)), (25, 445))
|
win.blit(SMALL_FONT.render(f"TRIPLE {self.score[4]:6d}", 1, (255, 255, 255)), (25, 445))
|
||||||
win.blit(SMALL_FONT.render(f"TRIPLE {self.score[4]:18d}", 1, (255, 255, 255)), (25, 460))
|
win.blit(SMALL_FONT.render(f"TETRIS {self.score[5]:6d}", 1, (255, 255, 255)), (25, 460))
|
||||||
win.blit(SMALL_FONT.render(f"TETRIS {self.score[5]:18d}", 1, (255, 255, 255)), (25, 475))
|
|
||||||
win.blit(SMALL_FONT.render(f"T-SPIN MINI NO L. {self.score[6]:7d}", 1, (255, 255, 255)), (25, 490))
|
|
||||||
win.blit(SMALL_FONT.render(f"T-SPIN MINI SINGLE {self.score[7]:6d}", 1, (255, 255, 255)), (25, 505))
|
|
||||||
win.blit(SMALL_FONT.render(f"T-SPIN MINI DOUBLE {self.score[8]:6d}", 1, (255, 255, 255)), (25, 520))
|
|
||||||
win.blit(SMALL_FONT.render(f"T-SPIN NO LINES {self.score[9]:9d}", 1, (255, 255, 255)), (25, 535))
|
|
||||||
win.blit(SMALL_FONT.render(f"T-SPIN SINGLE {self.score[10]:11d}", 1, (255, 255, 255)), (25, 550))
|
|
||||||
win.blit(SMALL_FONT.render(f"T-SPIN DOUBLE {self.score[11]:11d}", 1, (255, 255, 255)), (25, 565))
|
|
||||||
win.blit(SMALL_FONT.render(f"T-SPIN TRIPLE {self.score[12]:11d}", 1, (255, 255, 255)), (25, 580))
|
|
||||||
win.blit(SMALL_FONT.render(f"COMBO BONUS {self.score[13]:13d}", 1, (255, 255, 255)), (25, 595))
|
|
||||||
win.blit(SMALL_FONT.render(f"BACK-TO-BACK BONUS {self.score[14]:6d}", 1, (255, 255, 255)), (25, 610))
|
|
||||||
pygame.display.update()
|
pygame.display.update()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class NesLikeTetris(TetrisGameplay):
|
|
||||||
def __init__(self, size_x=FIELD_SIZE_X, size_y=FIELD_SIZE_Y, level=0):
|
|
||||||
super().__init__(size_x, size_y, level, 2, False, False, False, False, False, False, (267, 100), True, 1)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
ans = f"size_x={len(self.FIELD[0])}, size_y={len(self.FIELD)}, Field:"
|
|
||||||
for i in self.FIELD:
|
|
||||||
ans += f"\n{i}"
|
|
||||||
return ans
|
|
||||||
|
|
||||||
def clear_lines(self):
|
|
||||||
cleared = 0
|
|
||||||
frames_delay = 0
|
|
||||||
height = None
|
|
||||||
y = len(self.FIELD)
|
|
||||||
for i in self.FIELD:
|
|
||||||
ic = 0
|
|
||||||
for k in i:
|
|
||||||
if k is not None:
|
|
||||||
ic += 1
|
|
||||||
if ic == FIELD_SIZE_X:
|
|
||||||
cleared += 1
|
|
||||||
self.FIELD.remove(i)
|
|
||||||
new = list(range(FIELD_SIZE_X))
|
|
||||||
x = 0
|
|
||||||
while x != FIELD_SIZE_X:
|
|
||||||
new[x] = None
|
|
||||||
x += 1
|
|
||||||
self.FIELD.insert(0, new)
|
|
||||||
y -= 1
|
|
||||||
if ic > 0 and height is None:
|
|
||||||
height = y
|
|
||||||
frames_delay += 10 + (2 * int(height / 4))
|
|
||||||
|
|
||||||
if cleared >= 0:
|
|
||||||
self.cleared_lines[cleared - 1] += cleared
|
|
||||||
frames_delay += 18
|
|
||||||
if cleared == 1:
|
|
||||||
self.score[2] += 40 * (min(self.level, 29) + 1)
|
|
||||||
elif cleared == 2:
|
|
||||||
self.score[3] += 100 * (min(self.level, 29) + 1)
|
|
||||||
elif cleared == 3:
|
|
||||||
self.score[4] += 300 * (min(self.level, 29) + 1)
|
|
||||||
elif cleared == 4:
|
|
||||||
self.score[5] += 1200 * (min(self.level, 29) + 1)
|
|
||||||
if sum(self.cleared_lines) >= self.lines_for_level_up:
|
|
||||||
self.level += 1
|
|
||||||
self.lines_for_level_up += 10
|
|
||||||
return frames_delay
|
|
||||||
|
|
||||||
|
|
||||||
def draw_main_menu(selected, sel_lvl, sel_gl):
|
def draw_main_menu(selected, sel_lvl, sel_gl):
|
||||||
win.fill((25, 25, 25))
|
win.fill((25, 25, 25))
|
||||||
win.blit(FONT.render("TETRIS by dan63047", 1, (255, 255, 255)), (25, 25))
|
win.blit(FONT.render("TETRIS by dan63047", 1, (255, 255, 255)), (25, 25))
|
||||||
|
@ -960,7 +1110,7 @@ def main():
|
||||||
selected_level = 0
|
selected_level = 0
|
||||||
selected_gl = 0
|
selected_gl = 0
|
||||||
ticks_before_stats = 180
|
ticks_before_stats = 180
|
||||||
ticks_gone = 0
|
g = 0
|
||||||
menu_select = 0
|
menu_select = 0
|
||||||
on_pause = False
|
on_pause = False
|
||||||
corrupt_hard_drop = False
|
corrupt_hard_drop = False
|
||||||
|
@ -1000,36 +1150,36 @@ def main():
|
||||||
elif state == "pregameplay":
|
elif state == "pregameplay":
|
||||||
ticks_before_stats = 300
|
ticks_before_stats = 300
|
||||||
if selected_gl == 0:
|
if selected_gl == 0:
|
||||||
field = NesLikeTetris(level=selected_level)
|
|
||||||
elif selected_gl == 1:
|
|
||||||
field = TetrisGameplay(level=selected_level)
|
field = TetrisGameplay(level=selected_level)
|
||||||
|
elif selected_gl == 1:
|
||||||
|
field = NesLikeTetris(level=selected_level)
|
||||||
pygame.key.set_repeat(field.handling[0], field.handling[1])
|
pygame.key.set_repeat(field.handling[0], field.handling[1])
|
||||||
state = "gameplay"
|
state = "gameplay"
|
||||||
elif state == "gameplay":
|
elif state == "gameplay":
|
||||||
field.draw_game()
|
field.draw_game()
|
||||||
ticks_for_down = speed_and_lines_for_levels(field.level)[0]
|
|
||||||
if not field.game_over:
|
if not field.game_over:
|
||||||
if pygame.K_r in pressed_keys and ticks_gone >= 0:
|
if pygame.K_r in pressed_keys:
|
||||||
state = "pregameplay"
|
state = "pregameplay"
|
||||||
if pygame.K_p in pressed_keys and ticks_gone >= 0:
|
if pygame.K_p in pressed_keys:
|
||||||
on_pause = True
|
on_pause = True
|
||||||
state = "gameplay_stats"
|
state = "gameplay_stats"
|
||||||
if (pygame.K_UP in pressed_keys or pygame.K_x in pressed_keys) and ticks_gone >= 0:
|
if pygame.K_UP in pressed_keys or pygame.K_x in pressed_keys:
|
||||||
field.spin()
|
field.spin()
|
||||||
if pygame.K_z in pressed_keys and ticks_gone >= 0:
|
if pygame.K_z in pressed_keys:
|
||||||
field.spin(True)
|
field.spin(True)
|
||||||
if pygame.K_c in pressed_keys and ticks_gone >= 0 and field.support_hold and not field.hold_locked:
|
if pygame.K_c in pressed_keys and field.support_hold and not field.hold_locked:
|
||||||
field.hold_tetromino()
|
field.hold_tetromino()
|
||||||
if pygame.K_DOWN in pressed_keys and ticks_gone >= 0:
|
if pygame.K_DOWN in pressed_keys:
|
||||||
ticks_gone -= field.move_down(True)
|
g += 1
|
||||||
if pygame.K_LEFT in pressed_keys and ticks_gone >= 0:
|
field.score[0] += 1
|
||||||
|
if pygame.K_LEFT in pressed_keys:
|
||||||
field.move_side(-1)
|
field.move_side(-1)
|
||||||
if pygame.K_RIGHT in pressed_keys and ticks_gone >= 0:
|
if pygame.K_RIGHT in pressed_keys:
|
||||||
field.move_side(1)
|
field.move_side(1)
|
||||||
if pygame.K_SPACE in pressed_keys and not corrupt_hard_drop and field.can_hard_drop:
|
if pygame.K_SPACE in pressed_keys and not corrupt_hard_drop and field.can_hard_drop:
|
||||||
field.move_down(True, True)
|
field.move_down(True)
|
||||||
field.save_state()
|
field.save_state()
|
||||||
ticks_gone -= field.clear_lines()
|
field.clear_lines()
|
||||||
field.spawn_tetromino()
|
field.spawn_tetromino()
|
||||||
field.lock_delay_run = False
|
field.lock_delay_run = False
|
||||||
field.lock_delay_frames = 30
|
field.lock_delay_frames = 30
|
||||||
|
@ -1037,23 +1187,23 @@ def main():
|
||||||
field.game_time += clock.get_time()/1000
|
field.game_time += clock.get_time()/1000
|
||||||
if field.game_over:
|
if field.game_over:
|
||||||
ticks_before_stats -= 1
|
ticks_before_stats -= 1
|
||||||
ticks_gone += 1
|
if not field.game_over:
|
||||||
if ticks_gone >= ticks_for_down:
|
g += field.gravity_and_lines_table()[0]
|
||||||
ticks_gone = 0
|
while g >= 1:
|
||||||
if not field.game_over:
|
|
||||||
if field.support_lock_delay:
|
if field.support_lock_delay:
|
||||||
if not field.move_down():
|
if not field.move_down():
|
||||||
field.lock_delay_run = True
|
field.lock_delay_run = True
|
||||||
else:
|
else:
|
||||||
if not field.move_down():
|
if not field.move_down():
|
||||||
field.save_state()
|
field.save_state()
|
||||||
ticks_gone -= field.clear_lines()
|
ticks_gone = -field.clear_lines()
|
||||||
field.spawn_tetromino()
|
field.spawn_tetromino()
|
||||||
|
g -= 1
|
||||||
if field.lock_delay_run:
|
if field.lock_delay_run:
|
||||||
field.lock_delay_frames -= 1
|
field.lock_delay_frames -= 1
|
||||||
if field.lock_delay_frames <= 0 or not field.support_lock_delay:
|
if field.lock_delay_frames <= 0 or not field.support_lock_delay:
|
||||||
field.save_state()
|
field.save_state()
|
||||||
ticks_gone -= field.clear_lines()
|
field.clear_lines()
|
||||||
field.spawn_tetromino()
|
field.spawn_tetromino()
|
||||||
field.reset_lock_delay()
|
field.reset_lock_delay()
|
||||||
if ticks_before_stats <= 0:
|
if ticks_before_stats <= 0:
|
||||||
|
|
Loading…
Reference in New Issue