ef:gameprojekt:gruppenseiten:gruppe5:start

Dies ist eine alte Version des Dokuments!


Bomb It mit Python

Wir wollen ein Spiel programmieren, in welchem man mit dem Spieler auf einem Feld herumlaufen kann. Es gibt fixe Hindernisse und auch zerstörbare. Der Spieler kann Bomben platzieren. Bomben zerstören Hindernisse, welche dann Item droppen. Wenn man die Items aufsammelt, bekommt der Spieler ein Upgrade. Das Spiel spielt man zu zweit. Der Spieler der am längsten überlebt gewinnt. Andere Spieler werden durch Bomben getötet. Spieler 1 spielt mit W,A,S,D und Leertaste und Spieler 2 spielt mit dem Pfeiltasten und Enter.

import arcade
import random

#Scaling of Tiles from Tilset and of Player
TILE_SCALING = 1
PLAYER_SCALING = 0.34

#Scaling of Sprites
NATIVE_SPRITE_SIZE = 32
SPRITE_SCALING = 1
SPRITE_SIZE = int(NATIVE_SPRITE_SIZE * SPRITE_SCALING)

#Scaling of the Bomb
BOMB_SCALING = 0.2

#Datas for cration of Window Class
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 800
SCREEN_TITLE = "BombIt"
GRID_PIXEL_SIZE = NATIVE_SPRITE_SIZE * TILE_SCALING

#The Speed with witch the Player moves
MOVEMENT_SPEED = 1

#For the Creation of the Maze -> Do not Change!!!!
TILE_EMPTY = 0
TILE_CRATE = 1

# Gridsize of the Maze
# Maze must have an ODD number of rows and columns.
# Walls go on EVEN rows/columns.
# Openings go on ODD rows/columns
MAZE_HEIGHT = 21
MAZE_WIDTH = 21

#Maze Sprite Technologie
MERGE_SPRITES = False

#Create Empty Grid for the Maze
def create_empty_grid(width, height, default_value=TILE_EMPTY):
    """ Create an empty grid. """
    grid = []
    for row in range(height):
        grid.append([])
        for column in range(width):
            grid[row].append(default_value)
    return grid

#Create the Maze Structure
def make_maze_recursive_call(maze, top, bottom, left, right):
    """
    Recursive function to divide up the maze in four sections
    and create three gaps.
    Walls can only go on even numbered rows/columns.
    Gaps can only go on odd numbered rows/columns.
    Maze must have an ODD number of rows and columns.
    """

    # Figure out where to divide horizontally
    start_range = bottom + 2
    end_range = top - 1
    y = random.randrange(start_range, end_range, 2)

    # Do the division
    for column in range(left + 1, right):
        maze[y][column] = TILE_CRATE

    # Figure out where to divide vertically
    start_range = left + 2
    end_range = right - 1
    x = random.randrange(start_range, end_range, 2)

    # Do the division
    for row in range(bottom + 1, top):
        maze[row][x] = TILE_CRATE

    # Now we'll make a gap on 3 of the 4 walls.
    # Figure out which wall does NOT get a gap.
    wall = random.randrange(4)
    if wall != 0:
        gap = random.randrange(left + 1, x, 2)
        maze[y][gap] = TILE_EMPTY

    if wall != 1:
        gap = random.randrange(x + 1, right, 2)
        maze[y][gap] = TILE_EMPTY

    if wall != 2:
        gap = random.randrange(bottom + 1, y, 2)
        maze[gap][x] = TILE_EMPTY

    if wall != 3:
        gap = random.randrange(y + 1, top, 2)
        maze[gap][x] = TILE_EMPTY

    # If there's enough space, to a recursive call.
    if top > y + 3 and x > left + 3:
        make_maze_recursive_call(maze, top, y, left, x)

    if top > y + 3 and x + 3 < right:
        make_maze_recursive_call(maze, top, y, x, right)

    if bottom + 3 < y and x + 3 < right:
        make_maze_recursive_call(maze, y, bottom, x, right)

    if bottom + 3 < y and x > left + 3:
        make_maze_recursive_call(maze, y, bottom, left, x)


#Create the Maze
def make_maze_recursion(maze_width, maze_height):
    """ Make the maze by recursively splitting it into four rooms. """
    maze = create_empty_grid(maze_width, maze_height)

    # Start the recursive process
    make_maze_recursive_call(maze, maze_height - 1, 0, 0, maze_width - 1)
    return maze

#Class to Create the Player
class Player(arcade.Sprite):
    def update(self):
        """ Move the player """
        # Move player.
        # Remove these lines if physics engine is moving player.
        self.center_x += self.change_x
        self.center_y += self.change_y

        # Check for out-of-bounds
        if self.left < 0:
            self.left = 0
        elif self.right > SCREEN_WIDTH - 1:
            self.right = SCREEN_WIDTH - 1

        if self.bottom < 0:
            self.bottom = 0
        elif self.top > SCREEN_HEIGHT - 1:
            self.top = SCREEN_HEIGHT - 1
 
# Klasse für die Bombe definieren
class Bomb(arcade.Sprite): 
    def __init__(self, x, y):
        super().__init__(":resources:images/tiles/bomb.png", BOMB_SCALING)
        self.center_x = x
        self.center_y = y
        # Timer für die Explosion starten
        arcade.schedule(self.explode, 2)
        self.explosion_sound = arcade.load_sound(':resources:sounds/explosion2.wav')
    
    def explode(self, delta_time):
        self.append_texture(arcade.load_texture('./map/tiles/explosion.png'))
        self.set_texture(1)
        arcade.sound.play_sound(self.explosion_sound)
        arcade.unschedule(self.explode)
        arcade.schedule(self.remove_bomb, 1)

    #Bombe aus der Sprite-Liste entfernen        
    def remove_bomb(self, bomb):
        self.remove_from_sprite_lists()
        arcade.unschedule(self.remove_bomb)


class MyGame(arcade.Window):

    def __init__(self):

        super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)

        self.tile_map = None

        self.player_list = None
        self.wall_list = None
        self.ground_list = None
        self.fence_list = None
        self.wall_list = None

        self.player_sprite = None

        self.physics_engine = None


    def setup(self):

        self.player_list = arcade.SpriteList()
        self.wall_list = arcade.SpriteList()
        self.bomb_list = arcade.SpriteList()
        self.exploded_list = arcade.SpriteList()

                # Create the maze
        maze = make_maze_recursion(MAZE_WIDTH, MAZE_HEIGHT)

        # Create sprites based on 2D grid
        if not MERGE_SPRITES:
            # This is the simple-to-understand method. Each grid location
            # is a sprite.
            for row in range(MAZE_HEIGHT):
                for column in range(MAZE_WIDTH):
                    if maze[row][column] == 1:
                        wall = arcade.Sprite("./map/tiles/rock_big.png", SPRITE_SCALING)
                        wall.center_x = (column * SPRITE_SIZE + SPRITE_SIZE / 2)+64
                        wall.center_y = (row * SPRITE_SIZE + SPRITE_SIZE / 2)+64
                        self.wall_list.append(wall)
        else:
            # This uses new Arcade 1.3.1 features, that allow me to create a
            # larger sprite with a repeating texture. So if there are multiple
            # cells in a row with a wall, we merge them into one sprite, with a
            # repeating texture for each cell. This reduces our sprite count.
            for row in range(MAZE_HEIGHT):
                column = 0
                while column < len(maze):
                    while column < len(maze) and maze[row][column] == 0:
                        column += 1
                    start_column = column
                    while column < len(maze) and maze[row][column] == 1:
                        column += 1
                    end_column = column - 1

                    column_count = end_column - start_column + 1
                    column_mid = (start_column + end_column) / 2

                    wall = arcade.Sprite("./map/tiles/rock_big.png", SPRITE_SCALING)
                    wall.center_x = (column_mid * SPRITE_SIZE + SPRITE_SIZE / 2)+64
                    wall.center_y = (row * SPRITE_SIZE + SPRITE_SIZE / 2)+64
                    wall.width = SPRITE_SIZE * column_count
                    self.wall_list.append(wall)

        self.player_sprite = Player(
            ":resources:images/animated_characters/robot/robot_idle.png",
            PLAYER_SCALING,
        )

        playerPosition = random.randrange(4)
        if(playerPosition == 0):
            self.player_sprite.center_x = 80
            self.player_sprite.center_y = 80
        elif(playerPosition == 1):
            self.player_sprite.center_x = 800-80
            self.player_sprite.center_y = 80
        elif(playerPosition == 2):
            self.player_sprite.center_x = 800-80
            self.player_sprite.center_y = 800-80
        elif(playerPosition == 3):
            self.player_sprite.center_x = 80
            self.player_sprite.center_y = 800-80
        else:
            self.player_sprite.center_x = 80
            self.player_sprite.center_y = 80

        self.player_list.append(self.player_sprite)

        map_name = "map/map1.json"

        layer_options = {
            "Ground": {"use_spatial_hash": True},
            "Fences": {"use_spatial_hash": True},
        }

        self.tile_map = arcade.load_tilemap(
            './map1.json', layer_options=layer_options, scaling=TILE_SCALING
        )
        self.end_of_map = self.tile_map.width * GRID_PIXEL_SIZE

        self.ground_list = self.tile_map.sprite_lists["Ground"]
        self.fence_list = self.tile_map.sprite_lists["Fences"]

        if self.tile_map.background_color:
            arcade.set_background_color(self.tile_map.background_color)

        self.physics_engine = arcade.PhysicsEngineSimple(self.player_sprite, [self.fence_list, self.wall_list])

    def on_draw(self):
        self.clear()

        
        self.ground_list.draw()
        self.fence_list.draw()
        self.player_list.draw()
        self.wall_list.draw()
        self.bomb_list.draw()
        self.exploded_list.draw()
         

    def on_key_press(self, key, modifiers):

        if key == arcade.key.UP:
            self.player_sprite.change_y = MOVEMENT_SPEED
        elif key == arcade.key.DOWN:
            self.player_sprite.change_y = -MOVEMENT_SPEED
        elif key == arcade.key.LEFT:
            self.player_sprite.change_x = -MOVEMENT_SPEED
        elif key == arcade.key.RIGHT:
            self.player_sprite.change_x = MOVEMENT_SPEED

        # Bombe legen mit der Leertaste
        elif key == arcade.key.SPACE:
            bomb = Bomb((self.player_sprite.center_x//32)*32+16, (self.player_sprite.center_y//32)*32+16)
            self.bomb_list.append(bomb)

    def on_key_release(self, key, modifiers):
        
        if key == arcade.key.UP or key == arcade.key.DOWN:
            self.player_sprite.change_y = 0
        elif key == arcade.key.LEFT or key == arcade.key.RIGHT:
            self.player_sprite.change_x = 0

    def on_update(self, delta_time):



        self.player_list.update()
        self.physics_engine.update()




def main():
    window = MyGame()
    window.setup()
    arcade.run()


if __name__ == "__main__":
    main()

  • ef/gameprojekt/gruppenseiten/gruppe5/start.1675671702.txt.gz
  • Zuletzt geändert: 2023/02/06 09:21
  • von schallern