any help you can give me would be great. I am working on a simple game in python. I would like to have a countdown timer running on the screen. Based on other questions answered on this site, I think I have the code mostly correct, the problem I am having is that I am running the timer code using a "for" loop. I am not really sure why it is not working for me at the moment, when I run the game, I do not get any errors, the countdown displays but it has only counted down one second and it sticks on this time (01:29). Any suggestions would be really appreciated. The code that I am struggling with is towards the end of the program in a section called """Timer Countdown""" in the main loop for the game (line 354). Many thanks.
# Ice Hockey Game
from livewires import games, color
from tkinter import*
import pygame
import math, random
import os
import sys
import time
pygame.init()
games.init(screen_width = 1016, screen_height = 511, fps = 50)
################################################################################
"""timer variables"""
################################################################################
clock = pygame.time.Clock()
font = pygame.font.Font(None, 25)
red = ( 255, 0, 0)
frame_count = 0
frame_rate = 50
start_time = 90
done= False
output_string = ""
################################################################################
"""Score display variables"""
################################################################################
right_score = games.Text(value = 0, size = 25, color = color.black,
top = 30, right = games.screen.width - 250,
is_collideable = False)
games.screen.add(right_score)
left_score = games.Text(value = 0, size = 25, color = color.black,
top = 30, right = 250,
is_collideable = False)
games.screen.add(left_score)
player1_message = games.Message(value = "Player 1 Score",
size = 35,
color = color.black,
x = 250,
y = 15,
lifetime = 100000000,
is_collideable = False)
games.screen.add(player1_message)
player2_message = games.Message(value = "Player 2 Score",
size = 35,
color = color.black,
x = 750,
y = 15,
lifetime = 100000000,
is_collideable = False)
games.screen.add(player2_message)
###############################################################################
"""Player 1 and Player 2 WIN messages"""
###############################################################################
p1_won_message = games.Message(value = "Player 1 Wins!!!",
size = 100,
color = color.blue,
x = games.screen.width/2,
y = games.screen.height/2,
lifetime = 500,
after_death = games.screen.quit,
is_collideable = False)
p2_won_message = games.Message(value = "Player 2 Wins!!!",
size = 100,
color = color.blue,
x = games.screen.width/2,
y = games.screen.height/2,
lifetime = 500,
after_death = games.screen.quit,
is_collideable = False)
##############################################################################
"""Goal animation images and functions"""
################################################################################
"""Animation images"""
goal_anim_files = ["Goal_Anim_001.bmp", "Goal_Anim_002.bmp", "Goal_Anim_003.bmp",
"Goal_Anim_004.bmp","Goal_Anim_005.bmp","Goal_Anim_006.bmp",
"Goal_Anim_007.bmp","Goal_Anim_008.bmp","Goal_Anim_009.bmp","Goal_Anim_010.bmp", "Goal_Anim_011.bmp", "Goal_Anim_012.bmp", "Goal_Anim_013.bmp",
"Goal_Anim_014.bmp","Goal_Anim_015.bmp","Goal_Anim_016.bmp",
"Goal_Anim_017.bmp","Goal_Anim_018.bmp","Goal_Anim_019.bmp","Goal_Anim_020.bmp", "Goal_Anim_021.bmp","Goal_Anim_022.bmp", "Goal_Anim_023.bmp",
"Goal_Anim_024.bmp","Goal_Anim_025.bmp"]
def goal_msg_left(self):
global goal_anim_left
goal_anim_left = games.Animation(images = goal_anim_files, x = 250,
y= games.screen.height/2, n_repeats = 1,
repeat_interval = 1, is_collideable = False)
#print("inside goal_msg_left")
def goal_msg_right(self):
global goal_anim_right
goal_anim_right = games.Animation(images = goal_anim_files, x = 750,
y= games.screen.height/2, n_repeats = 1,
repeat_interval = 1, is_collideable = False)
#print("inside goal_msg_right")
class Leftgoalanim(games.Animation):
"""goal animation"""
def update(self):
self.check_collide()
def check_collide(self):
for player1 in self.overlapping_sprites:
player1.handle_player_collide()
for player2 in self.overlapping_sprites:
player2.handle_player_collide()
class Leftgoal(games.Sprite):
def update(self):
self.check_collide()
self.check_goal()
def check_collide(self):
""" Check for collision with puck. """
for puck in self.overlapping_sprites:
puck.handle_collide()
def handle_collide(self):
""" Move to a random screen location. """
self.dx = -self.dx
self.dy = 0
self.x = games.screen.width/2
self.y = games.screen.height/2
def check_goal(self):
""" Check if left goal. """
global goal_anim_left
for puck in self.overlapping_sprites:
#puck.handle_collide()
goal_msg_left(self)
games.screen.add(goal_anim_left)
right_score.value += 1
if right_score.value >= 10:
games.screen.add(p2_won_message)
class Rightgoal(games.Sprite):
def update(self):
self.check_collide()
self.check_goal()
def check_collide(self):
""" Check for collision with puck. """
for puck in self.overlapping_sprites:
puck.handle_collide()
def handle_collide(self):
""" Move to a random screen location. """
self.dx = -self.dx
self.dy = 0
self.x = games.screen.width/2
self.y = games.screen.height/2
def check_goal(self):
""" Check if left goal. """
for puck in self.overlapping_sprites:
#puck.handle_collide()
goal_msg_right(self)
games.screen.add(goal_anim_right)
left_score.value += 1
if left_score.value >= 10:
games.screen.add(p1_won_message)
################################################################################
"""Classes for Players sprites"""
################################################################################
class Player1(games.Sprite):
"""move the player 1"""
VELOCITY_STEP = .03
VELOCITY_MAX = 3
def update(self):
if games.keyboard.is_pressed(games.K_w):
self.y -= 3
if games.keyboard.is_pressed(games.K_s):
self.y += 3
if games.keyboard.is_pressed(games.K_a):
self.x -= 3
if games.keyboard.is_pressed(games.K_d):
self.x += 3
if self.right > 940:
self.x = 913
if self.left < 85:
self.x = 108
if self.bottom > games.screen.height:
self.y = 475
if self.top < 0:
self.y = 50
self.check_collide()
def check_collide(self):
""" Check for collision with puck. """
for puck in self.overlapping_sprites:
puck.handle_collide()
def handle_player_collide(self):
self.dx = -self.dx
self.dy = 0
def handle_collide(self):
""" Move to a random screen location. """
self.dx = -self.dx
self.dy = 0
class Player2(games.Sprite):
"""move the player 2"""
VELOCITY_STEP = .03
VELOCITY_MAX = 3
def update(self):
if games.keyboard.is_pressed(games.K_UP):
self.y -= 3
if games.keyboard.is_pressed(games.K_DOWN):
self.y += 3
if games.keyboard.is_pressed(games.K_LEFT):
self.x -= 3
if games.keyboard.is_pressed(games.K_RIGHT):
self.x += 3
if self.right > 940:
self.x = 913
if self.left < 85:
self.x = 108
if self.bottom > games.screen.height:
self.y = 475
if self.top < 0:
self.y = 50
self.check_collide()
def check_collide(self):
""" Check for collision with puck. """
for puck in self.overlapping_sprites:
puck.handle_collide()
def handle_collide(self):
""" Move to a random screen location. """
self.dx = -self.dx
self.dy = 0
def handle_player_collide(self):
self.dx = -self.dx
self.dy = 0
################################################################################
"""Class for Puck"""
################################################################################
class Puck(games.Sprite):
""" A bouncing puck. """
def update(self):
""" Reverse a velocity component if edge of screen reached. """
if self.right > games.screen.width or self.left < 0:
self.dx = -self.dx
if self.bottom > games.screen.height or self.top < 0:
self.dy = -self.dy
def handle_collide(self):
""" reverses x direction when collides. """
self.dx = -self.dx
self.dy = self.dy
def handle_goal(self):
"""what happens to the puck when goal"""
self.dx = -self.dx
self.dy = self.dy
################################################################################
"""Main Loop For Game"""
################################################################################
def main():
wall_image = games.load_image("Table_002_1016H_511W.jpg", transparent = False)
games.screen.background = wall_image
#########image left and right goal images and add them to game##########
left_goal_image = games.load_image("Goal_left_cropped.bmp")
the_left_goal = Leftgoal(image = left_goal_image,
x = 40,
y = games.screen.height/2,
)
right_goal_image = games.load_image("Goal_right_cropped.bmp")
the_right_goal = Rightgoal(image = right_goal_image,
x = 976,
y = games.screen.height/2,
)
#########player 1 import image and add to game##########################
player1_image = games.load_image("Player_red_half_50_75_Fixed.bmp")
the_player1 = Player1(image = player1_image,
x = games.screen.width/4,
y = games.screen.height/2)
games.screen.add(the_player1)
#########player 2 import image and add to game##########################
player2_image = games.load_image("Player_green_half_50_75_flipped_fixed.bmp")
the_player2 = Player2(image = player2_image,
x = 750,
y = games.screen.height/2)
games.screen.add(the_player2)
################Import image for the Puck and Add to the game###########
puck_image = games.load_image("puck_small.png", transparent = True)
the_puck = Puck(image = puck_image,
x = games.screen.width/2,
y = games.screen.height/2,
dx = -3,
dy = 3)
counter = 0
###########################################################################
"""TIMER COUNTDOWN"""
###########################################################################
clock = pygame.time.Clock()
font = pygame.font.Font(None, 25)
red = ( 255, 0, 0)
frame_count = 0
frame_rate = 50
start_time = 90
done= False
output_string = ""
for n in reversed(range(0, start_time)):
total_seconds = frame_count // frame_rate
minutes = total_seconds // 60
seconds = total_seconds % 60
output_string = "Time: {0:02}:{1:02}".format(minutes, seconds)
# Blit to the screen
text = font.render(output_string, True, red)
#screen.blit(text, [250, 250])
# --- Timer going down ---
# --- Timer going up ---
# Calculate total seconds
total_seconds = start_time - (frame_count // frame_rate)
if total_seconds < 0:
total_seconds = 0
# Divide by 60 to get total minutes
minutes = total_seconds // 60
# Use modulus (remainder) to get seconds
seconds = total_seconds % 60
# Use python string formatting to format in leading zeros
output_string = "Time left: {0:02}:{1:02}".format(minutes, seconds)
# Blit to the screen
text = font.render(output_string, True, red)
#screen.blit(text, [250, 280])
# ALL CODE TO DRAW SHOULD GO ABOVE THIS COMMENT
frame_count += 1
# Limit to 20 frames per second
clock.tick_busy_loop(50)
# Go ahead and update the screen with what we've drawn.
pygame.display.flip()
###Timer Display###
timer_text = games.Message(value = "TIME",
size = 45,
color = color.red,
top = 30, right = games.screen.width/2,
lifetime = 100000000,
is_collideable = False)
timer_countdown = games.Text(value = output_string, size = 25, color = color.red,
top = 60, right = 600,
is_collideable = False)
games.screen.add(timer_countdown)
games.screen.add(timer_text)
games.screen.add(the_left_goal)
games.screen.add(the_right_goal)
games.screen.add(the_puck)
games.screen.event_grab = True
games.mouse.is_visible = False
games.screen.mainloop()
# start the game
main()
Using pygame.time.get_ticks() to store a start time,
calling this again every frame will give a time greater than your stored start time, simply subtract your start time from this to get the interval in milliseconds since the timer started
As #jonrsharpe said however, it should be a code "sample", not the whole sodding thing, As such I might not have actually answered your question, I can't tell because I'm not going to read and understand the whole code.
Related
I'm making a racing game with almost realistic cars in pygame. I made the cars succesfully and I want to make the car move a bit slower when it's not touching the drive way. For that, I want to use pygame mask collisions. Instead of using bounding boxes, they use the pixels and count them based on how many pixels of something are touching something. This all works correctly, but when I use the cam.follow_object(player) function, the game behaves very weird and there rise unexplainable bugs.
I included each individual picture and file, but I also included it on github because I know it's annoying to download all images one by one.
Assets:
app.py:
import pygame
from pygame.locals import *
from random import choice, randint
import math, car, ui, pySave, camera, level
pygame.init()
# Basic Variables
screen_width = 1000
screen_height = 1000
fps = 80
screen = pygame.display.set_mode((screen_width, screen_height))
clock = pygame.time.Clock()
cam = camera.Camera(1, screen)
#cam.zoom_game(1.55)
stage = "home"
# Loading Images
images = {
"start" : pygame.transform.scale(pygame.image.load("road_texture.png"), (200*cam.zoom, 75*cam.zoom)).convert_alpha(),
"bcg" : pygame.transform.scale(pygame.image.load("map2.png"), (1000*cam.zoom, 1000*cam.zoom)).convert_alpha(),
"car" : pygame.image.load("car.png").convert_alpha()
}
# Functionality Functions
def play_game():
global stage
stage = "game"
# Instansiating stuff
pos_save = pySave.Save_Manager("saved_info", "pos")
start_button = ui.Button((500,500), images["start"], play_game, text="startgame")
test_car = car.CarSprite(images["car"], 400, 400,[2, 2.3, 2.7], 0.013, rotations=360, camera=cam)
speedometer = ui.TextWithBackground((100,50), (100,950), images["start"])
level = level.Level(images["bcg"], test_car,cam,pos = (0,100))
# Groups and Lists
car_group = pygame.sprite.Group()
# Adding to Groups
car_group.add(test_car)
# Game Functions
def render():
if stage == "home":
screen.fill((255,255,255))
start_button.update("Start Game")
start_button.draw(screen)
elif stage == "game":
screen.fill((0,76,18))
level.update(screen)#screen.blit(images["bcg"], (0-cam.scroll[0],0-cam.scroll[1]))
car_group.update()
car_group.draw(screen)
#cam.follow(test_car, )
#speedometer.draw(screen)
speedometer.update(screen,round(test_car.speed*60,2) , " km/h")
#cam.zoom_game(2)
def collisions():
pass
run = True
while run:
clock.tick_busy_loop(80)
render()
collisions()
for event in pygame.event.get():
if event.type == QUIT:
run = False
pos_save.save("x", test_car.rect.x)
pos_save.save("y", test_car.rect.y)
pos_save.apply()
print(f"Quit with {round(clock.get_fps(), 2)} FPS")
quit()
pygame.display.update()
car.py:
import pygame
from pygame.locals import *
from random import choice, randint
import math, camera
class CarSprite( pygame.sprite.Sprite ):
def __init__( self, car_image, x, y, max_speed, accel,rot_speed=[1.8, 2.2, 3] ,rotations=360, camera="" ):
pygame.sprite.Sprite.__init__(self)
self.rotated_images = {}
self.min_angle = ( 360 / rotations )
for i in range( rotations ):
rotated_image = pygame.transform.rotozoom( pygame.transform.scale(car_image, (12*camera.zoom,25*camera.zoom)), 360-90-( i*self.min_angle ), 1 )
self.rotated_images[i*self.min_angle] = rotated_image
self.min_angle = math.radians( self.min_angle )
self.image = self.rotated_images[0]
self.rect = self.image.get_rect()
self.rect.center = ( x, y )
self.reversing = False
self.heading = 0
self.speed = 0
self.velocity = pygame.math.Vector2( 0, 0 )
self.position = pygame.math.Vector2( x, y )
self.speed_hardening = 1
self.acc = False
self.steer_strenght_acc = rot_speed[0]
self.steer_strength_normal= rot_speed[1]
self.steer_strength_drift= rot_speed[2]
self.steer_strength = rot_speed[1]
self.drift_point = 0.00
self.accel = accel
self.max_speed = self.accel * 150
self.cam = camera
def turn( self, ori=1 ):
if self.speed > 0.1 or self.speed < 0. :
self.heading += math.radians( self.steer_strenght * ori )
image_index = int((self.heading + self.min_angle / 2) / self.min_angle) % len(self.rotated_images)
image = self.rotated_images[image_index]
if self.image is not image:
x,y = self.rect.center
self.image = image
self.rect = self.image.get_rect()
self.rect.center = (x,y)
def accelerate( self):
self.speed += self.accel
def brake( self ):
if self.speed > 0:
self.speed -= self.accel * 3
if abs(self.speed) < 0.1:
self.speed = 0
self.velocity.from_polar((self.speed, math.degrees(self.heading)))
def move(self):
keys = pygame.key.get_pressed()
if keys[K_w]:
self.accelerate()
if keys[K_s]:
self.brake()
if keys[K_a]:
self.turn(-1)
if keys[K_d]:
self.turn()
if keys[pygame.K_s] or keys [pygame.K_w]:
self.acc = True
else:
self.acc = False
def update( self ):
self.move()
self.speed_hardening = self.speed / 100
self.speed = round(self.speed, 3)
if self.acc:
self.steer_strenght = self.steer_strenght_acc
else:
self.steer_strenght = self.steer_strength_normal
if self.speed > self.max_speed and not pygame.key.get_pressed()[K_SPACE] and not self.drift_point > 0:
self.speed += self.accel / 4 - self.speed_hardening / 2
if self.speed > self.max_speed * 1.8:
self.speed = self.max_speed * 1.8
if self.speed < -self.max_speed / 4:
self.speed = -self.max_speed / 4
if not pygame.key.get_pressed()[K_SPACE]:
self.velocity.from_polar((self.speed, math.degrees(self.heading)))
self.speed += self.drift_point
self.drift_point -= 0.0001
if self.drift_point < 0:
self.drift_point = 0
self.speed -= self.drift_point
else:
self.steer_strenght = self.steer_strength_drift
self.drift_point += 0.0001
if self.drift_point > self.accel / 1.5:
self.drift_point = self.accel / 1.5
if not self.acc and not self.speed < 0.04:
self.speed -= (self.accel / 2) + self.speed_hardening
if self.speed < 0.05:
self.speed = 0
self.position += self.velocity
self.rect.center = self.position
level.py
import pygame
from pygame.locals import *
from random import choice, randint
import math, car, ui, pySave, camera
screen_width = 1000
screen_height = 1000
class Level:
def __init__(self,image, car, camera, pos=(0,0)):
# Convert the images to a more suitable format for faster blitting
self.image = image.convert()
self.road = image
self.cam = camera
self.x,self.y = pos
self.bcg_mask = pygame.mask.from_surface(self.road)
self.car = car
self.get_car_mask()
def update(self, screen):
# Calculate the overlap between the car mask and the background mask
overlap = self.bcg_mask.overlap_mask(
self.car_mask,
(self.car.rect.x, self.car.rect.y)
)
self.x = 0 - self.cam.scroll[0]
self.y = 0 - self.cam.scroll[1]
# Fill the screen with the background color
screen.blit(self.road.convert_alpha(), (self.x, self.y))
screen.blit(overlap.to_surface(unsetcolor=(0,0,0,0), setcolor=(255,255,255,255)), (self.x, self.y))
# Print the overlap count to the console
print(overlap.count())
def get_car_mask(self):
# Convert the car image to a more suitable format for faster blitting
carimg = self.car.image.convert()
carimg.set_colorkey((0,0,0))
self.carimg = carimg
self.car_mask = pygame.mask.from_surface(self.carimg)
camera.py:
import pygame
from pygame.locals import *
class Camera:
def __init__(self, speed, screen):
self.scroll = [5,5]
self.speed = speed
self.screen = screen
self.zoom = 1
def move_on_command(self):
keys = pygame.key.get_pressed()
if keys[K_UP]:
self.scroll[1] -= self.speed
if keys[K_DOWN]:
self.scroll[1] += self.speed
if keys[K_RIGHT]:
self.scroll[0] += self.speed
if keys[K_LEFT]:
self.scroll[0] -= self.speed
def follow(self, obj, speed=12):
#self.scroll[0], self.scroll[1] = obj.rect.x, obj.rect.y
if (obj.rect.x - self.scroll[0]) != self.screen.get_width()/2:
self.scroll[0] += ((obj.rect.x - (self.scroll[0] + self.screen.get_width()/2)))
if obj.rect.y - self.scroll[1] != self.screen.get_height()/2:
self.scroll[1] += ((obj.rect.y - (self.scroll[1] + self.screen.get_height()/2)))
def zoom_game(self, zoom):
self.zoom = zoom
ui.py :
import pygame
from pygame.locals import *
from random import choice, randint
class Button:
def __init__(self, pos, image, action, click_times=1, dissapear=True , text="", textcolor = (255,255,255), fontsize=30):
self.image = image
self.rect = self.image.get_rect(center=pos)
self.clicked = False
self.clicked_times = click_times
self.dissapear = dissapear
self.dont_draw = False
self.function = action
self.text= text
if not self.text == "":
self.font = pygame.font.SysFont("Arial", fontsize, False, False)
self.color = textcolor
def update(self, var=""):
pressed = pygame.mouse.get_pressed()[0]
if not self.text == "":
self.text = self.font.render(f"{var}", 1, self.color)
self.text_rect = self.text.get_rect(center = self.rect.center)
if pressed and not self.clicked and not self.clicked_times <= 0 and self.rect.collidepoint(pygame.mouse.get_pos()):
self.function()
self.clicked = True
self.clicked_times -= 1
if not pressed:
self.clicked = False
if self.clicked_times <= 0:
if self.dissapear:
self.dont_draw = True
def draw(self, screen):
if not self.dont_draw:
screen.blit(self.image, (self.rect.x,self.rect.y))
screen.blit(self.text, (self.text_rect.x, self.text_rect.y))
class TextWithBackground:
def __init__(self, image_size, pos, image, fontsize=30, colour=(255, 255, 255)):
self.image = pygame.transform.scale(image, image_size)
self.rect = self.image.get_rect(center=pos)
self.font = pygame.font.SysFont("Arial", fontsize, False, False)
self.color = colour
self.text = self.font.render("", 1, self.color)
self.other_text = None
self.other_rect = None
def update(self, screen, variable, othertext=""):
self.text = self.font.render(f"{variable}", 1, self.color)
self.text_rect = self.text.get_rect(center=self.rect.center)
if othertext:
self.other_text = self.font.render(f"{othertext}", 1, self.color)
self.other_rect = self.other_text.get_rect(topleft=(self.rect.center[0] - 5, self.rect.center[1] - 5))
screen.blit(self.image, (self.rect.x, self.rect.y))
screen.blit(self.text, (self.rect.x, self.rect.y))
if self.other_text:
screen.blit(self.other_text, (self.other_rect.x, self.other_rect.y))
Here you can find my images:
car.png
map2.png
road_texture.png
See PyGame collision with masks. You need to calculate the offset between the car and the map when you get the overlap area of the masks:
class Level:
# [...]
def update(self, screen):
self.x = 0 - self.cam.scroll[0]
self.y = 0 - self.cam.scroll[1]
# Calculate the overlap between the car mask and the background mask
offset = (self.car.rect.x - self.x, self.car.rect.y - self.y)
overlap = self.bcg_mask.overlap_mask(self.car_mask, offset)
# Fill the screen with the background color
screen.blit(self.road.convert_alpha(), (self.x, self.y))
screen.blit(overlap.to_surface(unsetcolor=(0,0,0,0), setcolor=(255,255,255,255)), (self.x, self.y))
# Print the overlap count to the console
print(overlap.count())
I am trying to make a game where you have to avoid objects falling from the sky. I am a beginner programmer (14yrs old) so I make a lot of mistakes. I solve all of them(for this program) but i dont know how to fix this one. The error is in title. Thank you.
Full code:
from livewires import games, color
import random
games.init(screen_width = 1280, screen_height = 720, fps = 150)
class Covjek(games.Sprite):
def update(self):
if self.overlapping_sprites:
self.destroy()
games.screen.quit()
self.x = games.mouse.x
if self.left < 0:
self.left = 0
if self.right > games.screen.width:
self.right = games.screen.width
class Budala(games.Sprite):
odds_change = 200
def __init__(self, y = 50, speed = 2, odds_change = 200):
super(Budala, self).__init__(image = games.load_image("nigga.jpg"),
x = games.screen.width/2,
y = y,
dx = speed)
self.odds_change = odds_change
self.time = 200
self.score = 0
games.screen.add(self.score)
self.text = games.Text(size = 50, x = games.screen.width - 20,
y = games.screen.height - 20, value = self.score,
color = color.red)
def update(self):
if self.right > games.screen.width:
self.dx = -self.dx
if self.left < 0:
self.dx = -self.dx
odd = random.randrange(Budala.odds_change + 1)
if odd == Budala.odds_change:
self.dx = -self.dx
self.time -= 1
if self.time == 0:
games.screen.add(Meteor(image = games.load_image("smeg.jpg"),
x = self.x,
y = self.y,
dy = 2))
self.time = 200
class Meteor (games.Sprite):
def __init__(self, chef, x = 640, y = 670,image = games.load_image("kamijonhehe.jpg")):
super(Meteor, self).__init__(x = x,
image = image,
y = y,
chef = budala)
self.chef = chef
def update(self):
if self.bottom > games.screen.height:
self.destroy()
self.chef.score += 1
games.screen.background = games.load_image("boaj.jpg")
budala = Budala()
games.screen.add(budala)
games.screen.add(Covjek(image = games.load_image("kamijonhehe.jpg"),
x = games.screen.width/2,
bottom = 720))
games.screen.event_grab = True
games.mouse.is_visible = False
games.music.load("smukwed.mp3")
games.music.play()
games.music.play()
games.screen.mainloop()
Full error code:
Traceback (most recent call last):
File "C:\Users\nikol\Desktop\Python\prugrami limun\izbegavalje.py", line
75, in <module>
games.screen.mainloop()
File "C:\Python31\lib\site-packages\livewires\games.py", line 303, in
mainloop
object._erase()
AttributeError: 'int' object has no attribute '_erase'
P.S. some of the words are in Serbian so they could be hard to remember.
Working in Python 3.1, pygame 1.9.1 and livewires. Line games.screen.mainloop() is throwing the error.
I created an AI in python/pygame but even after spending hours of debugging, I could not find why the individuals(dots) are not getting mutated. After few generations, all the individuals just overlap each other and follow the same exact path. But after mutation they should move a little bit differently.
Here is what a population size of 10 looks like after every 2-3 generations..
Image 1 Image 2 Image 3
As you can see, just after few generations they just overlap and all the individuals in the population move together, following exact same path! We need mutations!!!
I would be really grateful to you if you could find any mistake. Thank!
I saw the code from: https://www.youtube.com/watch?v=BOZfhUcNiqk&t
and tried to make it in python. Here's my code
import pygame, random
import numpy as np
pygame.init()
width = 800
height = 600
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("The Dots")
FPS = 30
clock = pygame.time.Clock()
gameExit = False
grey = [30, 30, 30]
white = [255, 255, 255]
black = [0, 0, 0]
red = [255, 0, 0]
goal = [400, 10]
class Dot():
def __init__(self):
self.x = int(width/2)
self.y = int(height - 150)
self.r = 3
self.c = black
self.xVel = self.yVel = 0
self.xAcc = 0
self.yAcc = 0
self.dead = False
self.steps = 0
self.reached = False
self.brain = Brain(200)
def show(self):
pygame.draw.circle(screen, self.c, [int(self.x), int(self.y)], self.r)
def update(self):
if (self.x >= width or self.x <= 0 or self.y >= height or self.y <= 0):
self.dead = True
elif (np.sqrt((self.x-goal[0])**2 + (self.y-goal[1])**2) < 5):
self.reached = True
if not self.dead and not self.reached:
if len(self.brain.directions) > self.steps:
self.xAcc = self.brain.directions[self.steps][0]
self.yAcc = self.brain.directions[self.steps][1]
self.steps += 1
self.xVel += self.xAcc
self.yVel += self.yAcc
if self.xVel > 5:
self.xVel = 5
if self.yVel > 5:
self.yVel = 5
self.x += self.xVel
self.y += self.yVel
else: self.dead = True
def calculateFitness(self):
distToGoal = np.sqrt((self.x-goal[0])**2 + (self.y-goal[1])**2)
self.fitness = 1/(distToGoal**2)
return self.fitness
def getChild(self):
child = Dot()
child.brain = self.brain
return child
class Brain():
def __init__(self, size):
self.size = size
self.directions = []
self.randomize()
def randomize(self):
self.directions.append((np.random.normal(size=(self.size, 2))).tolist())
self.directions = self.directions[0]
def mutate(self):
for i in self.directions:
rand = random.random()
if rand < 1:
i = np.random.normal(size=(1, 2)).tolist()[0]
class Population():
def __init__(self, size):
self.size = size
self.dots = []
self.fitnessSum = 0
for i in range(self.size):
self.dots.append(Dot())
def show(self):
for i in self.dots:
i.show()
def update(self):
for i in self.dots:
i.update()
def calculateFitness(self):
for i in self.dots:
i.calculateFitness()
def allDead(self):
for i in self.dots:
if not i.dead and not i.reached:
return False
return True
def calculateFitnessSum(self):
self.fitnessSum = 0
for i in self.dots:
self.fitnessSum += i.fitness
def SelectParent(self):
rand = random.uniform(0, self.fitnessSum)
runningSum = 0
for i in self.dots:
runningSum += i.fitness
if runningSum > rand:
return i
def naturalSelection(self):
newDots = []
self.calculateFitnessSum()
for i in self.dots:
parent = self.SelectParent()
newDots.append(parent.getChild())
self.dots = newDots
def mutate(self):
for i in self.dots:
i.brain.mutate()
test = Population(100)
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
screen.fill(white)
if test.allDead():
#Genetic Algorithm
test.calculateFitness()
test.naturalSelection()
test.mutate()
else:
test.update()
test.show()
pygame.draw.circle(screen, red, goal, 4)
clock.tick(FPS)
pygame.display.update()
pygame.quit()
Thanks for any help!
I didn't go through the whole code, but over here
def mutate(self):
for i in self.directions:
rand = random.random()
if rand < 1:
i = np.random.normal(size=(1, 2)).tolist()[0]
you are trying to assign a new value to i (which is an iterater), so it won't change anything, which explains why you'r having trouble with the mutations.
You should have something like this:
def mutate(self):
for i in range(len(self.directions)):
rand = random.random()
if rand < 1:
self.directions[i] = np.random.normal(size=(1, 2)).tolist()[0]
or you can use list comprehensions
https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions
I have some problems and I cant figure out how to fix them...
It is really simple game. A bar moved by the mouse and one ball is (or some balls) bouncing.
The user just need to keep the ball bouncing.
The user can choose how many balls he wants (1,2,3), the size of the bar (small, medium,large) and the speed of the balls (slow, normal, fast).
Problems:
- sometimes everything works fine, and sometimes the ball (or balls) just goes through the bar. Like if the collision function does not work. Is there any other way I can do?
everytime there is a collision, the score should add 10 points for the total displayed on top of the screen, but this score is been overwriting all the time.
For this game be run, I just have to call the function (startGame) from other file (settings), where it also sends the value of number of balls, size of bar and speed of balls.
If anyone can help I appreciate.
Thanks
from livewires import games, color
from tkinter import*
import random
games.init(screen_width = 735, screen_height = 350, fps = 60)
class Bounce(games.Sprite):
global total_score
total_score = 0
def update(self):
global total_score
if self.bottom == 315 and self.overlapping_sprites:
self.dy = -self.dy
total_score += 10
the_score = games.Text(value = 0, size = 25,
color = color.gray,x = 700, y = 20)
games.screen.add(the_score)
if self.right > games.screen.width or self.left < 0:
self.dx = -self.dx
if self.top < 0:
self.dy = -self.dy
if self.bottom == 400:
lose_message = games.Message(value = " - GAME OVER -",
size = 50,
color = color.gray,
x = games.screen.width/2,
y = games.screen.height/2,
lifetime = 300,
after_death = games.screen.quit)
games.screen.add(lose_message)
class Bar_moving(games.Sprite):
def update(self):
self.x = games.mouse.x
self.y = 315
if self.left < 0:
self.left = 0
if self.right > games.screen.width:
self.right = games.screen.width
class have_settings():
def __init__(self):
global the_ball_speed
global the_ball_number
global the_bar_size
if "the_ball_speed" not in globals():
the_ball_speed = "normal"
if "the_bar_size" not in globals():
the_bar_size = "medium"
if "the_ball_number" not in globals():
the_ball_number = 1
def set_all(self, number, size, speed):
global the_ball_speed
global the_bar_size
global the_ball_number
if speed in ("slow","normal","fast"):
the_ball_speed = speed
if size in ("small","medium","large"):
the_bar_size = size
if number in (1,2,3):
the_ball_number = number
def startGame():
call = have_settings()
background = games.load_image("BG.jpg", transparent = False)
games.screen.background = background
#-------------------------------------SPEED
sp_is = 0
if the_ball_speed == "slow":
sp_is = 2
elif the_ball_speed == "normal":
sp_is = 3
elif the_ball_speed == "fast":
sp_is = 4
#-------------------------------------BALL NUMBER
if the_ball_number in (1,2,3):
for n in range(the_ball_number):
position_x_list =(50,150,250,350,400,450,500,550)
position_x = random.choice(position_x_list)
position_y_list =(50,100,150,200,225,250)
position_y = random.choice(position_y_list)
vert_speed_list = (-2,2)
vert_speed = random.choice(vert_speed_list)
ball_img = games.load_image("ball.bmp")
ball = Bounce(image = ball_img,
x = position_x,
y = position_y,
dx = vert_speed,
dy = - sp_is)
games.screen.add(ball)
#-------------------------------------BAR SIZE
if the_bar_size in ("small","medium","large"):
if the_bar_size == "small":
bar_pic = "bar_small.jpg"
elif the_bar_size == "medium":
bar_pic = "bar_medium.jpg"
elif the_bar_size == "large":
bar_pic = "bar_large.jpg"
bar = games.load_image(bar_pic, transparent = False)
the_bar = Bar_moving(image = bar, x = games.mouse.x)
games.screen.add(the_bar)
games.mouse.is_visible = False
games.screen.event_grab = True
games.screen.mainloop()
You should do a greater than check rather than an equals check as follows:
if self.bottom >= 315 and self.overlapping_sprites:
^^
instead of
if self.bottom == 315 and self.overlapping_sprites:
This is because rarely will the ball's y position ever perfectly line up with the bottom. In some cases it may go from y==314 to y==316. In such cases, your method above wouldn't work. Therefore, you should be a greater than test rather than an equality test.
You can apply similar changes everywhere else and it should work.
I have no clue how I would implement a game menu into the game I've made, I was thinking about having buttons for instructions credits and a 'play game' button. So would someone mind helping me out in figuring how to make a simple menu in pygame or livewires? Thanks in advance :)
This is the complete code to my game:
# Asteroid Dodger
# Player must avoid asteroids
# make the score a global variable rather than tied to the asteroid.
import pygame
from livewires import games, color
import math, random
#score
games.init(screen_width = 640, screen_height = 480, fps = 50)
score = games.Text(value = 0, size = 25, color = color.green,
top = 5, right = games.screen.width - 10)
games.screen.add(score)
#lives
lives = games.Text(value = 3, size = 25, color = color.green,
top = 5, left = games.screen.width - 620)
games.screen.add(lives)
#inventory
inventory=[]
#Asteroid images
images = [games.load_image("asteroid_small.bmp"),
games.load_image("asteroid_med.bmp"),
games.load_image("asteroid_big.bmp")]
class Ship(games.Sprite):
"""
A Ship controlled by player that explodes when it by Asteroids.
"""
image = games.load_image("player.bmp")
VELOCITY_STEP = .05
def __init__(self):
""" Initialize Ship object """
super(Ship, self).__init__(image = Ship.image,
bottom = games.screen.height)
def update(self):
global inventory
""" uses A and D keys to move the ship """
if games.keyboard.is_pressed(games.K_a):
self.dx -= Ship.VELOCITY_STEP * 2
if games.keyboard.is_pressed(games.K_d):
self.dx += Ship.VELOCITY_STEP * 2
if self.left < 0:
self.left = 0
if self.right > games.screen.width:
self.right = games.screen.width
self.check_collison()
def ship_destroy(self):
self.destroy()
new_explosion = Explosion(x = self.x, y = self.y)
games.screen.add(new_explosion)
def check_collison(self):
""" Check for overlapping sprites in the ship. """
global lives
for items in self.overlapping_sprites:
items.handle_caught()
if lives.value <=0:
self.ship_destroy()
class Explosion(games.Animation):
sound = games.load_sound("explosion.wav")
images = ["explosion1.bmp",
"explosion2.bmp",
"explosion3.bmp",
"explosion4.bmp",
"explosion5.bmp",
"explosion6.bmp",
"explosion7.bmp",
"explosion8.bmp",
"explosion9.bmp"]
def __init__(self, x, y):
super(Explosion, self).__init__(images = Explosion.images,
x = x, y = y,
repeat_interval = 4, n_repeats = 1,
is_collideable = False)
Explosion.sound.play()
class Asteroid(games.Sprite):
global lives
global score
global inventory
"""
A asteroid which falls through space.
"""
image = games.load_image("asteroid_med.bmp")
speed = 3
def __init__(self, x,image, y = 10):
""" Initialize a asteroid object. """
super(Asteroid, self).__init__(image = image,
x = x, y = y,
dy = Asteroid.speed)
def update(self):
""" Check if bottom edge has reached screen bottom. """
if self.bottom>games.screen.height:
self.destroy()
score.value+=10
def handle_caught(self):
if lives.value>0:
lives.value-=1
self.destroy_asteroid()
if lives.value <= 0:
self.destroy_asteroid()
self.end_game()
def destroy_asteroid(self):
self.destroy()
def die(self):
self.destroy()
def end_game(self):
""" End the game. """
end_message = games.Message(value = "Game Over",
size = 90,
color = color.red,
x = games.screen.width/2,
y = games.screen.height/2,
lifetime = 5 * games.screen.fps,
after_death = games.screen.quit)
games.screen.add(end_message)
class Spawner(games.Sprite):
global images
"""
Spawns the asteroids
"""
image = games.load_image("spawner.bmp")
def __init__(self, y = 10, speed = 5, odds_change = 50):
super(Spawner, self).__init__(image = Spawner.image,
x = games.screen.width / 2,
y = y,
dx = speed)
self.odds_change = odds_change
self.time_til_drop = 0
def update(self):
""" Determine if direction needs to be reversed. """
if self.left < 0 or self.right > games.screen.width:
self.dx = -self.dx
elif random.randrange(self.odds_change) == 0:
self.dx = -self.dx
self.check_drop()
self.check_for_lives()
def check_drop(self):
""" Decrease countdown or drop asteroid and reset countdown. """
if self.time_til_drop > 0:
self.time_til_drop -= 0.7
else:
asteroid_size = random.choice(images)
new_asteroid = Asteroid(x = self.x,image = asteroid_size)
games.screen.add(new_asteroid)
# makes it so the asteroid spawns slightly below the spawner
self.time_til_drop = int(new_asteroid.height * 1.3 / Asteroid.speed) + 1
def check_for_lives(self):
droplives = random.randrange(0, 4000)
if droplives == 5:
lifetoken = Extralives(x = self.x)
g ames.screen.add(lifetoken)
class Extralives(games.Sprite):
global lives
image = games.load_image('addlives.png')
speed = 2
sound = games.load_sound("collectlives.wav")
def __init__(self,x,y = 10):
""" Initialize a asteroid object. """
super(Extralives, self).__init__(image = Extralives.image,
x = x, y = y,
dy = Extralives.speed)
def update(self):
""" Check if bottom edge has reached screen bottom. """
if self.bottom>games.screen.height:
self.destroy()
def handle_caught(self):
Extralives.sound.play()
lives.value+=1
self.destroy()
def main():
""" Play the game. """
bg = games.load_image("space.jpg", transparent = False)
games.screen.background = bg
the_spawner = Spawner()
games.screen.add(the_spawner)
pygame.mixer.music.load("Jumpshot.ogg")
pygame.mixer.music.play()
the_ship = Ship()
games.screen.add(the_ship)
games.mouse.is_visible = False
games.screen.event_grab = True
games.screen.mainloop()
#starts the game
main()
The Pygbutton module provides a way to create buttons in Pygame programs. You can download it via "pip install pygbutton". There are demos on the github: https://github.com/asweigart/pygbutton
Try this code out:
Game Menu function
def game_intro():
intro = True
while intro:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
gameDisplay.fill(white)
titleText = gameDisplay.blit(title, (170, 200)) # title is an image
titleText.center = ((display_width / 2), (display_height / 2))
# button(x, y, w, h, inactive, active, action=None)
button(100, 350, 195, 80, startBtn, startBtn_hover, game_loop)
button(300, 350, 195, 80, creditsBtn, creditsBtn_hover, #Your function)
pygame.display.update()
clock.tick(15)
you can call this menu above your game loop.
Button function
Pygame doesn't have buttons but it is pretty easy to make one!
def button(x, y, w, h, inactive, active, action=None):
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x + w > mouse[0] > x and y + h > mouse[1] > y:
gameDisplay.blit(active, (x, y))
if click[0] == 1 and action is not None:
action()
else:
gameDisplay.blit(inactive, (x, y))
you can call this function inside your game menu like this:
#Example function call
button(340, 560, 400, 200, randomBtn, randomBtn_hover, random_func)
Here's what each parameter means in button():
x: x-coordinate of button
y: y-coordinate of button
w: button width(in pixels)
h: button height(in pixels)
active: the picture of the button when it is active(e.g when the mouse is hovering ver it)
inactive: the picture of the button when it is idle
action: the function to be executed when the button is pressed
Note: It is better to make a button function since it is easier to make one and it saves a lot of time
Hope this helped!