Compare commits
No commits in common. "bd06c21a38efae2155823a0dad385c27a3c0bc22" and "48b66bbded621afe13f7444d80b1290be1685823" have entirely different histories.
bd06c21a38
...
48b66bbded
|
|
@ -138,9 +138,3 @@ dmypy.json
|
||||||
# Cython debug symbols
|
# Cython debug symbols
|
||||||
cython_debug/
|
cython_debug/
|
||||||
|
|
||||||
|
|
||||||
*_creations/
|
|
||||||
*.exe
|
|
||||||
*.zip
|
|
||||||
*.csv
|
|
||||||
*.txt
|
|
||||||
|
|
|
||||||
61
README.md
61
README.md
|
|
@ -1,61 +1,2 @@
|
||||||
# Devine-dessin
|
# Devinddessin
|
||||||
|
|
||||||
Jeu permettant de dessiner un mot choisi au hasard dans une liste.
|
|
||||||
|
|
||||||
Tant que le jeu n'est pas quitté, les mots de la liste ne sont pas proposé à nouveau.
|
|
||||||
|
|
||||||
## Liste de mot
|
|
||||||
|
|
||||||
La liste de mot peut être au format texte brut, avec un mot par ligne, ou au format CSV.
|
|
||||||
|
|
||||||
Si la liste est au format CSV, la première colonne doit contenir le mot à dessiner, et la seconde colonne peut contenir un indice.
|
|
||||||
Les colonnes du fichier CSV ne doivent pas avoir de titre.
|
|
||||||
|
|
||||||
Par défaut, le jeu cherche une liste dans un fichier du dossier courant nommé `mots.csv`.
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
Le jeu n'est pour l'instant pas packagé.
|
|
||||||
Pour le lancer:
|
|
||||||
|
|
||||||
- Construire une liste de mot comme présenté plus haut
|
|
||||||
- Créer un venv : `python -m venv <path_to_venv>`
|
|
||||||
- Activer le venv : `. <path_to_venv>/bin/activate`
|
|
||||||
- Installer les dépendances : `pip install -r requirements.txt`
|
|
||||||
- Récupérer le fichier `guess_what_I_draw.py`
|
|
||||||
- Lancer le jeu en exécutant le fichier.
|
|
||||||
|
|
||||||
|
|
||||||
## Contrôles:
|
|
||||||
|
|
||||||
### Tout le temps:
|
|
||||||
- **`Échap` :** Quitter le jeu immédiatement
|
|
||||||
|
|
||||||
### Quand le jeu n'est pas lancé:
|
|
||||||
- **`c`:** Ouvrir le menu de configuration
|
|
||||||
- **`Espace` :** Lancer la manche
|
|
||||||
|
|
||||||
### Quand le jeu est en cours:
|
|
||||||
- **Clic gauche** dans la zone de dessin : dessiner
|
|
||||||
- **`Ctrl + z` :** Annuler le dernier trait
|
|
||||||
- **`Entrer` :** Passer le mot en cours (une pénalité de temps est appliquée)
|
|
||||||
- **`Espace` :** Valider le mot en cours comme "trouvé"
|
|
||||||
- **`p` :** Activer/Désactiver la pause.
|
|
||||||
|
|
||||||
### Quand la manche est écoulée:
|
|
||||||
Le menu de récapitulation est affiché.
|
|
||||||
- **`Backspace` :** Passer au tour suivant
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
Dans le menu de configuration, il est possible de configurer :
|
|
||||||
- Le chemin vers la liste de mot ;
|
|
||||||
- La durée d'une manche ;
|
|
||||||
- Le temps de pénalité appliqué pour chaque mot passé.
|
|
||||||
|
|
||||||
Une fois la configuration effectuée, vous pouvez l'appliquer en cliquant en dehors de la pop-up du menu
|
|
||||||
|
|
||||||
|
|
||||||
## Dessins
|
|
||||||
Les dessins sont sauvegardés pour la postérité dans un dossier créé dans le répertoire courant, nommé `<date au format iso>T<heure-minutes>_creations`.
|
|
||||||
|
|
||||||
Le nom des fichiers de dessin sont au format `round-<i>_<mot à deviner>.png`, avec `i` le numéro de la manche.
|
|
||||||
|
|
|
||||||
|
|
@ -1,473 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
import re
|
|
||||||
import os
|
|
||||||
import csv
|
|
||||||
from random import random, randint, choice
|
|
||||||
from datetime import timedelta, datetime
|
|
||||||
from kivy.app import App
|
|
||||||
from kivy.uix.widget import Widget
|
|
||||||
from kivy.uix.button import Button, ButtonBehavior
|
|
||||||
from kivy.uix.label import Label
|
|
||||||
from kivy.graphics import Color, Ellipse, Line, Rectangle
|
|
||||||
from kivy.core.window import Window
|
|
||||||
from kivy.uix.boxlayout import BoxLayout
|
|
||||||
from kivy.uix.gridlayout import GridLayout
|
|
||||||
from kivy.clock import Clock
|
|
||||||
from kivy.uix.popup import Popup
|
|
||||||
from kivy.uix.colorpicker import ColorPicker
|
|
||||||
from kivy.uix.scrollview import ScrollView
|
|
||||||
from kivy.properties import StringProperty, BooleanProperty
|
|
||||||
from kivy.lang import Builder
|
|
||||||
from kivy.uix.textinput import TextInput
|
|
||||||
|
|
||||||
PASS_PENALTY = 4
|
|
||||||
DRAWING_TIME = 60
|
|
||||||
WORDS_FILE = "mots.csv"
|
|
||||||
|
|
||||||
Builder.load_string('''
|
|
||||||
<ScrollableLabel>:
|
|
||||||
Label:
|
|
||||||
size_hint_y: None
|
|
||||||
height: self.texture_size[1]
|
|
||||||
text_size: self.width, None
|
|
||||||
text: root.text
|
|
||||||
markup: root.markup
|
|
||||||
''')
|
|
||||||
|
|
||||||
class ScrollableLabel(ScrollView):
|
|
||||||
text = StringProperty('')
|
|
||||||
markup = BooleanProperty(False)
|
|
||||||
|
|
||||||
|
|
||||||
class NumberInput(TextInput):
|
|
||||||
def __init__(self, init_value, **kwargs):
|
|
||||||
self.init_value = init_value
|
|
||||||
kwargs["text"] = str(init_value)
|
|
||||||
super().__init__(**kwargs)
|
|
||||||
|
|
||||||
pat = r"^[0-9]+$"
|
|
||||||
def insert_text(self, substring, from_undo=False):
|
|
||||||
if not re.match(self.pat, substring):
|
|
||||||
s=''
|
|
||||||
else:
|
|
||||||
s = substring
|
|
||||||
super().insert_text(s, from_undo=from_undo)
|
|
||||||
|
|
||||||
class MyPaintWidget(Label):
|
|
||||||
_game_state = {"game_started": False,
|
|
||||||
"game_paused": False,
|
|
||||||
"game_finished": False,
|
|
||||||
"word passed": timedelta(0),
|
|
||||||
"word found": timedelta(0)
|
|
||||||
}
|
|
||||||
_game_wordlists = {"possible_wordlist": dict(),
|
|
||||||
"found_words": set(),
|
|
||||||
"unfound_words": set()
|
|
||||||
}
|
|
||||||
pen_characteristics = {"current_color": (0,0,0,1),
|
|
||||||
"current_width": 4
|
|
||||||
}
|
|
||||||
bg = None
|
|
||||||
current_round = 0
|
|
||||||
current_word = ""
|
|
||||||
message_label = None
|
|
||||||
time = timedelta(seconds=DRAWING_TIME)
|
|
||||||
_popup = None
|
|
||||||
|
|
||||||
def __init__(self, text="", **kwargs):
|
|
||||||
super().__init__(**kwargs)
|
|
||||||
self._keyboard = None
|
|
||||||
|
|
||||||
self._load_words()
|
|
||||||
with self.canvas.before:
|
|
||||||
Color(1,1,1, mode='rgb')
|
|
||||||
self.bg = Rectangle(pos=self.pos, size=self.size)
|
|
||||||
def resize_bg(self, obj):
|
|
||||||
self.bg.size = self.size
|
|
||||||
self.bg.pos = self.pos
|
|
||||||
self.bind(size=resize_bg, pos=resize_bg)
|
|
||||||
|
|
||||||
self._get_keyboard()
|
|
||||||
self._output_dir = datetime.now().isoformat(timespec='minutes').replace(":","-") + "_creations"
|
|
||||||
self._fullscreen = False
|
|
||||||
self.reset_game()
|
|
||||||
|
|
||||||
def _load_words(self):
|
|
||||||
try:
|
|
||||||
if WORDS_FILE.endswith(".csv"):
|
|
||||||
# read a CSV file
|
|
||||||
with open(WORDS_FILE, "r", newline='', encoding="utf-8") as wordfile:
|
|
||||||
my_reader = csv.reader(wordfile)
|
|
||||||
self._game_wordlists["possible_wordlist"] = {line[0]:
|
|
||||||
line[1] for line in my_reader}
|
|
||||||
else:
|
|
||||||
# read a plain text file
|
|
||||||
with open(WORDS_FILE, "r", encoding="utf-8") as wordfile:
|
|
||||||
self._wordlist = (word.strip() for word in wordfile.readlines())
|
|
||||||
self._game_wordlists["possible_wordlist"] = dict.fromkeys(self._wordlist)
|
|
||||||
except OSError:
|
|
||||||
errmsg = f"Erreur de lecture du fichier '{WORDS_FILE}'"
|
|
||||||
if self.bg:
|
|
||||||
Popup(title="Error", content=Label(text=errmsg)).open()
|
|
||||||
else:
|
|
||||||
print(errmsg)
|
|
||||||
self._game_wordlists["possible_wordlist"] = dict()
|
|
||||||
|
|
||||||
|
|
||||||
def _get_keyboard(self):
|
|
||||||
if self._keyboard is None:
|
|
||||||
self._keyboard = Window.request_keyboard(
|
|
||||||
self._keyboard_closed, self, 'text')
|
|
||||||
if self._keyboard.widget:
|
|
||||||
# If it exists, this widget is a VKeyboard object which you can use
|
|
||||||
# to change the keyboard layout.
|
|
||||||
pass
|
|
||||||
self._keyboard.bind(on_key_down=self._on_keyboard_down)
|
|
||||||
|
|
||||||
def _keyboard_closed(self):
|
|
||||||
print('My keyboard has been closed!')
|
|
||||||
self._keyboard.unbind(on_key_down=self._on_keyboard_down)
|
|
||||||
self._keyboard = None
|
|
||||||
|
|
||||||
def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
|
|
||||||
print('The key', keycode, 'have been pressed')
|
|
||||||
print(' - text is %r' % text)
|
|
||||||
print(' - modifiers are %r' % modifiers)
|
|
||||||
if not self._game_state["game_started"]:
|
|
||||||
if keycode[0] == 32:
|
|
||||||
self.start_game()
|
|
||||||
elif keycode[1] == 'c':
|
|
||||||
self.open_config()
|
|
||||||
|
|
||||||
elif keycode[1] == 'p':
|
|
||||||
self.toggle_pause()
|
|
||||||
|
|
||||||
elif self.is_game_playing:
|
|
||||||
if keycode[0] == 32:
|
|
||||||
self.next_word()
|
|
||||||
elif keycode[0] == 13:
|
|
||||||
self.pass_word()
|
|
||||||
elif keycode[1] == 'z' and "ctrl" in modifiers:
|
|
||||||
if self.canvas.after.children:
|
|
||||||
self.canvas.after.remove(self.canvas.after.children[-1])
|
|
||||||
self.canvas.after.remove(self.canvas.after.children[-1])
|
|
||||||
self.canvas.after.remove(self.canvas.after.children[-1])
|
|
||||||
elif self._game_state["game_finished"]:
|
|
||||||
if keycode[0] == 8:
|
|
||||||
self.reset_game()
|
|
||||||
|
|
||||||
if keycode[0] == 292:
|
|
||||||
print(Window.fullscreen)
|
|
||||||
if self._fullscreen:
|
|
||||||
Window.fullscreen = False
|
|
||||||
else:
|
|
||||||
Window.fullscreen = "auto"
|
|
||||||
self._fullscreen = not self._fullscreen
|
|
||||||
|
|
||||||
# Keycode is composed of an integer + a string
|
|
||||||
# If we hit escape, let the input through to leave the app
|
|
||||||
if keycode[1] == 'escape':
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Return True to accept the key. Otherwise, it will be used by
|
|
||||||
# the system.
|
|
||||||
return True
|
|
||||||
|
|
||||||
def toggle_pause(self):
|
|
||||||
self._game_state["game_paused"] = not self._game_state["game_paused"]
|
|
||||||
|
|
||||||
def start_game(self):
|
|
||||||
self.text=""
|
|
||||||
self._game_state["game_started"] = True
|
|
||||||
self._game_state["game_paused"] = False
|
|
||||||
self.current_round += 1
|
|
||||||
self.next_word(True)
|
|
||||||
|
|
||||||
def next_word(self, passed=False):
|
|
||||||
if not passed:
|
|
||||||
self._game_wordlists["found_words"].add(self.current_word)
|
|
||||||
if self.message_label and self.current_word:
|
|
||||||
if passed:
|
|
||||||
self.message_label.color = '#FF2A40'
|
|
||||||
self.message_label.text = f'"{self.current_word}" a été passé !'
|
|
||||||
else:
|
|
||||||
self.message_label.color = '#5BB834'
|
|
||||||
self.message_label.text = f'"{self.current_word}" a été trouvé !'
|
|
||||||
if not self._game_wordlists["possible_wordlist"]:
|
|
||||||
self.time = timedelta(0)
|
|
||||||
return
|
|
||||||
self.save_frame()
|
|
||||||
self.current_word = choice(list(self._game_wordlists["possible_wordlist"]))
|
|
||||||
value = self._game_wordlists["possible_wordlist"].pop(self.current_word)
|
|
||||||
if value:
|
|
||||||
self.message_label.text += '\n'+f'Le prochain mot est de type: {value}'
|
|
||||||
|
|
||||||
self.clear_drawing()
|
|
||||||
|
|
||||||
def pass_word(self):
|
|
||||||
self._game_wordlists["unfound_words"].add(self.current_word)
|
|
||||||
self.next_word(True)
|
|
||||||
if self.time - timedelta(seconds=PASS_PENALTY) > timedelta(0):
|
|
||||||
self.time -= timedelta(seconds=PASS_PENALTY)
|
|
||||||
else:
|
|
||||||
self.time = timedelta(0)
|
|
||||||
|
|
||||||
def save_frame(self):
|
|
||||||
if self.current_word:
|
|
||||||
if not os.path.isdir(self._output_dir):
|
|
||||||
os.mkdir(self._output_dir)
|
|
||||||
filename = os.path.join(self._output_dir,
|
|
||||||
f"round-{self.current_round}_" + os.path.normcase(self.current_word) + ".png")
|
|
||||||
self.export_to_png(filename)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_game_playing(self):
|
|
||||||
return (self._game_state["game_started"]
|
|
||||||
and not self._game_state["game_paused"]
|
|
||||||
and not self._game_state["game_finished"])
|
|
||||||
|
|
||||||
@property
|
|
||||||
def current_color(self):
|
|
||||||
return self.pen_characteristics["current_color"]
|
|
||||||
|
|
||||||
def on_touch_down(self, touch):
|
|
||||||
if self.is_game_playing:
|
|
||||||
with self.canvas.after:
|
|
||||||
if self.collide_point(touch.x, touch.y):
|
|
||||||
Color(*self.pen_characteristics["current_color"], mode='rgba')
|
|
||||||
diameter = self.pen_characteristics["current_width"]
|
|
||||||
Ellipse(pos=(touch.x - diameter / 2, touch.y - diameter / 2),
|
|
||||||
size=(2*diameter, 2*diameter))
|
|
||||||
touch.ud['line'] = Line(points=(touch.x, touch.y), width=diameter)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def on_touch_move(self, touch):
|
|
||||||
if self.is_game_playing:
|
|
||||||
if 'line' in touch.ud:
|
|
||||||
if self.collide_point(touch.x, touch.y):
|
|
||||||
touch.ud['line'].points += [touch.x, touch.y]
|
|
||||||
elif self.collide_point(touch.ud['line'].points[-2], touch.y):
|
|
||||||
touch.ud['line'].points += [touch.ud['line'].points[-2], touch.y]
|
|
||||||
elif self.collide_point(touch.x, touch.ud['line'].points[-1]):
|
|
||||||
touch.ud['line'].points += [touch.x, touch.ud['line'].points[-1]]
|
|
||||||
|
|
||||||
def open_config(self):
|
|
||||||
layout = GridLayout()
|
|
||||||
layout.cols=2
|
|
||||||
layout.add_widget(Label(text="Chemin vers la liste de mots"))
|
|
||||||
layout.add_widget(TextInput(text=WORDS_FILE, multiline=False))
|
|
||||||
layout.add_widget(Label(text="Temps de dessin\n(secondes"))
|
|
||||||
layout.add_widget(NumberInput(DRAWING_TIME, multiline=False))
|
|
||||||
layout.add_widget(Label(text="Temps de pénalité\nquand on passe\n(secondes)"))
|
|
||||||
layout.add_widget(NumberInput(PASS_PENALTY, multiline=False))
|
|
||||||
conf_popup = Popup(title='Configuration', content=layout, size_hint=(0.5, 0.5))
|
|
||||||
conf_popup.bind(on_dismiss=self.apply_conf)
|
|
||||||
conf_popup.open()
|
|
||||||
|
|
||||||
def apply_conf(self, obj):
|
|
||||||
global DRAWING_TIME
|
|
||||||
global PASS_PENALTY
|
|
||||||
global WORDS_FILE
|
|
||||||
try:
|
|
||||||
drawing_time = int(obj.content.children[2].text)
|
|
||||||
if drawing_time > 0:
|
|
||||||
DRAWING_TIME = drawing_time
|
|
||||||
except ValueError:
|
|
||||||
Popup(title="Error", content=Label(text="Mauvaise valeur pour temps de dessin")).open()
|
|
||||||
try:
|
|
||||||
pass_penalty = int(obj.content.children[0].text)
|
|
||||||
if pass_penalty > 0 and pass_penalty < drawing_time:
|
|
||||||
PASS_PENALTY = pass_penalty
|
|
||||||
except ValueError:
|
|
||||||
Popup(title="Error", content=Label(text="Mauvaise valeur pour pénalité")).open()
|
|
||||||
self.reset_game()
|
|
||||||
if obj.content.children[4].text != WORDS_FILE:
|
|
||||||
old_file = WORDS_FILE
|
|
||||||
WORDS_FILE = obj.content.children[4].text
|
|
||||||
try:
|
|
||||||
self._load_words()
|
|
||||||
except OSError:
|
|
||||||
Popup(title="Error", content=Label(text=f"Erreur de lecture du fichier '{WORDS_FILE}'")).open()
|
|
||||||
WORDS_FILE = old_file
|
|
||||||
self._get_keyboard()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def recap(self):
|
|
||||||
found_words = self._game_wordlists['found_words']
|
|
||||||
unfound_words =self._game_wordlists['unfound_words']
|
|
||||||
lines = ["[b]Tour terminé ![/b]\n"+
|
|
||||||
f"Trouvés: [color=#5BB834]{len(found_words)}[/color]",
|
|
||||||
"-"+ "\n-".join(found_words) if found_words else "",
|
|
||||||
f"Passés: [color=#FF2A40]{len(unfound_words)}[/color]",
|
|
||||||
"- "+ "\n- ".join(unfound_words) if unfound_words else ""]
|
|
||||||
self.save_frame()
|
|
||||||
self.clear_drawing()
|
|
||||||
self._popup = Popup(title='Fini !',
|
|
||||||
content=ScrollableLabel(text="[size=24]"+"\n".join(lines)+"[/size]",
|
|
||||||
markup=True),
|
|
||||||
size_hint=(0.6,0.6),
|
|
||||||
auto_dismiss=False)
|
|
||||||
self._popup.open()
|
|
||||||
|
|
||||||
def game_finished(self):
|
|
||||||
self._game_state["game_finished"] = True
|
|
||||||
self.recap()
|
|
||||||
|
|
||||||
def reset_game(self):
|
|
||||||
if self._popup:
|
|
||||||
self._popup.dismiss()
|
|
||||||
if self.message_label:
|
|
||||||
self.message_label.text = ""
|
|
||||||
self.color = (0,0,0,1)
|
|
||||||
self.text = "Appuyer sur 'espace' pour commencer à jouer"
|
|
||||||
self.current_word = ""
|
|
||||||
self._game_wordlists["found_words"] = set()
|
|
||||||
self._game_wordlists["unfound_words"] = set()
|
|
||||||
|
|
||||||
self.time = timedelta(seconds=DRAWING_TIME)
|
|
||||||
self._game_state["game_finished"] = False
|
|
||||||
self._game_state["game_started"] = False
|
|
||||||
|
|
||||||
def clear_drawing(self):
|
|
||||||
self.canvas.after.clear()
|
|
||||||
|
|
||||||
class SizeButton(ButtonBehavior, Widget):
|
|
||||||
def __init__(self, callback, size=1, **kwargs):
|
|
||||||
super().__init__(**kwargs)
|
|
||||||
self.dot_size = size
|
|
||||||
self.callback = callback
|
|
||||||
with self.canvas:
|
|
||||||
Color(0,0,0, mode="rgb")
|
|
||||||
self.bg = Rectangle(pos=self.pos, size=self.size)
|
|
||||||
Color(1,1,1, mode="rgb")
|
|
||||||
self.dot = Ellipse(pos=(self.center_x-size/2, self.center_y-size/2),
|
|
||||||
size = (size*2, size*2))
|
|
||||||
def redraw(self, args):
|
|
||||||
self.dot.pos = (self.center_x-size/2, self.center_y-size/2)
|
|
||||||
self.bg.pos = self.pos
|
|
||||||
self.bg.size = self.size
|
|
||||||
self.bind(size=redraw, pos=redraw)
|
|
||||||
|
|
||||||
def on_release(self):
|
|
||||||
self.callback(self.dot_size)
|
|
||||||
|
|
||||||
class GuessWhatIDrawApp(App):
|
|
||||||
state = False
|
|
||||||
init = True
|
|
||||||
|
|
||||||
def build(self):
|
|
||||||
Window.clearcolor = (1, 1, 1, 1)
|
|
||||||
#self.init_keyboard()
|
|
||||||
parent = BoxLayout(orientation='vertical')
|
|
||||||
|
|
||||||
self.painter = MyPaintWidget(size_hint=(0.9, 1))
|
|
||||||
Clock.schedule_interval(self.update_time, 1.0/10.0)
|
|
||||||
clearbtn = Button(text='Clear')
|
|
||||||
clearbtn.bind(on_release=self.clear_canvas)
|
|
||||||
togglebtn = Button(text='Inverser la couleur du fond')
|
|
||||||
togglebtn.bind(on_release=self.toggle_background)
|
|
||||||
|
|
||||||
self.right_row = BoxLayout(orientation="vertical", size_hint=(0.1,1))
|
|
||||||
color_picker_button = Button(text="Couleur")
|
|
||||||
color_picker_button.background_color = self.painter.pen_characteristics["current_color"]
|
|
||||||
color_picker_button.background_normal = ''
|
|
||||||
color_picker_button.bind(on_release=self.open_color_picker)
|
|
||||||
self.right_row.add_widget(color_picker_button)
|
|
||||||
for i in range(1,6):
|
|
||||||
size_button = SizeButton(self.set_cursor_size, 2*i)
|
|
||||||
self.right_row.add_widget(size_button)
|
|
||||||
|
|
||||||
middle_row = BoxLayout(orientation="horizontal", size_hint=(1, 0.75))
|
|
||||||
middle_row.add_widget(self.painter)
|
|
||||||
middle_row.add_widget(self.right_row)
|
|
||||||
|
|
||||||
bottom_row = BoxLayout(orientation='horizontal', spacing=5, size_hint=(1, .05))
|
|
||||||
bottom_row.add_widget(togglebtn)
|
|
||||||
bottom_row.add_widget(clearbtn)
|
|
||||||
|
|
||||||
top_row = BoxLayout(orientation='horizontal', spacing=5, size_hint=(1, .2))
|
|
||||||
self.word_label = Label(text="Mot:", color=[0,0,0,1], halign="left", valign="top", size_hint=(0.2,1))
|
|
||||||
def redraw(self, obj):
|
|
||||||
self.text_size = self.size
|
|
||||||
self.word_label.bind(size=redraw)
|
|
||||||
|
|
||||||
self.time_label = Label(text=f"{self.painter.time}", color=[0,0,0,1],
|
|
||||||
font_size='50pt', size_hint=(0.2,1))
|
|
||||||
message_label = Label(color=[0,0,0,1], halign="center", valign="top",
|
|
||||||
font_size='40pt', size_hint=(0.6,1))
|
|
||||||
message_label.bind(size=redraw)
|
|
||||||
top_row.add_widget(self.word_label)
|
|
||||||
top_row.add_widget(message_label)
|
|
||||||
top_row.add_widget(self.time_label)
|
|
||||||
self.painter.message_label = message_label
|
|
||||||
|
|
||||||
parent.add_widget(top_row)
|
|
||||||
parent.add_widget(middle_row)
|
|
||||||
parent.add_widget(bottom_row)
|
|
||||||
return parent
|
|
||||||
|
|
||||||
def set_cursor_size(self, size):
|
|
||||||
print(size)
|
|
||||||
self.painter.pen_characteristics["current_width"] = size
|
|
||||||
|
|
||||||
def open_color_picker(self, _):
|
|
||||||
clr_picker = ColorPicker()
|
|
||||||
clr_picker.color = self.painter.pen_characteristics["current_color"]
|
|
||||||
def on_color_change(instance, value):
|
|
||||||
self.painter.pen_characteristics["current_color"] = value
|
|
||||||
self.right_row.children[-1].background_color = self.painter.current_color
|
|
||||||
clr_picker.bind(color=on_color_change)
|
|
||||||
popup = Popup(title="Couleur du pinceau",
|
|
||||||
content=clr_picker,
|
|
||||||
size_hint=(0.5,0.5))
|
|
||||||
popup.open()
|
|
||||||
|
|
||||||
def update_time(self, _):
|
|
||||||
if self.painter.is_game_playing:
|
|
||||||
if self.painter.time > timedelta(0):
|
|
||||||
self.painter.time -= timedelta(milliseconds=100)
|
|
||||||
self.word_label.text = f"Mot: {self.painter.current_word}"
|
|
||||||
else:
|
|
||||||
self.painter.game_finished()
|
|
||||||
|
|
||||||
self.time_label.text = f"{formatTimedelta(self.painter.time)}"
|
|
||||||
|
|
||||||
def toggle_background(self, obj):
|
|
||||||
|
|
||||||
if self.state:
|
|
||||||
Window.clearcolor = (1, 1, 1, 1)
|
|
||||||
with self.painter.canvas.before:
|
|
||||||
Color(1,1,1, mode='rgb')
|
|
||||||
self.painter.bg = Rectangle(pos=self.painter.pos, size=self.painter.size)
|
|
||||||
self.painter.pen_characteristics["current_color"] = (0,0,0,1)
|
|
||||||
self.right_row.children[-1].background_color = self.painter.current_color
|
|
||||||
self.word_label.color = (0,0,0,1)
|
|
||||||
self.time_label.color = (0,0,0,1)
|
|
||||||
self.state = False
|
|
||||||
else:
|
|
||||||
Window.clearcolor = (0,0,0,1)
|
|
||||||
with self.painter.canvas.before:
|
|
||||||
Color(0,0,0, mode='rgb')
|
|
||||||
self.painter.bg = Rectangle(pos=self.painter.pos, size=self.painter.size)
|
|
||||||
self.painter.pen_characteristics["current_color"] = (1,1,1,1)
|
|
||||||
self.right_row.children[-1].background_color = self.painter.current_color
|
|
||||||
self.word_label.color = (1,1,1,1)
|
|
||||||
self.time_label.color = (1,1,1,1)
|
|
||||||
self.state = True
|
|
||||||
self.clear_canvas(obj)
|
|
||||||
|
|
||||||
def clear_canvas(self, _):
|
|
||||||
self.painter.clear_drawing()
|
|
||||||
|
|
||||||
def formatTimedelta(time:timedelta):
|
|
||||||
seconds = int(time.total_seconds())
|
|
||||||
minutes, reminder = divmod(seconds, 60)
|
|
||||||
|
|
||||||
return f"{minutes:02}:{reminder:02}.{int(time.microseconds/10000):02}"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
GuessWhatIDrawApp().run()
|
|
||||||
BIN
pictionnary.ico
BIN
pictionnary.ico
Binary file not shown.
|
Before Width: | Height: | Size: 766 B |
Loading…
Reference in New Issue