From f9468b0562f945634b663a0eb9d3f58ce8781b6e Mon Sep 17 00:00:00 2001 From: Dorian Pula Date: Wed, 20 Aug 2014 13:19:31 -0400 Subject: [PATCH] Add in game board view. Add in experimental OpenGL test to see if possible to use OpenGL as part of checkboard drawing. --- justcheckers/game/board.py | 18 +- justcheckers/ui/game_screen_landscape.xml | 405 --------------------- justcheckers/ui/game_screen_portrait.xml | 407 ---------------------- justcheckers/ui/game_view.py | 128 +++++++ justcheckers/ui/menu_view.py | 8 +- justcheckers/ui/window.py | 2 + requirements.txt | 1 + 7 files changed, 145 insertions(+), 824 deletions(-) delete mode 100644 justcheckers/ui/game_screen_landscape.xml delete mode 100644 justcheckers/ui/game_screen_portrait.xml create mode 100644 justcheckers/ui/game_view.py diff --git a/justcheckers/game/board.py b/justcheckers/game/board.py index 2a0ef98..7a772b3 100644 --- a/justcheckers/game/board.py +++ b/justcheckers/game/board.py @@ -313,17 +313,13 @@ class Board(object): # TODO: Implement the suicide game setup. pass - # /** - # * Returns a string to represent the board state. This string is formatted - # * for use as a simple board display in the command window. - # * - # * Legend ## - White space which the piece can not move on to. __ - - # * An empty space. LP - A light pawn. LK - A light king. DP - A dark pawn. - # * DK - A dark king. - # * - # * @return A string representing the current board state. - # */ def __str__(self): + """ + Override __str__ to get back an elegant unicode representation of the board. + + :returns: A text representation of the current state of the board. + """ + # TODO Fix up string building setup. Separate into smaller component functions. # Prepare for output with a nice looking to banner. output = " " @@ -350,7 +346,7 @@ class Board(object): else: output = u'{}{} '.format(output, row + 1) - # // Get current row's state. + # Get current row's state. for col in xrange(0, self.board_size): output = output + output_atom[self._board[row][col]] diff --git a/justcheckers/ui/game_screen_landscape.xml b/justcheckers/ui/game_screen_landscape.xml deleted file mode 100644 index 7de7b5d..0000000 --- a/justcheckers/ui/game_screen_landscape.xml +++ /dev/null @@ -1,405 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/justcheckers/ui/game_screen_portrait.xml b/justcheckers/ui/game_screen_portrait.xml deleted file mode 100644 index 8b82aed..0000000 --- a/justcheckers/ui/game_screen_portrait.xml +++ /dev/null @@ -1,407 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/justcheckers/ui/game_view.py b/justcheckers/ui/game_view.py new file mode 100644 index 0000000..ab5d36f --- /dev/null +++ b/justcheckers/ui/game_view.py @@ -0,0 +1,128 @@ +# +# Copyright (c) 2014 Dorian Pula +# +# justCheckers is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# justCheckers is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with justCheckers. If not, see . +# +# Please share and enjoy! +# + +from PySide import QtGui + +from PySide.QtOpenGL import QGLWidget +from OpenGL.GL import * +from OpenGL.GLUT import * +from OpenGL.GLU import * + + +# TODO Borrowed from: http://biospud.blogspot.ca/2012/02/proof-of-concept-opengl-program-in.html +def override(interface_class): + """ + Method to implement Java-like derived class method override annotation. + Courtesy of mkorpela's answer at + http://stackoverflow.com/questions/1167617/in-python-how-do-i-indicate-im-overriding-a-method + """ + def override(method): + assert(method.__name__ in dir(interface_class)) + return method + return override + + +# Install freeglut3 for the example. +class SphereTestGLWidget(QGLWidget): + "GUI rectangle that displays a teapot" + @override(QGLWidget) + def initializeGL(self): + "runs once, after OpenGL context is created" + glEnable(GL_DEPTH_TEST) + glClearColor(1,1,1,0) # white background + glShadeModel(GL_SMOOTH) + glEnable(GL_COLOR_MATERIAL) + glMaterialfv(GL_FRONT, GL_SPECULAR, [1.0, 1.0, 1.0, 1.0]) + glMaterialfv(GL_FRONT, GL_SHININESS, [50.0]) + glLightfv(GL_LIGHT0, GL_POSITION, [1.0, 1.0, 1.0, 0.0]) + glLightfv(GL_LIGHT0, GL_DIFFUSE, [1.0, 1.0, 1.0, 1.0]) + glLightfv(GL_LIGHT0, GL_SPECULAR, [1.0, 1.0, 1.0, 1.0]) + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, [1.0, 1.0, 1.0, 0.0]) + glEnable(GL_LIGHTING) + glEnable(GL_LIGHT0) + self.orientCamera() + glutInit() + gluLookAt(0, 0, -10, # camera + 0, 0, 0, # focus + 0, 1, 0) # up vector + + @override(QGLWidget) + def paintGL(self): + "runs every time an image update is needed" + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) + self.paintTeapot() + + @override(QGLWidget) + def resizeGL(self, w, h): + "runs every time the window changes size" + glViewport(0, 0, w, h) + self.orientCamera() + + def orientCamera(self): + "update projection matrix, especially when aspect ratio changes" + glPushAttrib(GL_TRANSFORM_BIT) # remember current GL_MATRIX_MODE + glMatrixMode(GL_PROJECTION) + glLoadIdentity() + gluPerspective (60.0, self.width()/float(self.height()), 1.0, 10.0) + glPopAttrib() # restore GL_MATRIX_MODE + + def paintTeapot(self): + glPushAttrib(GL_POLYGON_BIT) # remember current GL_FRONT_FACE indictor + glFrontFace(GL_CW) # teapot polygon vertex order is opposite to modern convention + glColor3f(0.2,0.2,0.5) # paint it blue + glutSolidTeapot(3.0) # thank you GLUT tool kit + glPopAttrib() # restore GL_FRONT_FACE + + +class GameBoardWidget(QGLWidget): + def __init__(self, parent): + QGLWidget.__init__(self, parent) + + +class GameView(QtGui.QWidget): + """Info viewer for the game's license, etc.""" + + # TODO Setup functional testing with PySide.QtTest + + def __init__(self): + super(GameView, self).__init__() + self.setup_components() + + def setup_components(self): + + self.game_board = SphereTestGLWidget(self) + + exit_button = QtGui.QPushButton('Back to Menu', self) + exit_button.setFixedHeight(50) + exit_button.clicked.connect(self.switch_to_menu_view) + + widget_layout = QtGui.QVBoxLayout(self) + widget_layout.addWidget(self.game_board) + + # TODO Add in number of captured pieces and whose turn it is. + + button_row = QtGui.QHBoxLayout(self) + button_row.addWidget(exit_button) + + widget_layout.addLayout(button_row) + + self.setLayout(widget_layout) + + def switch_to_menu_view(self): + self.parentWidget().setCurrentIndex(0) diff --git a/justcheckers/ui/menu_view.py b/justcheckers/ui/menu_view.py index de5c1cc..eba3cf9 100644 --- a/justcheckers/ui/menu_view.py +++ b/justcheckers/ui/menu_view.py @@ -36,7 +36,9 @@ class MainMenuView(QtGui.QWidget): """Setup the components that make up the widget.""" self.init_justcheckers_logo() - self.new_game = self.create_menu_button('&New Game') + self.new_game = self.create_menu_button('&New Game', enabled=True) + self.new_game.clicked.connect(self.switch_to_game_view) + self.open_game = self.create_menu_button('&Open Game') self.save_game = self.create_menu_button('&Save Game') @@ -83,5 +85,9 @@ class MainMenuView(QtGui.QWidget): """Exits the application.""" QtCore.QCoreApplication.instance().exit() + # TODO Remove magic numbers def switch_to_about_view(self): self.parentWidget().setCurrentIndex(1) + + def switch_to_game_view(self): + self.parentWidget().setCurrentIndex(2) diff --git a/justcheckers/ui/window.py b/justcheckers/ui/window.py index 883e267..7d16bb1 100644 --- a/justcheckers/ui/window.py +++ b/justcheckers/ui/window.py @@ -20,6 +20,7 @@ from PySide import QtGui +from justcheckers.ui.game_view import GameView from justcheckers.ui.info_view import InfoView from justcheckers.ui.menu_view import MainMenuView from justcheckers.ui import util @@ -50,6 +51,7 @@ class DesktopGameWindow(QtGui.QMainWindow): self.view_stack = QtGui.QStackedWidget() self.view_stack.addWidget(MainMenuView()) self.view_stack.addWidget(InfoView()) + self.view_stack.addWidget(GameView()) self.setCentralWidget(self.view_stack) def center(self): diff --git a/requirements.txt b/requirements.txt index aa30fc3..001bb95 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,6 +3,7 @@ # User interface PySide==1.2.2 Markdown==2.4.1 +PyOpenGL # Core logic enum34==0.9.19