Advertisement
Guest User

simple game

a guest
Mar 23rd, 2018
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.38 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Wed Mar 21 05:42:06 2018
  4.  
  5. @author: Hammer
  6. """
  7.  
  8. TITLE = "Hammer's Game"
  9. WIDTH = 480
  10. HEIGHT = 500
  11. FPS = 60
  12. FONT_NAME = 'arial'
  13. HS_FILE = "highscore.txt"
  14. SPRITESHEET = "spritesheet_jumper.png"
  15.  
  16. # Player properties
  17. PLAYER_ACC = 0.5
  18. PLAYER_FRICTION = -0.12
  19. PLAYER_GRAV = 0.8
  20. PLAYER_JUMP = 20
  21.  
  22. # Game properties
  23. BOOST_POWER = 60
  24. POW_SPAWN_PCT = 7
  25.  
  26. # Starting platforms
  27. PLATFORM_LIST = [(0, HEIGHT - 60),
  28. (WIDTH / 2 - 50, HEIGHT * 3 / 4 - 50),
  29. (125, HEIGHT - 350),
  30. (350, 200),
  31. (175, 100)]
  32.  
  33. # define colors
  34. WHITE = (255, 255, 255)
  35. BLACK = (0, 0, 0)
  36. RED = (255, 0, 0)
  37. GREEN = (0, 255, 0)
  38. BLUE = (0, 0, 255)
  39. YELLOW = (255, 255, 0)
  40. LIGHTBLUE = (0, 155, 155)
  41. BGCOLOR = LIGHTBLUE
  42. # Hammer's - Game
  43. import pygame as pg
  44. import random
  45. from settings import *
  46. from Sprites import *
  47. from os import path
  48.  
  49. class Game:
  50. def __init__(self):
  51. # initialize game window, etc
  52. pg.init()
  53. pg.mixer.init()
  54. self.screen = pg.display.set_mode((WIDTH, HEIGHT))
  55. pg.display.set_caption(TITLE)
  56. self.clock = pg.time.Clock()
  57. self.running = True
  58. self.font_name = pg.font.match_font(FONT_NAME)
  59. self.load_data()
  60.  
  61. def load_data(self):
  62. # load high score
  63. self.dir = path.dirname(__file__)
  64. with open(path.join(self.dir, HS_FILE), 'r') as f:
  65. try:
  66. self.highscore = int(f.read())
  67. except:
  68. self.highscore = 0
  69. # load spritesheet image
  70. img_dir = path.join(self.dir, 'img')
  71. self.spritesheet = Spritesheet(path.join(img_dir, SPRITESHEET))
  72. # load sounds
  73. self.snd_dir = path.join(self.dir, 'snd')
  74. self.jump_sound = pg.mixer.Sound(path.join(self.snd_dir, 'Jump33.wav'))
  75. self.boost_sound = pg.mixer.Sound(path.join(self.snd_dir, 'Boost16.wav'))
  76.  
  77. def new(self):
  78. # start a new game
  79. self.score = 0
  80. self.all_sprites = pg.sprite.Group()
  81. self.platforms = pg.sprite.Group()
  82. self.powerups = pg.sprite.Group()
  83. self.player = Player(self)
  84. for plat in PLATFORM_LIST:
  85. Platform(self, *plat)
  86. pg.mixer.music.load(path.join(self.snd_dir, 'King-Ham-Lit.ogg'))
  87. self.run()
  88.  
  89. def run(self):
  90. # Game Loop
  91. pg.mixer.music.play(loops=-1)
  92. self.playing = True
  93. while self.playing:
  94. self.clock.tick(FPS)
  95. self.events()
  96. self.update()
  97. self.draw()
  98. pg.mixer.music.fadeout(500)
  99.  
  100. def update(self):
  101. # Game Loop - Update
  102. self.all_sprites.update()
  103. # check if player hits a platform - only if falling
  104. if self.player.vel.y > 0:
  105. hits = pg.sprite.spritecollide(self.player, self.platforms, False)
  106. if hits:
  107. lowest = hits[0]
  108. for hit in hits:
  109. if hit.rect.bottom > lowest.rect.bottom:
  110. lowest = hit
  111. if self.player.pos.x < lowest.rect.right + 10 and \
  112. self.player.pos.x > lowest.rect.left - 10:
  113. if self.player.pos.y < lowest.rect.centery:
  114. self.player.pos.y = lowest.rect.top
  115. self.player.vel.y = 0
  116. self.player.jumping = False
  117.  
  118. # if player reaches top 1/4 of screen
  119. if self.player.rect.top <= HEIGHT / 4:
  120. self.player.pos.y += max(abs(self.player.vel.y), 2)
  121. for plat in self.platforms:
  122. plat.rect.y += max(abs(self.player.vel.y), 2)
  123. if plat.rect.top >= HEIGHT:
  124. plat.kill()
  125. self.score += 10
  126.  
  127. # if player hits powerup
  128. pow_hits = pg.sprite.spritecollide(self.player, self.powerups, True)
  129. for pow in pow_hits:
  130. if pow.type == 'boost':
  131. self.boost_sound.play()
  132. self.player.vel.y = -BOOST_POWER
  133. self.player.jumping = False
  134.  
  135. # Die!
  136. if self.player.rect.bottom > HEIGHT:
  137. for sprite in self.all_sprites:
  138. sprite.rect.y -= max(self.player.vel.y, 10)
  139. if sprite.rect.bottom < 0:
  140. sprite.kill()
  141. if len(self.platforms) == 0:
  142. self.playing = False
  143.  
  144. # spawn new platforms to keep same average number
  145. while len(self.platforms) < 6:
  146. width = random.randrange(50, 100)
  147. Platform(self, random.randrange(0, WIDTH - width),
  148. random.randrange(-75, -30))
  149.  
  150. def events(self):
  151. # Game Loop - events
  152. for event in pg.event.get():
  153. # check for closing window
  154. if event.type == pg.QUIT:
  155. if self.playing:
  156. self.playing = False
  157. self.running = False
  158. if event.type == pg.KEYDOWN:
  159. if event.key == pg.K_SPACE:
  160. self.player.jump()
  161. if event.type == pg.KEYUP:
  162. if event.key == pg.K_SPACE:
  163. self.player.jump_cut()
  164.  
  165. def draw(self):
  166. # Game Loop - draw
  167. self.screen.fill(BGCOLOR)
  168. self.all_sprites.draw(self.screen)
  169. self.screen.blit(self.player.image, self.player.rect)
  170. self.draw_text(str(self.score), 22, WHITE, WIDTH / 2, 15)
  171. # *after* drawing everything, flip the display
  172. pg.display.flip()
  173.  
  174. def show_start_screen(self):
  175. # game splash/start screen
  176. pg.mixer.music.load(path.join(self.snd_dir, 'Yippee.ogg'))
  177. pg.mixer.music.play(loops=-1)
  178. self.screen.fill(BGCOLOR)
  179. self.draw_text(TITLE, 48, WHITE, WIDTH / 2, HEIGHT / 4)
  180. self.draw_text("Arrows to move, Space to jump", 22, WHITE, WIDTH / 2, HEIGHT / 2)
  181. self.draw_text("Press a key to play", 22, WHITE, WIDTH / 2, HEIGHT * 3 / 4)
  182. self.draw_text("High Score: " + str(self.highscore), 22, WHITE, WIDTH / 2, 15)
  183. pg.display.flip()
  184. self.wait_for_key()
  185. pg.mixer.music.fadeout(500)
  186.  
  187. def show_go_screen(self):
  188. # game over/continue
  189. if not self.running:
  190. return
  191. pg.mixer.music.load(path.join(self.snd_dir, 'Yippee.ogg'))
  192. pg.mixer.music.play(loops=-1)
  193. self.screen.fill(BGCOLOR)
  194. self.draw_text("GAME OVER", 48, WHITE, WIDTH / 2, HEIGHT / 4)
  195. self.draw_text("Score: " + str(self.score), 22, WHITE, WIDTH / 2, HEIGHT / 2)
  196. self.draw_text("Press a key to play again", 22, WHITE, WIDTH / 2, HEIGHT * 3 / 4)
  197. if self.score > self.highscore:
  198. self.highscore = self.score
  199. self.draw_text("NEW HIGH SCORE!", 22, WHITE, WIDTH / 2, HEIGHT / 2 + 40)
  200. with open(path.join(self.dir, HS_FILE), 'w') as f:
  201. f.write(str(self.score))
  202. else:
  203. self.draw_text("High Score: " + str(self.highscore), 22, WHITE, WIDTH / 2, HEIGHT / 2 + 40)
  204. pg.display.flip()
  205. self.wait_for_key()
  206. pg.mixer.music.fadeout(500)
  207.  
  208. def wait_for_key(self):
  209. waiting = True
  210. while waiting:
  211. self.clock.tick(FPS)
  212. for event in pg.event.get():
  213. if event.type == pg.QUIT:
  214. waiting = False
  215. self.running = False
  216. if event.type == pg.KEYUP:
  217. waiting = False
  218.  
  219. def draw_text(self, text, size, color, x, y):
  220. font = pg.font.Font(self.font_name, size)
  221. text_surface = font.render(text, True, color)
  222. text_rect = text_surface.get_rect()
  223. text_rect.midtop = (x, y)
  224. self.screen.blit(text_surface, text_rect)
  225. from random import choice, randrange
  226. vec = pg.math.Vector2
  227.  
  228. class Spritesheet:
  229. # utility class for loading and parsing spritesheets
  230. def __init__(self, filename):
  231. self.spritesheet = pg.image.load(filename).convert()
  232.  
  233. def get_image(self, x, y, width, height):
  234. # grab an image out of a larger spritesheet
  235. image = pg.Surface((width, height))
  236. image.blit(self.spritesheet, (0, 0), (x, y, width, height))
  237. image = pg.transform.scale(image, (width // 2, height // 2))
  238. return image
  239.  
  240. class Player(pg.sprite.Sprite):
  241. def __init__(self, game):
  242. self.groups = game.all_sprites
  243. pg.sprite.Sprite.__init__(self, self.groups)
  244. self.game = game
  245. self.walking = False
  246. self.jumping = False
  247. self.current_frame = 0
  248. self.last_update = 0
  249. self.load_images()
  250. self.image = self.standing_frames[0]
  251. self.rect = self.image.get_rect()
  252. self.rect.center = (40, HEIGHT - 100)
  253. self.pos = vec(40, HEIGHT - 100)
  254. self.vel = vec(0, 0)
  255. self.acc = vec(0, 0)
  256.  
  257. def load_images(self):
  258. self.standing_frames = [self.game.spritesheet.get_image(614, 1063, 120, 191),
  259. self.game.spritesheet.get_image(690, 406, 120, 201)]
  260. for frame in self.standing_frames:
  261. frame.set_colorkey(BLACK)
  262. self.walk_frames_r = [self.game.spritesheet.get_image(678, 860, 120, 201),
  263. self.game.spritesheet.get_image(692, 1458, 120, 207)]
  264. self.walk_frames_l = []
  265. for frame in self.walk_frames_r:
  266. frame.set_colorkey(BLACK)
  267. self.walk_frames_l.append(pg.transform.flip(frame, True, False))
  268. self.jump_frame = self.game.spritesheet.get_image(382, 763, 150, 181)
  269. self.jump_frame.set_colorkey(BLACK)
  270.  
  271. def jump_cut(self):
  272. if self.jumping:
  273. if self.vel.y < -3:
  274. self.vel.y = -3
  275.  
  276. def jump(self):
  277. # jump only if standing on a platform
  278. self.rect.y += 2
  279. hits = pg.sprite.spritecollide(self, self.game.platforms, False)
  280. self.rect.y -= 2
  281. if hits and not self.jumping:
  282. self.game.jump_sound.play()
  283. self.jumping = True
  284. self.vel.y = -PLAYER_JUMP
  285.  
  286. def update(self):
  287. self.animate()
  288. self.acc = vec(0, PLAYER_GRAV)
  289. keys = pg.key.get_pressed()
  290. if keys[pg.K_LEFT]:
  291. self.acc.x = -PLAYER_ACC
  292. if keys[pg.K_RIGHT]:
  293. self.acc.x = PLAYER_ACC
  294.  
  295. # apply friction
  296. self.acc.x += self.vel.x * PLAYER_FRICTION
  297. # equations of motion
  298. self.vel += self.acc
  299. if abs(self.vel.x) < 0.1:
  300. self.vel.x = 0
  301. self.pos += self.vel + 0.5 * self.acc
  302. # wrap around the sides of the screen
  303. if self.pos.x > WIDTH + self.rect.width / 2:
  304. self.pos.x = 0 - self.rect.width / 2
  305. if self.pos.x < 0 - self.rect.width / 2:
  306. self.pos.x = WIDTH + self.rect.width / 2
  307.  
  308. self.rect.midbottom = self.pos
  309.  
  310. def animate(self):
  311. now = pg.time.get_ticks()
  312. if self.vel.x != 0:
  313. self.walking = True
  314. else:
  315. self.walking = False
  316. # show walk animation
  317. if self.walking:
  318. if now - self.last_update > 180:
  319. self.last_update = now
  320. self.current_frame = (self.current_frame + 1) % len(self.walk_frames_l)
  321. bottom = self.rect.bottom
  322. if self.vel.x > 0:
  323. self.image = self.walk_frames_r[self.current_frame]
  324. else:
  325. self.image = self.walk_frames_l[self.current_frame]
  326. self.rect = self.image.get_rect()
  327. self.rect.bottom = bottom
  328. # show idle animation
  329. if not self.jumping and not self.walking:
  330. if now - self.last_update > 350:
  331. self.last_update = now
  332. self.current_frame = (self.current_frame + 1) % len(self.standing_frames)
  333. bottom = self.rect.bottom
  334. self.image = self.standing_frames[self.current_frame]
  335. self.rect = self.image.get_rect()
  336. self.rect.bottom = bottom
  337.  
  338. class Platform(pg.sprite.Sprite):
  339. def __init__(self, game, x, y):
  340. self.groups = game.all_sprites, game.platforms
  341. pg.sprite.Sprite.__init__(self, self.groups)
  342. self.game = game
  343. images = [self.game.spritesheet.get_image(0, 288, 380, 94),
  344. self.game.spritesheet.get_image(213, 1662, 201, 100)]
  345. self.image = choice(images)
  346. self.image.set_colorkey(BLACK)
  347. self.rect = self.image.get_rect()
  348. self.rect.x = x
  349. self.rect.y = y
  350. if randrange(100) < POW_SPAWN_PCT:
  351. Pow(self.game, self)
  352.  
  353. class Pow(pg.sprite.Sprite):
  354. def __init__(self, game, plat):
  355. self.groups = game.all_sprites, game.powerups
  356. pg.sprite.Sprite.__init__(self, self.groups)
  357. self.game = game
  358. self.plat = plat
  359. self.type = choice(['boost'])
  360. self.image = self.game.spritesheet.get_image(820, 1805, 71, 70)
  361. self.image.set_colorkey(BLACK)
  362. self.rect = self.image.get_rect()
  363. self.rect.centerx = self.plat.rect.centerx
  364. self.rect.bottom = self.plat.rect.top - 5
  365.  
  366. def update(self):
  367. self.rect.bottom = self.plat.rect.top - 5
  368. if not self.game.platforms.has(self.plat):
  369. self.kill()
  370. g = Game()
  371. g.show_start_screen()
  372. while g.running:
  373. g.new()
  374. g.show_go_screen()
  375.  
  376. pg.quit()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement