From 64759e69e83b7b776272760d1638daa8fc4a2916 Mon Sep 17 00:00:00 2001 From: void-main Date: Tue, 5 May 2020 08:40:19 +0800 Subject: [PATCH 1/4] Transport T-Rex game --- ple/games/__init__.py | 1 + ple/games/trex/__init__.py | 455 ++++++++++++++++++++++++ ple/games/trex/sprites/cacti-small.png | Bin 0 -> 782 bytes ple/games/trex/sprites/cloud.png | Bin 0 -> 329 bytes ple/games/trex/sprites/dino.png | Bin 0 -> 1111 bytes ple/games/trex/sprites/dino_ducking.png | Bin 0 -> 714 bytes ple/games/trex/sprites/ground.png | Bin 0 -> 568 bytes ple/games/trex/sprites/numbers.png | Bin 0 -> 459 bytes ple/games/trex/sprites/ptera.png | Bin 0 -> 594 bytes 9 files changed, 456 insertions(+) create mode 100644 ple/games/trex/__init__.py create mode 100644 ple/games/trex/sprites/cacti-small.png create mode 100644 ple/games/trex/sprites/cloud.png create mode 100644 ple/games/trex/sprites/dino.png create mode 100644 ple/games/trex/sprites/dino_ducking.png create mode 100644 ple/games/trex/sprites/ground.png create mode 100644 ple/games/trex/sprites/numbers.png create mode 100644 ple/games/trex/sprites/ptera.png diff --git a/ple/games/__init__.py b/ple/games/__init__.py index bf995d2..81ddc5d 100644 --- a/ple/games/__init__.py +++ b/ple/games/__init__.py @@ -11,3 +11,4 @@ from ple.games.raycastmaze import RaycastMaze from ple.games.snake import Snake from ple.games.waterworld import WaterWorld +from ple.games.trex import TRex diff --git a/ple/games/trex/__init__.py b/ple/games/trex/__init__.py new file mode 100644 index 0000000..3bfb90f --- /dev/null +++ b/ple/games/trex/__init__.py @@ -0,0 +1,455 @@ +import os +import sys +import numpy as np +import random + +from collections import namedtuple + +import pygame +from ple.games import base +from pygame.constants import K_SPACE, K_DOWN, K_UP + +SCREEN_WIDTH = 600 +SCREEN_HEIGHT = 150 + +FPS = 60 +gravity = 0.6 + +black = (0, 0, 0) +white = (255, 255, 255) +background_col = (235, 235, 235) + + +class Dino(pygame.sprite.Sprite): + + def __init__(self, images, images_rect, ducking_images, ducking_images_rect): + self.images, self.rect = images, images_rect + self.images1, self.rect1 = ducking_images, ducking_images_rect + self.reset() + + def reset(self): + self.rect.bottom = int(0.98 * SCREEN_HEIGHT) + self.rect.left = SCREEN_WIDTH / 15 + self.image = self.images[0] + self.index = 0 + self.counter = 0 + self.score = 0 + self.isJumping = False + self.isDead = False + self.isDucking = False + self.isBlinking = False + self.movement = [0, 0] + self.jumpSpeed = 11.5 + self.screen_width = SCREEN_WIDTH + self.screen_height = SCREEN_HEIGHT + + self.stand_pos_width = self.rect.width + self.duck_pos_width = self.rect1.width + + def draw(self, screen): + screen.blit(self.image, self.rect) + + def check_bounds(self): + if self.rect.bottom > int(0.98 * self.screen_height): + self.rect.bottom = int(0.98 * self.screen_height) + self.isJumping = False + + def update(self): + if self.isJumping: + self.movement[1] = self.movement[1] + gravity + + if self.isJumping: + self.index = 0 + elif self.isBlinking: + if self.index == 0: + if self.counter % 400 == 399: + self.index = (self.index + 1) % 2 + else: + if self.counter % 20 == 19: + self.index = (self.index + 1) % 2 + + elif self.isDucking: + if self.counter % 5 == 0: + self.index = (self.index + 1) % 2 + else: + if self.counter % 5 == 0: + self.index = (self.index + 1) % 2 + 2 + + if self.isDead: + self.index = 4 + + if not self.isDucking: + self.image = self.images[self.index] + self.rect.width = self.stand_pos_width + else: + self.image = self.images1[self.index % 2] + self.rect.width = self.duck_pos_width + + self.rect = self.rect.move(self.movement) + self.check_bounds() + + if not self.isDead and self.counter % 7 == 6 and self.isBlinking is False: + self.score += 1 + self.counter = (self.counter + 1) + + +class Cactus(pygame.sprite.Sprite): + def __init__(self, images, rect, speed=5): + pygame.sprite.Sprite.__init__(self, self.containers) + self.images, self.rect = images, rect + self.rect.bottom = int(0.98 * SCREEN_HEIGHT) + self.rect.left = SCREEN_WIDTH + self.rect.width + self.image = self.images[random.randrange(0, 3)] + self.movement = [-1 * speed, 0] + + def draw(self, screen): + screen.blit(self.image, self.rect) + + def update(self): + self.rect = self.rect.move(self.movement) + + if self.rect.right < 0: + self.kill() + + +class Ptera(pygame.sprite.Sprite): + def __init__(self, images, rect, speed=5): + pygame.sprite.Sprite.__init__(self, self.containers) + self.images, self.rect = images, rect + self.ptera_height = [SCREEN_WIDTH * 0.82, SCREEN_HEIGHT * 0.75, SCREEN_HEIGHT * 0.60] + self.rect.centery = self.ptera_height[random.randrange(0, 3)] + self.rect.left = SCREEN_WIDTH + self.rect.width + self.image = self.images[0] + self.movement = [-1 * speed, 0] + self.index = 0 + self.counter = 0 + + def draw(self, screen): + screen.blit(self.image, self.rect) + + def update(self): + if self.counter % 10 == 0: + self.index = (self.index + 1) % 2 + self.image = self.images[self.index] + self.rect = self.rect.move(self.movement) + self.counter = (self.counter + 1) + if self.rect.right < 0: + self.kill() + + +class Ground(pygame.sprite.Sprite): + def __init__(self, image, rect, image_swap, rect_swap, speed=-5): + self.image, self.rect = image, rect + self.image1, self.rect1 = image_swap, rect_swap + self.speed = speed + self.reset() + + def reset(self): + self.rect.bottom = SCREEN_HEIGHT + self.rect1.bottom = SCREEN_HEIGHT + self.rect1.left = self.rect.right + + def draw(self, screen): + screen.blit(self.image, self.rect) + screen.blit(self.image1, self.rect1) + + def update(self): + self.rect.left += self.speed + self.rect1.left += self.speed + + if self.rect.right < 0: + self.rect.left = self.rect1.right + + if self.rect1.right < 0: + self.rect1.left = self.rect.right + + +class Scoreboard(pygame.sprite.Sprite): + def __init__(self, numbers_images, numbers_rect): + self.score = 0 + self.tempimages, self.temprect = numbers_images, numbers_rect + self.reset() + + def reset(self): + self.image = pygame.Surface((55, int(11 * 6 / 5))) + self.rect = self.image.get_rect() + self.rect.left = SCREEN_WIDTH * 0.89 + self.rect.top = SCREEN_HEIGHT * 0.1 + + def draw(self, screen): + screen.blit(self.image, self.rect) + + def update(self, score): + score_digits = self.extract_digits(score) + self.image.fill(background_col) + for s in score_digits: + self.image.blit(self.tempimages[s], self.temprect) + self.temprect.left += self.temprect.width + self.temprect.left = 0 + + def extract_digits(self, number): + if number > -1: + digits = [] + i = 0 + while number / 10 != 0: + digits.append(number % 10) + number = int(number / 10) + + digits.append(number % 10) + for i in range(len(digits), 5): + digits.append(0) + digits.reverse() + return digits + + +SpriteAsset = namedtuple('SpriteAsset', ['images', 'rect']) + + +class TRex(base.PyGameWrapper): + """ + Based on code from shivamshekhar's Chrome-T-Rex-Rush. + + Original game repo: https://github.com/shivamshekhar/Chrome-T-Rex-Rush + + Parameters + ---------- + width : int + Screen width. + + height : int + Screen height. + """ + + def __init__(self): + actions = { + 'jump': K_SPACE, + 'duck': K_DOWN, + 'stand': K_UP, + } + + base.PyGameWrapper.__init__(self, SCREEN_WIDTH, SCREEN_HEIGHT, actions=actions) + + self.score = 0.0 + self.game_tick = 0 + self.game_speed = 4 + + self.dino = None + self.ground = None + self.scoreboard = None + self.counter = 0 + + self.cacti = None + self.pteras = None + self.last_obstacle = None + + # so we can preload images + pygame.display.set_mode((1, 1), pygame.NOFRAME) + + self.cur_dir = os.path.dirname(os.path.abspath(__file__)) + self.asset_dir = os.path.join(self.cur_dir, 'sprites') + + # Preload images for performance + self.images = {} + + dino, dino_rect = self.load_sprite_sheet('dino.png', 5, 1, 44, 47, -1) + dino_ducking, dino_ducking_rect = self.load_sprite_sheet('dino_ducking.png', 2, 1, 59, 47, -1) + self.images['dino'] = SpriteAsset(images=dino, rect=dino_rect) + self.images['dino_ducking'] = SpriteAsset(images=dino_ducking, rect=dino_ducking_rect) + + bg, bg_rect = self.load_image('ground.png', -1, -1, -1) + self.images['background'] = SpriteAsset(images=bg, rect=bg_rect) + self.images['background_swap'] = SpriteAsset(images=bg, rect=bg_rect) + + numbers, numbers_rect = self.load_sprite_sheet('numbers.png', 12, 1, 11, int(11 * 6 / 5), -1) + self.images['numbers'] = SpriteAsset(images=numbers, rect=numbers_rect) + + pteras, pteras_rect = self.load_sprite_sheet('ptera.png', 3, 1, 46, 40, -1) + self.images['ptera'] = SpriteAsset(images=pteras, rect=pteras_rect) + + cactus, cactus_rect = self.load_sprite_sheet('cacti-small.png', 3, 1, 40, 40, -1) + self.images['cactus'] = SpriteAsset(images=cactus, rect=cactus_rect) + + def init(self): + self.game_speed = 4 + + if self.dino is None: + dino_asset = self.images['dino'] + dino_ducking_asset = self.images['dino_ducking'] + self.dino = Dino(dino_asset.images, + dino_asset.rect, + dino_ducking_asset.images, + dino_ducking_asset.rect) + self.dino.reset() + + if self.ground is None: + ground_asset = self.images['background'] + ground_swap_asset = self.images['background_swap'] + self.ground = Ground(ground_asset.images, + ground_asset.rect, + ground_swap_asset.images, + ground_swap_asset.rect, + -1 * self.game_speed) + self.ground.reset() + + if self.scoreboard is None: + numbers_asset = self.images['numbers'] + self.scoreboard = Scoreboard(numbers_asset.images, numbers_asset.rect) + self.scoreboard.reset() + + self.cacti = pygame.sprite.Group() + self.pteras = pygame.sprite.Group() + self.last_obstacle = pygame.sprite.Group() + + Cactus.containers = self.cacti + Ptera.containers = self.pteras + + self.score = 0.0 + self.lives = 1 + self.game_tick = 0 + self.counter = 0 + + def _handle_player_events(self): + for event in pygame.event.get(): + if event.type == pygame.QUIT: + pygame.quit() + sys.exit() + + if event.type == pygame.KEYDOWN: + if event.key == pygame.K_SPACE: + if self.dino.rect.bottom == int(0.98 * SCREEN_HEIGHT): + self.dino.isJumping = True + self.dino.movement[1] = -1 * self.dino.jumpSpeed + + if event.key == pygame.K_DOWN: + if not (self.dino.isJumping and self.dino.isDead): + self.dino.isDucking = True + + if event.key == pygame.K_UP: + if not self.dino.isDead: + self.dino.isDucking = False + + def step(self, dt): + self.game_tick += 1 + + self.score += self.rewards['tick'] + + self._handle_player_events() + + for c in self.cacti: + c.movement[0] = -1 * self.game_speed + if pygame.sprite.collide_mask(self.dino, c): + self.dino.isDead = True + if c.rect.right <= self.dino.rect.left < c.rect.right + 4: + self.score += self.rewards["positive"] + + for p in self.pteras: + p.movement[0] = -1 * self.game_speed + if pygame.sprite.collide_mask(self.dino, p): + self.dino.isDead = True + if (p.x - p.width / 2) <= self.player.pos_x < (p.x - p.width / 2 + 4): + self.score += self.rewards["positive"] + + if len(self.cacti) < 2: + cactus_asset = self.images['cactus'] + if len(self.cacti) == 0: + self.last_obstacle.empty() + self.last_obstacle.add(Cactus(cactus_asset.images, cactus_asset.rect, self.game_speed)) + else: + for l in self.last_obstacle: + if l.rect.right < SCREEN_WIDTH * 0.7 and random.randrange(0, 50) == 10: + self.last_obstacle.empty() + self.last_obstacle.add(Cactus(cactus_asset.images, cactus_asset.rect, self.game_speed)) + + if len(self.pteras) == 0 and random.randrange(0, 200) == 10 and self.counter > 500: + pteras_asset = self.images['pteras'] + for l in self.last_obstacle: + if l.rect.right < SCREEN_WIDTH * 0.8: + self.last_obstacle.empty() + self.last_obstacle.add(Ptera(pteras_asset.images, pteras_asset.rect, self.game_speed)) + + if self.dino.isDead: + self.score += self.rewards['loss'] + + self.dino.update() + self.cacti.update() + self.pteras.update() + self.ground.update() + self.scoreboard.update(self.dino.score) + + self.screen.fill(background_col) + self.ground.draw(self.screen) + self.scoreboard.draw(self.screen) + self.cacti.draw(self.screen) + self.pteras.draw(self.screen) + self.dino.draw(self.screen) + + def getScore(self): + return self.score + + def game_over(self): + return self.dino.isDead or self.score >= 150 + + def getGameState(self): + return {} + + # Helper methods + def load_sprite_sheet( + self, + sheet_name, + nx, + ny, + scale_x=-1, + scale_y=-1, + color_key=None, + ): + fullname = os.path.join(self.asset_dir, sheet_name) + sheet = pygame.image.load(fullname) + sheet = sheet.convert() + + sheet_rect = sheet.get_rect() + + sprites = [] + + size_x = sheet_rect.width / nx + size_y = sheet_rect.height / ny + + for i in range(0, ny): + for j in range(0, nx): + rect = pygame.Rect((j * size_x, i * size_y, size_x, size_y)) + image = pygame.Surface(rect.size) + image = image.convert() + image.blit(sheet, (0, 0), rect) + + if color_key is not None: + if color_key is -1: + color_key = image.get_at((0, 0)) + image.set_colorkey(color_key, pygame.RLEACCEL) + + if scale_x != -1 or scale_y != -1: + image = pygame.transform.scale(image, (scale_x, scale_y)) + + sprites.append(image) + + sprite_rect = sprites[0].get_rect() + + return sprites, sprite_rect + + def load_image( + self, + name, + size_x=-1, + size_y=-1, + color_key=None, + ): + fullname = os.path.join(self.asset_dir, name) + image = pygame.image.load(fullname) + image = image.convert() + if color_key is not None: + if color_key is -1: + color_key = image.get_at((0, 0)) + image.set_colorkey(color_key, pygame.RLEACCEL) + + if size_x != -1 or size_y != -1: + image = pygame.transform.scale(image, (size_x, size_y)) + + return image, image.get_rect() diff --git a/ple/games/trex/sprites/cacti-small.png b/ple/games/trex/sprites/cacti-small.png new file mode 100644 index 0000000000000000000000000000000000000000..9d354cec250d07a2c70e2f305825d9772824275b GIT binary patch literal 782 zcmeAS@N?(olHy`uVBq!ia0vp^XMos^gAGVFa8~;ODVAa<&kznEsNqQI0P;BtJR*x3 z82FBWFymBhK4}I9rVXAhjv*Cu-rlwKdt)GSw2(PCFklmtnA6#~2@zaE)eGmfZea52 zdg&Gr$)xR9qxR2&^MCx$d(!u&uC4BW)Z)Xzz_6uY>$AhlKVScTW&Ztpch>&e8NK#! z>*=Z;R{}48eZkbAYZ>!tp@rqVdva<2_kC3ZS700Ka*ZaR8q)zba9dRKx z0T0=2CYC|(&&w;e{F;1ZX`hDq!JxI1j-}ehyy}R0!_CReks)!y@A>-ocQ|j{yJ*nx zU{Ua;&bVCtC%;nwlRKz&nEya_dm3wWQVt`-nV^nddpX+dPq1Fa2$MY zb8ji1_?mWkpm#19G&HnG-AU29e27fZJ(524^-)Jn1M+Oq{6sQe}4Gly7O}L zGJvl6GG)yd+1+c`u2o)kCeH6@%(tc6 zue^4B+Ma019RY!d*4S=eZ@M$))rz;5Qf|Jk+A-r6C<0`hBL2xuh>LlZ;p!_i{j0{` zc{A2Nik{Nw_AlmePU@n+=6bIm1|9cM;Zc}jqZ(b+w&Hq9;Yv_cU-6oy`%WGhL22&~ zFM0lD@w})~u=tZ#E2hfyo!>SQ7!=Zn~1 zlakt0-AJ@-QLWX{jy?75X* zPd$GusutH-+`5jfIOoFhbzlC4{#aBl|KR54Y3~+<*Bfo09@C;79`}KEj!}3d-)CH`S0Jd1g1RhPFT2Vx#jveMh1ogp7Pb=2CrWJ{5<_? z_Kqk2&b};|S?9fP>yv08(Kqe=>rigS1}`odhKV8;3`%pu^cO5Q|6E(~yJGFqKg;+3 zui5_PYx>FU(`vF$ZohW%^VNfl0-lY`3X_=F9hTgke=;Ne!0PmUwr_nZ-an568~G&q z^^2dc9x!xl`Mp}hz4p)RzcuIxYyb^t}UhP~anwWNT-<EZ$l2$gU6ROL);2hbpP!^Tig17MKAf^-JkRB)wIj?f7jaXsg0w+p`$x zq|_-eCEtyZ4bs{#f9KxYzjc1@>Yzway&rWI980i}ytHy|1y5 z@7mwB$yW3Isuj5~zr3meMx4v9bwpG#FHAx8Ok_iH_px7>n#;M}`0l;??`zp?fDT&q`R~Q&-Y09# z?%%WtE~@D~-+mh8Mo8rDU8oBS=T2-C5cJEuyHD(e*8yE;eci}PIB)*?xhL=6lIsA5d~)>F%AfUfcW*twi7Jzw+yvd5rl$Kc{{6J)Qji&;D~iYb=&SQ^%6^+d@{jw49Q>2rL;GJYD@<);T3K F0RS?23^V`$ literal 0 HcmV?d00001 diff --git a/ple/games/trex/sprites/dino_ducking.png b/ple/games/trex/sprites/dino_ducking.png new file mode 100644 index 0000000000000000000000000000000000000000..5858b4419195ca820671fdb9fcb77675b53390d3 GIT binary patch literal 714 zcmeAS@N?(olHy`uVBq!ia0vp^Z-6+SgAGW&?$tgIq*#ibJVQ8upoSx*1IXtr@Q5sC zVBk9f!i-b3`J@>bm~uQ_978JRyuG_ISK3g7Ey22AqFQiDgU%B@XOC*@7J5we|Y%!^5Zyh zXZu&XmX$BoXV`J~@(XT{z}XS*lPBa)4h!exc8pVfv;6#heY^j^K0bX^oaw5y_RHq= z8R@H4r|p`zr#K*#dF*CCzrmO znNb!e!e;U#*R*KmLAxyuMw1&A)43Y8S73eKMzX>IMOq!%hOc z+>TxE53e&iy=L7vy^Xul3Z_dmWkzr;N>n_tx}5p!mYLf&pZm7gzw~TMTWf-pSW^bj z?mPF7y_vkw^E!S*@O^=&`+J?%U3ZlWw`}zs?eV zeWynRN6`(Q+rR3KjkDXXS$)6Pon+X2bD-r1~`7#I>nHJ9FAeSZD*)w^V7#J!f$IL^et5Hclb*WO(htG-(v z@UeS(faCu82%EVq3=M7X@|WBzWq(t@xSC;xFHCXCme*d>#SA7-v;5$*Z%Xp>!kcEf zb!Ub&pR~O3J*o5f6Cwz;@#_giMBdP3Q!J0OwT-E)3* zJ*)Dmd%Iva|C5Y^G7snU|7&^u;`-&=pMOm0n^~CdmSiPX{B{1XRqHvPui3ZCyO#BS z=gWwyvsa&9Jy?AExLc;|)phgTqfM?XeY@?>#Xq|JUrkT#yMOxPkKp*Vj&V)9u7p3m n627r#)BEpA|6s9#MqB-6ZqGTIzUqfqHb}NFeI5>FdjyN|0F zo_cAoi*_H;^&7>WiM#TCxr!t0UsERH{(E}@0Js+o7$|Hze>r#QQY!KL9G$Xh%W6~O z(J@7&K{I7NtV5PF&+tX!8LC*W@96%^x?iHr3{QG>p$7&EqX7ejZLQ7ENLo^ktFl@v z)7Fexa?i0#v3vWH%6ig6&-JjB%}!-2qXz~GqX7ejZSp41g^pe;tKB{`MZIgbb;a>U%s6|}>db#HEQ^3L z&;tX7(SU)%w$@@6Xk?0hwDIW+8=~u1S?1%6|8Sn^fq}wkz(8TCZ{&!2g2J;Tl$IRJ=gzyJW;;S01oDVAa<&kznEsNqQI0P;BtJR*x3 z82FBWFymBhK4}I9#xI^Ojv*Cu-rn8l#q21;dch@k%L)1DpT{+~2wi@~A~Wsg-J9jb ze&Q~XaeDoy4Z4>LGnmdzw`chM>(9P_fByaXR?~Uzz~wjW4Z55b7g^?H=x>&9$lW^k z_t(dt-k-m0wUgJ+gi(D~gRn1qeZkAQci6z}1D)Hd*z>JpR#z>zo^@}}bg$P>%)q*t z{I)!_ySn@Jgd82zqmgiW>)S;%O98cPRv+*cK0nyxD9J> zPv7>g;p(~2?c2WZxxC+BdQJut$nslvEq}ZzzP|On`S!H(L)YF^u78{H9ARH^6#JW* zwSL+6tSr{J9q3eh;IjMmgJ|oh=Wq6I-mz_4bDr&g_u1vv@o?kbeK(rJY+Zgo$T}Y` z_GS0Qt5%OL6~}x(f4t}1ZJ003_R5F7Zn52be(&^EcK`3~$t_p}38jDGweDYw-_N`E z_sd@EpSM15I|#B^xM0!I(hpnj|6F}-rTg2z=Q7T}_ygDS)VgBpZuzSr^OwVdVQmci z^_`K2V3t7)fSBKI&tCrSEC<|u4}azS=38(MDzZiTr0_w#X0?0gfr)~_)78&qol`;+ E0B&^_D*ylh literal 0 HcmV?d00001 From b687bed81ddf9f4fd0e6b227c9e0c5e2fffb432e Mon Sep 17 00:00:00 2001 From: void-main Date: Tue, 5 May 2020 09:46:58 +0800 Subject: [PATCH 2/4] add unit test --- tests/test_ple.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/test_ple.py b/tests/test_ple.py index a814040..963af77 100644 --- a/tests/test_ple.py +++ b/tests/test_ple.py @@ -85,6 +85,11 @@ def test_doom_not_defined(self): def invoke_doom(): DoomWrapper assert_raises(NameError,invoke_doom) + + def test_t_rex(self): + from ple.games.trex import TRex + game = TRex() + self.run_a_game(game) if __name__ == "__main__": From d5d528126d62cd8e8d893e147566c95983a1ab8e Mon Sep 17 00:00:00 2001 From: void-main Date: Tue, 5 May 2020 10:10:29 +0800 Subject: [PATCH 3/4] limit max_score default to 150 --- ple/games/trex/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ple/games/trex/__init__.py b/ple/games/trex/__init__.py index 3bfb90f..ad0f9f0 100644 --- a/ple/games/trex/__init__.py +++ b/ple/games/trex/__init__.py @@ -220,7 +220,7 @@ class TRex(base.PyGameWrapper): Screen height. """ - def __init__(self): + def __init__(self, max_score=150): actions = { 'jump': K_SPACE, 'duck': K_DOWN, @@ -232,6 +232,7 @@ def __init__(self): self.score = 0.0 self.game_tick = 0 self.game_speed = 4 + self.max_score = max_score self.dino = None self.ground = None @@ -387,7 +388,7 @@ def getScore(self): return self.score def game_over(self): - return self.dino.isDead or self.score >= 150 + return self.dino.isDead or self.score >= self.max_score def getGameState(self): return {} From 82386e5facfd0ffd0c8202e6f3db9fbb69d58c11 Mon Sep 17 00:00:00 2001 From: void-main Date: Tue, 5 May 2020 19:19:57 +0800 Subject: [PATCH 4/4] set max_score to 50; fix background image bug; make it easier to generate cacti and pteras --- ple/games/trex/__init__.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/ple/games/trex/__init__.py b/ple/games/trex/__init__.py index ad0f9f0..012f273 100644 --- a/ple/games/trex/__init__.py +++ b/ple/games/trex/__init__.py @@ -220,7 +220,7 @@ class TRex(base.PyGameWrapper): Screen height. """ - def __init__(self, max_score=150): + def __init__(self, max_score=50): actions = { 'jump': K_SPACE, 'duck': K_DOWN, @@ -258,8 +258,9 @@ def __init__(self, max_score=150): self.images['dino_ducking'] = SpriteAsset(images=dino_ducking, rect=dino_ducking_rect) bg, bg_rect = self.load_image('ground.png', -1, -1, -1) + bg_swap, bg_swap_rect = self.load_image('ground.png', -1, -1, -1) self.images['background'] = SpriteAsset(images=bg, rect=bg_rect) - self.images['background_swap'] = SpriteAsset(images=bg, rect=bg_rect) + self.images['background_swap'] = SpriteAsset(images=bg_swap, rect=bg_swap_rect) numbers, numbers_rect = self.load_sprite_sheet('numbers.png', 12, 1, 11, int(11 * 6 / 5), -1) self.images['numbers'] = SpriteAsset(images=numbers, rect=numbers_rect) @@ -350,18 +351,18 @@ def step(self, dt): if (p.x - p.width / 2) <= self.player.pos_x < (p.x - p.width / 2 + 4): self.score += self.rewards["positive"] - if len(self.cacti) < 2: + if len(self.cacti) < 4: cactus_asset = self.images['cactus'] if len(self.cacti) == 0: self.last_obstacle.empty() self.last_obstacle.add(Cactus(cactus_asset.images, cactus_asset.rect, self.game_speed)) else: for l in self.last_obstacle: - if l.rect.right < SCREEN_WIDTH * 0.7 and random.randrange(0, 50) == 10: + if l.rect.right < SCREEN_WIDTH * 0.7 and random.randrange(0, 10) == 0: self.last_obstacle.empty() self.last_obstacle.add(Cactus(cactus_asset.images, cactus_asset.rect, self.game_speed)) - if len(self.pteras) == 0 and random.randrange(0, 200) == 10 and self.counter > 500: + if len(self.pteras) == 0 and random.randrange(0, 50) == 0 and self.counter > 500: pteras_asset = self.images['pteras'] for l in self.last_obstacle: if l.rect.right < SCREEN_WIDTH * 0.8: