Skip to content

Commit

Permalink
toy:AmazingBrick
Browse files Browse the repository at this point in the history
  • Loading branch information
FaithALL committed Nov 2, 2021
1 parent 7bf4431 commit 656240a
Show file tree
Hide file tree
Showing 6 changed files with 294 additions and 0 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,7 @@
* [lifeGame](toy/lifeGame/)[生命游戏](https://baike.baidu.com/item/%E5%BA%B7%E5%A8%81%E7%94%9F%E5%91%BD%E6%B8%B8%E6%88%8F/22668799?fromtitle=%E7%94%9F%E5%91%BD%E6%B8%B8%E6%88%8F&fromid=2926434&fr=aladdin),依赖SDL2

<img src="pic/lifeGame.gif" style="zoom: 67%;" />

* AmazingBrick

<img src="pic/AmazingBrick.gif" alt="AmazingBrick" style="zoom:67%;" />
Binary file added pic/AmazingBrick.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
82 changes: 82 additions & 0 deletions toy/AmazingBrick/game/block.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import pygame

import game.game_config as config


class Block:
def __init__(self, x, y, color):
self.x = x
self.y = y
self.color = color

def draw(self, screen):
pygame.draw.rect(screen, self.color, (self.x, self.y,
config.BLOCK_LEN, config.BLOCK_LEN))

def get_points(self):
return [(self.x, self.y), (self.x + config.BLOCK_LEN, self.y),
(self.x + config.BLOCK_LEN, self.y + config.BLOCK_LEN),
(self.x, self.y + config.BLOCK_LEN)]

def move_y_pos(self, y):
self.y -= y


class Pipe(Block):
def __init__(self, x, y, w, color):
super().__init__(x, y, color)
self.w = w
self.scored = False

def draw(self, screen):
pygame.draw.rect(screen, self.color, (self.x, self.y,
self.w, config.PIPE_HEIGHT))

def get_points(self):
return [(self.x, self.y), (self.x + self.w, self.y), (self.x + self.w, self.y + config.PIPE_HEIGHT),
(self.x, self.y + config.PIPE_HEIGHT)]


class Player(Block):
def __init__(self, x, y, color):
super().__init__(x, y, color)
self.vx = 0
self.vy = 0
self.g = config.GRAVITY
self.ax = config.ACC_X
self.ay = config.ACC_Y

def get_points(self):
points = [(self.x + config.PLAYER_LEN, self.y), (self.x, self.y + config.PLAYER_LEN),
(self.x - config.PLAYER_LEN, self.y), (self.x, self.y - config.PLAYER_LEN)]
return points

def draw(self, screen):
points = self.get_points()
pygame.draw.polygon(screen, self.color, points)

def no_move(self):
self.vy += self.g
self.__move()

def move_left(self):
self.vx = 0
self.vy = 0
self.vx -= self.ax
self.vy -= (self.ay - self.g)
self.__move()

def move_right(self):
self.vx = 0
self.vy = 0
self.vx += self.ax
self.vy -= (self.ay - self.g)
self.__move()

def __move(self):
self.x += self.vx
self.y += self.vy
if self.x - config.PLAYER_LEN < 0:
self.x = config.PLAYER_LEN
elif self.x + config.PLAYER_LEN > config.WINDOW_WIDTH:
self.x = config.WINDOW_WIDTH - config.PLAYER_LEN
134 changes: 134 additions & 0 deletions toy/AmazingBrick/game/game.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import random

import pygame

import game.game_config as config
from game.block import Block, Pipe, Player
from pygame_colliders import ConvexCollider

pygame.init()

SCREEN = pygame.display.set_mode((config.WINDOW_WIDTH, config.WINDOW_HEIGHT), pygame.NOFRAME)


class Game:
def __init__(self):
self.score = 0
self.colorId = 0
self.pipes = []
self.blocks = []
self.player = Player(config.WINDOW_WIDTH / 2,
config.WINDOW_HEIGHT / 2, config.PLAYER_COLOR)
self.start = False
self.__draw()

def reset(self):
self.__init__()

def frame_step(self, action):
if action == config.ACTION.NOTHING:
if self.start:
self.player.no_move()
elif action == config.ACTION.LEFT:
self.start = True
self.player.move_left()
elif action == config.ACTION.RIGHT:
self.start = True
self.player.move_right()

self.__handle_pipe_blocks()
self.__move_y_pos()
self.__calculate_score()
self.__draw()
return self.__is_collision()

def __handle_pipe_blocks(self):
n = len(self.pipes)
if n == 0:
gap_y = -config.PIPE_HEIGHT
gap_x = self.__create_pipe(gap_y)
self.__create_block(gap_x, gap_y)
elif n < 6:
gap_y = self.pipes[n - 1].y - config.WINDOW_HEIGHT / 2
gap_x = self.__create_pipe(gap_y)
self.__create_block(gap_x, gap_y, True)
else:
pipe = self.pipes[0]
if pipe.y >= config.WINDOW_HEIGHT:
self.pipes.pop(0)
self.pipes.pop(0)

while self.blocks[0].y >= config.WINDOW_HEIGHT:
self.blocks.pop(0)

def __create_pipe(self, y):
gap_x = random.randint(config.PIPE_GAP_X[0], config.PIPE_GAP_X[1])
self.pipes.append(Pipe(0, y, gap_x, config.COLORS[self.colorId]))
self.pipes.append(
Pipe(gap_x + config.PIPE_GAP_LEN, y, config.WINDOW_WIDTH - gap_x - config.PIPE_GAP_LEN,
config.COLORS[self.colorId]))
return gap_x

def __create_block(self, gap_x, gap_y, two=False):
mid_x = gap_x + config.PIPE_GAP_LEN / 2
mid_y = gap_y + config.PIPE_HEIGHT / 2
if two:
dx = random.randint(int(config.BLOCK_AREA_WIDTH[0]), int(config.BLOCK_AREA_WIDTH[1]))
dy = random.randint(int(config.BLOCK_AREA_HEIGHT[0]), int(config.BLOCK_AREA_HEIGHT[1]))
self.blocks.append(Block(mid_x + dx, mid_y + dy, config.COLORS[self.colorId]))
dx = random.randint(int(config.BLOCK_AREA_WIDTH[0]), int(config.BLOCK_AREA_WIDTH[1]))
dy = random.randint(int(config.BLOCK_AREA_HEIGHT[0]), int(config.BLOCK_AREA_HEIGHT[1]))
self.blocks.append(Block(mid_x + dx, mid_y - dy, config.COLORS[self.colorId]))

def __move_y_pos(self):
t = self.player.y - config.WINDOW_HEIGHT / 2
if t < 0:
self.player.move_y_pos(t)
for pipe in self.pipes:
pipe.move_y_pos(t)
for block in self.blocks:
block.move_y_pos(t)

def __draw(self):
SCREEN.fill(config.BACKGROUND_COLOR)
for pipe in self.pipes:
pipe.draw(SCREEN)
for block in self.blocks:
block.draw(SCREEN)
self.player.draw(SCREEN)
pygame.display.update()

def __is_collision(self):
if self.player.y + config.PLAYER_LEN >= config.WINDOW_HEIGHT:
return True
player_points = self.player.get_points()
collider_player = ConvexCollider(player_points)
for pipe in self.pipes:
if pipe.y + config.PIPE_HEIGHT < self.player.y - config.PLAYER_LEN:
break
else:
pipe_points = pipe.get_points()
collider_pipe = ConvexCollider(pipe_points)
if collider_player.collide(collider_pipe):
return True

for block in self.blocks:
if block.y + config.BLOCK_LEN < self.player.y - config.PLAYER_LEN:
break
else:
block_points = block.get_points()
collider_block = ConvexCollider(block_points)
if collider_player.collide(collider_block):
return True

return False

def __calculate_score(self):
for pipe in self.pipes:
if not pipe.scored:
if pipe.y >= config.WINDOW_HEIGHT / 2:
self.score += 0.5
pipe.scored = True
else:
break
self.colorId = int(self.score) // len(config.COLORS) % len(config.COLORS)
44 changes: 44 additions & 0 deletions toy/AmazingBrick/game/game_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from enum import Enum

# 帧数
FPS = 60

# 窗口大小
WINDOW_WIDTH = 378
WINDOW_HEIGHT = 680

# 颜色
BACKGROUND_COLOR = (250, 255, 250)
PLAYER_COLOR = (0, 0, 0)
COLORS = (
[140, 188, 255],
[149, 93, 182],
[238, 92, 66],
[232, 219, 34],
[139, 232, 146]
)

# 玩家方块大小
PLAYER_LEN = 15

# 矩形障碍物
PIPE_HEIGHT = 36
PIPE_GAP_LEN = 128
PIPE_GAP_X = (0 + 30, WINDOW_WIDTH - PIPE_GAP_LEN - 30)

# 正方形障碍物
BLOCK_LEN = 25
BLOCK_AREA_WIDTH = (-PIPE_GAP_LEN * 0.4, PIPE_GAP_LEN * 0.4)
BLOCK_AREA_HEIGHT = (PIPE_GAP_LEN * 0.6, PIPE_GAP_LEN * 0.8)

# 物理参数
GRAVITY = 0.25
ACC_X = 1.0
ACC_Y = 8.5


# 动作
class ACTION(Enum):
NOTHING = 0
LEFT = 1
RIGHT = 2
31 changes: 31 additions & 0 deletions toy/AmazingBrick/user_play.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from game.game import Game
from game.game_config import FPS
from game.game_config import ACTION
import pygame

game_state = Game()

fps_clock = pygame.time.Clock()

run = True
while run:
action = ACTION.NOTHING
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
action = ACTION.LEFT
elif event.key == pygame.K_RIGHT:
action = ACTION.RIGHT
elif event.key == pygame.K_ESCAPE:
run = False

done = game_state.frame_step(action)
if done:
print(game_state.score)
game_state.reset()

fps_clock.tick(FPS)

pygame.quit()

0 comments on commit 656240a

Please sign in to comment.