class TetrisNextCube(GameObject): def __init__(self, type, position = None, rotation = None): self.cube = TetrisCube(type, position, rotation) self.setType(type) self.time = glutGet(GLUT_ELAPSED_TIME) def display(self): self.cube.display() def setType(self, type): self.cube.setType(type) if self.cube.type == 0: for pos in self.cube.position: pos[0] += 0.0 pos[1] -= 0.1 if self.cube.type == 1: for pos in self.cube.position: pos[0] += 0.5 pos[1] -= 0.2 if self.cube.type == 2: for pos in self.cube.position: pos[0] -= 0.5 pos[1] += 0.3 if self.cube.type == 5 or self.cube.type == 6: for pos in self.cube.position: pos[0] += 0.5 pos[1] -= 0.5
class TetrisHUD(GameObject): def __init__(self, Tetris3d): self.Tetris3d = Tetris3d self.data = Tetris3d.data self.time = glutGet(GLUT_ELAPSED_TIME) self.state = 'mainMenu' self.menuitem = 'start' self.texture = Textures() self.tstring = TextureString(Tetris3d.data) self.playername = '' self.planes = {} self.skins = {} self.stringPlane = {} self.textureWidthRatio = 512.0 / 640.0 self.textureHeightRatio = 512.0 / 480.0 self.generateStringTexture('mainMenu') self.generateStringTexture('gameoverMenu') self.generateStringTexture('enterName') self.generateStringTexture('pause') self.generateStringTexture('play') self.generateStringTexture('highscore') self.backgroundTexture = self.texture.createTex(self.data.get('texture/menu/menu.jpg')) self.stringTexture = self.texture.createTex(self.stringPlane['mainMenu']) self.planes['0_background'] = {'texture': self.backgroundTexture, 'coord': [16.7, 12.525, 16.6]} self.planes['1_strings'] = {'texture': self.stringTexture, 'coord': [16.7, 12.525, 16.59]} self.cubePos = {'mainMenu': { 'start': [4,4.6,0], 'highscore': [10,0.2,0], 'exit': [3,-4,0] }, 'gameoverMenu': { 'start': [10.5,2.4,0], 'highscore': [10,-2,0], 'exit': [3,-6.2,0] }} self.cube = TetrisCube(1, self.cubePos[self.state][self.menuitem]) def generateStringTexture(self, name): if self.stringPlane.has_key(name): del self.stringPlane[name] if name == 'mainMenu': self.registerString('mainMenu', self.tstring.create('Cubix'), 320, 20, 'center', 1) self.registerString('mainMenu', self.tstring.create('Start'), 320, 145, 'center', 0.8) self.registerString('mainMenu', self.tstring.create('Highscores'), 320, 215, 'center', 0.8) self.registerString('mainMenu', self.tstring.create('Exit'), 320, 290, 'center', 0.8) elif name == 'gameoverMenu': self.registerString('gameoverMenu', self.tstring.create('Game Over'), 320, 20, 'center', 1) self.registerString('gameoverMenu', self.tstring.create('Your Score: ' + str(self.Tetris3d.objects['mainGrid'].score.value)), 320, 120, 'center', 0.35) self.registerString('gameoverMenu', self.tstring.create('Try Again!'), 320, 180, 'center', 0.8) self.registerString('gameoverMenu', self.tstring.create('Highscores'), 320, 250, 'center', 0.8) self.registerString('gameoverMenu', self.tstring.create('Exit'), 320, 320, 'center', 0.8) elif name == 'enterName': self.registerString('enterName', self.tstring.create('Game Over'), 320, 20, 'center', 1) self.registerString('enterName', self.tstring.create('Enter Your Name:'), 320, 120, 'center', 0.4) self.registerString('enterName', self.tstring.create(self.playername), 320, 215, 'center', 0.5) elif name == 'pause': self.registerString('pause', self.tstring.create('Pause'), 320, 180, 'center', 1) elif name == 'highscore' or name == 'highscoreHighlight': if name == 'highscoreHighlight' and self.stringPlane.has_key('highscore'): del self.stringPlane['highscore'] self.registerString('highscore', self.tstring.create('Highscores'), 320, 20, 'center', 1) self.registerString('highscore', self.tstring.create('Press escape to go back to menu'), 320, 110, 'center', 0.32) id = self.Tetris3d.objects['mainGrid'].db.getNewestId() extraSpace = 0 i = 1 for score in self.Tetris3d.objects['mainGrid'].db.getToTen(): if score[2] == id and name == 'highscoreHighlight': size = 0.5 else: size = 0.35 nameString = self.tstring.create(score[0]) scoreString = self.tstring.create(str(score[1])) # To prevent that the name and score overlap each other in the list if int((nameString.size[0] + scoreString.size[0]) * size) > 540: ratio = 540.0 / ((nameString.size[0] + scoreString.size[0]) * size) size *= ratio self.registerString('highscore', nameString, 50, 120 + 30 * i + extraSpace, 'left', size) self.registerString('highscore', scoreString, 590, 120 + 30 * i + extraSpace, 'right', size) if score[2] == id and name == 'highscoreHighlight': extraSpace = 8 i += 1 elif name == 'play': self.registerString('play', self.tstring.create('Cubix'), 320, 30, 'left', 1) self.registerString('play', self.tstring.create('Score:'), 320, 365, 'left', 0.33) self.registerString('play', self.tstring.create('Level:'), 320, 423, 'left', 0.33) def registerString(self, skin, image, x, y, align, size): x = int(x * self.textureWidthRatio) y = int(y * self.textureHeightRatio) if not self.stringPlane.has_key(skin): self.stringPlane[skin] = new('RGBA', (512, 512)) width = int(image.size[0] * size * self.textureWidthRatio) height = int(image.size[1] * size * self.textureHeightRatio) image = image.resize((width, height), ANTIALIAS) posY = y if align == 'left': posX = x elif align == 'right': posX = x - width elif align == 'center': posX = x - (width / 2) else: posX = 0 self.stringPlane[skin].paste(image, (posX, posY)) def setState(self, state): if state == 'mainMenu': self.state = 'mainMenu' self.texture.createTex(self.stringPlane['mainMenu'], self.stringTexture) self.menuitem = 'start' self.cube.renderPos = self.cubePos[self.state][self.menuitem] elif state == 'gameoverMenu': self.state = 'gameoverMenu' self.generateStringTexture('gameoverMenu') self.texture.createTex(self.data.get('texture/menu/menu.jpg'), self.backgroundTexture) self.texture.createTex(self.stringPlane['gameoverMenu'], self.stringTexture) self.menuitem = 'start' self.cube.renderPos = self.cubePos[self.state][self.menuitem] elif state == 'play': self.state = 'play' self.Tetris3d.objects['mainGrid'].run = True self.texture.createTex(self.data.get('texture/menu/front.jpg'), self.backgroundTexture) self.texture.createTex(self.stringPlane['play'], self.stringTexture) if self.Tetris3d.objects['mainGrid'].gameover: self.Tetris3d.objects['mainGrid'].gameover = 0 self.Tetris3d.objects['mainGrid'].clearGrid() elif state == 'pause': self.state = 'pause' self.Tetris3d.objects['mainGrid'].run = None self.texture.createTex(self.data.get('texture/menu/menu.jpg'), self.backgroundTexture) self.texture.createTex(self.stringPlane['pause'], self.stringTexture) elif state == 'highscore': if self.state == 'enterName': self.generateStringTexture('highscoreHighlight') else: self.generateStringTexture('highscore') self.state = 'highscore' self.texture.createTex(self.data.get('texture/menu/highscore.jpg'), self.backgroundTexture) self.texture.createTex(self.stringPlane['highscore'], self.stringTexture) elif state == 'enterName': self.state = 'enterName' self.generateStringTexture('enterName') self.texture.createTex(self.data.get('texture/menu/menu.jpg'), self.backgroundTexture) self.texture.createTex(self.stringPlane['enterName'], self.stringTexture) def keyboardSpecial(self, key, x, y): if self.state == 'mainMenu' or self.state == 'gameoverMenu': if key == 101: # up arrow key if self.menuitem == 'start': self.menuitem = 'exit' elif self.menuitem == 'exit': self.menuitem = 'highscore' elif self.menuitem == 'highscore': self.menuitem = 'start' elif key == 103: # down arrow key if self.menuitem == 'start': self.menuitem = 'highscore' elif self.menuitem == 'highscore': self.menuitem = 'exit' elif self.menuitem == 'exit': self.menuitem = 'start' self.cube.renderPos = self.cubePos[self.state][self.menuitem] def keyboard(self, key, x, y): if self.state == 'mainMenu' or self.state == 'gameoverMenu': if ord(key) == 27: # key = esc sys.exit() if ord(key) == 13: # key = enter if self.menuitem == 'start': self.setState('play') elif self.menuitem == 'highscore': self.setState('highscore') elif self.menuitem == 'exit': sys.exit() elif self.state == 'highscore': if ord(key) == 27: # key = esc self.setState('mainMenu') elif self.state == 'enterName': if self.tstring.data.has_key(key) and len(self.playername) < 13: self.playername += key elif ord(key) == 8: # key = backspace self.playername = self.playername[:-1] self.generateStringTexture('enterName') self.texture.createTex(self.stringPlane['enterName'], self.stringTexture) if ord(key) == 13 and len(self.playername) != 0: # key = enter self.Tetris3d.objects['mainGrid'].db.addScore(unicode(self.playername), self.Tetris3d.objects['mainGrid'].score.getValue()) self.setState('highscore') elif ord(key) == 27: # key = esc self.setState('mainMenu') elif self.state == 'pause': if key == 'p': self.setState('play') if ord(key) == 27: # key = esc self.Tetris3d.objects['mainGrid'].gameOver() elif self.state == 'play': if key == 'p': self.setState('pause') if ord(key) == 27: # key = esc self.Tetris3d.objects['mainGrid'].gameOver() def display(self): for name, plane in self.planes.iteritems(): x = plane['coord'][0] y = plane['coord'][1] z = plane['coord'][2] glEnable (GL_BLEND) glBlendFunc (GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA) glEnable(GL_TEXTURE_2D) glBindTexture(GL_TEXTURE_2D, plane['texture']) glBegin(GL_QUADS) glTexCoord2f(1.0, 0.0); glVertex3f(-x, -y, z) # Bottom Right glTexCoord2f(0.0, 0.0); glVertex3f( x, -y, z) # Bottom Left glTexCoord2f(0.0, 1.0); glVertex3f( x, y, z) # Top Left glTexCoord2f(1.0, 1.0); glVertex3f(-x, y, z) # Top Right glEnd() glDisable(GL_TEXTURE_2D) glDisable(GL_BLEND) if self.state == 'mainMenu' or self.state == 'gameoverMenu': glPushMatrix() glScaled(0.2,0.2,0.2) glTranslated(0,0,-0.2) self.cube.display() glPopMatrix() def update(self, delay): if self.time + 1000 < glutGet(GLUT_ELAPSED_TIME) and (self.state == 'mainMenu' or self.state == 'gameoverMenu'): new = randrange(0,6) if new >= self.cube.type: self.cube.setType(new + 1) else: self.cube.setType(new) if self.cube.type == 0: for pos in self.cube.position: pos[0] += 0.5 elif self.cube.type == 2: for pos in self.cube.position: pos[1] += 0.5 elif self.cube.type == 3 or self.cube.type == 4: for pos in self.cube.position: pos[0] -= 0.5 elif self.cube.type == 5 or self.cube.type == 6: for pos in self.cube.position: pos[1] -= 0.5 self.time = glutGet(GLUT_ELAPSED_TIME)
class TetrisGrid(GameObject): def __init__(self, Tetris3d, width, height): self.Tetris3d = Tetris3d self.grid = [] self.tempGrid = [] self.width = width self.height = height self.run = None self.gameover = 0 self.dropTime = 500 self.db = TetrisDB('score.db') self.keyDown = { 'key': None, 'time': None } self.initKeyEvent = None self.score = TetrisNum(-15,-16.53,0) self.level = TetrisNum(-15,-19.34,0) for row in range(self.height): self.grid.append(self.getEmptyRow()) for row in range(self.height): temp = [] for column in range(self.width): temp.append(Cube(1, [1,1,1])) self.tempGrid.append(temp) self.tCube = TetrisCube(randrange(0,7), [2.55, 10.5, 16]) self.helperCube = TetrisCube(self.tCube.type, [2.55, 10.5, 16]) self.updateHelperCube() for color in self.helperCube.colors: color[0] = 0.2 color[1] = 0.2 color[2] = 0.2 self.cubeTime = glutGet(GLUT_ELAPSED_TIME) self.completeRows = [] self.tempRows = None self.nextCube = TetrisNextCube(randrange(0,7), [-13.45, 3.5, 16]) self.blinkTime = 0 self.cheatChangeCube = None self.cheatHelperCube = None try: open('slidecheat') self.cheatSlideCube = True except: self.cheatSlideCube = None self.blinkCount = 0 for row in range(self.height): self.completeRows.append(True) self.level.value = 1 def update(self, delay): if self.run: self.keyEvents() self.stickCube() self.completeRow() self.updateGrid() self.updateHelperCube() def display(self): if self.run == True: rowPos = 0 for row in self.grid: colPos = 0 for cube in row: if cube: glPushMatrix() glTranslated(2.55, 10.5, 0) glTranslated((self.width - colPos - 1) * 1.1, -rowPos * 1.1, 16) cube.display() glPopMatrix() colPos += 1 rowPos += 1 if type(self.tCube) == types.InstanceType: self.tCube.display() if self.cheatHelperCube: self.helperCube.display() self.score.display() self.level.display() self.nextCube.display() def getEmptyRow(self): row = [] for col in range(self.width): row.append(None) return row def clearGrid(self): for row in range(self.height): for col in range(self.width): self.grid[row][col] = None self.score.value = 0 self.level.value = 1 self.nextCube.setType(randrange(0,7)) self.tCube.setType(randrange(0,7)) self.dropTime = 500 def keyboard(self, key, x, y): if self.run: if ord(key) == 32 and type(self.tCube) == types.InstanceType: # spacebar while not self.checkCollision(): self.moveVert(1) if self.cheatSlideCube == True: self.cubeTime = glutGet(GLUT_ELAPSED_TIME) else: self.cubeTime -= self.dropTime if ord(key) > ord('0') and ord(key) < ord('8') and self.cheatChangeCube == True and type(self.tCube) == types.InstanceType: self.tCube.setType(ord(key) - ord('8')) def keyboardSpecial(self, key, x, y): if self.run: # cube thingy if key == 100: # left arrow key self.moveHoriz(1) self.initKeyEvent = True self.keyDown['key'] = 'left' self.keyDown['time'] = glutGet(GLUT_ELAPSED_TIME) if key == 102: # right arrow key self.moveHoriz(-1) self.initKeyEvent = True self.keyDown['key'] = 'right' self.keyDown['time'] = glutGet(GLUT_ELAPSED_TIME) if key == 103: # down arrow key self.moveVert(1) self.initKeyEvent = True self.keyDown['key'] = 'down' self.keyDown['time'] = glutGet(GLUT_ELAPSED_TIME) if key == 101: # up arrow key self.rotate() self.initKeyEvent = True self.keyDown['key'] = 'up' self.keyDown['time'] = glutGet(GLUT_ELAPSED_TIME) #cube thingy def keyboardSpecialUp(self, key, x, y): if self.run: if key == 100 and self.keyDown['key'] == 'left': # left arrow key self.keyDown['key'] = None self.keyDown['time'] = None if key == 102 and self.keyDown['key'] == 'right': # right arrow key self.keyDown['key'] = None self.keyDown['time'] = None if key == 103 and self.keyDown['key'] == 'down': # down arrow key self.keyDown['key'] = None self.keyDown['time'] = None if key == 101 and self.keyDown['key'] == 'up': # up arrow key self.keyDown['key'] = None self.keyDown['time'] = None def keyEvents(self): if self.keyDown['key'] != None: key = self.keyDown['key'] time = self.keyDown['time'] if self.initKeyEvent == True: halt = 140 else: halt = 35 if time + halt < glutGet(GLUT_ELAPSED_TIME): if key == 'left': self.moveHoriz(1) elif key == 'right': self.moveHoriz(-1) elif key == 'down': self.moveVert(1) elif key == 'up': self.rotate() self.initKeyEvent = None self.keyDown['time'] = glutGet(GLUT_ELAPSED_TIME) def stickCube(self): if self.cubeTime + self.dropTime < glutGet(GLUT_ELAPSED_TIME) and type(self.tCube) == types.InstanceType: if self.checkCollision(): if self.tCube.position[0][0] == 0 and self.tCube.position[0][1] == self.tCube.types[self.tCube.type][0][1]: self.gameOver() for row, col in self.tCube.position: self.grid[row][self.width - 1 - col] = Cube(1, self.tCube.getColor()) self.tCube = None def checkCollision(self, cube = None): if cube == None: cube = self.tCube for row, col in cube.position: if (row + 1 >= self.height) or (self.grid[row + 1][self.width - 1 - col]): return True return None def completeRow(self): if self.tCube == None: for rowNumber in range(20): self.completeRows[rowNumber] = True rowNumber = 0 for row in self.grid: if row.count(None) > 0: self.completeRows[rowNumber] = None rowNumber += 1 if self.completeRows.count(True) > 0: self.tCube = 'blinkrows' self.blinkCount = 6 def updateGrid(self): if type(self.tCube) == types.InstanceType: if self.cubeTime + self.dropTime < glutGet(GLUT_ELAPSED_TIME): self.moveVert(1) self.cubeTime = glutGet(GLUT_ELAPSED_TIME) elif self.tCube == None: self.tCube = TetrisCube(self.nextCube.cube.type, [2.55, 10.5, 16]) self.nextCube.setType(randrange(0,7)) self.cubeTime = glutGet(GLUT_ELAPSED_TIME) elif self.tCube == 'blinkrows': if self.blinkCount > 0: if self.blinkTime + (self.dropTime / 8) < glutGet(GLUT_ELAPSED_TIME): rowNum = 0 for rowStatus in self.completeRows: if rowStatus == True: tempRow = self.grid[rowNum] self.grid[rowNum] = self.tempGrid[rowNum] self.tempGrid[rowNum] = tempRow rowNum += 1 self.blinkCount -= 1 self.blinkTime = glutGet(GLUT_ELAPSED_TIME) else: if self.cheatHelperCube: addScore = 4 else: addScore = 5 rowNum = 0 for rowStatus in self.completeRows: if rowStatus == True: self.grid.pop(rowNum) self.grid.insert(0, self.getEmptyRow()) addScore *= 2 rowNum += 1 if self.isGridEmpty() == True: addScore *= 2 self.addScore(addScore) self.tCube = None def updateHelperCube(self): if type(self.tCube) != types.InstanceType: return update = None cube = 0 for pos in self.helperCube.position: if pos[1] != self.tCube.position[cube][1]: update = True elif pos[0] == self.tCube.position[cube][0] and pos[1] == self.tCube.position[cube][1]: update = True cube += 1 if self.helperCube.type != self.tCube.type: update = True if update: self.helperCube.setType(self.tCube.type) for cube in range(len(self.helperCube.position)): self.helperCube.position[cube][0] = self.tCube.position[cube][0] self.helperCube.position[cube][1] = self.tCube.position[cube][1] drop = True while drop: if self.checkCollision(self.helperCube): drop = None else: for pos in self.helperCube.position: pos[0] += 1 def isGridEmpty(self): if self.grid[self.height - 1].count(None) == self.width: return True else: return None def gameOver(self): scores = self.db.getToTen() self.run = None self.gameover = 1 if (len(scores) == 10 and self.score.getValue() < scores[9][1]) or (self.score.getValue() == 0): self.Tetris3d.objects['TetrisHUD'].setState('gameoverMenu') else: self.Tetris3d.objects['TetrisHUD'].setState('enterName') def addScore(self, score): self.score.add(score) if self.score.value >= 250 * self.level.value: self.level.add(1) self.dropTime -= 25 if self.dropTime < 100: self.dropTime = 100 # cube movement def moveHoriz(self, length): if type(self.tCube) == types.InstanceType: move = True for row, col in self.tCube.position: if (col + length < 0) or (col + length >= self.width): move = None elif self.grid[row][self.width - 1 - col - length]: move = None #test border if move: for pos in self.tCube.position: pos[1] += length def moveVert(self, length): if type(self.tCube) == types.InstanceType: move = True for row, col in self.tCube.position: if row + length >= self.height: move = None elif self.grid[row + length][self.width - 1 - col]: move = None if move: for pos in self.tCube.position: pos[0] += length def rotate(self): if type(self.tCube) == types.InstanceType: rotate = True for row, col in self.tCube.getRotation(): if (row < -1 or row >= self.height): # top/bottom border test rotate = None break if (col < 0 or col >= self.width): # left/right border test rotate = None break if row != -1: if self.grid[row][self.width - 1 - col]: # grid test rotate = None break if rotate: self.tCube.rotate()