diff --git a/README.md b/README.md index c127aeb..2b3b5eb 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,7 @@ -# python_billiards +# python-台球 +## 文件结构 + +### common + +该文件用于存放一些游戏中的基类和继承类, \ No newline at end of file diff --git a/common/game/billiards/baseBilliard.py b/common/game/billiards/baseBilliard.py index 7721c37..27f9c7a 100644 --- a/common/game/billiards/baseBilliard.py +++ b/common/game/billiards/baseBilliard.py @@ -1,21 +1,24 @@ import pygame.draw from common.drawableItem import DrawableItem -from enums.Color import BLACK -from enums.category import Category +from enums import color from config.sys import * import pymunk +from enums.color import BLACK + class BaseBilliard(DrawableItem): - def __init__(self, score: int, category: Category, color: tuple[int, int, int], pos=(0, 0)): + def __init__(self, score: int, category: int, color: tuple[int, int, int], pos=(0, 0)): self.__score = score - self.__category = category self.__color = color self.__rigid_body = pymunk.Body(BALL_MASS, 1) self.__rigid_body.position = pos self.__shape = pymunk.Circle(self.__rigid_body, BALL_RADIUS) + self.__shape.collision_type = category self.__shape.elasticity = 1.0 + self.__rigid_body.velocity = pymunk.Vec2d.zero() + self.activity = True @property def score(self): @@ -23,7 +26,7 @@ class BaseBilliard(DrawableItem): @property def category(self): - return self.__category + return self.__shape.collision_type @property def color(self): @@ -59,5 +62,8 @@ class BaseBilliard(DrawableItem): return v = self.__rigid_body.velocity.scale_to_length(length - TABLE_FRICTION_FACTOR / FPS) if v.length <= 1: - v = (0, 0) + v = pymunk.Vec2d.zero() self.__rigid_body.velocity = v + + def is_stable(self): + return self.__rigid_body.velocity.length <= 1.0 or self.__rigid_body.velocity == pymunk.Vec2d.zero() diff --git a/common/game/cue.py b/common/game/cue.py index 53733a3..d5917bb 100644 --- a/common/game/cue.py +++ b/common/game/cue.py @@ -3,21 +3,23 @@ import pymunk from common.drawableItem import DrawableItem from common.game.billiards.baseBilliard import BaseBilliard +from common.game.billiards.cueBall import CueBall +from common.game.gameData import GameData from config.sys import CUE_LENGTH, CUE_WIDTH, BALL_RADIUS -from enums.Color import BLACK, WHITE +from enums.color import BLACK, WHITE class Cue(DrawableItem): - def __init__(self, cue_ball: BaseBilliard): + def __init__(self, cue_ball: CueBall, game_data: GameData): self.__cue_ball = cue_ball self.__mouse_pos: tuple[float, float] = (0, 0) + self.__game_data = game_data pass def draw(self, window: pygame.Surface): if not self.__cue_ball: return - if self.__cue_ball.rigid_body.velocity != pymunk.Vec2d.zero(): - print(self.__cue_ball.rigid_body.velocity) + if not self.__game_data.is_stable(): return cue_ball_pos = self.__cue_ball.pos mouse_pos = pymunk.Vec2d(self.__mouse_pos[0], self.__mouse_pos[1]) diff --git a/common/game/hole.py b/common/game/hole.py index b13dba3..4f83ad4 100644 --- a/common/game/hole.py +++ b/common/game/hole.py @@ -3,14 +3,16 @@ import pymunk from common.drawableItem import DrawableItem from common.game.billiards.baseBilliard import BaseBilliard +from common.game.gameData import GameData from config.sys import HOLE_RADIUS, BALL_RADIUS -from enums.Color import GARY +from enums.color import GARY class Hole(DrawableItem): - def __init__(self, pos): + def __init__(self, pos, game_data: GameData): self.__pos = pos + self.__game_data = game_data pass def draw(self, window: pygame.Surface): @@ -20,8 +22,9 @@ class Hole(DrawableItem): for _ in balls: pos = pygame.Vector2(_.rigid_body.position.x - self.__pos[0], _.rigid_body.position.y - self.__pos[1]) if pos.length() <= HOLE_RADIUS: - _.rigid_body.position = pymunk.Vec2d(-BALL_RADIUS, -BALL_RADIUS) - space.remove(_.rigid_body) - balls.remove(_) + _.rigid_body.position = pymunk.Vec2d(99999, 99999) + _.rigid_body.velocity = pymunk.Vec2d.zero() + _.activity = False + self.__game_data.goal_balls.append(_.category) pass diff --git a/common/game/table.py b/common/game/table.py index eac1efd..164d51a 100644 --- a/common/game/table.py +++ b/common/game/table.py @@ -2,14 +2,16 @@ import pygame.draw import pymunk from common.drawableItem import DrawableItem +from common.game.gameData import GameData from common.game.hole import Hole from config.sys import * -from enums.Color import BLACK, GREEN +from enums.color import BLACK, GREEN class Table(DrawableItem): - def __init__(self): + def __init__(self, game_data: GameData): self.__size = TABLE_SIZE + self.__game_data = game_data self.__cushing_body = [ pymunk.Body(body_type=pymunk.Body.STATIC), pymunk.Body(body_type=pymunk.Body.STATIC), @@ -32,8 +34,9 @@ class Table(DrawableItem): (TABLE_WIDTH - HOLE_RADIUS, 0), 1), ] self.__holes = [ - Hole((0, 0)), Hole((TABLE_WIDTH / 2, 0)), Hole((TABLE_WIDTH, 0)), - Hole((0, TABLE_HEIGHT)), Hole((TABLE_WIDTH / 2, TABLE_HEIGHT)), Hole((TABLE_WIDTH, TABLE_HEIGHT)) + Hole((0, 0), game_data), Hole((TABLE_WIDTH / 2, 0), game_data), + Hole((TABLE_WIDTH, 0), game_data),Hole((0, TABLE_HEIGHT), game_data), + Hole((TABLE_WIDTH / 2, TABLE_HEIGHT), game_data),Hole((TABLE_WIDTH, TABLE_HEIGHT), game_data) ] for _ in self.__cushing_shape: _.elasticity = 1.0 diff --git a/config/sys.py b/config/sys.py index b2ab954..6bc52c6 100644 --- a/config/sys.py +++ b/config/sys.py @@ -2,7 +2,7 @@ BALL_RADIUS = 10.5 BALL_MASS = 5 TABLE_SIZE = (TABLE_WIDTH, TABLE_HEIGHT) = (892.25, 444.5) -HOLE_RADIUS = BALL_RADIUS * 1.8 +HOLE_RADIUS = BALL_RADIUS * 4 TABLE_LINE_WIDTH = 3 TABLE_FRICTION_FACTOR = 60 diff --git a/enums/Color.py b/enums/Color.py index 3892a3f..04cf829 100644 --- a/enums/Color.py +++ b/enums/Color.py @@ -2,3 +2,9 @@ WHITE = (255, 255, 255) BLACK = (0, 0, 0) GREEN = (0, 128, 0) GARY = (128, 128, 128) +RED = (192, 0, 0) +BLUE = (0, 0, 192) +YELLOW = (255, 255, 128) +CLAN = (64, 192, 64) +COFFEE = (192, 128, 32) +PINK = (255, 192, 255) diff --git a/enums/category.py b/enums/category.py index 0b917f4..ccdc552 100644 --- a/enums/category.py +++ b/enums/category.py @@ -1,15 +1,11 @@ -from enum import Enum - - -class Category(Enum): - CUE_BALL = 0 - RED_BALL = 1 - YELLOW_BALL = 2 - GREEN_BALL = 3 - BROWN_BALL = 4 - BLUE_BALL = 5 - PINK_BALL = 6 - BLACK_BALL = 7 - COLORED_BALLS = [_ for _ in range(2, 8)] - pass +RED_BALL = 1 +YELLOW_BALL = 2 +CLAN_BALL = 3 +COFFEE_BALL = 4 +BLUE_BALL = 5 +PINK_BALL = 6 +BLACK_BALL = 7 +CUE_BALL = 8 +BALL = 9 +COLORED_BALLS = [_ for _ in range(2, 8)] diff --git a/main.py b/main.py index 66dbe26..8d40308 100644 --- a/main.py +++ b/main.py @@ -1,76 +1,4 @@ -import pygame -import pymunk +from common.game.game import Game -from common import drawableItem -from common.game.billiards.baseBilliard import BaseBilliard -from common.game.cue import Cue -from common.game.table import Table -from config.sys import * -from enums.Color import * -from enums.category import * - - -def new_ball(space, pos): - ball = BaseBilliard(0, Category.BLACK_BALL, BLACK, pos) - body = ball.rigid_body - shape = ball.shape - space.add(body, shape) - balls.append(ball) - return shape - - -table = Table() -balls: list[BaseBilliard] = [BaseBilliard(0, Category.CUE_BALL, WHITE, (200, 150))] -cue = Cue(balls[0]) - -pygame.init() -window = pygame.display.set_mode(SCREEN_SIZE) -pygame.display.set_caption(TITLE) -clock = pygame.time.Clock() -space = pymunk.Space() -space.gravity = (0, 0) - -for _ in range(6): - space.add(table.cushing_body[_], table.cushing_shape[_]) -space.add(balls[0].rigid_body, balls[0].shape) - -force = 5 -add_force = False - -while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: - pygame.quit() - exit() - if event.type == pygame.MOUSEMOTION: - cue.mouse_pos = event.pos - if event.type == pygame.MOUSEBUTTONDOWN: - if event.button == 1: - add_force = True - if event.type == pygame.MOUSEBUTTONUP: - if event.button == 1: - pos_x = event.pos[0] - (SCREEN_WIDTH - TABLE_WIDTH) / 2 - pos_y = event.pos[1] - (SCREEN_HEIGHT - TABLE_HEIGHT) / 2 - balls[0].rigid_body.velocity = pymunk.Vec2d(pos_x - balls[0].rigid_body.position.x, - pos_y - balls[0].rigid_body.position.y).scale_to_length(force) - add_force = False - force = 5 - if event.button == 3: - pos_x = event.pos[0] - (SCREEN_WIDTH - TABLE_WIDTH) / 2 - pos_y = event.pos[1] - (SCREEN_HEIGHT - TABLE_HEIGHT) / 2 - new_ball(space, (pos_x, pos_y)) - # balls[0].rigid_body.velocity = (256, 0) - if add_force: - force += 5 - if force >= 512: - force = 512 - window.fill(WHITE) - table.goal(space, balls) - table.draw(window) - cue.draw(window) - for _ in balls: - _.resistance() - _.draw(window) - space.step(1 / FPS) - pygame.display.update() - clock.tick(FPS) +game = Game() +game.start()