From b3731d4828f6c435e4447d99c1110f3fef39b4ff Mon Sep 17 00:00:00 2001 From: Tyler B Date: Tue, 21 Jul 2009 08:07:16 +0000 Subject: Changed util load_image to no longer look in seperate folder for images. Further updates to tower efficiency, also added stats to reflect how well the player did. --- diff --git a/TowerBackground2.bmp b/TowerBackground2.bmp new file mode 100644 index 0000000..fdaf3e8 --- /dev/null +++ b/TowerBackground2.bmp Binary files differ diff --git a/TowerWindow.bmp b/TowerWindow.bmp new file mode 100644 index 0000000..8e015c5 --- /dev/null +++ b/TowerWindow.bmp Binary files differ diff --git a/WallTile.bmp b/WallTile.bmp new file mode 100644 index 0000000..a93ba50 --- /dev/null +++ b/WallTile.bmp Binary files differ diff --git a/brick_wall_bg.bmp b/brick_wall_bg.bmp new file mode 100644 index 0000000..17c442a --- /dev/null +++ b/brick_wall_bg.bmp Binary files differ diff --git a/bridge_bg_2.bmp b/bridge_bg_2.bmp new file mode 100644 index 0000000..cbfd7bd --- /dev/null +++ b/bridge_bg_2.bmp Binary files differ diff --git a/bridge_controls_3.bmp b/bridge_controls_3.bmp new file mode 100644 index 0000000..53ab1cc --- /dev/null +++ b/bridge_controls_3.bmp Binary files differ diff --git a/bridge_piece3 - Copy.bmp b/bridge_piece3 - Copy.bmp new file mode 100644 index 0000000..68989fb --- /dev/null +++ b/bridge_piece3 - Copy.bmp Binary files differ diff --git a/bridge_piece3.bmp b/bridge_piece3.bmp new file mode 100644 index 0000000..6ad7793 --- /dev/null +++ b/bridge_piece3.bmp Binary files differ diff --git a/fork.bmp b/fork.bmp new file mode 100644 index 0000000..91cc32a --- /dev/null +++ b/fork.bmp Binary files differ diff --git a/grass.bmp b/grass.bmp new file mode 100644 index 0000000..d07dff1 --- /dev/null +++ b/grass.bmp Binary files differ diff --git a/horrid_door.bmp b/horrid_door.bmp new file mode 100644 index 0000000..7b91b23 --- /dev/null +++ b/horrid_door.bmp Binary files differ diff --git a/house2_map.bmp b/house2_map.bmp new file mode 100644 index 0000000..dca52b7 --- /dev/null +++ b/house2_map.bmp Binary files differ diff --git a/house_map.bmp b/house_map.bmp new file mode 100644 index 0000000..31797be --- /dev/null +++ b/house_map.bmp Binary files differ diff --git a/lake_bg.bmp b/lake_bg.bmp new file mode 100644 index 0000000..dfe037d --- /dev/null +++ b/lake_bg.bmp Binary files differ diff --git a/map.bmp b/map.bmp new file mode 100644 index 0000000..1a65b39 --- /dev/null +++ b/map.bmp Binary files differ diff --git a/map_foreground2.bmp b/map_foreground2.bmp new file mode 100644 index 0000000..005adc5 --- /dev/null +++ b/map_foreground2.bmp Binary files differ diff --git a/numberPlate.bmp b/numberPlate.bmp new file mode 100644 index 0000000..7c91d4e --- /dev/null +++ b/numberPlate.bmp Binary files differ diff --git a/parchment.bmp b/parchment.bmp new file mode 100644 index 0000000..2b72149 --- /dev/null +++ b/parchment.bmp Binary files differ diff --git a/sky.jpg b/sky.jpg new file mode 100644 index 0000000..37d7c6b --- /dev/null +++ b/sky.jpg Binary files differ diff --git a/start.py b/start.py index dfd9cac..5a29645 100644..100755 --- a/start.py +++ b/start.py @@ -1,10 +1,6 @@ -import tower, levelone, leveltwo, levelthree, levelfour, util +import tower def main(): - levelone.run() - levelfour.run() - leveltwo.run() - levelthree.run() tower.run() -if __name__ == '__main__': main() +if __name__ == '__main__': main() \ No newline at end of file diff --git a/stonehedge_map.bmp b/stonehedge_map.bmp new file mode 100644 index 0000000..35d1dd5 --- /dev/null +++ b/stonehedge_map.bmp Binary files differ diff --git a/tower.py b/tower.py index a08bbac..c209367 100755 --- a/tower.py +++ b/tower.py @@ -1,4 +1,4 @@ -import random, os.path +import random, os.path, time import util import pygame @@ -358,9 +358,13 @@ def run(): shownGap1, shownGap2 = None, None #Variables will represent gaps that will be displayed (if they get hit or stepped on) fallWait, topHoleWait = 0, 0 #Variables representing timers for if the hero is falling or a gap is being displayed because it was stepped on + gapFails = 0 + run = 1 #Variable representing if the game is running runCounter = 0 #The number of run loops the game has gone through + startTime = time.clock() + #The main game loop of the program while run: runCounter = runCounter+1 @@ -444,6 +448,8 @@ def run(): if hero.collidelist(impassableGaps) != -1: fallWait = 60 #Sets the variable representing the fact that the hero is falling, because they went the wrong way shownGap1 = impassableGaps[hero.collidelist(impassableGaps)] + gapFails = gapFails + 1 + print "Falling! (#%d)"%(gapFails) #checks if the hero is standing on top of a gap they cannot pass through tempHero = hero.inflate(-70,0) @@ -476,8 +482,8 @@ def run(): updateRects.append(shownGap2) #Code which spawns a drop which contains a number, only called every 100 loops - if runCounter%75 == 0: - newDrop = generateDropNumber(heroNumber,levelNum) + if runCounter%100 == 0: + newDrop = generateDropNumber(heroNumber,levelNum,dropValues) dropRects.append(pygame.Rect(random.randint(150,850),0,50,50)) dropValues.append(newDrop[0:2]) dropStrings.append(newDrop[2]) @@ -547,7 +553,12 @@ def run(): if hero.topleft[1] <= -80: levelNum = levelNum+1 if levelNum == 8: #Made it to the top of the tower! - victoryCinematic(screen) + #victoryCinematic(screen) + timeTaken = int(time.clock() - startTime) + minutesTaken = timeTaken/60 + secondsTaken = timeTaken%60 + topString = "You have reached the top!\nTime Taken: %dm %ds\nFails: %d"%(minutesTaken,secondsTaken,gapFails) + util.ok_box(topString, (450,400), 300, 50, screen) break #Copy copies the second floor displayed on the screen so it can be shown as the very bottom on the next level @@ -581,8 +592,8 @@ def run(): background.blit(copy, (100,850)) print "Now on level %d."%(levelNum) - print clock - clock.tick(30) #limits to 40 FPS + #print clock + clock.tick(35) #limits to 40 FPS def main(): @@ -626,9 +637,23 @@ def victoryCinematic(screen): util.ok_box("You have reached the top of the tower!", (450,400), 300, 50, screen) -def generateDropNumber(heroNumber,level): +def generateDropNumber(heroNumber,level,currentValues): #Randomly selects if the drop will have addition, subtraction, multiplication, or division, addition and subtraction being more likely - type = random.sample([0,0,0,0,0,0,1,1,1,1,1,1],1)[0] + + #Only need to check the last 2 that dropped + currentValues = currentValues[len(currentValues)-2:] + + type = random.sample([0,1],1)[0] + + #Checks the previous entries to make sure we don't have the same type of operation more then twice + #As it is randomly generated, having +, +, +, +... etc over and over would not work well + if len(currentValues) == 2: + if currentValues[0][0] == currentValues[1][0]: + if currentValues[0][0] == 1: + type = 0 + else: + type = 1 + levelAverage = (levelRanges[level][0]+levelRanges[level][1])/2 returnString = "" if type == 0: #Addition drop @@ -651,4 +676,4 @@ def generateDropNumber(heroNumber,level): return (type,number,returnString) #runs main if called via other naming convention -if __name__ == '__main__': main() +if __name__ == '__main__': main() \ No newline at end of file diff --git a/tower.pyc b/tower.pyc new file mode 100755 index 0000000..b6725de --- /dev/null +++ b/tower.pyc Binary files differ diff --git a/tower.py~ b/tower.py~ new file mode 100644 index 0000000..33bf43c --- /dev/null +++ b/tower.py~ @@ -0,0 +1,654 @@ +import random, os.path +import util + +import pygame +import pygame.font +from pygame.locals import * + +#Global variables: + +#List representing the range of the numbers that are in the gaps on each level, the first level has numbers from 0~20 and so on +levelRanges = [(0,20),(10,30),(20,40),(30,50),(45,65),(60,80),(65,85),(80,100)] + +#Generates a tower "floor", given the amount of holes in the floor and the height on the screen it will be placed on +#Returns a list of 4 things each representing different aspects of the floor: +# 1. A list of the rectangles which make up the "walls" of the floor" +# 2. A list of the rectangles which represent the gaps between the floor walls +# 3. A list of the rectangles which will contain the numbers (all within the walls, on either side of the gaps) +# 4. A list representing which number boxes are associated with each gap + +def generateFloor(holes, height, type = 1): + walls, gaps = [], [] + numBoxes = [] + rect = [] + gapPattern = [] + if holes == 1: + holeSize = random.randint(10,50)*10 + holeStart = random.randint(0,70-holeSize/10)*10 + + walls.append(pygame.Rect(150,height,100+holeStart,50)) + walls.append(pygame.Rect(250+holeStart+holeSize,height,800-holeStart-holeSize,50)) + + gaps.append(pygame.Rect(250+holeStart, height, holeSize, 20)) + + numBoxes.append(pygame.Rect(155+holeStart, height+5, 90, 40)) + numBoxes.append(pygame.Rect(255+holeStart+holeSize,height+5,90,40)) + + gapPattern = [(0,1)] + + elif holes == 2 and type == 1: + + hole1Size = random.randint(10,24)*10 + hole2Size = random.randint(10,24)*10 + centerSize = random.randint(22,70-hole1Size/10-hole2Size/10)*10 + holeStart = random.randint(0,70-hole1Size/10-hole2Size/10-centerSize/10)*10 + + #print "Hole 1 Size:%d\nHole 2 Size: %d\n Center Size: %d\nHole Start: %d"%(hole1Size,hole2Size,centerSize,holeStart) + + walls.append(pygame.Rect(150,height,100+holeStart,50)) + walls.append(pygame.Rect(250+holeStart+hole1Size,height,centerSize,50)) + walls.append(pygame.Rect(250+holeStart+hole1Size+centerSize+hole2Size,height,800-(holeStart+hole1Size+centerSize+hole2Size),50)) + + gaps.append(pygame.Rect(250+holeStart,height,hole1Size,20)) + gaps.append(pygame.Rect(250+holeStart+hole1Size+centerSize,height,hole2Size,20)) + + numBoxes.append(pygame.Rect(155+holeStart,height+5,90,40)) + numBoxes.append(pygame.Rect(255+holeStart+hole1Size,height+5,90,40)) + numBoxes.append(pygame.Rect(155+holeStart+hole1Size+centerSize,height+5,90,40)) + numBoxes.append(pygame.Rect(255+holeStart+hole1Size+centerSize+hole2Size,height+5,90,40)) + + gapPattern = [(0,1),(2,3)] + + elif holes == 2 and type != 1: + #Randomly assigns hole sizes + hole1Size = random.randint(10,50)*10 + hole2Size = random.randint(10,60-(hole1Size/10))*10 + holeStart = random.randint(0,60-(hole1Size+hole2Size)/10)*10 + + walls.append(pygame.Rect(150,height,100+holeStart,50)) + walls.append(pygame.Rect(250+holeStart+hole1Size,height,100,50)) + walls.append(pygame.Rect(350+holeStart+hole1Size+hole2Size,height,700-holeStart-hole1Size-hole2Size,50)) + + gaps.append(pygame.Rect(250+holeStart, height, hole1Size, 20)) + gaps.append(pygame.Rect(350+holeStart+hole1Size, height, hole2Size, 20)) + + numBoxes.append(pygame.Rect(155+holeStart,height+5,90,40)) + numBoxes.append(pygame.Rect(255+holeStart+hole1Size,height+5,90,40)) + numBoxes.append(pygame.Rect(355+holeStart+hole1Size+hole2Size,height+5,90,40)) + + gapPattern = [(0,1),(1,2)] + + elif holes == 3 and type == 1: + holeStart = random.randint(0,2)*10 + hole1Size = random.randint(0,1)*10 + hole2Size = random.randint(0,2)*10 + hole3Size = random.randint(0,1)*10 + centerSize = random.randint(0,3)*10 + + if random.randint(0,1) == 1: + walls.append(pygame.Rect(150,height,100+holeStart,50)) + walls.append(pygame.Rect(350+holeStart+hole1Size,height,210+centerSize,50)) + walls.append(pygame.Rect(660+holeStart+hole1Size+centerSize+hole2Size,height,100,50)) + walls.append(pygame.Rect(860+holeStart+hole1Size+centerSize+hole2Size+hole3Size,height,190-(holeStart+hole1Size+centerSize+hole2Size+hole3Size),50)) + + gaps.append(pygame.Rect(250+holeStart,height,100+hole1Size,20)) + gaps.append(pygame.Rect(560+holeStart+hole1Size+centerSize,height,100+hole2Size,20)) + gaps.append(pygame.Rect(760+holeStart+hole1Size+centerSize+hole2Size,height,100+hole3Size,20)) + + numBoxes.append(pygame.Rect(155+holeStart,height+5,90,40)) + numBoxes.append(pygame.Rect(355+holeStart+hole1Size,height+5,90,40)) + numBoxes.append(pygame.Rect(465+holeStart+hole1Size+centerSize,height+5,90,40)) + numBoxes.append(pygame.Rect(665+holeStart+hole1Size+centerSize+hole2Size,height+5,90,40)) + numBoxes.append(pygame.Rect(865+holeStart+hole1Size+centerSize+hole2Size+hole3Size,height+5,90,40)) + + gapPattern = [(0,1),(2,3),(3,4)] + + else: + walls.append(pygame.Rect(150,height,100+holeStart,50)) + walls.append(pygame.Rect(350+holeStart+hole1Size,height,100,50)) + walls.append(pygame.Rect(550+holeStart+hole1Size+hole2Size,height,210+centerSize,50)) + walls.append(pygame.Rect(860+holeStart+hole1Size+centerSize+hole2Size+hole3Size,height,190-(holeStart+hole1Size+centerSize+hole2Size+hole3Size),50)) + + gaps.append(pygame.Rect(250+holeStart,height,100+hole1Size,20)) + gaps.append(pygame.Rect(450+holeStart+hole1Size,height,100+hole2Size,20)) + gaps.append(pygame.Rect(760+holeStart+hole1Size+centerSize+hole2Size,height,100+hole3Size,20)) + + numBoxes.append(pygame.Rect(155+holeStart,height+5,90,40)) + numBoxes.append(pygame.Rect(355+holeStart+hole1Size,height+5,90,40)) + numBoxes.append(pygame.Rect(555+holeStart+hole1Size+hole2Size,height+5,90,40)) + numBoxes.append(pygame.Rect(665+holeStart+hole1Size+centerSize+hole2Size,height+5,90,40)) + numBoxes.append(pygame.Rect(865+holeStart+hole1Size+centerSize+hole2Size+hole3Size,height+5,90,40)) + + gapPattern = [(0,1),(1,2),(3,4)] + + elif holes == 3 and type != 1: + + holeStart = random.randint(0,10)*10 + hole1Size = random.randint(0,15-holeStart/10)*10 + hole2Size = random.randint(0,17-(holeStart+hole1Size)/10)*10 + hole3Size = random.randint(0,20-(holeStart+hole1Size+hole2Size)/10)*10 + + walls.append(pygame.Rect(150,height,100+holeStart,50)) + walls.append(pygame.Rect(350+holeStart+hole1Size,height,100,50)) + walls.append(pygame.Rect(550+holeStart+hole1Size+hole2Size,height,100,50)) + walls.append(pygame.Rect(750+holeStart+hole1Size+hole2Size+hole3Size,height,300-(holeStart+hole1Size+hole2Size+hole3Size),50)) + + gaps.append(pygame.Rect(250+holeStart,height,100+hole1Size,20)) + gaps.append(pygame.Rect(450+holeStart+hole1Size,height,100+hole2Size,20)) + gaps.append(pygame.Rect(650+holeStart+hole1Size+hole2Size,height,100+hole3Size,20)) + + numBoxes.append(pygame.Rect(155+holeStart,height+5,90,40)) + numBoxes.append(pygame.Rect(355+holeStart+hole1Size,height+5,90,40)) + numBoxes.append(pygame.Rect(555+holeStart+hole1Size+hole2Size,height+5,90,40)) + numBoxes.append(pygame.Rect(755+holeStart+hole1Size+hole2Size+hole3Size,height+5,90,40)) + + gapPattern = [(0,1),(1,2),(2,3)] + + elif holes == 4: + walls.append(pygame.Rect(150,height,100,50)) + walls.append(pygame.Rect(350,height,100,50)) + walls.append(pygame.Rect(550,height,100,50)) + walls.append(pygame.Rect(750,height,100,50)) + walls.append(pygame.Rect(950,height,100,50)) + + gaps.append(pygame.Rect(250,height,100,20)) + gaps.append(pygame.Rect(450,height,100,20)) + gaps.append(pygame.Rect(650,height,100,20)) + gaps.append(pygame.Rect(850,height,100,20)) + + numBoxes.append(pygame.Rect(155,height+5,90,40)) + numBoxes.append(pygame.Rect(355,height+5,90,40)) + numBoxes.append(pygame.Rect(555,height+5,90,40)) + numBoxes.append(pygame.Rect(755,height+5,90,40)) + numBoxes.append(pygame.Rect(955,height+5,90,40)) + + gapPattern = [(0,1),(1,2),(2,3),(3,4)] + + return (walls, gaps, numBoxes, gapPattern) + + + +def generateScreen(background, levelNum): + + #defines the locations of the outer walls + leftWall = pygame.Rect(100,0,50,900) + rightWall = pygame.Rect(1050,0,50,900) + bottomWall = pygame.Rect(100,850,1000,50) + + #loads up the sky graphic, selects a random portion + skyGraphic = util.load_image('sky.jpg') + background.blit(skyGraphic,(0,0),(random.randint(0,600),0,100,900)) + background.blit(skyGraphic,(1100,0),(random.randint(0,600),0,100,900)) + + if levelNum == 0:#only draw grass on the bottom level! + grass = util.load_image('grass.bmp') + background.blit(grass,(0,850)) + background.blit(grass,(1100,850)) + + #Generates/saves the two middle floors of the tower + if levelNum == 0: + floor1size = random.sample([1,1,2,2,2,2,2],1)[0] + floor2size = random.sample([1,2,2,2,2,2,3,3,3,3,4],1)[0] + floor1type = random.randint(0,1) + floor2type = random.randint(0,1) + + else: + floor1size = random.sample([1,2,2,2,2,2,3,3,3,3,3,4,4],1)[0] + floor2size = random.sample([1,2,2,2,2,2,3,3,3,3,3,4,4],1)[0] + floor1type = random.randint(0,1) + floor2type = random.randint(0,1) + + floor1 = generateFloor(floor1size,500,floor1type) + floor2 = generateFloor(floor2size,150,floor2type) + + floor1Numbers = len(floor1[2]) + + centerWalls = util.merge(floor1[0],floor2[0]) + gaps = util.merge(floor1[1],floor2[1]) + numbers = util.merge(floor1[2],floor2[2]) + + gapPattern = floor1[3] + + for pair in floor2[3]: + gapPattern.append((pair[0]+floor1Numbers, pair[1]+floor1Numbers)) + + floorNumbers = [] + gapNumbers = [] + + #Goes through every number box (around each gap), and randomly assigns a number to it, based on the number range of the current level + for i in range(len(numbers)): + floorNumbers.append(random.randint(levelRanges[levelNum][0],levelRanges[levelNum][1])) + + walls = [leftWall, rightWall, bottomWall] + walls = util.merge(walls,centerWalls) + + #Loads the two background image files into surfaces + towerWallTile = util.load_image('WallTile.bmp') + windowTile = util.load_image('TowerWindow.bmp') + + #Prints each wall tile + for i in range(18): + for j in range(18): + background.blit(towerWallTile, (150+50*i,50*j)) + + #Draws the four windows on the screen + background.blit(windowTile, (400,300)) + background.blit(windowTile, (750,300)) + background.blit(windowTile, (400,650)) + background.blit(windowTile, (750,650)) + + #loads the image for the walls + wallSprite = util.load_image('wall.bmp') + + #Draws the walls + for wall in walls: + pygame.draw.rect(background, [100,100,100], wall) + if wall.width == 50: #draws the vertical walls + x = wall.topleft[0] + y = wall.topleft[1] + while y < wall.height: + background.blit(wallSprite, (x,y)) + y = y + 50 + else: #draws the horizontal walls + x = wall.topleft[0] + y = wall.topleft[1] + #Checks if the horizontal wall touches the right one, if so adds a small bit of tile first, to make sure it tiles properly on the right side + if wall.topright[0] == 1050: + if wall.width%50 != 0: + background.blit(wallSprite,(x,y),pygame.Rect(50-(wall.width%50),0,wall.width%50,50)) + x = x + wall.width % 50 + while x < wall.topright[0]: + background.blit(wallSprite, (x,y)) + x = x + 50 + if wall.topright[0] - x < 50: + background.blit(wallSprite,(x,y),pygame.Rect(0,0,wall.topright[0] - x,50)) + x = wall.topright[0] + + + #Goes through every gap and associates the numbers with it, also checks the randomized numbers to make sure they are passable, if not generates a new one + index = 0 + for gap in gaps: + #makes sure there is a difference of at least two around each gap so there is room to go through + while -1 <= floorNumbers[gapPattern[index][0]] - floorNumbers[gapPattern[index][1]] <= 1: + floorNumbers[gapPattern[index][1]] = random.randint(levelRanges[levelNum][0],levelRanges[levelNum][1]) + gapNumbers.append((floorNumbers[gapPattern[index][0]],floorNumbers[gapPattern[index][1]])) + index = index+1 + + index = 0 + numberPlate = util.load_image('numberPlate.bmp') #The background image behind the numbers + + #Draws all the numbers/its background image around every gap + for numBox in numbers: + numberText = stringFactor(floorNumbers[index]) + + #Sets up the font which will be used in the box containing the number + fontSize = 40 + font = pygame.font.Font(None, fontSize) + + displayBox = font.render(numberText, 1, (50,50,50)) + textSize = font.size(numberText) + + background.blit(numberPlate, numBox.topleft) + background.blit(displayBox, (numBox.topleft[0]+(90-textSize[0])/2,numBox.topleft[1]+(40-textSize[1])/2)) + + index = index+1 + + background.convert() + return (background,walls,gaps,gapNumbers) + +def run(): + #Must initialize pygame before doing anything else + pygame.init() + random.seed() + + display_flags = DOUBLEBUF + + #XO laptop is 1200x900 resolution + width, height = 1200, 900 + + if pygame.display.mode_ok((width, height), display_flags ): + screen = pygame.display.set_mode((width, height), display_flags) + + #display background + background = pygame.Surface(screen.get_size()) + background = background.convert() + background.fill((200, 200, 200)) + + + heroNumber = random.randint(3,17) + levelNum = 0 + + level = generateScreen(background,levelNum) + background = level[0] + walls = level[1] + gaps = level[2] + gapNumbers = level[3] + + #Grid, for display purposes + grid = 0 + if grid == 1: + for i in range(24): + pygame.draw.line(background, [0,0,0], (50*i,0),(50*i,900)) + for i in range(18): + pygame.draw.line(background, [0,0,0], (0,50*i),(1200,50*i)) + + + screen.blit(background, (0, 0)) + pygame.display.flip() + + + hero = pygame.Rect(600, 700, 70, 100) #The rectangle representing the hero + + dropRects = [] + dropValues = [] + dropStrings = [] + + updateGaps = 1 #The variable that stores if the gaps need to be updated(set to 1 whenever the heroes number changes), also need to update at start + updateRects = [] #The list of rectangles on the screen representing the portions of the screen that need to be updated + + #Sets the movement speeds for the character, in pixels per loop increment (game runs at 40 FPS) + sideSpeed = 10 + upSpeed = 20 + gravity = 10 + xchange = 0 + ychange = gravity + + clock = pygame.time.Clock() + + shownGap1, shownGap2 = None, None #Variables will represent gaps that will be displayed (if they get hit or stepped on) + fallWait, topHoleWait = 0, 0 #Variables representing timers for if the hero is falling or a gap is being displayed because it was stepped on + + run = 1 #Variable representing if the game is running + runCounter = 0 #The number of run loops the game has gone through + + #The main game loop of the program + while run: + runCounter = runCounter+1 + events = pygame.event.get() + for event in events: + #User decides to exit program + if event.type == QUIT: + run = 0 #stop running + + #Triggers when a key is first pressed down + elif event.type == pygame.KEYDOWN: + if event.key == 273: #up + ychange += -upSpeed + elif event.key == 274: #down + ychange += 0 + elif event.key == 275: #right + xchange += sideSpeed + elif event.key == 276: #left + xchange += -sideSpeed + elif event.unicode == "+": + heroNumber = heroNumber+1 + updateGaps = 1 + elif event.unicode == "-": + heroNumber = heroNumber-1 + updateGaps = 1 + + #Triggers when a pressed down key is no longer being pressed + elif event.type == pygame.KEYUP: + if event.key == 273: + ychange += +upSpeed + elif event.key == 274: + ychange += 0 + elif event.key == 275: + xchange += -sideSpeed + elif event.key == 276: + xchange += +sideSpeed + + #Sees if the lists storing the gaps which are impassable need to be updated + if updateGaps != 0: + updateGaps = 0 + + impassableGaps = [] #The list that will store all the gaps that are not currently passable because of the heroes current number + impassableWalls = util.merge([],walls) #Combined list representing impassable gaps and all walls + + #Goes through every gap on the screen and checks if it is impassable or not, if so adds to appropriate lists + for i in range(len(gaps)): + if not(gapNumbers[i][0]<=heroNumber<=gapNumbers[i][1] or gapNumbers[i][0]>=heroNumber>=gapNumbers[i][1]): + if hero.collidelist([gaps[i]]) == -1: #makes sure the hero isn't in the gap currently (prevents it from getting stuck) + impassableGaps.append(gaps[i]) + impassableWalls.append(pygame.Rect(gaps[i][0],gaps[i][1],gaps[i][2],1)) + + #Start of hero movement/collision detection block + if fallWait != 0: #The hero is falling, so movement is not based on arrow keys pressed + fallWait = fallWait - 1 + tempXChange = 0 #hero does not move left or right, just falls based o gravity + tempYChange = gravity + if fallWait <= 20: #After done falling for a while stops showing the gap which was hit + shownGap1 = None + else: #hero is not falling, movement based on the modifiers from the arrow keys. + shownGap1 = None + tempXChange = xchange + tempYChange = ychange + + tempHero = hero.move(tempXChange,tempYChange) + + if tempHero.collidelist(impassableWalls) == -1: #no collision problems, hero moves normally + hero = tempHero + else: + tempHero = hero.move(tempXChange,0) # first checks if collision is from vertical movement, + if tempHero.collidelist(impassableWalls) == -1: # if it is, move hero horizontally only + hero = tempHero + else: + tempHero = hero.move(0,tempYChange) # otherwise, checks if collision is from horizontal movement + if tempHero.collidelist(impassableWalls) == -1: + hero = tempHero + + + #If collison comes from both horizontal and verical movements, the hero does not get moved + + #checks if the hero hits a gap they cannot pass through from the bottom + if hero.collidelist(impassableGaps) != -1: + fallWait = 60 #Sets the variable representing the fact that the hero is falling, because they went the wrong way + shownGap1 = impassableGaps[hero.collidelist(impassableGaps)] + + #checks if the hero is standing on top of a gap they cannot pass through + tempHero = hero.inflate(-70,0) + tempHero = tempHero.move(0,1) + if tempHero.collidelist(impassableGaps) != -1: + topHoleWait = 5 #gap hero is standing on stays for 5 increments after it's off + gap = impassableGaps[tempHero.collidelist(impassableGaps)] + shownGap2 = pygame.Rect(gap.topleft,(gap.width,20)) + + + + #re-draws the background + #screen.blit(background, (0, 0)) + for rect in updateRects: + screen.blit(background,rect,rect) + + prevUpdateRects = updateRects + updateRects = [] + + pygame.draw.rect(screen, [255,50,50], hero) #draws the hero + updateRects.append(hero) + + #Checks if any impassable gaps have been hit or stepped on and thus need to be displayed + if shownGap1 != None: + pygame.draw.rect(screen, [250,100,100,50], shownGap1) + updateRects.append(shownGap1) + if topHoleWait != 0: + topHoleWait = topHoleWait - 1 + pygame.draw.rect(screen, [250,100,100,50], shownGap2) + updateRects.append(shownGap2) + + #Code which spawns a drop which contains a number, only called every 100 loops + if runCounter%75 == 0: + newDrop = generateDropNumber(heroNumber,levelNum) + dropRects.append(pygame.Rect(random.randint(150,850),0,50,50)) + dropValues.append(newDrop[0:2]) + dropStrings.append(newDrop[2]) + + #Checks if hero has hit any drops + if hero.collidelist(dropRects) != -1: + i = hero.collidelist(dropRects) + if dropValues[i][0] == 0: #hit an addition drop + if heroNumber + dropValues[i][1] < 1000: + heroNumber = heroNumber + dropValues[i][1] + dropRects.pop(i) + dropValues.pop(i) + dropStrings.pop(i) + updateGaps = 1 + + elif dropValues[i][0] == 1: #hit a subtraction drop + if -1000 < heroNumber - dropValues[i][1]: + heroNumber = heroNumber - dropValues[i][1] + dropRects.pop(i) + dropValues.pop(i) + dropStrings.pop(i) + updateGaps = 1 + + elif dropValues[i][0] == 2: #Multiplication drop + if -1000 < heroNumber*dropValues[i][1] < 1000: + heroNumber = heroNumber * dropValues[i][1] + dropRects.pop(i) + dropValues.pop(i) + dropStrings.pop(i) + updateGaps = 1 + + elif dropValues[i][0] == 3: #Division drop + if heroNumber%dropValues[i][1] == 0: + heroNumber = heroNumber / dropValues[i][1] + dropRects.pop(i) + dropValues.pop(i) + dropStrings.pop(i) + updateGaps = 1 + + #Goes through every drop currently on screen (starting with most recently spawned), draws it to the screen with the appropriate number, and moves it down + dropIndexs = range(len(dropRects)) + dropIndexs.reverse() + + font = pygame.font.Font(None,42) #The font + for i in dropIndexs: + dropBox = font.render(dropStrings[i], 1, (50,50,230)) + textSize = font.size(dropStrings[i]) + dropRect = pygame.Rect(dropRects[i].topleft[0]+(50-textSize[0])/2,dropRects[i].topleft[1]+(50-textSize[1])/2,textSize[0],textSize[1]) + #screen.blit(dropBox, (dropRects[i].topleft[0]+(50-textSize[0])/2,dropRects[i].topleft[1]+(50-textSize[1])/2)) + screen.blit(dropBox, dropRect) + updateRects.append(dropRect) + dropRects[i] = dropRects[i].move(0,2) + if dropRects[i].topleft[1]>=900: #Removes from all applicable lists if no longer on screen + dropRects.pop(i) + dropValues.pop(i) + dropStrings.pop(i) + + #Sets up and displays the box which contains the number the hero currently has + numBox = pygame.Rect(0,0,60,30) + hero_number_box = util.render_textrect(str(heroNumber),pygame.font.Font(None, 40),numBox,(50,50,50),[250,250,250],0,1) + screen.blit(hero_number_box, (hero.topleft[0]+5,hero.topleft[1]+35)) + #pygame.display.flip() #updates screen + pygame.display.update(prevUpdateRects) + pygame.display.update(updateRects) + + #Made it off the top of the screen, must advance to next level + if hero.topleft[1] <= -80: + levelNum = levelNum+1 + if levelNum == 8: #Made it to the top of the tower! + victoryCinematic(screen) + break + + #Copy copies the second floor displayed on the screen so it can be shown as the very bottom on the next level + for gap in gaps: + pygame.draw.rect(background,[250,100,100,50], gap) + + copy = background.subsurface(pygame.Rect(100,150,1000,50)).copy() + + #Clears background, generate new level/get it saved into variables + background.fill((200, 200, 200)) + level = generateScreen(background,levelNum) + background = level[0] + walls = level[1] + gaps = level[2] + gapNumbers = level[3] + + #Clear the falling numbers from the screen + dropRects, dropValues, dropStrings = [], [], [] + + #Reset heros vertical location + hero = pygame.Rect(hero.topleft[0],700,70,100) + + #As the level has changed, gaps need to be updated again + updateGaps = 1 + + #As there is a new background, need to set to update the whole screen + updateRects = [pygame.Rect(0,0,1200,900)] + prevUpdateRects = [] + + #makes the botton floor of the new screen the same as the top floor of the old one + background.blit(copy, (100,850)) + print "Now on level %d."%(levelNum) + + print clock + clock.tick(40) #limits to 40 FPS + + +def main(): + print "Running Tower" + run() + + +#Given a number, returns a string representing the number, randomly formated into a short math equasion +def stringFactor(number): + #The list which represents the string posibilities which will be chosen from later + choices = [] + + if number == 0: #special case if the number is 0, string possibilites are 0 times a number from 2~12 + for i in range(13)[1:]: + choices.append("%dx%d"%(0,i)) + choices.append("%dx%d"%(i,0)) + else: # Number is non-zero + #Checks if the number is a multiple of 2~12x2~12, adds all possibilities to list + for i in range(13)[2:]: + if number%i == 0: + if 1 < number/i <= 12: + choices.append("%dx%d"%(i,number/i)) + + + #Sees if no possibilities found yet: + if len(choices) == 0: + #Adds the number itself to choices multiple times to make that choice more likely + for i in range(6): + choices.append("%d"%(number)) + #choices.append(u"%d\u00F75"%(number*5)) #Five times the number divided by 5 + choices.append(u"%d\u00F72"%(number*2)) # Double the number divided by 2 + if number<100: + choices.append("%dx10+%d"%(number/10,number%10))#expanded notation + + #selects a single entry at random from the possible choices, and returns the string + return random.sample(choices,1)[0] + + +# Executed once the player reaches the top of the tower +def victoryCinematic(screen): + + util.ok_box("You have reached the top of the tower!", (450,400), 300, 50, screen) + +def generateDropNumber(heroNumber,level): + #Randomly selects if the drop will have addition, subtraction, multiplication, or division, addition and subtraction being more likely + type = random.sample([0,0,0,0,0,0,1,1,1,1,1,1],1)[0] + levelAverage = (levelRanges[level][0]+levelRanges[level][1])/2 + returnString = "" + if type == 0: #Addition drop + number = random.randint(2,15) + if heroNumber-levelAverage < -30: + number = random.sample([number,-number-heroNumber+levelAverage],1)[0] + returnString = "+%d"%(number) + elif type == 1: #Subtraction drop + number = random.randint(2,9) + if heroNumber-levelAverage > 30: + number = random.sample([number,number+heroNumber-levelAverage],1)[0] + returnString = "-%d"%(number) + elif type == 2: #Multiplication drop + number = random.randint(2,5) + returnString = "x%d"%(number) + elif type == 3: #Division drop + number = random.randint(2,5) + returnString = u"\u00F7%d"%(number) + + return (type,number,returnString) + +#runs main if called via other naming convention +if __name__ == '__main__': main() \ No newline at end of file diff --git a/tower_map.bmp b/tower_map.bmp new file mode 100644 index 0000000..16da85e --- /dev/null +++ b/tower_map.bmp Binary files differ diff --git a/tower_outside.bmp b/tower_outside.bmp new file mode 100644 index 0000000..2ab4b68 --- /dev/null +++ b/tower_outside.bmp Binary files differ diff --git a/tower_outside_controls.bmp b/tower_outside_controls.bmp new file mode 100644 index 0000000..e743d14 --- /dev/null +++ b/tower_outside_controls.bmp Binary files differ diff --git a/util.py b/util.py index 778d2e9..70c5307 100644..100755 --- a/util.py +++ b/util.py @@ -7,7 +7,7 @@ import string def load_image(file, trans = 0): "loads an image, prepares it for play" - file = os.path.join('data', file) + #file = os.path.join('data', file) try: surface = pygame.image.load(file) if trans == 1: diff --git a/util.pyc b/util.pyc new file mode 100755 index 0000000..139cd4b --- /dev/null +++ b/util.pyc Binary files differ diff --git a/wall.bmp b/wall.bmp new file mode 100644 index 0000000..8c46027 --- /dev/null +++ b/wall.bmp Binary files differ diff --git a/watch3.bmp b/watch3.bmp new file mode 100644 index 0000000..e5cff2d --- /dev/null +++ b/watch3.bmp Binary files differ diff --git a/watch_broken2.bmp b/watch_broken2.bmp new file mode 100644 index 0000000..a1a038c --- /dev/null +++ b/watch_broken2.bmp Binary files differ diff --git a/watch_drop_bg.bmp b/watch_drop_bg.bmp new file mode 100644 index 0000000..4d2e939 --- /dev/null +++ b/watch_drop_bg.bmp Binary files differ diff --git a/wave.bmp b/wave.bmp new file mode 100644 index 0000000..08f276d --- /dev/null +++ b/wave.bmp Binary files differ diff --git a/wave2.bmp b/wave2.bmp new file mode 100644 index 0000000..320d67d --- /dev/null +++ b/wave2.bmp Binary files differ -- cgit v0.9.1