My code:
import pgzrun, pgzero, pygame, math, time, random, os
from pgzero.builtins import Actor, animate, keyboard
screen = pgzero.screen.Screen
# screen
WIDTH = 800
HEIGHT = 600
pygame.init()
pygame.mouse.set_visible(False)
os.chdir("c:/Users/carter.breshears/Documents/CSPVSC/Final/Images")
font = pygame.font.Font("Minecraft.ttf", 30)
# player images
playerIdle = pygame.image.load("playerIdle.png")
playerWalkImages = [pygame.image.load("playerRun1.png"), pygame.image.load("playerRun2.png"), pygame.image.load("playerRun3.png"), pygame.image.load("playerRun4.png")]
#variables
# gameloop
gameover = False
# classes
class Player:
def __init__(self, x, y):
self.x = x
self.y = y
self.animationCount = 0
self.movingRight = False
self.movingLeft = False
self.movingUp = False
self.movingDown = False
def main(self, screen):
if self.animationCount + 1 >= 24:
self.animationCount = 0
self.animationCount += 1
if self.movingRight or self.movingUp or self.movingDown:
screen.blit(pygame.transform.scale(playerWalkImages[self.animationCount//6], (40,74)), (self.x, self.y))
elif self.movingLeft:
screen.blit(pygame.transform.scale(pygame.transform.flip(playerWalkImages[self.animationCount//6], True, False), (40,74)), (self.x, self.y))
else:
screen.blit(pygame.transform.scale(playerIdle, (40,74)), (self.x, self.y)) ##### This line!
self.movingRight = False
self.movingLeft = False
self.movingUp = False
self.movingDown = False
class PlayerBullet:
def __init__(self, x, y, mouseX, mouseY):
self.x = x
self.y = y
self.mouseX = mouseX
self.mouseY = mouseY
speed = 6
self.angle = math.atan2(y - mouseY, x - mouseX)
self.x_vel = math.cos(self.angle) * speed
self.y_vel = math.sin(self.angle) * speed
def main(self, screen):
self.x -= int(self.x_vel)
self.y -= int(self.y_vel)
print("bang")
pygame.draw.circle(screen, "yellow", (self.x+16, self.y+16), 5)
class InvaderEnemy:
def __init__(self, x, y):
self.x = x
self.y = y
self.greenAnimationImages = [pygame.image.load("virus g.png"), pygame.image.load("virus g2.png")]
self.yellowAnimationImages = [pygame.image.load("virus y.png"), pygame.image.load("virus y2.png")]
self.blueAnimationImages = [pygame.image.load("virus b.png"), pygame.image.load("virus b2.png")]
self.redAnimationImages = [pygame.image.load("virus r.png"), pygame.image.load("virus r2.png")]
self.animationCount = 0
self.velocity = 1
self.lerpFactor = 0.05
def main(self, screen):
if self.animationCount + 1 == 8:
self.animationCount = 0
self.animationCount += 1
spawnPos = (random.randint(-1000, 1000), random.randint(-1000, 1000))
targetVector = pygame.math.Vector2(player.x, player.y)
enemyVector = pygame.math.Vector2(spawnPos.x, spawnPos.y)
newEnemyVector = pygame.math.Vector2(spawnPos.x, spawnPos.y)
distance = enemyVector.distance_to(targetVector)
minDistance = 25
maxDistance = 1000
if distance > minDistance:
directionVector = (targetVector - enemyVector)/2
self.minStep = max(0, distance - maxDistance)
self.maxStep = distance - minDistance
self.stepDistance = self.minStep + (self.maxStep - self.minStep) * self.lerpFactor
newEnemyVector = enemyVector + directionVector * self.stepDistance
return(newEnemyVector.x, newEnemyVector.y)
# player
player = Player(400,300)
displayScroll = [0,0]
# shooting
playerBullets = []
# invader
invaders = []
invaderEnemy = InvaderEnemy(100,100)
invaderSpawnRate = 1
# functions
def update():
# movement
keys = pygame.key.get_pressed()
if keys[pygame.K_a]:
displayScroll[0] -= 2
player.movingLeft = True
for bullet in playerBullets:
bullet.x += 2
if keys[pygame.K_d]:
displayScroll[0] += 2
player.movingRight = True
for bullet in playerBullets:
bullet.x -= 2
if keys[pygame.K_w]:
displayScroll[1] -= 2
player.movingUp = True
for bullet in playerBullets:
bullet.y += 2
if keys[pygame.K_s]:
displayScroll[1] += 2
player.movingDown = True
for bullet in playerBullets:
bullet.y -= 2
player.main(screen)
# shooting
mouseX, mouseY = pygame.mouse.get_pos()
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
playerBullets.append(PlayerBullet(player.x, player.y, mouseX, mouseY))
for bullet in playerBullets:
PlayerBullet.main(screen)
#enemies
global spawnPos
if time.perf_counter() - invaderSpawnRate > 1:
invaders.append(InvaderEnemy(spawnPos.x, spawnPos.y))
for invader in invaders:
InvaderEnemy.main(screen)
# run
pgzrun.go()
I've tried everything I know of, Im new to this. I know that it worked before because I tested this on my home computer but whenever I downloaded the file on my school computer it stopped working so something must have changed between python versions.
Related
This question already exists:
in my shooting game, my players are positioned on top of my head (player) which is very abnormal and also once the game starts, they start shooting [closed]
Closed 6 months ago.
i have earlier tried to format my question properly but i hope this one is better. am creating a shooter game from https://github.com/russs123/Shooter. however my problem is that my enemies are stacked vertically upwards in a straight line when i run my game and the enemies don't start off at their predefined location. below is the full code i wrote. perhaps if you can run it, it will be better understood.
import pygame, sys
from player import Player
import os
import random
import csv
pygame.init()
screen_width = 600
scroll_thresh = 200
screen_scroll = 0
bg_scroll = 0
screen_height = int(screen_width * 0.8)
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Shooter Game")
clock = pygame.time.Clock()
fps = 60
# define game variables
GRAVITY = 0.75
level = 1
ROWS = 16
COLS = 150
TILE_SIZE = screen_height // ROWS
TILE_TYPES = 21
img_list = []
for x in range(TILE_TYPES):
img = pygame.image.load(f"img/tile/{x}.png")
img = pygame.transform.scale(img, (TILE_SIZE, TILE_SIZE))
img_list.append(img)
# color variables
bg = (144, 201, 120)
RED = (255, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
BLACK = (0, 0, 0)
# define player action variables
moving_left = False
moving_right = False
shoot = False
grenade = False
grenade_thrown = False
# load up images
pine1_img = pygame.image.load("img/Background/pine1.png").convert_alpha()
pine2_img = pygame.image.load("img/Background/pine2.png").convert_alpha()
mountain_img = pygame.image.load("img/Background/mountain.png").convert_alpha()
sky_cloud_img = pygame.image.load("img/Background/sky_cloud.png").convert_alpha()
bullet_img = pygame.image.load("img/icons/bullet.png").convert_alpha()
grenade_img = pygame.image.load("img/icons/grenade.png").convert_alpha()
# pick up boxes
health_box_img = pygame.image.load("img/icons/health_box.png").convert_alpha()
ammo_box_img = pygame.image.load("img/icons/ammo_box.png").convert_alpha()
grenade_box_img = pygame.image.load("img/icons/grenade_box.png").convert_alpha()
# name_dt = type(name)
item_boxes = {
"Health": health_box_img,
"Ammo": ammo_box_img,
"Grenade": grenade_img,
}
# define fonts
font = pygame.font.SysFont("Futura", 30)
def draw_text(text, font, text_col, x, y):
img = font.render(text, True, text_col)
screen.blit(img, (x, y))
def draw_bg():
screen.fill(bg)
screen.blit(sky_cloud_img, (0, 0))
screen.blit(mountain_img, (0, screen_height - mountain_img.get_height() - 300))
screen.blit(pine1_img, (0, screen_height - pine1_img.get_height() - 150))
screen.blit(pine2_img, (0, screen_height - pine2_img.get_height()))
class Soldier(pygame.sprite.Sprite):
def __init__(self, char_type, x, y, scale, speed, ammo, grenades):
pygame.sprite.Sprite.__init__(self)
self.alive = True
self.char_type = char_type
self.speed = speed
self.ammo = ammo
self.start_ammo = ammo
self.shoot_cooldown = 0
self.grenades = grenades
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.animation_list = []
self.frame_index = 0
self.action = 0
# ai specific variables
self.move_counter = 0
self.vision = pygame.Rect(0, 0, 150, 20)
self.idling = 0
self.idling_counter = 0
self.update_time = pygame.time.get_ticks()
# load all images for the players
animation_types = ["idle", "run", "jump", "death"]
for animation in animation_types:
temp_list = []
# reset temporary list of images
# count number of files in the folder
num_of_frames = len(os.listdir(f"img/{self.char_type}/{animation}"))
for i in range(num_of_frames):
img = pygame.image.load(f"img/{self.char_type}/{animation}/{i}.png").convert_alpha()
img = pygame.transform.scale(img, (int(img.get_width() * scale), int(img.get_height() * scale)))
temp_list.append(img)
self.animation_list.append(temp_list)
self.image = self.animation_list[self.action][self.frame_index]
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.update_animation()
self.check_alive()
# update cooldown
if self.shoot_cooldown > 0:
self.shoot_cooldown -= 1
def move(self, moving_left, moving_right):
screen_scroll = 0
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 = -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
# 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, ie falling
elif self.vel_y >= 0:
self.vel_y = 0
self.in_air = False
dy = tile[1].top - self.rect.bottom
self.rect.x += dx
self.rect.y += dy
# update scroll based on player position
if self.char_type == "player":
if self.rect.right > screen_width - scroll_thresh or self.rect.left < scroll_thresh:
self.rect.x = -dx
screen_scroll = -dx
return screen_scroll
def shoot(self):
if self.shoot_cooldown == 0 and self.ammo > 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)
# reduce ammo after each shot
self.ammo -= 1
def ai(self):
if self.alive and player.alive:
if self.idling == False and random.randint(1, 200) == 1:
self.update_action(0)
self.idling = True
self.idling_counter = 50
# check if ai is near the player
if self.vision.colliderect(player.rect):
# stop running and face the player
self.update_action(0)
self.shoot()
else:
if self.idling == False:
if self.direction == 1:
ai_moving_right = True
else:
ai_moving_right = False
ai_moving_left = not ai_moving_right
self.move(ai_moving_left, ai_moving_right)
self.update_action(1)
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
# scroll
self.rect.x = screen_scroll
def update_animation(self):
ANIMATION_COOLDOWN = 100
# update image depending on current index
self.image = self.animation_list[self.action][self.frame_index]
# check if enough time has passed since the last update
if pygame.time.get_ticks() - self.update_time > ANIMATION_COOLDOWN:
self.update_time = pygame.time.get_ticks()
self.frame_index += 1
# if animation has run out then restart to the first
if self.frame_index >= len(self.animation_list[self.action]):
if self.action == 3:
self.frame_index = len(self.animation_list[self.action]) - 1
else:
self.frame_index = 0
def check_alive(self):
if self.health <= 0:
self.health = 0
self.speed = 0
self.alive = False
self.update_action(3)
def update_action(self, new_action):
# check if new action is different from the previous one
if new_action != self.action:
self.action = new_action
# update animation settings
self.frame_index = 0
self.update_time = pygame.time.get_ticks()
def draw(self):
screen.blit(pygame.transform.flip(self.image, self.flip, False), self.rect)
class HealthBar():
def __init__(self, health, x, y, max_health):
self.x = x
self.y = y
self.health = health
self.max_health = max_health
def draw(self, health):
self.health = health
pygame.draw.rect(screen, BLACK, (self.x - 2, self.y - 2, 154, 24))
pygame.draw.rect(screen, RED, (self.x, self.y, 150, 20))
ratio = self.health / self.max_health
pygame.draw.rect(screen, GREEN, (self.x, self.y, 150 * ratio, 20))
class World():
def __init__(self):
self.obstacle_list = []
def process_data(self, data):
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 0 <= tile <= 8:
self.obstacle_list.append(tile_data)
elif 9 <= tile <= 10:
# water
water = Water(img, x * TILE_SIZE, y * TILE_SIZE, )
water_group.add(water)
pass
elif 11 <= tile <= 14:
# decoration
decoration = Decoration(img, x * TILE_SIZE, y * TILE_SIZE)
decoration_group.add(decoration)
elif tile == 15:
# create a player
player = Soldier("player", x * TILE_SIZE, y * TILE_SIZE, 1.65, 5, 20, 5)
health_bar = HealthBar(10, 10, player.health, player.health)
elif tile == 16:
# create enemy
enemy = Soldier("enemy", x * TILE_SIZE, y * TILE_SIZE, 1.65, 2, 20, 0)
enemy_group.add(enemy)
elif tile == 17:
# create ammo box
item_box = ItemBox("Ammo", x * TILE_SIZE, y * TILE_SIZE)
item_box_group.add(item_box)
elif tile == 18:
# create grenade box
item_box = ItemBox("Grenade", x * TILE_SIZE, y * TILE_SIZE)
item_box_group.add(item_box)
elif tile == 19:
# create health box
item_box = ItemBox("Health", x * TILE_SIZE, y * TILE_SIZE)
item_box_group.add(item_box)
elif tile == 20:
# create exit point
exit = Exit(img, x * TILE_SIZE, y * TILE_SIZE, )
exit_group.add(exit)
return player, health_bar
def draw(self):
for tile in self.obstacle_list:
tile[1][0] += screen_scroll
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.midtop = (x + TILE_SIZE // 2, y + (TILE_SIZE - self.image.get_height()))
def update(self):
self.rect.x += screen_scroll
class Water(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()))
def update(self):
self.rect.x += screen_scroll
class Exit(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 ItemBox(pygame.sprite.Sprite):
def __init__(self, item_type, x, y):
pygame.sprite.Sprite.__init__(self)
self.item_type = item_type
self.image = item_boxes[self.item_type]
self.rect = self.image.get_rect()
self.rect.midtop = (x + TILE_SIZE // 2, y + (TILE_SIZE - self.image.get_height()))
def update(self):
# scroll
self.rect.x += screen_scroll
# check if player has picked up the box
if pygame.sprite.collide_rect(self, player):
# check what kind of box it was
if self.item_type == "Health":
player.health += 25
if player.health > player.max_health:
player.health = player.max_health
elif self.item_type == "Ammo":
player.ammo += 15
elif self.item_type == "Grenade":
player.grenades += 3
# delete the item box
self.kill()
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
# check if bullet has left the screen
if self.rect.right < 0 and self.rect.left > screen_width:
self.kill()
# check for collision with level
for tile in world.obstacle_list:
if tile[1].colliderect(self.rect):
self.kill()
# check collision with characters
if pygame.sprite.spritecollide(player, bullet_group, False):
if player.alive:
player.health -= 5
self.kill()
for enemy in enemy_group:
if pygame.sprite.spritecollide(enemy, bullet_group, False):
if enemy.alive:
enemy.health -= 25
self.kill()
class Grenade(pygame.sprite.Sprite):
def __init__(self, x, y, direction):
pygame.sprite.Sprite.__init__(self)
self.timer = 100
self.vel_y = -11
self.speed = 7
self.image = grenade_img
self.rect = self.image.get_rect()
self.rect.center = (x, y)
self.direction = direction
self.width = self.image.get_width()
self.height = self.image.get_height()
def update(self):
self.vel_y += GRAVITY
dx = self.direction * self.speed
dy = self.vel_y
# check for collision with level
for tile in world.obstacle_list:
# check if grenade has hit a wall
if tile[1].colliderect(self.rect.x + dx, self.rect.y, self.width, self.height):
self.direction *= -1
dx = self.direction * self.speed
if tile[1].colliderect(self.rect.x, self.rect.y + dy, self.width, self.height):
self.speed = 0
# check if below the ground, i.e thrown
if self.vel_y < 0:
self.y = 0
dy = tile[1].bottom - self.rect.top
# check if above the ground, ie falling
elif self.vel_y >= 0:
self.vel_y = 0
dy = tile[1].top - self.rect.bottom
# update grenade position
self.rect.x += dx
self.rect.y += dy
# explosion countdown
self.timer -= 1
if self.timer <= 0:
self.kill()
explosion = Explosion(self.rect.x, self.rect.y, 0.5)
explosion_group.add(explosion)
# do damage to anyone nearby
if abs(self.rect.centerx - player.rect.centerx) < TILE_SIZE * 2 and \
abs(self.rect.centery - player.rect.centery) < TILE_SIZE * 2:
player.health -= 50
for enemy in enemy_group:
if abs(self.rect.centerx - enemy.rect.centerx) < TILE_SIZE * 2 and \
abs(self.rect.centery - enemy.rect.centery) < TILE_SIZE * 2:
enemy.health -= 50
class Explosion(pygame.sprite.Sprite):
def __init__(self, x, y, scale):
pygame.sprite.Sprite.__init__(self)
self.images = []
for num in range(1, 6):
img = pygame.image.load(f"img/explosion/exp{num}.png").convert_alpha()
img = pygame.transform.scale(img, (int(img.get_width() * scale), (int(img.get_height() * scale))))
self.images.append(img)
self.frame_index = 0
self.image = self.images[self.frame_index]
self.rect = self.image.get_rect()
self.rect.center = (x, y)
self.counter = 0
def update(self):
EXPLOSION_SPEED = 4
# update explosion animation
self.counter += 1
if self.counter >= EXPLOSION_SPEED:
self.counter = 0
self.frame_index += 1
# if animation is complete, then delete the explosion
if self.frame_index >= len(self.images):
self.kill()
else:
self.image = self.images[self.frame_index]
# create sprite groups
enemy_group = pygame.sprite.Group()
bullet_group = pygame.sprite.Group()
grenade_group = pygame.sprite.Group()
explosion_group = pygame.sprite.Group()
item_box_group = pygame.sprite.Group()
decoration_group = pygame.sprite.Group()
water_group = pygame.sprite.Group()
exit_group = pygame.sprite.Group()
# create empty tile list
world_data = []
for row in range(ROWS):
r = [-1] * COLS
world_data.append(r)
# load in level data and create world
with open(f"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)
print(world_data)
world = World()
player, health_bar = world.process_data(world_data)
run = True
while run:
clock.tick(fps)
draw_bg()
world.draw()
health_bar.draw(player.health)
# show ammo
draw_text("AMMO:", font, WHITE, 10, 35)
for x in range(player.ammo):
screen.blit(bullet_img, (90 + (x * 10), 40))
# show grenade
draw_text("GRENADES: ", font, WHITE, 10, 65)
for x in range(player.grenades):
screen.blit(grenade_img, (130 + (x * 15), 66))
player.update()
player.draw()
for enemy in enemy_group:
enemy.ai()
enemy.update()
enemy.draw()
# update and draw groups
bullet_group.update()
grenade_group.update()
explosion_group.update()
item_box_group.update()
decoration_group.update()
water_group.update()
exit_group.update()
bullet_group.draw(screen)
grenade_group.draw(screen)
explosion_group.draw(screen)
item_box_group.draw(screen)
decoration_group.draw(screen)
water_group.draw(screen)
exit_group.draw(screen)
# update player actions, 1 is run, 0 = idle, 2 = in air
if player.alive:
# shoot bullet
if shoot:
player.shoot()
elif grenade and grenade_thrown == False and player.grenades > 0:
grenade = Grenade(player.rect.centerx + (0.5 * player.rect.size[0] * player.direction),
player.rect.top, player.direction)
grenade_group.add(grenade)
# reduce grenades
player.grenades -= 1
grenade_thrown = True
if player.in_air:
player.update_action(2)
elif moving_left or moving_right:
player.update_action(1)
else:
player.update_action(0)
screen_scroll = player.move(moving_left, moving_right)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# keyboard presses
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_SPACE:
shoot = True
if event.key == pygame.K_q:
grenade = True
if event.key == pygame.K_w and player.alive:
player.jump = True
if event.key == pygame.K_ESCAPE:
run = False
# keyboard button released
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_SPACE:
shoot = False
if event.key == pygame.K_q:
grenade = False
grenade_thrown = False
pygame.display.update()
pygame.quit()
i have looked at this code for days but cant seem to find out the problem exactly. so, the question once again is how to properly arrange the enemies on the screen at their various predefined positions and not directly on top of my player.
When I shoot at my cement block sprites I have it set so that self.score is self.score += 1 in my player collision function, but when I shoot my cement blocks and destroy them, either 1 or 2 points is added at random to my score. Why? How can I fix this? A clear example is, I shoot at and destroy 2 cement blocks in a row and 1 point is added for each one destroyed which means my score is 2, which is what I want cause I want to add 1 point to my score whenever I destroy a cement block, but then when I shoot and destroy the third cement block, 2 points are added instead of 1 bringing my score to 4 instead of being a score of 3 points.
Github: https://github.com/Enoc-Mena99/AutoPilot
My code:
import random
import pygame
import pygame.freetype
pygame.init()
#screen settings
WIDTH = 1000
HEIGHT = 400
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("AutoPilot")
screen.fill((255, 255, 255))
#fps
FPS = 120
clock = pygame.time.Clock()
#load images
bg = pygame.image.load('background/street.png').convert_alpha() # background
bullets = pygame.image.load('car/bullet.png').convert_alpha()
debris_img = pygame.image.load('debris/cement.png')
#define game variables
shoot = False
#player class
class Player(pygame.sprite.Sprite):
def __init__(self, scale, speed):
pygame.sprite.Sprite.__init__(self)
self.bullet = pygame.image.load('car/bullet.png').convert_alpha()
self.bullet_list = []
self.speed = speed
#self.x = x
#self.y = y
self.moving = True
self.frame = 0
self.flip = False
self.direction = 0
self.score = 0
#load car
self.images = []
img = pygame.image.load('car/car.png').convert_alpha()
img = pygame.transform.scale(img, (int(img.get_width()) * scale, (int(img.get_height()) * scale)))
self.images.append(img)
self.image = self.images[0]
self.rect = self.image.get_rect()
self.update_time = pygame.time.get_ticks()
self.movingLeft = False
self.movingRight = False
self.rect.x = 465
self.rect.y = 325
#draw car to screen
def draw(self):
screen.blit(self.image, (self.rect.centerx, self.rect.centery))
#move car
def move(self):
#reset the movement variables
dx = 0
dy = 0
#moving variables
if self.movingLeft and self.rect.x > 33:
dx -= self.speed
self.flip = True
self.direction = -1
if self.movingRight and self.rect.x < 900:
dx += self.speed
self.flip = False
self.direction = 1
#update rectangle position
self.rect.x += dx
self.rect.y += dy
#shoot
def shoot(self):
bullet = Bullet(self.rect.centerx + 18, self.rect.y + 30, self.direction)
bullet_group.add(bullet)
#check collision
def collision(self, debris_group):
for debris in debris_group:
if pygame.sprite.spritecollide(debris, bullet_group, True):
debris.health -= 1
if debris.health <= 0:
self.score += 1
#player stats
def stats(self):
myfont = pygame.font.SysFont('comicsans', 30)
scoretext = myfont.render("Score: " + str(self.score), 1, (0,0,0))
screen.blit(scoretext, (100,10))
#bullet class
class Bullet(pygame.sprite.Sprite):
def __init__(self, x, y, direction):
pygame.sprite.Sprite.__init__(self)
self.speed = 5
self.image = bullets
self.rect = self.image.get_rect()
self.rect.center = (x,y)
self.direction = direction
def update(self):
self.rect.centery -= self.speed
#check if bullet has gone off screen
if self.rect.centery < 1:
self.kill()
#debris class
class Debris(pygame.sprite.Sprite):
def __init__(self,scale,speed):
pygame.sprite.Sprite.__init__(self)
self.scale = scale
self.x = random.randrange(100,800)
self.speed_y = 10
self.y = 15
self.speed = speed
self.vy = 0
self.on_ground = True
self.move = True
self.health = 4
self.max_health = self.health
self.alive = True
self.velocity = random.randrange(1,2)
self.speed_x = random.randrange(-3,3)
self.moving_down = True
self.is_destroyed = False
#load debris
self.image = debris_img
self.rect = self.image.get_rect()
self.rect.x = random.randrange(100, 800)
self.rect.y = random.randrange(-150, -100)
self.rect.center = (self.x,self.y)
#load explosion
self.img_explosion_00 = pygame.image.load('explosion/0.png').convert_alpha()
self.img_explosion_00 = pygame.transform.scale(self.img_explosion_00, (self.img_explosion_00.get_width() * 2,
self.img_explosion_00.get_height() * 2))
self.img_explosion_01 = pygame.image.load('explosion/1.png').convert_alpha()
self.img_explosion_01 = pygame.transform.scale(self.img_explosion_01, (self.img_explosion_01.get_width() * 2,
self.img_explosion_01.get_height() * 2))
self.img_explosion_02 = pygame.image.load('explosion/2.png').convert_alpha()
self.img_explosion_02 = pygame.transform.scale(self.img_explosion_02, (self.img_explosion_02.get_width() * 2,
self.img_explosion_02.get_height() * 2))
self.img_explosion_03 = pygame.image.load('explosion/3.png').convert_alpha()
self.img_explosion_03 = pygame.transform.scale(self.img_explosion_03, (self.img_explosion_03.get_width() * 2,
self.img_explosion_03.get_height() * 2))
#explosion list
self.anim_explosion = [self.img_explosion_00,
self.img_explosion_01,
self.img_explosion_02,
self.img_explosion_03]
self.anim_index = 0
self.frame_len = 10
#spawn new debris
def spawn_new_debris(self):
self.rect.x = random.randrange(100, 800)
self.rect.y = random.randrange(-150, -100)
self.velocity = random.randrange(1, 2)
self.speed_x = random.randrange(-3, 3)
#respawn debris when they go of the screen
def boundaries(self):
if self.rect.left > WIDTH + 10 or self.rect.right < -10 or self.rect.top > HEIGHT + 10:
self.spawn_new_debris()
#update image
def update(self):
self.rect.y += self.velocity
self.rect.x += self.speed_x
self.boundaries()
if self.health <= 0:
max_index = len(self.anim_explosion) - 1
if self.anim_index > max_index:
self.kill()
else:
if self.frame_len == 0:
self.image = self.anim_explosion[self.anim_index]
self.anim_index += 1
self.frame_len = 10
else:
self.frame_len -= 1
#make debris fall down
def falldown(self):
self.rect.centery += self.velocity
if self.moving_down and self.rect.y > 350:
self.kill()
######################CAR/DEBRIS##########################
player = Player(1,5)
##########################################################
#groups
bullet_group = pygame.sprite.Group()
debris_group = pygame.sprite.Group()
all_sprites = pygame.sprite.Group()
for x in range(50):
d = Debris(1, 5)
debris_group.add(d)
all_sprites.add(d)
#game runs here
run = True
while run:
#draw street
screen.blit(bg, [0, 0])
#update groups
bullet_group.update()
bullet_group.draw(screen)
debris_group.update()
debris_group.draw(screen)
#draw car
player.draw()
player.move()
player.collision(debris_group)
player.stats()
#update all sprites
all_sprites.update()
all_sprites.draw(screen)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
#check if key is down
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
run = False
if event.key == pygame.K_a:
player.movingLeft = True
if event.key == pygame.K_d:
player.movingRight = True
if event.key == pygame.K_SPACE:
player.shoot()
shoot = True
#check if key is up
if event.type == pygame.KEYUP:
if event.key == pygame.K_a:
player.movingLeft = False
if event.key == pygame.K_d:
player.movingRight = False
#update the display
pygame.display.update()
pygame.display.flip()
clock.tick(FPS)
pygame.quit()
Do not count debris objects with healt <= 0:
class Player(pygame.sprite.Sprite):
# [...]
def collision(self, debris_group):
for debris in debris_group:
# if health > 0 and collision:
if debris.health > 0 and pygame.sprite.spritecollide(debris, bullet_group, True):
debris.health -= 1
if debris.health <= 0:
self.score += 1
This question already has answers here:
Pygame sprite disappearing with layeredUpdates at a certain Y coordinate
(2 answers)
pygame.sprite.LayeredUpdates.move_to_front() does not work
(1 answer)
Closed 1 year ago.
I have started making a simple 2D game in python.
Thats my code
import clock
import time
import inspect
import itertools
import threading
import sys
pygame.init()
# defining the game window
gameDisplay = pygame.display.set_mode((1280, 640))
# displaying the game window
pygame.display.set_caption("Game")
background = pygame.image.load("images/background.jpg")
right = [pygame.image.load("images/animate/a1_r.png"), pygame.image.load("images/animate/a2_r.png"),
pygame.image.load("images/animate/a3_r.png"), pygame.image.load("images/animate/a4_r.png")]
standing = pygame.image.load("images/animate/standing.png") # 65x87 px
shaking = pygame.image.load("images/animate/shaking.png")
crouching = pygame.image.load("images/animate/crouching.png")
left = [pygame.image.load("images/animate/a1_l.png"), pygame.image.load("images/animate/a2_l.png"),
pygame.image.load("images/animate/a3_l.png"), pygame.image.load("images/animate/a4_l.png")]
shop_img = pygame.image.load("images/shop.png") # 230x140 px
clock = pygame.time.Clock()
isJump = False
jumpCount = 10
height = 87
width = 65
def border(x):
if x <= 0 and keys[pygame.K_a]:
return False
elif x >= 1225 and keys[pygame.K_d]:
return False
else:
return True
class StickMan(object):
def __init__(self, x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
self.vel = 7
self.steps = 0
self.left = False
self.right = False
self.crouching = False
self.shaking = False
self.hitbox = (self.x + 20, self.y, 70, 60)
def draw(self):
if self.steps + 1 >= 20:
self.steps = 0
if self.left:
gameDisplay.blit(left[self.steps // 5], (self.x, self.y))
self.steps += 1
elif self.right:
gameDisplay.blit(right[self.steps // 5], (self.x, self.y))
self.steps += 1
elif self.shaking:
gameDisplay.blit(shaking, (self.x, self.y))
elif self.crouching:
gameDisplay.blit(crouching, (self.x, self.y))
else:
gameDisplay.blit(standing, (self.x, self.y))
self.steps = 0
def move(self):
if self.vel > 0:
self.x += self.vel
def current_width(self):
self.width = 65
def current_height(self):
if not keys[pygame.K_s]:
self.height = 87
else:
self.height = 50
class shop(object):
def __init__(self, x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
def draw(self):
gameDisplay.blit(shop_img, (self.x, self.y))
Shop = shop( 200, 410, 230, 140)
Player = StickMan( 100, 470, 65, 87)
def draw():
gameDisplay.blit(background, (0, 0))
Player.draw()
Shop.draw()
run = True
# main Loop
while run:
for event in pygame.event.get():
pygame.display.update()
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_a] and border(Player.x):
Player.x -= Player.vel
Player.left = True
Player.right = False
if keys[pygame.K_d] and border(Player.x):
Player.x += Player.vel
Player.left = False
Player.right = True
if not keys[pygame.K_d] and not keys[pygame.K_a]:
Player.left = False
Player.right = False
if keys[pygame.K_s]:
Player.crouching = True
else:
Player.crouching = False
if keys[pygame.K_q]:
Player.shaking = True
else:
Player.shaking = False
if not isJump:
if keys[pygame.K_SPACE]:
isJump = True
else:
if jumpCount >= -10:
Player.y -= (jumpCount * abs(jumpCount)) * 0.5
jumpCount -= 1
else:
jumpCount = 10
isJump = False
pygame.display.flip()
draw()
pygame.display.update()
clock.tick(60)
I've got problem with layers. - My character is running behind the shop. I was trying to fix this by using pygame.sprite (http://www.pygame.org/docs/ref/sprite.html#pygame.sprite.Sprite) but after many trials my man still runs behind the shop. Have you got any ideas how can I fix it ?
I'm making a 2D game using pygame. I'm pretty new to python object oriented programming and don't quite understand classes and objects in full, so my coding approach might be a little weird. I have a player and entity class, and a key listener to change the player x and y (actually the background picture's x/y coords) relative to keys pressed. Currently, I have only one entity object named monster, because in order to properly move the player, I need to move every entity as well or else the entities will just move along with the player.
How do I reference every single entity I create simultaneously so I can change their x and y values, so I don't have to reference them one by one in the key listener functions?
Is there some entity.objects.all() sort of thing? Thank you if somebody can help, here's my code.
import os
import time
import threading
p.init()
c = p.time.Clock()
SCREEN_W = 800
SCREEN_H = 600
w = p.display.set_mode((SCREEN_W, SCREEN_H))
p.display.set_caption("Mason's Game")
walkRight = [p.image.load('game/r1.png'), p.image.load('game/r2.png'), p.image.load('game/r3.png'), p.image.load('game/r4.png'), p.image.load('game/r5.png'), p.image.load('game/r6.png'), p.image.load('game/r7.png'), p.image.load('game/r8.png'), p.image.load('game/r9.png')]
walkLeft = [p.image.load('game/l1.png'), p.image.load('game/l2.png'), p.image.load('game/l3.png'), p.image.load('game/l4.png'), p.image.load('game/l5.png'), p.image.load('game/l6.png'), p.image.load('game/l7.png'), p.image.load('game/l8.png'), p.image.load('game/l9.png')]
bg = p.image.load('game/bg.jpg')
char = p.image.load('game/standing.png')
mob = p.image.load('game/mob.png')
health = [p.image.load('game/h0.png'), p.image.load('game/h1.png'), p.image.load('game/h2.png'), p.image.load('game/h3.png'), p.image.load('game/h4.png'), p.image.load('game/h5.png'), p.image.load('game/h6.png'), p.image.load('game/h7.png'), p.image.load('game/h8.png'), p.image.load('game/h9.png'), p.image.load('game/h10.png'),]
def delay(x):
later = p.time.get_ticks() + x
if p.time.get_ticks() >= later:
pass
class entity(object):
def __init__(self, spawnx, spawny, x,y, level, health):
self.x=x
self.y=y
self.spawnx = spawnx
self.spawny= spawny
self.velocity=14
self.level = level
self.health = health
self.dead = False
def draw(self, w):
w.blit(mob, (self.x,self.y))
def printCoords(self):
print('x: ' , (-1*(m.x - monster.x) - 3600) - 300, " y: ", ((-1*(m.y - monster.y) - 3700) - 300)*-1)
def pace(self):
reachedRight = False
reachedLeft = False
if not reachedRight:
self.x += self.velocity/10
if self.x >= (self.spawnx + 100):
reachedRight = True
if reachedRight:
self.velocity *= -1
if self.x <= (self.spawnx - 100):
reachedLeft = True
if reachedLeft:
self.velocity*=-1
def stop(self):
self.velocity = 0
def followPlayer(self, player):
#if (abs(ogre.x - monster.x)) < 160 or (abs(ogre.y - monster.y)) < 160:
# monster.attackPlayer()
#if monster is left of player, close enough, but not too close
if self.x < player.x - 128 and self.x > player.x - 400:
self.velocity = 5
self.x += self.velocity
#if monster is right of player, close enough, but not too close
elif self.x > player.x + 128 and self.x < player.x + 400:
self.velocity = -5
self.x += self.velocity
#if monster is south of player, close enough, but not too close
if self.y < player.y - 128 and self.y > player.y - 400:
self.velocity = 5
self.y += self.velocity
#if monster is north of player, close enough, but not too close
elif self.y > player.y + 128 and self.y < player.y + 400:
self.velocity = -5
self.y += self.velocity
def attackPlayer(self, player):
def hitPlayer():
if player.health > 0:
player.sethealth(player.health - 1)
else:
player.death()
t=threading.Timer(5.0,hitPlayer)
t.start()
class mapp(object):
def __init__(self,x,y):
self.x= -3600
self.y= -3700
self.velocity = 14
self.left = False
self.right = False
self.standing = True
def draw(self, w):
w.blit(bg, (self.x,self.y))
class player(object):
def __init__(self, x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
self.vel = 14
self.j = False
self.jc = 10
self.right = False
self.left = False
self.walk = 0
self.standing = True
self.health = 10
self.travX = (-3600 - m.x)
self.travY = (-3700 - m.y)
def respawn(self):
time.sleep(0.4)
monster.x = (-1*(m.x - monster.x) - 3600)
monster.y = (-1*(m.y - monster.y) - 3700)
m.x += (-3600 - m.x)
m.y += (-3700 - m.y)
#monster.y += (-1*(m.y - monster.y) - 3700)
def death(self):
self.sethealth(10)
self.respawn()
def sethealth(self, x):
self.health = x
def draw(self,w):
w.blit(health[self.health], (730, 20))
if self.walk + 1 >= 27:
self.walk = 0
if not(self.standing):
if self.left:
w.blit(walkLeft[self.walk//3], (self.x,self.y))
self.walk += 1
elif self.right:
w.blit(walkRight[self.walk//3], (self.x,self.y))
self.walk += 1
else:
if self.left:
w.blit(walkLeft[0], (self.x,self.y))
else:
w.blit(walkRight[0], (self.x,self.y))
def drawGame():
m.draw(w)
ogre.draw(w)
monster.draw(w)
monster.followPlayer(ogre)
p.display.update()
####### main ############
m = mapp(-3600,-3700)
ogre = player(400, 300, 64, 64)
monster = entity(-200, 600, -200, 600, 5, 100)
monster2 = entity(-300, 630, -300, 630, 5, 100)
####### main ############
run = True
while run:
c.tick(27)
for event in p.event.get():
if event.type == p.QUIT:
run = False
k = p.key.get_pressed()
#monster.printCoords()
### left right up down player ####
if k[p.K_a]:
monster.x +=m.velocity
monster.spawnx+=m.velocity
m.x+=m.velocity
ogre.left = True
ogre.right = False
ogre.standing = False
elif k[p.K_d]:
monster.x -=m.velocity
monster.spawnx-=m.velocity
m.x-=m.velocity
ogre.right = True
ogre.left = False
ogre.standing = False
elif k[p.K_w]:
monster.y +=m.velocity
monster.spawny+=m.velocity
m.y+=m.velocity
ogre.right = False
ogre.left = False
ogre.standing = True
elif k[p.K_s]:
monster.y -=m.velocity
monster.spawny-=m.velocity
m.y-=m.velocity
ogre.right = False
ogre.left = False
ogre.standing = True
elif k[p.K_j]:
#monster.attackPlayer()
ogre.death()
else:
ogre.standing = True
ogre.walk = 0
drawGame()
p.quit()```
Set the variables move_x and move_y dependent on the pressed key:
move_x = 0
move_y = 0
if k[p.K_a]:
move_x = m.velocity
# [...]
elif k[p.K_d]:
move_x = -m.velocity
# [...]
elif k[p.K_w]:
move_y = m.velocity
# [...]
elif k[p.K_s]:
move_y = -m.velocity
# [...]
Create a list of monsters:
monsters = [
entity(-200, 600, -200, 600, 5, 100)
entity(-300, 630, -300, 630, 5, 100)
]
Move each individual monster in a for loop:
for monster in monsters:
monster.x += move_x
monster.y += move_y
monster.spawnx += move_x
monster.spawny += move_y
application loop:
m = mapp(-3600,-3700)
ogre = player(400, 300, 64, 64)
monsters = [
entity(-200, 600, -200, 600, 5, 100)
entity(-300, 630, -300, 630, 5, 100)
]
run = True
while run:
c.tick(27)
for event in p.event.get():
if event.type == p.QUIT:
run = False
k = p.key.get_pressed()
### left right up down player ####
move_x = 0
move_y = 0
if k[p.K_a]:
move_x = m.velocity
ogre.left = True
ogre.right = False
ogre.standing = False
elif k[p.K_d]:
move_x = -m.velocity
ogre.right = True
ogre.left = False
ogre.standing = False
elif k[p.K_w]:
move_y = m.velocity
ogre.right = False
ogre.left = False
ogre.standing = True
elif k[p.K_s]:
move_y = -m.velocity
ogre.right = False
ogre.left = False
ogre.standing = True
elif k[p.K_j]:
#monster.attackPlayer()
ogre.death()
else:
ogre.standing = True
ogre.walk = 0
for monster in monsters:
monster.x += move_x
monster.y += move_y
monster.spawnx += move_x
monster.spawny += move_y
m.x += move_x
m.y += move_y
drawGame()
My character won't jump properly, he keeps glitching through the ground. If i hold key up, my character won't stop going higher. Do you have some ideas for how I could fix it?
import pygame,sys
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((1200, 800))
screen.fill((0,0,0))
pygame.display.set_caption('Jump and Run')
BLACK = (0,0,0)
WHITE = (250, 250,250)
RED = (250, 0, 0)
BLUE = (0,0,250)
direction = 'right'
way = 0
jump_high = 0
class Hero():
def __init__(self, x, y):
self.x = x
self.y = y
self.image = pygame.image.load('hero.bmp')
self.groundcontact = True
self.vy = 0
alive = True
def check_pos(self):
if self.y >= 400:
self.groundcontact = True
elif self.y <= 400:
self.groundcontact = False
def load_picture(self,surface):
surface.blit(self.image,(self.x, self.y))
def check_input(self):
key = pygame.key.get_pressed()
if key[pygame.K_RIGHT]:
self.x += 10
elif key[pygame.K_LEFT]:
self.x -= 10
elif key[pygame.K_UP]:
self.y -= 50
if not self.groundcontact:
self.vy += 1 #max(min(2,200), -200)
#self.y += self.vy
print "not self.groundcontact"
else:
self.vy = 0
#self.y += self.vy
self.y += self.vy
class Monster():
def __init__(self, x, y):
self.x = x
self.y = y
self.image = pygame.image.load('monster.bmp')
self.collision = False
self.alive = True
def load_picture(self,surface):
surface.blit(self.image,(self.x, self.y))
def walk(self):
global direction
global way
if direction == "right":
self.x += 4
way += 1
if way == 100:
direction = "left"
elif direction == "left":
self.x -= 4
way -= 1
if way == 0:
direction = "right"
monster2 = Monster( 200, 333)
monster1 = Monster(400, 450)
hero = Hero(0, 400)
clock = pygame.time.Clock()
pygame.draw.rect(screen, WHITE,(0,500, 1200, 50))
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
hero.check_pos()
monster1.walk()
monster2.walk()
hero.check_input()
screen.fill(BLACK)
hero.load_picture(screen)
monster1.load_picture(screen)
monster2.load_picture(screen)
pygame.draw.rect(screen, WHITE,(0,500, 1200, 50))
pygame.display.update()
clock.tick(40)
Regarding my comment above, changing the Hero class to somthing like this:
JUMP_POWER = 10
class Hero():
...
def check_input(self):
key = pygame.key.get_pressed()
...
elif key[pygame.K_UP]:
if self.groundcontact:
self.vy -= JUMP_SPEED