diff --git a/assets/image/grid/background.png b/assets/image/grid/background.png new file mode 100644 index 0000000..44a705b Binary files /dev/null and b/assets/image/grid/background.png differ diff --git a/assets/image/boat/body.png b/assets/image/grid/boat/body.png similarity index 100% rename from assets/image/boat/body.png rename to assets/image/grid/boat/body.png diff --git a/assets/image/boat/broken.png b/assets/image/grid/boat/broken.png similarity index 100% rename from assets/image/boat/broken.png rename to assets/image/grid/boat/broken.png diff --git a/assets/image/boat/edge.png b/assets/image/grid/boat/edge.png similarity index 100% rename from assets/image/boat/edge.png rename to assets/image/grid/boat/edge.png diff --git a/assets/image/bomb/animation/bomb_anim_i1.png b/assets/image/grid/bomb/animation/bomb_anim_i1.png similarity index 100% rename from assets/image/bomb/animation/bomb_anim_i1.png rename to assets/image/grid/bomb/animation/bomb_anim_i1.png diff --git a/assets/image/bomb/animation/bomb_anim_i10.png b/assets/image/grid/bomb/animation/bomb_anim_i10.png similarity index 100% rename from assets/image/bomb/animation/bomb_anim_i10.png rename to assets/image/grid/bomb/animation/bomb_anim_i10.png diff --git a/assets/image/bomb/animation/bomb_anim_i11.png b/assets/image/grid/bomb/animation/bomb_anim_i11.png similarity index 100% rename from assets/image/bomb/animation/bomb_anim_i11.png rename to assets/image/grid/bomb/animation/bomb_anim_i11.png diff --git a/assets/image/bomb/animation/bomb_anim_i12.png b/assets/image/grid/bomb/animation/bomb_anim_i12.png similarity index 100% rename from assets/image/bomb/animation/bomb_anim_i12.png rename to assets/image/grid/bomb/animation/bomb_anim_i12.png diff --git a/assets/image/bomb/animation/bomb_anim_i13.png b/assets/image/grid/bomb/animation/bomb_anim_i13.png similarity index 100% rename from assets/image/bomb/animation/bomb_anim_i13.png rename to assets/image/grid/bomb/animation/bomb_anim_i13.png diff --git a/assets/image/bomb/animation/bomb_anim_i14.png b/assets/image/grid/bomb/animation/bomb_anim_i14.png similarity index 100% rename from assets/image/bomb/animation/bomb_anim_i14.png rename to assets/image/grid/bomb/animation/bomb_anim_i14.png diff --git a/assets/image/bomb/animation/bomb_anim_i15.png b/assets/image/grid/bomb/animation/bomb_anim_i15.png similarity index 100% rename from assets/image/bomb/animation/bomb_anim_i15.png rename to assets/image/grid/bomb/animation/bomb_anim_i15.png diff --git a/assets/image/bomb/animation/bomb_anim_i16.png b/assets/image/grid/bomb/animation/bomb_anim_i16.png similarity index 100% rename from assets/image/bomb/animation/bomb_anim_i16.png rename to assets/image/grid/bomb/animation/bomb_anim_i16.png diff --git a/assets/image/bomb/animation/bomb_anim_i17.png b/assets/image/grid/bomb/animation/bomb_anim_i17.png similarity index 100% rename from assets/image/bomb/animation/bomb_anim_i17.png rename to assets/image/grid/bomb/animation/bomb_anim_i17.png diff --git a/assets/image/bomb/animation/bomb_anim_i18.png b/assets/image/grid/bomb/animation/bomb_anim_i18.png similarity index 100% rename from assets/image/bomb/animation/bomb_anim_i18.png rename to assets/image/grid/bomb/animation/bomb_anim_i18.png diff --git a/assets/image/bomb/animation/bomb_anim_i19.png b/assets/image/grid/bomb/animation/bomb_anim_i19.png similarity index 100% rename from assets/image/bomb/animation/bomb_anim_i19.png rename to assets/image/grid/bomb/animation/bomb_anim_i19.png diff --git a/assets/image/bomb/animation/bomb_anim_i2.png b/assets/image/grid/bomb/animation/bomb_anim_i2.png similarity index 100% rename from assets/image/bomb/animation/bomb_anim_i2.png rename to assets/image/grid/bomb/animation/bomb_anim_i2.png diff --git a/assets/image/bomb/animation/bomb_anim_i20.png b/assets/image/grid/bomb/animation/bomb_anim_i20.png similarity index 100% rename from assets/image/bomb/animation/bomb_anim_i20.png rename to assets/image/grid/bomb/animation/bomb_anim_i20.png diff --git a/assets/image/bomb/animation/bomb_anim_i21.png b/assets/image/grid/bomb/animation/bomb_anim_i21.png similarity index 100% rename from assets/image/bomb/animation/bomb_anim_i21.png rename to assets/image/grid/bomb/animation/bomb_anim_i21.png diff --git a/assets/image/bomb/animation/bomb_anim_i22.png b/assets/image/grid/bomb/animation/bomb_anim_i22.png similarity index 100% rename from assets/image/bomb/animation/bomb_anim_i22.png rename to assets/image/grid/bomb/animation/bomb_anim_i22.png diff --git a/assets/image/bomb/animation/bomb_anim_i23.png b/assets/image/grid/bomb/animation/bomb_anim_i23.png similarity index 100% rename from assets/image/bomb/animation/bomb_anim_i23.png rename to assets/image/grid/bomb/animation/bomb_anim_i23.png diff --git a/assets/image/bomb/animation/bomb_anim_i3.png b/assets/image/grid/bomb/animation/bomb_anim_i3.png similarity index 100% rename from assets/image/bomb/animation/bomb_anim_i3.png rename to assets/image/grid/bomb/animation/bomb_anim_i3.png diff --git a/assets/image/bomb/animation/bomb_anim_i4.png b/assets/image/grid/bomb/animation/bomb_anim_i4.png similarity index 100% rename from assets/image/bomb/animation/bomb_anim_i4.png rename to assets/image/grid/bomb/animation/bomb_anim_i4.png diff --git a/assets/image/bomb/animation/bomb_anim_i5.png b/assets/image/grid/bomb/animation/bomb_anim_i5.png similarity index 100% rename from assets/image/bomb/animation/bomb_anim_i5.png rename to assets/image/grid/bomb/animation/bomb_anim_i5.png diff --git a/assets/image/bomb/animation/bomb_anim_i6.png b/assets/image/grid/bomb/animation/bomb_anim_i6.png similarity index 100% rename from assets/image/bomb/animation/bomb_anim_i6.png rename to assets/image/grid/bomb/animation/bomb_anim_i6.png diff --git a/assets/image/bomb/animation/bomb_anim_i7.png b/assets/image/grid/bomb/animation/bomb_anim_i7.png similarity index 100% rename from assets/image/bomb/animation/bomb_anim_i7.png rename to assets/image/grid/bomb/animation/bomb_anim_i7.png diff --git a/assets/image/bomb/animation/bomb_anim_i8.png b/assets/image/grid/bomb/animation/bomb_anim_i8.png similarity index 100% rename from assets/image/bomb/animation/bomb_anim_i8.png rename to assets/image/grid/bomb/animation/bomb_anim_i8.png diff --git a/assets/image/bomb/animation/bomb_anim_i9.png b/assets/image/grid/bomb/animation/bomb_anim_i9.png similarity index 100% rename from assets/image/bomb/animation/bomb_anim_i9.png rename to assets/image/grid/bomb/animation/bomb_anim_i9.png diff --git a/assets/image/bomb/missed.png b/assets/image/grid/bomb/missed.png similarity index 100% rename from assets/image/bomb/missed.png rename to assets/image/grid/bomb/missed.png diff --git a/assets/image/bomb/touched.png b/assets/image/grid/bomb/touched.png similarity index 100% rename from assets/image/bomb/touched.png rename to assets/image/grid/bomb/touched.png diff --git a/source/gui/scene/Settings.py b/source/gui/scene/Settings.py index 8964763..75d43ec 100644 --- a/source/gui/scene/Settings.py +++ b/source/gui/scene/Settings.py @@ -3,7 +3,7 @@ from typing import TYPE_CHECKING import pyglet from source.gui.scene.abc import Scene -from source.gui.widget import Checkbox, Scroller, Button +from source.gui.widget import Checkbox, Scroller, Button, GameGrid if TYPE_CHECKING: from source.gui.window import Window @@ -23,6 +23,8 @@ class Settings(Scene): texture_button_hover = pyglet.image.load("./assets/image/button/hovering.png") texture_button_click = pyglet.image.load("./assets/image/button/clicking.png") + texture_grid_background = pyglet.image.load("./assets/image/grid/background.png") + self.back = self.add_widget( Button, x=20, y=20, width=0.2, height=0.1, @@ -57,7 +59,17 @@ class Settings(Scene): text_transform=lambda value: round(value, 2), ) + self.grid = self.add_widget( + GameGrid, + + x=0.5, y=0.5, width=0.4, height=0.4, + + rows=10, columns=5, + texture_background=texture_grid_background, + ) + def on_draw(self): self.checkbox.draw() self.scroller.draw() self.back.draw() + self.grid.draw() diff --git a/source/gui/widget/GameGrid.py b/source/gui/widget/GameGrid.py new file mode 100644 index 0000000..1f6a9a1 --- /dev/null +++ b/source/gui/widget/GameGrid.py @@ -0,0 +1,106 @@ +from typing import TYPE_CHECKING + +import pyglet.shapes + +from source.gui.sprite import Sprite +from source.gui.widget.abc import BoxWidget +from source.type import Distance + + +if TYPE_CHECKING: + from source.gui.scene.abc import Scene + + +class GameGrid(BoxWidget): + def __init__(self, scene: "Scene", + + rows: int, + columns: int, + + texture_background: pyglet.image.AbstractImage, + + line_width: int = 2, + + x: Distance = 0, + y: Distance = 0, + width: Distance = None, + height: Distance = None, + + **kwargs): + super().__init__(scene, x, y, width, height) + + self._rows = rows + self._columns = columns + + self.background = Sprite(img=texture_background) + + self.lines: list[pyglet.shapes.Line] = [ + pyglet.shapes.Line(0, 0, 0, 0, width=line_width) + for _ in range((self._columns - 1) + (self._rows - 1)) + ] + + self.cursor = pyglet.shapes.Rectangle(0, 0, 0, 0, color=(0, 0, 0, 100)) + + self._refresh_size() + + def get_cell_from_rel(self, rel_x: int, rel_y: int) -> tuple[int, int]: + """ + Return the cell of the grid from a point relative position + """ + + return int(rel_x / self.cell_width), int(rel_y / self.cell_height) + + # refresh + + def _refresh_size(self): + self.background.x, self.background.y = self.x, self.y + self.background.width, self.background.height = self.width, self.height + + for column, line in enumerate(self.lines[:self._columns-1], start=1): + line.x = self.x + self.cell_width * column + line.x2 = line.x + line.y = self.y + line.y2 = self.y + self.height + + for row, line in enumerate(self.lines[-self._rows+1:], start=1): + line.x = self.x + line.x2 = self.x + self.width + line.y = self.y + self.cell_height * row + line.y2 = line.y + + # property + + @property + def cell_width(self) -> float: + return self.width / self._columns + + @property + def cell_height(self) -> float: + return self.height / self._rows + + @property + def cell_size(self) -> tuple[float, float]: + return self.cell_width, self.cell_height + + # event + + def on_hover(self, rel_x: int, rel_y: int): + cell_x, cell_y = self.get_cell_from_rel(rel_x, rel_y) + + self.cursor.x = self.x + cell_x * self.width / self._columns + self.cursor.y = self.y + cell_y * self.height / self._rows + self.cursor.width, self.cursor.height = self.cell_size + + def on_hover_leave(self, rel_x: int, rel_y: int): + self.cursor.width, self.cursor.height = 0, 0 + + def on_release(self, rel_x: int, rel_y: int, button: int, modifiers: int): + print("click", (rel_x, rel_y), self.get_cell_from_rel(rel_x, rel_y)) + + def on_resize(self, width: int, height: int): + self._refresh_size() + + def draw(self): + self.background.draw() + self.cursor.draw() + for line in self.lines: line.draw() diff --git a/source/gui/widget/Scroller.py b/source/gui/widget/Scroller.py index 12cdfde..1272d32 100644 --- a/source/gui/widget/Scroller.py +++ b/source/gui/widget/Scroller.py @@ -26,7 +26,7 @@ class Scroller(BoxWidget): value: float = 0.5, to: float = 1, - cursor_width: Percentage = 0.1, + cursor_width: Distance = 0.1, text_transform: Callable[[float], Any] = lambda value: value, **kwargs): diff --git a/source/gui/widget/__init__.py b/source/gui/widget/__init__.py index 096854d..4b98369 100644 --- a/source/gui/widget/__init__.py +++ b/source/gui/widget/__init__.py @@ -4,3 +4,4 @@ from .Input import Input from .Image import Image from .Checkbox import Checkbox from .Scroller import Scroller +from .GameGrid import GameGrid diff --git a/source/gui/widget/abc/BoxWidget.py b/source/gui/widget/abc/BoxWidget.py index ddca25c..1cf53cc 100644 --- a/source/gui/widget/abc/BoxWidget.py +++ b/source/gui/widget/abc/BoxWidget.py @@ -133,16 +133,26 @@ class BoxWidget(Widget, ABC): old_hovering = self.hovering self.hovering = in_bbox((x, y), self.bbox) - if old_hovering != self.hovering: # if the hover changed - if self.hovering: self.on_hover_enter() # call the hover enter event - else: self.on_hover_leave() # call the hover leave event + rel_x, rel_y = x - self.x, y - self.y - def on_hover_enter(self): + if old_hovering != self.hovering: # if the hover changed + if self.hovering: self.on_hover_enter(rel_x, rel_y) # call the hover enter event + else: self.on_hover_leave(rel_x, rel_y) # call the hover leave event + + if self.hovering: # if the mouse motion is inside the collision + self.on_hover(rel_x, rel_y) # call the hover event + + def on_hover(self, rel_x: int, rel_y: int): + """ + This event is called when the mouse move in the bbox of the widget + """ + + def on_hover_enter(self, rel_x: int, rel_y: int): """ This event is called when the mouse enter the bbox of the widget """ - def on_hover_leave(self): + def on_hover_leave(self, rel_x: int, rel_y: int): """ This event is called when the mouse leave the bbox of the widget """