diff --git a/mu/logic.py b/mu/logic.py index eb48b103f..306f21704 100644 --- a/mu/logic.py +++ b/mu/logic.py @@ -140,10 +140,39 @@ "top.png", "bottom.png", "background.png", + "background1.png", + "background2.png", + "ball.png", + "bar.png", + "block.png", + "enemy_bullet.png", + "enemy1_1.png", + "enemy1_2.png", + "explosion1.png", + "explosion2.png", + "grass.png", + "player_bullet.png", + "player.png", + "tank_blue.png", + "tank_dark.png", + "tank_green.png", + "tank_red.png", + "tank_sand.png", + "wall.png", +] +EXAMPLE_PGZ_SOUNDS = [ + "sfx_exp_medium12.wav", + "sfx_sounds_interaction25.wav", +] +EXAMPLE_PGZ_MUSIC = [ + "main_theme.mp3", ] EXAMPLE_PGZ = [ "flappybird.py", "flappybird_neosoco.py", + "battle_city.py", + "breakout.py", + "tweenbee.py", ] EXAMPLE_NEOPIA = [ "01-01_KobiBot.py", @@ -1007,6 +1036,20 @@ def setup(self, modes): shutil.copy( path(sfx, "pygamezero/"), os.path.join(example_pgz_path + 'images', sfx) ) + if not os.path.exists(example_pgz_path + 'sounds'): + logger.debug("Creating directory: {}".format('sounds')) + os.makedirs(example_pgz_path + 'sounds') + for sfx in EXAMPLE_PGZ_SOUNDS: + shutil.copy( + path(sfx, "pygamezero/"), os.path.join(example_pgz_path + 'sounds', sfx) + ) + if not os.path.exists(example_pgz_path + 'music'): + logger.debug("Creating directory: {}".format('music')) + os.makedirs(example_pgz_path + 'music') + for sfx in EXAMPLE_PGZ_MUSIC: + shutil.copy( + path(sfx, "pygamezero/"), os.path.join(example_pgz_path + 'music', sfx) + ) # Neopia examples if not os.path.exists(example_neopia_path): logger.debug("Creating directory: {}".format(example_neopia_path)) diff --git a/mu/resources/pygamezero/background1.png b/mu/resources/pygamezero/background1.png new file mode 100644 index 000000000..bad92b7b1 Binary files /dev/null and b/mu/resources/pygamezero/background1.png differ diff --git a/mu/resources/pygamezero/background2.png b/mu/resources/pygamezero/background2.png new file mode 100644 index 000000000..c105a3c5c Binary files /dev/null and b/mu/resources/pygamezero/background2.png differ diff --git a/mu/resources/pygamezero/ball.png b/mu/resources/pygamezero/ball.png new file mode 100644 index 000000000..eeb974ddd Binary files /dev/null and b/mu/resources/pygamezero/ball.png differ diff --git a/mu/resources/pygamezero/bar.png b/mu/resources/pygamezero/bar.png new file mode 100644 index 000000000..daa3a3128 Binary files /dev/null and b/mu/resources/pygamezero/bar.png differ diff --git a/mu/resources/pygamezero/battle_city.py b/mu/resources/pygamezero/battle_city.py new file mode 100644 index 000000000..8e8477180 --- /dev/null +++ b/mu/resources/pygamezero/battle_city.py @@ -0,0 +1,190 @@ +from pgzhelper import * +import random + +WIDTH = 800 +HEIGHT = 600 + +bullets = [] +bullet_delay_cnt = 0 +BULLET_DELAY = 50 +enemy_bullets = [] +explosions = [] +winner = '' + +tank = Actor("tank_blue", (400, 575)) +tank.angle = 90 + +ENEMY_MOVE_DELAY = 20 +MAX_ENEMIES = 3 +enemies = [] +for i in range(MAX_ENEMIES): + enemy = Actor("tank_red") + enemy.angle = 270 + enemy.x = (i + 1) * WIDTH / (MAX_ENEMIES + 1) + enemy.y = 25 + enemy.move_cnt = 0 + enemies.append(enemy) + +walls = [] +WALL_SIZE = 50 +# 50x50 pixel sized walls +for x in range(int(WIDTH / WALL_SIZE)): + # Substract 2 to blank both first and last row + for y in range(int(HEIGHT / WALL_SIZE - 2)): + # Randomly leave blank without wall + if random.randint(0, 100) < 50: + wall = Actor("wall", anchor=("left", "top")) + wall.x = x * WALL_SIZE + wall.y = y * WALL_SIZE + WALL_SIZE # Add WALL_SIZE to blank first row + walls.append(wall) + + +def move_player(player): + # Save the original position of the tank + original_x = player.x + original_y = player.y + + if player == tank: # My tank + if keyboard.right: + player.angle = 0 + player.x += 2 + elif keyboard.left: + player.angle = 180 + player.x -= 2 + elif keyboard.up: + player.angle = 90 + player.y -= 2 + elif keyboard.down: + player.angle = 270 + player.y += 2 + else: # Enemy + if player.angle == 0: + player.x += 2 + elif player.angle == 90: + player.y -= 2 + elif player.angle == 180: + player.x -= 2 + elif player.angle == 270: + player.y += 2 + + # Return player to original position if colliding with wall + if player.collidelist(walls) != -1: + player.x = original_x + player.y = original_y + + # Don't drive off the screen! + if player.left < 0 or player.right > WIDTH \ + or player.top < 0 or player.bottom > HEIGHT: + player.x = original_x + player.y = original_y + + +def fire_bullets(player, bullets): + if player == tank: + bullet = Actor("bulletblue2") + else: + bullet = Actor("bulletred2") + + bullet.angle = player.angle + bullet.pos = player.pos + bullets.append(bullet) + + +def collide_bullets(bullets): + global winner + + for bullet in bullets: + if bullet.angle == 0: + bullet.x += 5 + elif bullet.angle == 90: + bullet.y -= 5 + elif bullet.angle == 180: + bullet.x -= 5 + elif bullet.angle == 270: + bullet.y += 5 + + # Walls + wall_index = bullet.collidelist(walls) + if wall_index != -1: + del walls[wall_index] + enemies.remove(enemies[hit]) + bullets.remove(bullet) + + # Out of screen + if bullet.x < 0 or bullet.x > 800 \ + or bullet.y < 0 or bullet.y > 600: + bullets.remove(bullet) + + # Enemies + if bullets != enemy_bullets: + enemy_index = bullet.collidelist(enemies) + if enemy_index != -1: + bullets.remove(bullet) + explosion = Actor("explosion3") + explosion.pos = enemies[enemy_index].pos + explosion.images = ["explosion3", "explosion4"] + explosion.fps = 8 + explosion.duration = 15 + explosions.append(explosion) + del enemies[enemy_index] + if len(enemies) == 0: + winner = "You" + else: + if bullet.colliderect(tank): + winner = "Enemy" + + # Animate explosion + for explosion in explosions: + explosion.animate() + explosion.duration -= 1 + if explosion.duration == 0: + explosions.remove(explosion) + + +def draw(): + screen.blit('grass', (0, 0)) + tank.draw() + for enemy in enemies: + enemy.draw() + for wall in walls: + wall.draw() + for bullet in bullets: + bullet.draw() + for bullet in enemy_bullets: + bullet.draw() + for explosion in explosions: + explosion.draw() + + if winner: + screen.draw.text(winner + " Win!", \ + midbottom=(WIDTH / 2, HEIGHT / 2), fontsize=100) + + +def update(): + global bullet_delay_cnt, enemy_move_cnt + + # This part is for my tank + if winner == '': + move_player(tank) + if bullet_delay_cnt == 0: # Re-launch possible after the delay ends + if keyboard.space: + sounds.sfx_exp_medium12.play() + fire_bullets(tank, bullets) + bullet_delay_cnt = BULLET_DELAY + else: + bullet_delay_cnt -= 1 + collide_bullets(bullets) + + # This part is for the enemies + for enemy in enemies: + choice = random.randint(0, 2) + if enemy.move_cnt > 0: # Move tank + enemy.move_cnt -= 1 + move_player(enemy) + elif choice == 0: # Init movement delay + enemy.move_cnt = ENEMY_MOVE_DELAY + elif choice == 1: # Turn directions + enemy.angle = random.randint(0, 3) * 90 + else: # Fire canon shot + fire_bullets(enemy, enemy_bullets) + collide_bullets(enemy_bullets) diff --git a/mu/resources/pygamezero/block.png b/mu/resources/pygamezero/block.png new file mode 100644 index 000000000..7f47b328b Binary files /dev/null and b/mu/resources/pygamezero/block.png differ diff --git a/mu/resources/pygamezero/breakout.py b/mu/resources/pygamezero/breakout.py new file mode 100644 index 000000000..0a5352263 --- /dev/null +++ b/mu/resources/pygamezero/breakout.py @@ -0,0 +1,82 @@ +from pgzhelper import * + +TITLE = 'Breakout' +WIDTH = 800 +HEIGHT = 600 + +GAP_FROM_SCREEN = 50 +ball = Actor('ball', (WIDTH / 2, HEIGHT / 2)) +ball.radius = ball.width / 2 +bar = Actor('bar', (WIDTH / 2, HEIGHT - GAP_FROM_SCREEN)) + +# Create 4 x 8 block dummy +blocks = [] +for block_row in range(4): + for block_col in range(8): + block = Actor( + 'block', + (block_col * 100, block_row * 32 + GAP_FROM_SCREEN), + anchor=('left', 'top') + ) + blocks.append(block) + +# Set velocity of ball +vx = 5 +vy = -5 + + +def draw(): + screen.blit('background', (0, 0)) + ball.draw() + bar.draw() + for block in blocks: + block.draw() + +def update(): + global vx, vy + + # Limit the movement of bar in the window + if bar.left < 0: + bar.left = 0 + if bar.right > WIDTH: + bar.right = WIDTH + + # Move the ball by velocity + ball.move_ip(vx, vy) + + # When the ball hits left or rignt wall + if ball.left < 0 or ball.right > WIDTH: + vx = -vx # Make x of velocity opposite direction + sounds.wall.play() + + # When the ball hits upper wall + if ball.top < 0: + vy = -vy # Make y of velocity opposite direction + sounds.wall.play() + + # When the ball hits the bar + if ball.circle_colliderect(bar) == True: + ball.y -= 10 # 10픽셀 수직으로 먼저 튀어오르기 + vy = -vy # Make y of velocity opposite direction + sounds.bar.play() + + # When the ball hits the block + b_index = ball.collidelist(blocks) + if b_index != -1: + vy = -vy # Make y of velocity opposite direction + sounds.block.play() + blocks.pop(b_index) + + # Exit the game + if ball.bottom > HEIGHT: + sounds.die.play() + game.exit() + + if not blocks: + sounds.win.play() + vx = 0 + vy = 0 + +def on_mouse_move(pos): + x, y = pos + bar.centerx = x \ No newline at end of file diff --git a/mu/resources/pygamezero/enemy1_1.png b/mu/resources/pygamezero/enemy1_1.png new file mode 100644 index 000000000..9ca2bf6bb Binary files /dev/null and b/mu/resources/pygamezero/enemy1_1.png differ diff --git a/mu/resources/pygamezero/enemy1_2.png b/mu/resources/pygamezero/enemy1_2.png new file mode 100644 index 000000000..bfa622429 Binary files /dev/null and b/mu/resources/pygamezero/enemy1_2.png differ diff --git a/mu/resources/pygamezero/enemy_bullet.png b/mu/resources/pygamezero/enemy_bullet.png new file mode 100644 index 000000000..13238c799 Binary files /dev/null and b/mu/resources/pygamezero/enemy_bullet.png differ diff --git a/mu/resources/pygamezero/explosion1.png b/mu/resources/pygamezero/explosion1.png new file mode 100644 index 000000000..56e911c47 Binary files /dev/null and b/mu/resources/pygamezero/explosion1.png differ diff --git a/mu/resources/pygamezero/explosion2.png b/mu/resources/pygamezero/explosion2.png new file mode 100644 index 000000000..434677535 Binary files /dev/null and b/mu/resources/pygamezero/explosion2.png differ diff --git a/mu/resources/pygamezero/grass.png b/mu/resources/pygamezero/grass.png new file mode 100644 index 000000000..8e2592beb Binary files /dev/null and b/mu/resources/pygamezero/grass.png differ diff --git a/mu/resources/pygamezero/main_theme.mp3 b/mu/resources/pygamezero/main_theme.mp3 new file mode 100644 index 000000000..9d459ec0e Binary files /dev/null and b/mu/resources/pygamezero/main_theme.mp3 differ diff --git a/mu/resources/pygamezero/player.png b/mu/resources/pygamezero/player.png new file mode 100644 index 000000000..a6c7f14bc Binary files /dev/null and b/mu/resources/pygamezero/player.png differ diff --git a/mu/resources/pygamezero/player_bullet.png b/mu/resources/pygamezero/player_bullet.png new file mode 100644 index 000000000..737e0847e Binary files /dev/null and b/mu/resources/pygamezero/player_bullet.png differ diff --git a/mu/resources/pygamezero/sfx_exp_medium12.wav b/mu/resources/pygamezero/sfx_exp_medium12.wav new file mode 100644 index 000000000..41e6afb70 Binary files /dev/null and b/mu/resources/pygamezero/sfx_exp_medium12.wav differ diff --git a/mu/resources/pygamezero/sfx_sounds_interaction25.wav b/mu/resources/pygamezero/sfx_sounds_interaction25.wav new file mode 100644 index 000000000..41a1d7a1b Binary files /dev/null and b/mu/resources/pygamezero/sfx_sounds_interaction25.wav differ diff --git a/mu/resources/pygamezero/tank_blue.png b/mu/resources/pygamezero/tank_blue.png new file mode 100644 index 000000000..e3d5912dc Binary files /dev/null and b/mu/resources/pygamezero/tank_blue.png differ diff --git a/mu/resources/pygamezero/tank_dark.png b/mu/resources/pygamezero/tank_dark.png new file mode 100644 index 000000000..25b26a4d3 Binary files /dev/null and b/mu/resources/pygamezero/tank_dark.png differ diff --git a/mu/resources/pygamezero/tank_green.png b/mu/resources/pygamezero/tank_green.png new file mode 100644 index 000000000..4c90e4dcd Binary files /dev/null and b/mu/resources/pygamezero/tank_green.png differ diff --git a/mu/resources/pygamezero/tank_red.png b/mu/resources/pygamezero/tank_red.png new file mode 100644 index 000000000..ca3f95b2e Binary files /dev/null and b/mu/resources/pygamezero/tank_red.png differ diff --git a/mu/resources/pygamezero/tank_sand.png b/mu/resources/pygamezero/tank_sand.png new file mode 100644 index 000000000..cf08c3337 Binary files /dev/null and b/mu/resources/pygamezero/tank_sand.png differ diff --git a/mu/resources/pygamezero/twinbee.py b/mu/resources/pygamezero/twinbee.py new file mode 100644 index 000000000..ab12adc00 --- /dev/null +++ b/mu/resources/pygamezero/twinbee.py @@ -0,0 +1,149 @@ +from pgzhelper import * +import random + +WIDTH = 800 +HEIGHT = 600 + +backgrounds = [] +background1 = Actor("background1", (WIDTH / 2, HEIGHT / 2)) +backgrounds.append(background1) +background2 = Actor("background2", (WIDTH / 2, (HEIGHT / 2) - HEIGHT)) +backgrounds.append(background2) +player = Actor("player", (400, 500)) + +MAX_BULLETS = 3 +bullets = [] + +enemies = [] +enemy_bullets = [] +explosions = [] + +score = 0 +game_over = False + +music.play('main_theme') + + +def move_player(): + if keyboard.right: + player.x += 5 + if keyboard.left: + player.x -= 5 + if keyboard.up: + player.y -= 5 + if keyboard.down: + player.y += 5 + if player.right > WIDTH: + player.right = WIDTH + if player.left < 0: + player.left = 0 + if player.bottom > HEIGHT: + player.bottom = HEIGHT + if player.top < 0: + player.top = 0 + + +def shoot_bullets(): + if keyboard.space and len(bullets) < MAX_BULLETS: + sounds.sfx_sounds_interaction25.play() + bullet_delay = 5 + bullet = Actor("player_bullet") + bullet.pos = player.pos + bullet.angle = 90 + bullets.append(bullet) + + for bullet in bullets: + bullet.move_forward(15) + if bullet.y < 0: + bullets.remove(bullet) + + +def create_enemies(): + if random.randint(0, 1000) > 980: + enemy = Actor("enemy1_1") + enemy.images = ["enemy1_1", "enemy1_2"] + enemy.fps = 5 + enemy.y = -50 + enemy.x = random.randint(100, WIDTH - 100) + enemy.direction = random.randint(-100, -80) + enemies.append(enemy) + + for enemy in enemies: + enemy.move_in_direction(4) + enemy.animate() + if enemy.top > HEIGHT: + enemies.remove(enemy) + if random.randint(0, 1000) > 990: + bullet = Actor("enemy_bullet") + bullet.pos = enemy.pos + bullet.angle = random.randint(0, 359) + enemy_bullets.append(bullet) + + for bullet in enemy_bullets: + bullet.move_forward(5) + if bullet.x < 0 or bullet.x > WIDTH or bullet.y < 0 or bullet.y > HEIGHT: + enemy_bullets.remove(bullet) + + + +def check_collision(): + global score, game_over + + for bullet in bullets: + enemy_index = bullet.collidelist(enemies) + if enemy_index != -1: + bullets.remove(bullet) + explosion = Actor("explosion1") + explosion.pos = enemies[enemy_index].pos + explosion.images = ["explosion1", "explosion2"] + explosion.fps = 8 + explosion.duration = 15 + explosions.append(explosion) + del enemies[enemy_index] +# enemies.remove(enemies[enemy_index]) + score += 1 + + for explosion in explosions: + explosion.animate() + explosion.duration -= 1 + if explosion.duration == 0: + explosions.remove(explosion) + + if player.collidelist(enemy_bullets) != -1 or player.collidelist(enemies) != -1: + game_over = True + + +def draw_text(): + screen.draw.text("Score " + str(score), (50, 0), color="black", fontsize=30) + if game_over: + screen.draw.text( + "Game over", midbottom=(WIDTH / 2, HEIGHT / 2), color="blue", fontsize=100 + ) + + +def draw(): + for background in backgrounds: + background.draw() + player.draw() + for enemy in enemies: + enemy.draw() + for bullet in bullets: + bullet.draw() + for explosion in explosions: + explosion.draw() + for bullet in enemy_bullets: + bullet.draw() + draw_text() + + +def update(): + for background in backgrounds: + background.y += 3 + if background.top > HEIGHT: + background.y = (HEIGHT / 2) - HEIGHT + + create_enemies() + if game_over == False: + move_player() + shoot_bullets() + check_collision() diff --git a/mu/resources/pygamezero/wall.png b/mu/resources/pygamezero/wall.png new file mode 100644 index 000000000..3251b8247 Binary files /dev/null and b/mu/resources/pygamezero/wall.png differ diff --git a/mu/wheels/__init__.py b/mu/wheels/__init__.py index 0fd23c5be..af4418f72 100644 --- a/mu/wheels/__init__.py +++ b/mu/wheels/__init__.py @@ -48,7 +48,7 @@ class WheelsBuildError(WheelsError): # For Neopia mode ("neopia", ("neopia>=0.3.6",)), # For pgzero's extenstion - ("pgzhelper", ("pgzhelper_rw>=1.0.8",)), + ("pgzhelper", ("pgzhelper_rw>=1.0.9",)), ]