Project reorganization to use with fbs
5
.gitignore
vendored
@ -18,8 +18,7 @@ lib/
|
|||||||
lib64/
|
lib64/
|
||||||
parts/
|
parts/
|
||||||
sdist/
|
sdist/
|
||||||
Tetris2000.build/
|
target/
|
||||||
Tetris2000.build/
|
|
||||||
var/
|
var/
|
||||||
wheels/
|
wheels/
|
||||||
*.egg-info/
|
*.egg-info/
|
||||||
@ -31,7 +30,7 @@ MANIFEST
|
|||||||
# Usually these files are written by a python script from a template
|
# Usually these files are written by a python script from a template
|
||||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
*.manifest
|
*.manifest
|
||||||
#*.spec
|
*.spec
|
||||||
|
|
||||||
# Installer logs
|
# Installer logs
|
||||||
pip-log.txt
|
pip-log.txt
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
Another TETRIS® clone
|
|
||||||
Tetris Game Design by Alexey Pajitnov.
|
|
||||||
Parts of comments issued from 2009 Tetris Design Guideline
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
import sys
|
|
||||||
from qtpy import QtWidgets
|
|
||||||
|
|
||||||
from source.game_gui import Window
|
|
||||||
|
|
||||||
|
|
||||||
app = QtWidgets.QApplication.instance() or QtWidgets.QApplication(sys.argv)
|
|
||||||
win = Window()
|
|
||||||
win.show()
|
|
||||||
win.frames.new_game()
|
|
||||||
sys.exit(app.exec_())
|
|
@ -1,43 +0,0 @@
|
|||||||
# -*- mode: python -*-
|
|
||||||
|
|
||||||
block_cipher = None
|
|
||||||
|
|
||||||
|
|
||||||
a = Analysis(['TETRIS2000.py'],
|
|
||||||
pathex=[],
|
|
||||||
binaries=[],
|
|
||||||
datas=[
|
|
||||||
("backgrounds/*", "backgrounds"),
|
|
||||||
("fonts/*.ttf", "fonts"),
|
|
||||||
("fonts/*.otf", "fonts"),
|
|
||||||
("icons/*.ico", "icons"),
|
|
||||||
("icons/splash_screen.png", "icons"),
|
|
||||||
("locale/*.qm", "locale"),
|
|
||||||
("musics/*.mp3", "musics"),
|
|
||||||
("sfx/*.wav", "sfx")
|
|
||||||
],
|
|
||||||
hiddenimports=[],
|
|
||||||
hookspath=[],
|
|
||||||
runtime_hooks=[],
|
|
||||||
excludes=["PyQt4", "PySide", "PySide2"],
|
|
||||||
win_no_prefer_redirects=False,
|
|
||||||
win_private_assemblies=False,
|
|
||||||
cipher=block_cipher)
|
|
||||||
pyz = PYZ(a.pure, a.zipped_data,
|
|
||||||
cipher=block_cipher)
|
|
||||||
exe = EXE(pyz,
|
|
||||||
a.scripts,
|
|
||||||
exclude_binaries=True,
|
|
||||||
name='TETRIS2000',
|
|
||||||
debug=False,
|
|
||||||
strip=False,
|
|
||||||
upx=False,
|
|
||||||
console=False,
|
|
||||||
icon='icons\icon.ico')
|
|
||||||
coll = COLLECT(exe,
|
|
||||||
a.binaries,
|
|
||||||
a.zipfiles,
|
|
||||||
a.datas,
|
|
||||||
strip=False,
|
|
||||||
upx=False,
|
|
||||||
name='TETRIS2000')
|
|
101
src/main/NSIS/Installer.nsi
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
!include MUI2.nsh
|
||||||
|
!include FileFunc.nsh
|
||||||
|
|
||||||
|
;--------------------------------
|
||||||
|
;Perform Machine-level install, if possible
|
||||||
|
|
||||||
|
!define MULTIUSER_EXECUTIONLEVEL Highest
|
||||||
|
;Add support for command-line args that let uninstaller know whether to
|
||||||
|
;uninstall machine- or user installation:
|
||||||
|
!define MULTIUSER_INSTALLMODE_COMMANDLINE
|
||||||
|
!include MultiUser.nsh
|
||||||
|
!include LogicLib.nsh
|
||||||
|
|
||||||
|
Function .onInit
|
||||||
|
!insertmacro MULTIUSER_INIT
|
||||||
|
;Do not use InstallDir at all so we can detect empty $InstDir!
|
||||||
|
${If} $InstDir == "" ; /D not used
|
||||||
|
${If} $MultiUser.InstallMode == "AllUsers"
|
||||||
|
StrCpy $InstDir "$PROGRAMFILES\%{app_name}"
|
||||||
|
${Else}
|
||||||
|
StrCpy $InstDir "$LOCALAPPDATA\%{app_name}"
|
||||||
|
${EndIf}
|
||||||
|
${EndIf}
|
||||||
|
FunctionEnd
|
||||||
|
|
||||||
|
Function un.onInit
|
||||||
|
!insertmacro MULTIUSER_UNINIT
|
||||||
|
FunctionEnd
|
||||||
|
|
||||||
|
;--------------------------------
|
||||||
|
;General
|
||||||
|
|
||||||
|
Name "%{app_name}"
|
||||||
|
OutFile "..\%{app_name}Setup.exe"
|
||||||
|
|
||||||
|
;--------------------------------
|
||||||
|
;Interface Settings
|
||||||
|
|
||||||
|
!define MUI_ABORTWARNING
|
||||||
|
|
||||||
|
;--------------------------------
|
||||||
|
;Pages
|
||||||
|
|
||||||
|
!define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of %{app_name}.$\r$\n$\r$\n$\r$\nClick Next to continue."
|
||||||
|
!insertmacro MUI_PAGE_WELCOME
|
||||||
|
!insertmacro MUI_PAGE_DIRECTORY
|
||||||
|
!insertmacro MUI_PAGE_INSTFILES
|
||||||
|
!define MUI_FINISHPAGE_NOAUTOCLOSE
|
||||||
|
!define MUI_FINISHPAGE_RUN
|
||||||
|
!define MUI_FINISHPAGE_RUN_CHECKED
|
||||||
|
!define MUI_FINISHPAGE_RUN_TEXT "Run %{app_name}"
|
||||||
|
!define MUI_FINISHPAGE_RUN_FUNCTION "LaunchLink"
|
||||||
|
!insertmacro MUI_PAGE_FINISH
|
||||||
|
|
||||||
|
!insertmacro MUI_UNPAGE_CONFIRM
|
||||||
|
!insertmacro MUI_UNPAGE_INSTFILES
|
||||||
|
|
||||||
|
;--------------------------------
|
||||||
|
;Languages
|
||||||
|
|
||||||
|
!insertmacro MUI_LANGUAGE "English"
|
||||||
|
|
||||||
|
;--------------------------------
|
||||||
|
;Installer Sections
|
||||||
|
|
||||||
|
!define UNINST_KEY \
|
||||||
|
"Software\Microsoft\Windows\CurrentVersion\Uninstall\%{app_name}"
|
||||||
|
Section
|
||||||
|
SetOutPath "$InstDir"
|
||||||
|
File /r "..\%{app_name}\*"
|
||||||
|
WriteRegStr SHCTX "Software\%{app_name}" "" $InstDir
|
||||||
|
WriteUninstaller "$InstDir\uninstall.exe"
|
||||||
|
CreateShortCut "$SMPROGRAMS\%{app_name}.lnk" "$InstDir\%{app_name}.exe"
|
||||||
|
WriteRegStr SHCTX "${UNINST_KEY}" "DisplayName" "%{app_name}"
|
||||||
|
WriteRegStr SHCTX "${UNINST_KEY}" "UninstallString" \
|
||||||
|
"$\"$InstDir\uninstall.exe$\" /$MultiUser.InstallMode"
|
||||||
|
WriteRegStr SHCTX "${UNINST_KEY}" "QuietUninstallString" \
|
||||||
|
"$\"$InstDir\uninstall.exe$\" /$MultiUser.InstallMode /S"
|
||||||
|
WriteRegStr SHCTX "${UNINST_KEY}" "Publisher" "%{author}"
|
||||||
|
${GetSize} "$InstDir" "/S=0K" $0 $1 $2
|
||||||
|
IntFmt $0 "0x%08X" $0
|
||||||
|
WriteRegDWORD SHCTX "${UNINST_KEY}" "EstimatedSize" "$0"
|
||||||
|
|
||||||
|
SectionEnd
|
||||||
|
|
||||||
|
;--------------------------------
|
||||||
|
;Uninstaller Section
|
||||||
|
|
||||||
|
Section "Uninstall"
|
||||||
|
|
||||||
|
RMDir /r "$InstDir"
|
||||||
|
Delete "$SMPROGRAMS\%{app_name}.lnk"
|
||||||
|
DeleteRegKey /ifempty SHCTX "Software\%{app_name}"
|
||||||
|
DeleteRegKey SHCTX "${UNINST_KEY}"
|
||||||
|
|
||||||
|
SectionEnd
|
||||||
|
|
||||||
|
Function LaunchLink
|
||||||
|
!addplugindir "."
|
||||||
|
ShellExecAsUser::ShellExecAsUser "open" "$SMPROGRAMS\%{app_name}.lnk"
|
||||||
|
FunctionEnd
|
BIN
src/main/NSIS/ShellExecAsUser.dll
Normal file
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
11
src/main/icons/README.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|

|
||||||
|
|
||||||
|
This directory contains the icons that are displayed for your app. Feel free to
|
||||||
|
change them.
|
||||||
|
|
||||||
|
The difference between the icons on Mac and the other platforms is that on Mac,
|
||||||
|
they contain a ~5% transparent margin. This is because otherwise they look too
|
||||||
|
big (eg. in the Dock or in the app switcher).
|
||||||
|
|
||||||
|
You can create Icon.ico from the .png files with
|
||||||
|
[an online tool](http://icoconvert.com/Multi_Image_to_one_icon/).
|
Before Width: | Height: | Size: 183 B After Width: | Height: | Size: 183 B |
Before Width: | Height: | Size: 802 B After Width: | Height: | Size: 802 B |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
BIN
src/main/icons/linux/16.png
Normal file
After Width: | Height: | Size: 183 B |
BIN
src/main/icons/linux/32.png
Normal file
After Width: | Height: | Size: 802 B |
BIN
src/main/icons/linux/48.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
src/main/icons/mac/16.png
Normal file
After Width: | Height: | Size: 183 B |
BIN
src/main/icons/mac/32.png
Normal file
After Width: | Height: | Size: 802 B |
BIN
src/main/icons/mac/48.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
@ -3,30 +3,27 @@
|
|||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from qtpy import QtGui
|
from PyQt5 import QtGui
|
||||||
|
|
||||||
|
|
||||||
# Paths
|
# Paths
|
||||||
PATH = os.path.dirname(os.path.abspath(__file__))
|
ICON_PATH = "icons/icon.ico"
|
||||||
PATH = os.path.dirname(PATH)
|
BG_IMAGE_DIR = "backgrounds"
|
||||||
ICON_PATH = os.path.join(PATH, "icons", "icon.ico")
|
START_BG_IMAGE_PATH = os.path.join(BG_IMAGE_DIR, "01-spacefield_a-000.png")
|
||||||
BG_IMAGE_DIR = os.path.join(PATH, "backgrounds")
|
MUSICS_DIR = "musics"
|
||||||
START_BG_IMAGE_NAME = "01-spacefield_a-000.png"
|
SFX_DIR = "sfx"
|
||||||
MUSICS_DIR = os.path.join(PATH, "musics")
|
|
||||||
SFX_DIR = os.path.join(PATH, "sfx")
|
|
||||||
LINE_CLEAR_SFX_PATH = os.path.join(SFX_DIR, "line_clear.wav")
|
LINE_CLEAR_SFX_PATH = os.path.join(SFX_DIR, "line_clear.wav")
|
||||||
TETRIS_SFX_PATH = os.path.join(SFX_DIR, "tetris.wav")
|
TETRIS_SFX_PATH = os.path.join(SFX_DIR, "tetris.wav")
|
||||||
ROTATE_SFX_PATH = os.path.join(SFX_DIR, "rotate.wav")
|
ROTATE_SFX_PATH = os.path.join(SFX_DIR, "rotate.wav")
|
||||||
HARD_DROP_SFX_PATH = os.path.join(SFX_DIR, "hard_drop.wav")
|
HARD_DROP_SFX_PATH = os.path.join(SFX_DIR, "hard_drop.wav")
|
||||||
WALL_SFX_PATH = os.path.join(SFX_DIR, "wall.wav")
|
WALL_SFX_PATH = os.path.join(SFX_DIR, "wall.wav")
|
||||||
LOCALE_PATH = os.path.join(PATH, "locale")
|
LOCALE_PATH = "locale"
|
||||||
FONTS_DIR = os.path.join(PATH, "fonts")
|
FONTS_DIR = "fonts"
|
||||||
STATS_FONT_PATH = os.path.join(FONTS_DIR, "PixelCaps!.otf")
|
STATS_FONT_PATH = os.path.join(FONTS_DIR, "PixelCaps!.otf")
|
||||||
STATS_FONT_NAME = "PixelCaps!"
|
STATS_FONT_NAME = "PixelCaps!"
|
||||||
MATRIX_FONT_PATH = os.path.join(FONTS_DIR, "maass slicer Italic.ttf")
|
MATRIX_FONT_PATH = os.path.join(FONTS_DIR, "maass slicer Italic.ttf")
|
||||||
MATRIX_FONT_NAME = "Maassslicer"
|
MATRIX_FONT_NAME = "Maassslicer"
|
||||||
|
SPLASH_SCREEN_PATH = "splashscreen/splashscreen.png"
|
||||||
SPLASH_SCREEN_PATH = os.path.join(PATH, "icons", "splash_screen.png")
|
|
||||||
|
|
||||||
# Coordinates and direction
|
# Coordinates and direction
|
||||||
L, R, U, D = -1, 1, -1, 1 # Left, Right, Up, Down
|
L, R, U, D = -1, 1, -1, 1 # Left, Right, Up, Down
|
@ -7,13 +7,14 @@ import itertools
|
|||||||
import locale
|
import locale
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
from qtpy import QtWidgets, QtCore, QtGui, QtMultimedia
|
from PyQt5 import QtWidgets, QtCore, QtGui, QtMultimedia
|
||||||
|
QtCore.Signal = QtCore.pyqtSignal
|
||||||
|
|
||||||
from . import consts
|
import consts
|
||||||
from .consts import L, R, CLOCKWISE, COUNTERCLOCKWISE
|
from consts import L, R, CLOCKWISE, COUNTERCLOCKWISE
|
||||||
from .__version__ import __title__, __author__, __version__
|
from __version__ import __title__, __author__, __version__
|
||||||
from .point import Point
|
from point import Point
|
||||||
from .tetromino import Block, Tetromino, GhostPiece
|
from tetromino import Block, Tetromino, GhostPiece
|
||||||
|
|
||||||
|
|
||||||
class Grid(QtWidgets.QWidget):
|
class Grid(QtWidgets.QWidget):
|
||||||
@ -92,10 +93,10 @@ class Matrix(Grid):
|
|||||||
drop_signal = QtCore.Signal(int)
|
drop_signal = QtCore.Signal(int)
|
||||||
lock_signal = QtCore.Signal(int, str)
|
lock_signal = QtCore.Signal(int, str)
|
||||||
|
|
||||||
def __init__(self, frames):
|
def __init__(self, frames, app):
|
||||||
super().__init__(frames)
|
super().__init__(frames)
|
||||||
|
|
||||||
self.load_sfx()
|
self.load_sfx(app)
|
||||||
|
|
||||||
self.game_over = False
|
self.game_over = False
|
||||||
self.text = ""
|
self.text = ""
|
||||||
@ -112,17 +113,17 @@ class Matrix(Grid):
|
|||||||
|
|
||||||
self.cells = []
|
self.cells = []
|
||||||
|
|
||||||
def load_sfx(self):
|
def load_sfx(self, app):
|
||||||
self.wall_sfx = QtMultimedia.QSoundEffect(self)
|
self.wall_sfx = QtMultimedia.QSoundEffect(self)
|
||||||
url = QtCore.QUrl.fromLocalFile(consts.WALL_SFX_PATH)
|
url = QtCore.QUrl.fromLocalFile(app.get_resource(consts.WALL_SFX_PATH))
|
||||||
self.wall_sfx.setSource(url)
|
self.wall_sfx.setSource(url)
|
||||||
|
|
||||||
self.rotate_sfx = QtMultimedia.QSoundEffect(self)
|
self.rotate_sfx = QtMultimedia.QSoundEffect(self)
|
||||||
url = QtCore.QUrl.fromLocalFile(consts.ROTATE_SFX_PATH)
|
url = QtCore.QUrl.fromLocalFile(app.get_resource(consts.ROTATE_SFX_PATH))
|
||||||
self.rotate_sfx.setSource(url)
|
self.rotate_sfx.setSource(url)
|
||||||
|
|
||||||
self.hard_drop_sfx = QtMultimedia.QSoundEffect(self)
|
self.hard_drop_sfx = QtMultimedia.QSoundEffect(self)
|
||||||
url = QtCore.QUrl.fromLocalFile(consts.HARD_DROP_SFX_PATH)
|
url = QtCore.QUrl.fromLocalFile(app.get_resource(consts.HARD_DROP_SFX_PATH))
|
||||||
self.hard_drop_sfx.setSource(url)
|
self.hard_drop_sfx.setSource(url)
|
||||||
|
|
||||||
def new_game(self):
|
def new_game(self):
|
||||||
@ -551,12 +552,12 @@ class Stats(QtWidgets.QWidget):
|
|||||||
|
|
||||||
temporary_text = QtCore.Signal(str)
|
temporary_text = QtCore.Signal(str)
|
||||||
|
|
||||||
def __init__(self, frames):
|
def __init__(self, frames, app):
|
||||||
super().__init__(frames)
|
super().__init__(frames)
|
||||||
self.frames = frames
|
self.frames = frames
|
||||||
self.setStyleSheet("background-color: transparent")
|
self.setStyleSheet("background-color: transparent")
|
||||||
|
|
||||||
self.load_sfx()
|
self.load_sfx(app)
|
||||||
|
|
||||||
self.setSizePolicy(
|
self.setSizePolicy(
|
||||||
QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding
|
QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding
|
||||||
@ -569,13 +570,13 @@ class Stats(QtWidgets.QWidget):
|
|||||||
|
|
||||||
self.high_score = int(qsettings.value(self.tr("High score"), 0))
|
self.high_score = int(qsettings.value(self.tr("High score"), 0))
|
||||||
|
|
||||||
def load_sfx(self):
|
def load_sfx(self, app):
|
||||||
self.line_clear_sfx = QtMultimedia.QSoundEffect(self)
|
self.line_clear_sfx = QtMultimedia.QSoundEffect(self)
|
||||||
url = QtCore.QUrl.fromLocalFile(consts.LINE_CLEAR_SFX_PATH)
|
url = QtCore.QUrl.fromLocalFile(app.get_resource(consts.LINE_CLEAR_SFX_PATH))
|
||||||
self.line_clear_sfx.setSource(url)
|
self.line_clear_sfx.setSource(url)
|
||||||
|
|
||||||
self.tetris_sfx = QtMultimedia.QSoundEffect(self)
|
self.tetris_sfx = QtMultimedia.QSoundEffect(self)
|
||||||
url = QtCore.QUrl.fromLocalFile(consts.TETRIS_SFX_PATH)
|
url = QtCore.QUrl.fromLocalFile(app.get_resource(consts.TETRIS_SFX_PATH))
|
||||||
self.tetris_sfx.setSource(url)
|
self.tetris_sfx.setSource(url)
|
||||||
|
|
||||||
def new_game(self):
|
def new_game(self):
|
||||||
@ -790,8 +791,9 @@ class Frames(QtWidgets.QWidget):
|
|||||||
Manage interactions between them.
|
Manage interactions between them.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent, app):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
|
self.app = app
|
||||||
self.setSizePolicy(
|
self.setSizePolicy(
|
||||||
QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding
|
QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding
|
||||||
)
|
)
|
||||||
@ -801,9 +803,9 @@ class Frames(QtWidgets.QWidget):
|
|||||||
self.load_music()
|
self.load_music()
|
||||||
|
|
||||||
self.hold_queue = HoldQueue(self)
|
self.hold_queue = HoldQueue(self)
|
||||||
self.matrix = Matrix(self)
|
self.matrix = Matrix(self, app)
|
||||||
self.next_piece = Grid(self)
|
self.next_piece = Grid(self)
|
||||||
self.stats = Stats(self)
|
self.stats = Stats(self, app)
|
||||||
self.next_queue = NextQueue(self)
|
self.next_queue = NextQueue(self)
|
||||||
|
|
||||||
self.matrices = (self.hold_queue, self.matrix, self.next_piece)
|
self.matrices = (self.hold_queue, self.matrix, self.next_piece)
|
||||||
@ -852,7 +854,7 @@ class Frames(QtWidgets.QWidget):
|
|||||||
self.matrix.lock_signal.connect(self.stats.update_score)
|
self.matrix.lock_signal.connect(self.stats.update_score)
|
||||||
|
|
||||||
self.bg_image = QtGui.QImage(
|
self.bg_image = QtGui.QImage(
|
||||||
os.path.join(consts.BG_IMAGE_DIR, consts.START_BG_IMAGE_NAME)
|
os.path.join(app.get_resource(consts.START_BG_IMAGE_PATH))
|
||||||
)
|
)
|
||||||
self.resize_bg_image()
|
self.resize_bg_image()
|
||||||
|
|
||||||
@ -860,8 +862,9 @@ class Frames(QtWidgets.QWidget):
|
|||||||
|
|
||||||
def load_music(self):
|
def load_music(self):
|
||||||
playlist = QtMultimedia.QMediaPlaylist(self)
|
playlist = QtMultimedia.QMediaPlaylist(self)
|
||||||
for entry in os.scandir(consts.MUSICS_DIR):
|
MUSICS_DIR = self.app.get_resource(consts.MUSICS_DIR)
|
||||||
path = os.path.join(consts.MUSICS_DIR, entry.name)
|
for entry in os.scandir(MUSICS_DIR):
|
||||||
|
path = os.path.join(MUSICS_DIR, entry.name)
|
||||||
url = QtCore.QUrl.fromLocalFile(path)
|
url = QtCore.QUrl.fromLocalFile(path)
|
||||||
music = QtMultimedia.QMediaContent(url)
|
music = QtMultimedia.QMediaContent(url)
|
||||||
playlist.addMedia(music)
|
playlist.addMedia(music)
|
||||||
@ -901,9 +904,10 @@ class Frames(QtWidgets.QWidget):
|
|||||||
self.resize_bg_image()
|
self.resize_bg_image()
|
||||||
|
|
||||||
def reset_backgrounds(self):
|
def reset_backgrounds(self):
|
||||||
|
BG_IMAGE_DIR = self.app.get_resource(consts.BG_IMAGE_DIR)
|
||||||
backgrounds = tuple(
|
backgrounds = tuple(
|
||||||
QtGui.QImage((os.path.join(consts.BG_IMAGE_DIR, entry.name)))
|
QtGui.QImage((os.path.join(BG_IMAGE_DIR, entry.name)))
|
||||||
for entry in os.scandir(consts.BG_IMAGE_DIR)
|
for entry in os.scandir(BG_IMAGE_DIR)
|
||||||
)
|
)
|
||||||
self.backgrounds_cycle = itertools.cycle(backgrounds)
|
self.backgrounds_cycle = itertools.cycle(backgrounds)
|
||||||
|
|
||||||
@ -1223,21 +1227,21 @@ class SettingsDialog(QtWidgets.QDialog):
|
|||||||
class Window(QtWidgets.QMainWindow):
|
class Window(QtWidgets.QMainWindow):
|
||||||
""" Main window """
|
""" Main window """
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, app):
|
||||||
splash_screen = QtWidgets.QSplashScreen(
|
splash_screen = QtWidgets.QSplashScreen(
|
||||||
QtGui.QPixmap(consts.SPLASH_SCREEN_PATH)
|
QtGui.QPixmap(app.get_resource(consts.SPLASH_SCREEN_PATH))
|
||||||
)
|
)
|
||||||
splash_screen.show()
|
splash_screen.show()
|
||||||
|
|
||||||
self.set_locale()
|
|
||||||
|
|
||||||
self.load_settings()
|
|
||||||
|
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.setWindowTitle(__title__.upper())
|
self.setWindowTitle(__title__.upper())
|
||||||
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
|
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
|
||||||
|
|
||||||
self.setWindowIcon(QtGui.QIcon(consts.ICON_PATH))
|
self.set_locale(app)
|
||||||
|
|
||||||
|
self.load_settings()
|
||||||
|
|
||||||
|
self.setWindowIcon(app.app_icon)
|
||||||
# Windows' taskbar icon
|
# Windows' taskbar icon
|
||||||
try:
|
try:
|
||||||
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(
|
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(
|
||||||
@ -1252,16 +1256,14 @@ class Window(QtWidgets.QMainWindow):
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
os.environ['QT_API'] = 'pyqt5'
|
||||||
self.setStyleSheet(qdarkstyle.load_stylesheet_from_environment())
|
self.setStyleSheet(qdarkstyle.load_stylesheet_from_environment())
|
||||||
|
|
||||||
for font_path in consts.STATS_FONT_PATH, consts.MATRIX_FONT_PATH:
|
for font_path in consts.STATS_FONT_PATH, consts.MATRIX_FONT_PATH:
|
||||||
QtGui.QFontDatabase.addApplicationFont(font_path)
|
QtGui.QFontDatabase.addApplicationFont(app.get_resource(font_path))
|
||||||
|
|
||||||
self.frames = Frames(self)
|
self.frames = Frames(self, app)
|
||||||
self.setCentralWidget(self.frames)
|
self.setCentralWidget(self.frames)
|
||||||
self.hold_queue = self.frames.hold_queue
|
|
||||||
self.matrix = self.frames.matrix
|
|
||||||
self.stats = self.frames.stats
|
|
||||||
|
|
||||||
self.menu = self.menuBar()
|
self.menu = self.menuBar()
|
||||||
|
|
||||||
@ -1278,24 +1280,28 @@ class Window(QtWidgets.QMainWindow):
|
|||||||
|
|
||||||
splash_screen.finish(self)
|
splash_screen.finish(self)
|
||||||
|
|
||||||
def set_locale(self):
|
def show(self):
|
||||||
app = QtWidgets.QApplication.instance()
|
super().show()
|
||||||
|
self.frames.new_game()
|
||||||
|
|
||||||
|
def set_locale(self, app):
|
||||||
|
qapp = QtWidgets.QApplication.instance()
|
||||||
|
|
||||||
# Set appropriate thounsand separator characters
|
# Set appropriate thounsand separator characters
|
||||||
locale.setlocale(locale.LC_ALL, "")
|
locale.setlocale(locale.LC_ALL, "")
|
||||||
# Qt
|
# Qt
|
||||||
language = QtCore.QLocale.system().name()[:2]
|
language = QtCore.QLocale.system().name()[:2]
|
||||||
|
|
||||||
qt_translator = QtCore.QTranslator(app)
|
qt_translator = QtCore.QTranslator(qapp)
|
||||||
qt_translation_path = QtCore.QLibraryInfo.location(
|
qt_translation_path = QtCore.QLibraryInfo.location(
|
||||||
QtCore.QLibraryInfo.TranslationsPath
|
QtCore.QLibraryInfo.TranslationsPath
|
||||||
)
|
)
|
||||||
if qt_translator.load("qt_" + language, qt_translation_path):
|
if qt_translator.load("qt_" + language, qt_translation_path):
|
||||||
app.installTranslator(qt_translator)
|
qapp.installTranslator(qt_translator)
|
||||||
|
|
||||||
tetris2000_translator = QtCore.QTranslator(app)
|
tetris2000_translator = QtCore.QTranslator(qapp)
|
||||||
if tetris2000_translator.load(language, consts.LOCALE_PATH):
|
if tetris2000_translator.load(language, app.get_resource(consts.LOCALE_PATH)):
|
||||||
app.installTranslator(tetris2000_translator)
|
qapp.installTranslator(tetris2000_translator)
|
||||||
|
|
||||||
def load_settings(self):
|
def load_settings(self):
|
||||||
global s
|
global s
|
||||||
@ -1517,7 +1523,7 @@ Sound effects made with voc-one by Simple-Media"""
|
|||||||
self.frames.music.stop()
|
self.frames.music.stop()
|
||||||
|
|
||||||
# Save settings
|
# Save settings
|
||||||
qsettings.setValue(self.tr("High score"), self.stats.high_score)
|
qsettings.setValue(self.tr("High score"), self.frames.stats.high_score)
|
||||||
qsettings.setValue("WindowGeometry", self.saveGeometry())
|
qsettings.setValue("WindowGeometry", self.saveGeometry())
|
||||||
qsettings.setValue("WindowState", int(self.windowState()))
|
qsettings.setValue("WindowState", int(self.windowState()))
|
||||||
|
|
25
src/main/python/main.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
Another TETRIS® clone
|
||||||
|
Tetris Game Design by Alexey Pajitnov.
|
||||||
|
Parts of comments issued from 2009 Tetris Design Guideline
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
from fbs_runtime.application_context import ApplicationContext
|
||||||
|
from game_gui import Window
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
class AppContext(ApplicationContext): # 1. Subclass ApplicationContext
|
||||||
|
def run(self): # 2. Implement run()
|
||||||
|
win = Window(self)
|
||||||
|
win.show()
|
||||||
|
return self.app.exec_() # 3. End run() with this line
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
appctxt = AppContext() # 4. Instantiate the subclass
|
||||||
|
exit_code = appctxt.run() # 5. Invoke run()
|
||||||
|
sys.exit(exit_code)
|
@ -2,9 +2,9 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
|
||||||
from qtpy import QtCore
|
from PyQt5 import QtCore
|
||||||
|
|
||||||
from .consts import CLOCKWISE
|
from consts import CLOCKWISE
|
||||||
|
|
||||||
|
|
||||||
class Point(QtCore.QPoint):
|
class Point(QtCore.QPoint):
|
@ -3,11 +3,11 @@
|
|||||||
|
|
||||||
|
|
||||||
import random
|
import random
|
||||||
from qtpy import QtCore, QtGui
|
from PyQt5 import QtCore, QtGui
|
||||||
|
|
||||||
from . import consts
|
import consts
|
||||||
from .consts import L, R, U, D, CLOCKWISE, COUNTERCLOCKWISE
|
from consts import L, R, U, D, CLOCKWISE, COUNTERCLOCKWISE
|
||||||
from .point import Point
|
from point import Point
|
||||||
|
|
||||||
|
|
||||||
class Block:
|
class Block:
|
Before Width: | Height: | Size: 444 KiB After Width: | Height: | Size: 444 KiB |
Before Width: | Height: | Size: 291 KiB After Width: | Height: | Size: 291 KiB |
Before Width: | Height: | Size: 220 KiB After Width: | Height: | Size: 220 KiB |
Before Width: | Height: | Size: 467 KiB After Width: | Height: | Size: 467 KiB |
Before Width: | Height: | Size: 945 KiB After Width: | Height: | Size: 945 KiB |
Before Width: | Height: | Size: 456 KiB After Width: | Height: | Size: 456 KiB |
Before Width: | Height: | Size: 549 KiB After Width: | Height: | Size: 549 KiB |
Before Width: | Height: | Size: 754 KiB After Width: | Height: | Size: 754 KiB |
Before Width: | Height: | Size: 642 KiB After Width: | Height: | Size: 642 KiB |
Before Width: | Height: | Size: 377 KiB After Width: | Height: | Size: 377 KiB |
Before Width: | Height: | Size: 526 KiB After Width: | Height: | Size: 526 KiB |
Before Width: | Height: | Size: 669 KiB After Width: | Height: | Size: 669 KiB |
Before Width: | Height: | Size: 597 KiB After Width: | Height: | Size: 597 KiB |
Before Width: | Height: | Size: 800 KiB After Width: | Height: | Size: 800 KiB |
Before Width: | Height: | Size: 416 KiB After Width: | Height: | Size: 416 KiB |
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 80 KiB |
29
src/main/resources/base/mac-frozen/Contents/Info.plist
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>${app_name}</string>
|
||||||
|
<key>CFBundleDisplayName</key>
|
||||||
|
<string>${app_name}</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleIconFile</key>
|
||||||
|
<string>Icon.icns</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>${mac_bundle_identifier}</string>
|
||||||
|
<key>LSBackgroundOnly</key>
|
||||||
|
<string>0</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>${version}</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>${version}</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>${app_name}</string>
|
||||||
|
<!-- Enable Retina support on OS X: -->
|
||||||
|
<key>NSPrincipalClass</key>
|
||||||
|
<string>NSApplication</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |