import pygame
import random
import csv
import button
pygame.init()
Width = 1900
Height = 950
screen = pygame.display.set_mode((Width, Height))
pygame.display.set_caption("Dark Souls IV")
#set framerate
clock = pygame.time.Clock()
FPS = 60
font = pygame.font.Font("C:/Users/paull/OneDrive/Dokumente/Informatik/Pixeled.ttf", 15)
Black = (0, 0, 0)
#def game variables
Gravity = 0.7
Rows = 50
Cols = 100
Tile_size = Height // Rows
Tile_types = 15
level = 1
start_game = False
level_complete = False
#def player action variables
moving_left = False
moving_right = False
shoot = False
interaction = False
#load images
#buttons
start_img = pygame.image.load("C:/Users/paull/OneDrive/Dokumente/Informatik/img/Buttons/start_button.png")
end_img = pygame.image.load("C:/Users/paull/OneDrive/Dokumente/Informatik/img/Buttons/end_button.png")
reset_img = pygame.image.load("C:/Users/paull/OneDrive/Dokumente/Informatik/img/Buttons/reset_button.png")
#store tiles in a list
img_list = []
for x in range(Tile_types):
img = pygame.image.load(f"C:/Users/paull/OneDrive/Dokumente/Informatik/img/Tile/{x}.png")
img = pygame.transform.scale(img, (Tile_size *1, Tile_size *1))
img_list.append(img)
bullet_img = pygame.image.load("C:/Users/paull/OneDrive/Dokumente/Informatik/img/Abilities/deamon_shot.png").convert_alpha()
bullet_img = pygame.transform.scale(bullet_img, (bullet_img.get_width() *2, bullet_img.get_width() *2))
#def colours
bg = (66, 79, 179)
hud = (77,77,77)
Grey = (112,111,110)
Green = (0,255,0)
Red = (255,0,0)
def draw_bg():
screen.fill(bg)
def reset_level():
enemy_group.empty()
bullet_group.empty()
chest_group.empty()
decoration_group.empty()
tp_group.empty()
boost_group.empty()
data = []
for Row in range(Rows):
r = [-1]* Cols
data.append(r)
return data
class Soldier(pygame.sprite.Sprite):
def __init__(self, char_type, x, y, scale, speed):
pygame.sprite.Sprite.__init__(self)
self.alive = True
self.char_type = char_type
self.speed = speed
self.shoot_cooldown = 0
self.health = 100
self.money = 1000
self.max_health = self.health
self.direction = -1
self.vel_y = 0
self.jump = False
self.in_air = True
self.flip = False
self.move_counter = 0
self.vision = pygame.Rect(0, 0, 150, 20)
self.idling = False
self.idling_counter = 0
img = pygame.image.load("C:/Users/paull/OneDrive/Dokumente/Informatik/img/Tile/11.png").convert_alpha()
self.image = pygame.transform.scale(img, (int(img.get_width() * scale), int(img.get_height() * scale)))
self.rect = self.image.get_rect()
self.rect.center = (x, y)
self.width = self.image.get_width()
self.height = self.image.get_height()
def update(self):
self.check_alive()
#self.update_animation()
self.move(moving_left, moving_right)
if self.shoot_cooldown > 0:
self.shoot_cooldown -= 1
def move(self, moving_left, moving_right):
dx = 0
dy = 0
if moving_left:
dx = -self.speed
self.flip = True
self.direction = -1
if moving_right:
dx = self.speed
self.flip = False
self.direction = 1
if self.jump == True and self.in_air == False:
self.vel_y = -7
self.jump = False
self.in_air = True
self.vel_y += Gravity
if self.vel_y > 10:
self.vel_y = 10
dy += self.vel_y
for tile in world.obstacle_list:
if tile[1].colliderect(self.rect.x + dx, self.rect.y, self.width, self.height):
dx = 0
if tile[1].colliderect(self.rect.x, self.rect.y + dy, self.width, self.height):
if self.vel_y < 0:
dy = tile[1].bottom - self.rect.top
self.vel_y = 0
elif self.vel_y >= 0:
dy = tile[1].top - self.rect.bottom
self.vel_y = 0
self.in_air = False
if self.rect.bottom > Height:
self.health = 0
if self.char_type == "player":
if self.rect.left + dx < 0 or self.rect.right + dx > Width:
dx = 0
if self.char_type == "player":
if self.rect.top + dy < 0 or self.rect.bottom + dy > Height:
dy = 0
self.rect.x += dx
self.rect.y += dy
def shoot(self):
if self.shoot_cooldown == 0:
self.shoot_cooldown = 20
bullet = Bullet(self.rect.centerx + (0.75 * self.rect.size[0] * self.direction), self.rect.centery, self.direction)
bullet_group.add(bullet)
def check_alive(self):
if self.health <= 0:
self.health = 0
self.speed = 0
self.alive = False
def draw(self):
screen.blit(pygame.transform.flip(self.image, self.flip, False), self.rect)
class Enemy(pygame.sprite.Sprite):
def __init__(self, char_type, x, y, speed):
pygame.sprite.Sprite.__init__(self)
self.alive = True
self.char_type = char_type
self.speed = speed
self.shoot_cooldown = 0
self.health = 100
self.max_health = self.health
self.direction = 1
self.vel_y = 0
self.jump = False
self.in_air = True
self.flip = False
self.move_counter = 0
self.vision = pygame.Rect(0, 0, 150, 20)
self.idling = False
self.idling_counter = 0
enemy_img = []
for x in range(1,3):
img = pygame.image.load(f"C:/Users/paull/OneDrive/Dokumente/Informatik/img/Enemy/{x}.PNG").convert_alpha()
self.image = pygame.transform.scale(img, (int(img.get_width() * 0.3), int(img.get_height() * 0.3)))
self.rect = self.image.get_rect()
self.rect.center = (x, y)
self.width = self.image.get_width()
self.height = self.image.get_height()
enemy_img.append(img)
def update(self):
self.check_alive()
#self.update_animation()
self.move(moving_left, moving_right)
if self.shoot_cooldown > 0:
self.shoot_cooldown -= 1
def move(self, moving_left, moving_right):
#reset movement variables
dx = 0
dy = 0
#assign movement variables if moving left or right
if moving_left:
dx = -self.speed
self.flip = True
self.direction = -1
if moving_right:
dx = self.speed
self.flip = False
self.direction = 1
#jump
if self.jump == True and self.in_air == False:
self.vel_y = -11
self.jump = False
self.in_air = True
#apply gravity
self.vel_y += Gravity
if self.vel_y > 10:
self.vel_y
dy += self.vel_y
#check for collision
for tile in world.obstacle_list:
#check collision in the x direction
if tile[1].colliderect(self.rect.x + dx, self.rect.y, self.width, self.height):
dx = 0
#if the ai has hit a wall then make it turn around
if self.char_type == 'enemy':
self.direction *= -1
self.move_counter = 0
#check for collision in the y direction
if tile[1].colliderect(self.rect.x, self.rect.y + dy, self.width, self.height):
#check if below the ground, i.e. jumping
if self.vel_y < 0:
self.vel_y = 0
dy = tile[1].bottom - self.rect.top
#check if above the ground, i.e. falling
elif self.vel_y >= 0:
self.vel_y = 0
self.in_air = False
dy = tile[1].top - self.rect.bottom
#check if fallen off the map
if self.rect.bottom > Height:
self.health = 0
#check if going off the edges of the screen
if self.char_type == 'player':
if self.rect.left + dx < 0 or self.rect.right + dx > Width:
dx = 0
#update rectangle position
self.rect.x += dx
self.rect.y += dy
return level_complete
def shoot(self):
if self.shoot_cooldown == 0:
self.shoot_cooldown = 50
bullet = Bullet(self.rect.centerx + (0.75 * self.rect.size[0] * self.direction), self.rect.centery, self.direction)
bullet_group.add(bullet)
def ai(self):
if self.alive and player.alive:
if self.idling == False and random.randint(1, 200) == 1:
self.idling = True
#check if the ai in near the player
if self.vision.colliderect(player.rect):
#shoot
self.shoot()
else:
if self.idling == False:
if self.direction == 1:
self.flip = True
ai_moving_right = True
else:
self.flip = False
ai_moving_right = False
ai_moving_left = not ai_moving_right
self.move(ai_moving_left, ai_moving_right)
self.move_counter += 1
#update ai vision as the enemy moves
self.vision.center = (self.rect.centerx + 75 * self.direction, self.rect.centery)
if self.move_counter > Tile_size:
self.direction *= -1
self.move_counter *= -1
else:
self.idling_counter -= 1
if self.idling_counter <= 0:
self.idling = False
else:
self.kill()
player.money += 100
def check_alive(self):
if self.health <= 0:
self.health = 0
self.speed = 0
self.alive = False
def draw(self):
screen.blit(pygame.transform.flip(self.image, self.flip, False), self.rect)
class World():
def __init__(self):
self.obstacle_list = []
def process_data(self, data):
self.level_length = len(data[0])
for y, row in enumerate(data):
for x, tile in enumerate(row):
if tile >= 0:
img = img_list[tile]
img_rect = img.get_rect()
img_rect.x = x * Tile_size
img_rect.y = y * Tile_size
tile_data = (img, img_rect)
if tile >= 0 and tile <= 7:
self.obstacle_list.append(tile_data)
elif tile >=8 and tile <= 10:
decoration = Decoration(img, x * Tile_size, y * Tile_size)
decoration_group.add(decoration)
elif tile == 11:
player = Soldier("player", x * Tile_size, y * Tile_size, 1, 3)
health_bar = Health(10, 10, player.health, player.health)
money_counter = Money(10, 10, player.money)
elif tile == 12:
chest = Chest(img, x * Tile_size, y * Tile_size)
chest_group.add(chest)
elif tile == 13:
tp = Tp(img, x * Tile_size, y * Tile_size, player.money)
tp_group.add(tp)
elif tile == 14:
boost = Boost(img, x * Tile_size, y * Tile_size)
boost_group.add(boost)
return player, health_bar, money_counter
def draw(self):
for tile in self.obstacle_list:
screen.blit(tile[0], tile[1])
class Decoration(pygame.sprite.Sprite):
def __init__(self, img, x, y):
pygame.sprite.Sprite.__init__(self)
self.image = img
self.rect = self.image.get_rect()
self.rect.topleft = (x, y)
class Chest(pygame.sprite.Sprite):
def __init__(self, img, x, y):
pygame.sprite.Sprite.__init__(self)
self.image = img
self.rect = self.image.get_rect()
self.rect.midtop = (x + Tile_size // 2, y + (Tile_size- self.image.get_height()))
class Tp(pygame.sprite.Sprite):
def __init__(self, img, x, y, money):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.transform.scale(img, (Tile_size * 2.5, Tile_size * 2.3))
self.rect = self.image.get_rect()
self.rect.midtop = (x + Tile_size // 2, y + (Tile_size- self.image.get_height()))
self.money = money
def update(self):
if self.money >= 1000:
if pygame.sprite.spritecollide(player, tp_group, False):
if player.alive:
pass
#level = level+1
#level_complete = True
class Boost(pygame.sprite.Sprite):
def __init__(self, img, x, y):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.transform.scale(img, (Tile_size * 3, Tile_size * 3))
self.rect = self.image.get_rect()
self.rect.midtop = (x + Tile_size // 2, y + (Tile_size- self.image.get_height()))
def update(self):
if pygame.sprite.collide_rect(self, player):
player.rect.y -= 50
player.vel_y = -10
class Money():
def __init__(self, x, y, money):
self.x = x
self.y = y
self.money = money
def draw(self, money):
self.money = money
pygame.draw.rect(screen, Grey, (self.x -2 , self.y + 30, 80, 24))
money_text = str(money)
screen.blit((font.render(money_text, True, "Black")), (self.x, self.y + 17))
class Health():
def __init__(self, x, y, health, max_health):
self.x = x
self.y = y
self.health = health
self.max_health = max_health
def draw(self, health):
self.health = health
ratio = self.health / self.max_health
pygame.draw.rect(screen, Grey, (self.x -2 , self.y - 2, 154, 24))
pygame.draw.rect(screen, Red, (self.x, self.y, 150, 20))
pygame.draw.rect(screen, Green, (self.x, self.y, 150 * ratio, 20))
class Bullet(pygame.sprite.Sprite):
def __init__(self, x, y, direction):
pygame.sprite.Sprite.__init__(self)
self.speed = 10
self.image = bullet_img
self.rect = self.image.get_rect()
self.rect.center = (x, y)
self.direction = direction
def update(self):
self.rect.x += (self.direction * self.speed)
if self.rect.right < 0 or self.rect.left > Width:
self.kill()
for tile in world.obstacle_list:
if tile[1].colliderect(self.rect):
self.kill()
if pygame.sprite.spritecollide(player, bullet_group, False):
if player.alive:
player.health -= 2
self.kill()
for enemy in enemy_group:
if pygame.sprite.spritecollide(enemy, bullet_group, False):
if enemy.alive:
enemy.health -= 25
self.kill()
#Create Buttons
start_button = button.Button(Width // 2- 0, Height //2 -100, start_img, 5)
end_button = button.Button(Width // 2- 0, Height //2 + 50, end_img, 5)
reset_button = button.Button(Width // 2, Height //2 - 50, end_img, 5)
#Sprite Groups
enemy_group = pygame.sprite.Group()
decoration_group = pygame.sprite.Group()
chest_group = pygame.sprite.Group()
tp_group = pygame.sprite.Group()
boost_group = pygame.sprite.Group()
bullet_group = pygame.sprite.Group()
world_data = []
for Row in range(Rows):
r = [-1]* Cols
world_data.append(r)
with open(f"C:/Users/paull/OneDrive/Dokumente/Informatik/img/Level/level{level}_data.csv", newline="") as csvfile:
reader = csv.reader(csvfile, delimiter=";")
for x, row in enumerate(reader):
for y, tile in enumerate(row):
world_data[x][y] = int(tile)
world = World()
player, health_bar, money_counter = world.process_data(world_data)
enemy = Enemy('enemy', 300, 200, 1)
enemy_group.add(enemy)
run = True
while run:
clock.tick(FPS)
if start_game == False:
screen.fill(bg)
if start_button.draw(screen):
start_game = True
if end_button.draw(screen):
run = False
else:
draw_bg()
world.draw()
health_bar.draw(player.health)
money_counter.draw(player.money)
player.update()
player.draw()
for enemy in enemy_group:
enemy.ai()
enemy.update()
enemy.draw()
#update and draw groups
decoration_group.update()
chest_group.update()
tp_group.update()
boost_group.update()
bullet_group.update()
enemy_group.update()
decoration_group.draw(screen)
chest_group.draw(screen)
tp_group.draw(screen)
boost_group.draw(screen)
bullet_group.draw(screen)
enemy_group.draw(screen)
if player.alive:
if shoot:
player.shoot()
else:
if reset_button.draw(screen):
with open(f"C:/Users/paull/OneDrive/Dokumente/Informatik/img/Level/level{level}_data.csv", newline="") as csvfile:
reader = csv.reader(csvfile, delimiter=";")
for x, row in enumerate(reader):
for y, tile in enumerate(row):
world_data[x][y] = int(tile)
world = World()
player, health_bar, money_counter = world.process_data(world_data)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
shoot = True
if event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
shoot = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
moving_left = True
if event.key == pygame.K_d:
moving_right = True
if event.key == pygame.K_e:
interaction = True
if event.key == pygame.K_SPACE:
player.jump = True
if event.key == pygame.K_ESCAPE:
run = False
if event.type == pygame.KEYUP:
if event.key == pygame.K_a:
moving_left = False
if event.key == pygame.K_d:
moving_right = False
if event.key == pygame.K_e:
interaction = False
pygame.display.update()
pygame.quit()
So first of all thank you for helping.
I am working on a School Projekt and wanted to make a game. I use a csv file to load in my map. But somehow I get an error and dont know how to fix it.
IndexError: list assignment index out of range
I do understand what this error means but cant figure out how to fix it.
I am thankful for every answer and hope this Problem can be solved.
Thank you
First thing I tried was to check the “tile_types” variable but couldn’t find the solution here.
Next I looked at the csv file but vagain didn’t found a solution.
Paul is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
1