Apologies in advance if this is a simple fix but I couldn't find anything on it. I am relatively new to pygame but I can't understand why when I run this the first bar that is drawn is always half cut off. To me anyway I should start a 0,400 and draw from 0 across 40 and then up. If this is not the case please enlighten a curious mind
from pygame import *
import pygame, sys, random
pygame.init()
screen = pygame.display.set_mode((1000,400))
colour = (0, 255, 0)
array = []
x, y, z, b = -80, 0, 0, 0
flag = True
for c in range(5):
array.append(random.randint(100, 400));
for c in array:
print c
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if len(array) == z:
flag = False
if flag == True:
b = array[z]
x += 80
z += 1
pygame.draw.line(screen, colour, (x, 400), (x, (400-b)), 40)
pygame.display.update()
pygame is drawing a line from (0,400) to (0, 400-b), with line thickness 40.
Here is an way to shift the lines so each is fully visible:
for i, b in enumerate(array):
x = i*80 + 20 # <-- add 20 to shift by half the linewidth
pygame.draw.line(screen, colour, (x, 400), (x, (400-b)), 40)
import sys
import random
import pygame
pygame.init()
screen = pygame.display.set_mode((1000,400))
colour = (0, 255, 0)
array = [random.randint(100, 400) for c in range(5)]
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
linewidth = 40
for i, b in enumerate(array):
x = i*linewidth*2 + linewidth//2
pygame.draw.line(screen, colour, (x, 400), (x, (400-b)), linewidth)
pygame.display.update()
Related
The program is supposed to make 3 squares and move them to the right. That works well. However, there are 2 squares that move down even though there are no functions to do that. there are only 3 square creating functions but there are 2 more that appear
import pygame
import random
import time
enemyCoordList = []
pygame.init()
rand = random.Random()
screen = pygame.display.set_mode((1000, 600))
px = 30
py = 30
def enemy(x, y, sizex=30, sizey=30, health=0, speed=6,):
# pygame.draw.rect(screen, (0, 255, 0), pygame.Rect(x, y, sizex, sizey))
enemyCoordList.append(x)
enemyCoordList.append(y)
def drawEnemy():
for l in range(len(enemyCoordList)-1):
# print(range(len(enemyCoordList)))
pygame.draw.rect(screen, (0, 255, 0), pygame.Rect(enemyCoordList[l], enemyCoordList[l+1], 50, 50))
enemy(30, 30)
enemy(50, 50)
enemy(100,100)
print(enemyCoordList)
run = True
while run:
time.sleep(0.05)
screen.fill((9, 68, 43))
drawEnemy()
for i in range(len(enemyCoordList)):
#print(i)
if i % 2 != 0:
#print(i)
continue
# print(enemyCoordList)
#print(i)
enemyCoordList[i] += 1
# for i in enemyCoordList:
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
A coordinate has 2 components so:
for l in range(len(enemyCoordList)-1):
for l in range(0, len(enemyCoordList), 2):
Correct drawEnemy function:
def drawEnemy():
for l in range(0, len(enemyCoordList), 2):
pygame.draw.rect(screen, (0, 255, 0), pygame.Rect(enemyCoordList[l], enemyCoordList[l+1], 50, 50))
However, it would be much easier to work with a list of coordinate pairs (list of lists):
import pygame
import random
import time
pygame.init()
rand = random.Random()
screen = pygame.display.set_mode((1000, 600))
def enemy(x, y, sizex=30, sizey=30, health=0, speed=6):
enemyCoordList.append([x, y])
def drawEnemy():
for x, y in enemyCoordList:
pygame.draw.rect(screen, (0, 255, 0), pygame.Rect(x, y, 50, 50))
enemyCoordList = []
enemy(30, 30)
enemy(50, 50)
enemy(100,100)
print(enemyCoordList)
run = True
while run:
time.sleep(0.05)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
for pos in enemyCoordList:
pos[0] += 1
screen.fill((9, 68, 43))
drawEnemy()
pygame.display.update()
pygame.quit()
I made a script, which should take the user input of a mathematical function (f(x)=...) and draw it. I used pygame for that because I want to use that mechanic for a game.
I have to run the code of a function once without any output once, but after that, it flawlessly works
heres the code:
import pygame
def replace_x(function):
f = lambda x: eval(function)
return f
def convert_y(y_coords):
y_coords = 540 - y_coords
return y_coords
def convert_x(x_coord):
x_coord = x_coord + 960
return x_coord
# variables
background_colour = (255, 255, 255)
screen = pygame.display.set_mode((1920, 1080))
running = True
current_y = 0
previous_y = 0
pygame.init()
pygame.display.set_caption('Mathe Kreativarbeit')
screen.fill(background_colour)
pygame.display.flip()
function_input = input("Funktion: ")
function_input = function_input.replace("^", "**")
pygame.display.flip()
for x_coords in range(-15, 17):
f = replace_x(function_input)
current_y = convert_y(f(x_coords))
previous_y = convert_y(f(x_coords - 1))
start_pos = (convert_x((x_coords - 1) * 60), previous_y)
end_pos = (convert_x(x_coords * 60), current_y)
print(start_pos)
print(end_pos)
pygame.draw.aaline(screen, (0, 0, 0), start_pos, end_pos)
pygame.display.flip()
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
Create a list of points from the function:
f = replace_x(function_input)
pt_list = []
for x in range(-20, 20):
pt_list.append((x, f(x)))
Either print the list of points:
print(pt_list)
or print the list in a loop:
for pt in pt_list:
print(pt)
Create a list of screen coordinates from the list of point:
coord_list = []
for pt in pt_list:
x = round(convert_x(pt[0] * 20))
y = round(convert_y(pt[1]))
coord_list.append((x, y))
Draw the curve in the application loop with pygame.draw.aalines():
clock = pygame.time.Clock()
running = True
while running:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.draw.aalines(screen, (0, 0, 0), False, coord_list)
pygame.display.flip()
pygame.quit()
Example for input x**3:
I'm trying to create a animation that runs around a shape. The method I came up with is similar to the snake game, drawing the desired part and refresh it with white screen.
For example, if I want to draw a linear line animation, with the max animated length of 3:
lst = [1, 2, 3]
dummy_lst = [1, 1, 1, 2, 3, 3, 3]
colored_position = [[1,1,1], [1,1,2], [1,2,3], [2,3,3], [3,3,3]] # if the numbers overlapped, it draws the same place which is fine
and then I iterate the colored_position to get the animation done.
The real code:
import pygame
import sys
SCREEN_WIDTH = 800
CELLSIZE = 10
x, y = 150, 200
position = [[x+CELLSIZE*i, y] for i in range(50)] +\
[[x+CELLSIZE*50, y+CELLSIZE*i] for i in range(50)] +\
[[x+CELLSIZE*50-CELLSIZE*i, y+CELLSIZE*50]for i in range(50)] +\
[[x, y+CELLSIZE*50-CELLSIZE*i]for i in range(50)]
# creates fake firsts and lasts
def dummy_list(list, length):
return [list[0]]*(length-1) + list + [list[-1]]*(length-1)
def main():
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_WIDTH))
count = 0
while True:
clock.tick(10)
screen.fill((255, 255, 255))
dummy = dummy_list(position, 50)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
count = 0
while count < 1: # I could chaget this to see many times it rotates
for i in range(len(dummy)-50+1):
for j in range(9): # change this to adjust how wide the colored part is
pygame.draw.rect(screen, (255, 0, 0), pygame.Rect(
dummy[i+j][0], dummy[i+j][1], CELLSIZE, CELLSIZE), 0)
pygame.display.update()
screen.fill((255, 255, 255))
count += 1
pygame.display.update()
But it seems very hard-coding. since I have to know each part of the desired position's Xs and Ys. What's the smarter way to complete the task?
You want to move the object along a path. I don't see any problem in defining the path through a list of points.
However you can write a function that generates the list of points from a pygame.Rect object:
def generate_positions(rect, step):
return [[x, rect.top] for x in range(rect.left, rect.right, step)] +\
[[rect.right, y] for y in range(rect.top, rect.bottom, step)] +\
[[x, rect.bottom] for x in range(rect.right, rect.left, -step)] +\
[[rect.left, y] for y in range(rect.bottom, rect.top, -step)]
CELLSIZE = 10
x, y = 150, 200
position = generate_positions(pygame.Rect(x, y, 50*CELLSIZE, 50*CELLSIZE), CELLSIZE)
I recommend to use the application loop to draw the snake:
import pygame
import sys
SCREEN_WIDTH = 800
def generate_positions(rect, step):
return [[x, rect.top] for x in range(rect.left, rect.right, step)] +\
[[rect.right, y] for y in range(rect.top, rect.bottom, step)] +\
[[x, rect.bottom] for x in range(rect.right, rect.left, -step)] +\
[[rect.left, y] for y in range(rect.bottom, rect.top, -step)]
CELLSIZE = 10
x, y = 150, 200
position = generate_positions(pygame.Rect(x, y, 10*CELLSIZE, 10*CELLSIZE), CELLSIZE)
def main():
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_WIDTH))
current_point = None
snake_len = 9
while True:
clock.tick(10)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
current_point = -snake_len
screen.fill((255, 255, 255))
if current_point != None:
for i in range(max(0, current_point), min(len(position), current_point+snake_len)):
pygame.draw.rect(screen, (255, 0, 0), pygame.Rect(*position[i], CELLSIZE, CELLSIZE), 0)
current_point += 1
if current_point >= len(position):
current_point = None
pygame.display.update()
main()
In this program, I want a bigger movable circle and many multi-colored smaller circles. However, when I run the program all of the smaller circles are all the same color and I cannot figure out how to randomly give each of them a different color. How do I fix this?
import pygame as pg
import random as rd
pg.init()
screen = pg.display.set_mode((800, 600))
p_1_x = 200
p_1_y = 200
p_1_change_x = 0
def p_1(x, y):
player_1 = pg.draw.circle(screen, (2, 2, 0), (x, y), 15)
locations = []
small_color = []
for i in range(50):
red = rd.randint(0, 220)
blue = rd.randint(0, 220)
green = rd.randint(0, 220)
x = rd.randint(100, 700)
y = rd.randint(100, 500)
locations.append((x, y))
small_color.append((red, blue, green))
while True:
screen.fill((255, 255, 255))
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
if event.type == pg.KEYDOWN:
if event.key == pg.K_RIGHT:
p_1_change_x = 1
if event.key == pg.K_LEFT:
p_1_change_x = -1
if event.type == pg.KEYUP:
if event.key == pg.K_RIGHT or pg.K_LEFT:
p_1_change_x = 0
p_1_x += p_1_change_x
p_1(p_1_x, p_1_y)
for locate in locations:
pg.draw.circle(screen, (small_color[i]), locate, 5)
pg.display.update()
In the main loop, you're using i which never changes. Use enumerate to return an index while looping through the locations collection.
Try this code:
for i,locate in enumerate(locations):
pg.draw.circle(screen, (small_color[i]), locate, 5)
be sure you import random library at the first line:
import random as rd
Here is a simple function, which generate random color:
def random_color():
r = rd.randint(0, 255)
g = rd.randint(0, 255)
b = rd.randint(0, 255)
return (r, g, b)
so you can call it when ever you need to:
color = random_color()
draw.circle(screen, color, (x, y), SIZE)
Github repo
I make a repo in the GitHub and did some changes,
Dots are colorful, new dot gets random color and the ball gets bigger whenever eats a dot.
https://github.com/peymanmajidi/Ball-And-Dots-Game__Pygame
I want to draw a parabola in pygame. I have made a pixelarray object and loop through it to determine if a pixel is on the parabola or not. I seem to get an image that has gaps between the points. How do I make it a single continuous line?
import pygame
import sys
from pygame.locals import *
import math
WIDTH = 640
HEIGHT = 480
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT), 0, 32)
pxarray = pygame.PixelArray(screen)
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
screen.fill((0,0,0))
for y, py in enumerate(pxarray):
for x, px in enumerate(py):
if int(x) == (int(y)*int(y)) - 30*int(y) + 450:
pxarray[y][x] = 0xFFFFFF
pygame.display.update()
color = 255, 0, 0
first = True
prev_x, prev_y = 0, 0
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
screen.fill((0,0,0))
for y, py in enumerate(pxarray):
for x, px in enumerate(py):
if int(x) == (int(y)*int(y)) - 30*int(y) + 450:
pxarray[y][x] = 0xFFFFFF
if first:
first = False
prev_x, prev_y = x, y
continue
pygame.draw.line(screen, color, (prev_y, prev_x), (y, x))
prev_x, prev_y = x, y
first = True
pygame.display.flip()
You'll need to draw the parabola as a series of line segments. How many segments you use will determine how smooth it will look, so if you're computing the parabola x = y^2 + 30y + 450, you'd compute the x values for a number of y values and draw lines from (x0,y0) to (x1,y1) and so on.
If you don't have a line drawing primitive, you'll need to implement one using something like Bresenham's Algorithm.