Skip to content

Instantly share code, notes, and snippets.

@xjimtim
Last active August 29, 2015 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xjimtim/a1894ca4fe0215b4fe11 to your computer and use it in GitHub Desktop.
Save xjimtim/a1894ca4fe0215b4fe11 to your computer and use it in GitHub Desktop.
import random, sys, time, math, pygame
from pygame.locals import *
變數 = 30
螢幕高 = 640 # width of the program's window, in pixels
螢幕寬 = 480 # height in pixels
螢幕半高 = int(螢幕高 / 2)
螢幕半寬 = int(螢幕寬 / 2)
草野幽色 = (24, 255, 0)
白 = (255, 255, 255)
紅 = (255, 0, 0)
距離 = 90 # how far from the center the squirrel moves before moving the camera
移動速度 = 9 # how fast the player moves
成長速度 = 6 # how fast the player bounces (large is slower)
得分 = 30 # how high the player bounces
原始大小 = 25 # how big the player starts off
最後大小 = 300 # how big the player needs to be to win
無敵秒數 = 2 # how long the player is invulnerable after being hit in seconds
結束遊戲 = 4 # how long the "game over" text stays on the screen in seconds
血量上限 = 3 # how much health the player starts with
草野幽地數 = 80 # number of grass objects in the active area
丁丁密度 = 30 # number of squirrels in the active area
最慢速度 = 3 # slowest squirrel speed
最快速度 = 7 # fastest squirrel speed
變向 = 2 # % chance of direction change per frame
左 = 'left'
右 = 'right'
"""
This program has three data structures to represent the player, enemy squirrels, and grass background objects. The data structures are dictionaries with the following keys:
Keys used by all three data structures:
'甲' - the left edge coordinate of the object in the game world (not a pixel coordinate on the screen)
'乙' - the top edge coordinate of the object in the game world (not a pixel coordinate on the screen)
'rect' - the pygame.Rect object representing where on the screen the object is located.
Player data structure keys:
'surface' - the pygame.Surface object that stores the image of the squirrel which will be drawn to the screen.
'facing' - either set to 左 or 右, stores which direction the player is facing.
'size' - the width and height of the player in pixels. (The width & height are always the same.)
'bounce' - represents at what point in a bounce the player is in. 0 means standing (no bounce), up to 成長速度 (the completion of the bounce)
'health' - an integer showing how many more times the player can be hit by a larger squirrel before dying.
Enemy Squirrel data structure keys:
'surface' - the pygame.Surface object that stores the image of the squirrel which will be drawn to the screen.
'movex' - how many pixels per frame the squirrel moves horizontally. A negative integer is moving to the left, a positive to the right.
'movey' - how many pixels per frame the squirrel moves vertically. A negative integer is moving up, a positive moving down.
'width' - the width of the squirrel's image, in pixels
'height' - the height of the squirrel's image, in pixels
'bounce' - represents at what point in a bounce the player is in. 0 means standing (no bounce), up to 成長速度 (the completion of the bounce)
'成長速度' - how quickly the squirrel bounces. A lower number means a quicker bounce.
'得分' - how high (in pixels) the squirrel bounces
Grass data structure keys:
'grassImage' - an integer that refers to the index of the pygame.Surface object in 草野幽圖 used for this grass object
"""
def main():
global 變數時, 顯示, 基本字體, 左圖片, 右圖片, 草野幽圖
pygame.init()
變數時 = pygame.time.Clock()
pygame.display.set_icon(pygame.image.load('gameicon.png'))
顯示 = pygame.display.set_mode((螢幕高, 螢幕寬))
pygame.display.set_caption('Squirrel Eat Squirrel')
基本字體 = pygame.font.Font('freesansbold.ttf', 32)
# load the image files
左圖片 = pygame.image.load('squirrel.png')
右圖片 = pygame.transform.flip(左圖片, True, False)
草野幽圖 = []
for 丁 in range(1, 5):
草野幽圖.append(pygame.image.load('grass%s.png' % 丁))
while True:
開始遊戲()
def 開始遊戲():
# set up variables for the start of a new game
無敵狀態 = False # if the player is invulnerable
無敵時間 = 0 # time the player became invulnerable
結束狀態 = False # if the player has lost
結束時間 = 0 # time the player lost
勝利狀態 = False # if the player has won
# create the surfaces to hold game text
遊戲結束字體 = 基本字體.render('Game Over', True, 白)
遊戲結束反映 = 遊戲結束字體.get_rect()
遊戲結束反映.center = (螢幕半高, 螢幕半寬)
勝利字體 = 基本字體.render('You have achieved OMEGA SQUIRREL!', True, 白)
勝利反映 = 勝利字體.get_rect()
勝利反映.center = (螢幕半高, 螢幕半寬)
勝利字體2 = 基本字體.render('(Press "r" to restart.)', True, 白)
勝利反映2 = 勝利字體2.get_rect()
勝利反映2.center = (螢幕半高, 螢幕半寬 + 30)
# 相機甲 and 相機乙 are the top left of where the camera view is
相機甲 = 0
相機乙 = 0
草野幽地物件 = [] # stores all the grass objects in the game
丁丁物件 = [] # stores all the non-player squirrel objects
# stores the player object:
玩家丁丁 = {'表面': pygame.transform.scale(左圖片, (原始大小, 原始大小)),
'面朝': 左,
'尺寸': 原始大小,
'甲': 螢幕半高,
'乙': 螢幕半寬,
'成長':0,
'血量': 血量上限}
左移 = False
右移 = False
上移 = False
下移 = False
# start off with some random grass images on the screen
for 丁 in range(10):
草野幽地物件.append(建草野幽地(相機甲, 相機乙))
草野幽地物件[丁]['甲'] = random.randint(0, 螢幕高)
草野幽地物件[丁]['乙'] = random.randint(0, 螢幕寬)
while True: # main game loop
# Check if we should turn off invulnerability
if 無敵狀態 and time.time() - 無敵時間 > 無敵秒數:
無敵狀態 = False
# move all the squirrels
for 己物體 in 丁丁物件:
# move the squirrel, and adjust for their bounce
己物體['甲'] += 己物體['移動量x']
己物體['乙'] += 己物體['移動量y']
己物體['成長'] += 1
if 己物體['成長'] > 己物體['成長速度']:
己物體['成長'] = 0 # reset bounce amount
# random chance they change direction
if random.randint(0, 99) < 變向:
己物體['移動量x'] = 隨機速度()
己物體['移動量y'] = 隨機速度()
if 己物體['移動量x'] > 0: # faces right
己物體['表面'] = pygame.transform.scale(右圖片, (己物體['寬'], 己物體['高']))
else: # faces left
己物體['表面'] = pygame.transform.scale(左圖片, (己物體['寬'], 己物體['高']))
# go through all the objects and see if any need to be deleted.
for 丁 in range(len(草野幽地物件) - 1, -1, -1):
if 林老師你好(相機甲, 相機乙, 草野幽地物件[丁]):
del 草野幽地物件[丁]
for 丁 in range(len(丁丁物件) - 1, -1, -1):
if 林老師你好(相機甲, 相機乙, 丁丁物件[丁]):
del 丁丁物件[丁]
# add more grass & squirrels if we don't have enough.
while len(草野幽地物件) < 草野幽地數:
草野幽地物件.append(建草野幽地(相機甲, 相機乙))
while len(丁丁物件) < 丁丁密度:
丁丁物件.append(創造新丁丁(相機甲, 相機乙))
# adjust 相機甲 and 相機乙 if beyond the "camera slack"
玩家x座標 = 玩家丁丁['甲'] + int(玩家丁丁['尺寸'] / 2)
玩家y座標 = 玩家丁丁['乙'] + int(玩家丁丁['尺寸'] / 2)
if (相機甲 + 螢幕半高) - 玩家x座標 > 距離:
相機甲 = 玩家x座標 + 距離 - 螢幕半高
elif 玩家x座標 - (相機甲 + 螢幕半高) > 距離:
相機甲 = 玩家x座標 - 距離 - 螢幕半高
if (相機乙 + 螢幕半寬) - 玩家y座標 > 距離:
相機乙 = 玩家y座標 + 距離 - 螢幕半寬
elif 玩家y座標 - (相機乙 + 螢幕半寬) > 距離:
相機乙 = 玩家y座標 - 距離 - 螢幕半寬
# draw the green background
顯示.fill(草野幽色)
# draw all the grass objects on the screen
for 庚物體 in 草野幽地物件:
gRect = pygame.Rect( (庚物體['甲'] - 相機甲,
庚物體['乙'] - 相機乙,
庚物體['寬'],
庚物體['高']) )
顯示.blit(草野幽圖[庚物體['草野幽地模樣']], gRect)
# draw the other squirrels
for 己物體 in 丁丁物件:
己物體['rect'] = pygame.Rect( (己物體['甲'] - 相機甲,
己物體['乙'] - 相機乙 - 得分機制(己物體['成長'], 己物體['成長速度'], 己物體['得分']),
己物體['寬'],
己物體['高']) )
顯示.blit(己物體['表面'], 己物體['rect'])
# draw the player squirrel
無敵啟動 = round(time.time(), 1) * 10 % 2 == 1
if not 結束狀態 and not (無敵狀態 and 無敵啟動):
玩家丁丁['rect'] = pygame.Rect( (玩家丁丁['甲'] - 相機甲,
玩家丁丁['乙'] - 相機乙 - 得分機制(玩家丁丁['成長'], 成長速度, 得分),
玩家丁丁['尺寸'],
玩家丁丁['尺寸']) )
顯示.blit(玩家丁丁['表面'], 玩家丁丁['rect'])
# draw the 血量 meter
畫血條(玩家丁丁['血量'])
for event in pygame.event.get(): # event handling loop
if event.type == QUIT:
終止()
elif event.type == KEYDOWN:
if event.key in (K_UP, K_w):
下移 = False
上移 = True
elif event.key in (K_DOWN, K_s):
上移 = False
下移 = True
elif event.key in (K_LEFT, K_a):
右移 = False
左移 = True
if 玩家丁丁['面朝'] != 左: # change player image
玩家丁丁['表面'] = pygame.transform.scale(左圖片, (玩家丁丁['尺寸'], 玩家丁丁['尺寸']))
玩家丁丁['面朝'] = 左
elif event.key in (K_RIGHT, K_d):
左移 = False
右移 = True
if 玩家丁丁['面朝'] != 右: # change player image
玩家丁丁['表面'] = pygame.transform.scale(右圖片, (玩家丁丁['尺寸'], 玩家丁丁['尺寸']))
玩家丁丁['面朝'] = 右
elif 結束時間 and event.key == K_r:
return
elif event.type == KEYUP:
# stop moving the player's squirrel
if event.key in (K_LEFT, K_a):
左移 = False
elif event.key in (K_RIGHT, K_d):
右移 = False
elif event.key in (K_UP, K_w):
上移 = False
elif event.key in (K_DOWN, K_s):
下移 = False
elif event.key == K_ESCAPE:
終止()
if not 結束狀態:
# actually move the player
if 左移:
玩家丁丁['甲'] -= 移動速度
if 右移:
玩家丁丁['甲'] += 移動速度
if 上移:
玩家丁丁['乙'] -= 移動速度
if 下移:
玩家丁丁['乙'] += 移動速度
if (上移 or 右移 or 左移 or 右移) or 玩家丁丁['成長'] != 0:
玩家丁丁['成長'] += 1
if 玩家丁丁['成長'] > 成長速度:
玩家丁丁['成長'] = 0 # reset bounce amount
# check if the player has collided with any squirrels
for 丁 in range(len(丁丁物件)-1, -1, -1):
sq物體 = 丁丁物件[丁]
if 'rect' in sq物體 and 玩家丁丁['rect'].colliderect(sq物體['rect']):
# a player/squirrel collision has occurred
if sq物體['寬'] * sq物體['高'] <= 玩家丁丁['尺寸']**2:
# player is larger and eats the squirrel
玩家丁丁['尺寸'] += int( (sq物體['寬'] * sq物體['高'])**0.2 ) + 1
del 丁丁物件[丁]
if 玩家丁丁['面朝'] == 左:
玩家丁丁['表面'] = pygame.transform.scale(左圖片, (玩家丁丁['尺寸'], 玩家丁丁['尺寸']))
if 玩家丁丁['面朝'] == 右:
玩家丁丁['表面'] = pygame.transform.scale(右圖片, (玩家丁丁['尺寸'], 玩家丁丁['尺寸']))
if 玩家丁丁['尺寸'] > 最後大小:
結束時間 = True # turn on "win mode"
elif not 無敵狀態:
# player is smaller and takes damage
無敵狀態 = True
無敵時間 = time.time()
玩家丁丁['血量'] -= 1
if 玩家丁丁['血量'] == 0:
結束狀態 = True # turn on "game over mode"
結束時間 = time.time()
else:
# game is over, show "game over" text
顯示.blit(遊戲結束字體, 遊戲結束反映)
if time.time() - 結束時間 > 結束遊戲:
return # end the current game
# check if the player has won.
if 結束時間:
顯示.blit(勝利字體, 勝利反映)
顯示.blit(勝利字體2, 勝利反映2)
pygame.display.update()
變數時.tick(變數)
def 畫血條(正血量):
for 丁 in range(正血量): # draw 紅 health bars
pygame.draw.rect(顯示, 紅, (15, 5 + (10 * 血量上限) - 丁 * 10, 20, 10))
for 丁 in range(血量上限): # draw the white outlines
pygame.draw.rect(顯示, 白, (15, 5 + (10 * 血量上限) - 丁 * 10, 20, 10), 1)
def 終止():
pygame.quit()
sys.exit()
def 得分機制(正確得分, 成長速度, 得分):
# Returns the number of pixels to offset based on the bounce.
# Larger 成長速度 means a slower bounce.
# Larger 得分 means a higher bounce.
# currentBounce will always be less than 成長速度
return int(math.sin( (math.pi / float(成長速度)) * 正確得分 ) * 得分)
def 隨機速度():
速度 = random.randint(最慢速度, 最快速度)
if random.randint(0, 1) == 0:
return 速度
else:
return -速度
def 隨機位置取得(相機甲, 相機乙, 物體寬, 物體高):
# create a Rect of the camera view
取得中心 = pygame.Rect(相機甲, 相機乙, 螢幕高, 螢幕寬)
while True:
甲 = random.randint(相機甲 - 螢幕高, 相機甲 + (2 * 螢幕高))
乙 = random.randint(相機乙 - 螢幕寬, 相機乙 + (2 * 螢幕寬))
# create a Rect object with the random coordinates and use colliderect()
# to make sure the right edge isn't in the camera view.
物體呼叫 = pygame.Rect(甲, 乙, 物體寬, 物體高)
if not 物體呼叫.colliderect(取得中心):
return 甲, 乙
def 創造新丁丁(相機甲, 相機乙):
創造 = {}
一般距離 = random.randint(5, 25)
倍率 = random.randint(1, 3)
創造['寬'] = (一般距離 + random.randint(0, 10)) * 倍率
創造['高'] = (一般距離 + random.randint(0, 10)) * 倍率
創造['甲'], 創造['乙'] = 隨機位置取得(相機甲, 相機乙, 創造['寬'], 創造['高'])
創造['移動量x'] = 隨機速度()
創造['移動量y'] = 隨機速度()
if 創造['移動量x'] < 0: # squirrel is facing left
創造['表面'] = pygame.transform.scale(左圖片, (創造['寬'], 創造['高']))
else: # squirrel is facing right
創造['表面'] = pygame.transform.scale(右圖片, (創造['寬'], 創造['高']))
創造['成長'] = 0
創造['成長速度'] = random.randint(10, 18)
創造['得分'] = random.randint(10, 50)
return 創造
def 建草野幽地(相機甲, 相機乙):
草野幽 = {}
草野幽['草野幽地模樣'] = random.randint(0, len(草野幽圖) - 1)
草野幽['寬'] = 草野幽圖[0].get_width()
草野幽['高'] = 草野幽圖[0].get_height()
草野幽['甲'], 草野幽['乙'] = 隨機位置取得(相機甲, 相機乙, 草野幽['寬'], 草野幽['高'])
草野幽['rect'] = pygame.Rect( (草野幽['甲'], 草野幽['乙'], 草野幽['寬'], 草野幽['高']) )
return 草野幽
def 林老師你好(相機甲, 相機乙, 物體):
# Return False if 相機甲 and 相機乙 are more than
# a half-window length beyond the edge of the window.
左邊邊 = 相機甲 - 螢幕高
上邊邊 = 相機乙 - 螢幕寬
物體實際 = pygame.Rect(左邊邊, 上邊邊, 螢幕高 * 3, 螢幕寬 * 3)
全貌 = pygame.Rect(物體['甲'], 物體['乙'], 物體['寬'], 物體['高'])
return not 物體實際.colliderect(全貌)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment