Ye i know this is quite noob question but problem is this.
i'm making a game and i wanna randomize stars to a huge space area
But results that i get are:
The space keeps recaculating places of stars so everything moves.
It Shows only 1 star on the upper left corner of window.
Here is the full code:
import os
import pygame
from pygame.locals import *
import random
gstars = 500
gstarmax = 0
red = (255,0,0)
yellow = (240,250,60)
timer = 0
size = [1600, 1000]
screen = pygame.display.set_mode((1600, 1000), HWSURFACE | DOUBLEBUF | RESIZABLE)
pygame.display.set_caption('planet system test')
clock = pygame.time.Clock()
area = pygame.image.load("screenMonitor.png")
done = False
while done == False:
pygame.event.pump()
mouse_x, mouse_y = pygame.mouse.get_pos()
timer += 1
if timer > 99:
timer = 0
screen.fill((0,0,0))
pygame.draw.rect(screen, red, (20, 20, 1350, 480), 2)
pygame.draw.rect(screen,yellow,(2,2,2,2),2)
go = True
if go == True:
for i in range(gstars):
s1 = random.randrange(1,1600)
s2 = random.randrange(1,1000)
colorSelect = random.randrange(0,5)
if colorSelect == 1:
yellow = (240,250,60)
if colorSelect == 2:
yellow = (249,173,60)
if colorSelect == 3:
yellow = (226,43,68)
if colorSelect == 4:
yellow = (52,173,84)
go = False
pygame.draw.rect(screen,yellow,(2+s1,2+s2,2,2),2)
pygame.display.flip()
clock.tick(30)
pygame.quit()
The trouble is in the main/event loop.
You put the code for position your stars inside the main loop. Since it is randomize at every iteration, it will move.
I remove the go = False that probably cause the error to display only one star.
In the following code, I create a list of star that have the position in indices 0 and 1, and the tuple of the color in 2.
The tuple of color is randomly choose using the random.choice(Sequence) function. https://docs.python.org/2/library/random.html
import pygame
from pygame import *
import random
gstars = 500
gstarmax = 0
red = (255,0,0)
yellow = (240,250,60)
timer = 0
size = [1600, 1000]
pygame.init()
pygame.display.set_caption('planet system test')
screen = pygame.display.set_mode((size[0], size[1]))
clock = pygame.time.Clock()
area = pygame.image.load("screenMonitor.png")
color = ((240,250,60),(249,173,60),(226,43,68),(52,173,84))
stars = []
for i in range(gstars):
s1 = random.randrange(1,1600)
s2 = random.randrange(1,1000)
starcolor = random.choice(color)
stars.append([s1, s2, starcolor])
done = False
while done == False:
for event in pygame.event.get():
if event.type == pygame.QUIT: #Quit the game if X
done = False
screen.fill(0)
pygame.draw.rect(screen, red, (20, 20, 1350, 480), 2)
pygame.draw.rect(screen,yellow,(2,2,2,2),2)
for star in stars:
pygame.draw.rect(screen,star[2],(2+star[0],2+star[1],2,2),2)
pygame.display.flip()
clock.tick(30)
EDIT : Correct the code following the advice of Ted Klein Bergman.
Related
I'm trying to recreate a game of pong just for fun.
Here is my full code as of right now.
import pygame, random, math
pygame.init()
#colours:-------------------------------------------------------------
R = random.randrange(1,255)
B = random.randrange(1,255)
G = random.randrange(1,255)
WHITE = (255, 255, 255)
GREEN = (39, 133, 20)
YELLOW = (252, 252, 25)
BLACK = (0, 0, 0)
BLUE = (30, 100, 225)
RED = (255,0,0)
RANDOM_COLOR = (R, B, G)
#Surface:-------------------------------------------------------------
width = 700
height = 600
size = (width, height)
screen = pygame.display.set_mode(size)
screen_rect = screen.get_rect()
pygame.display.set_caption("Pong Remake")
background = pygame.image.load("background.png").convert()
background = pygame.transform.scale(background, (width, height))
logo = pygame.image.load("logo.png").convert()
logo.set_colorkey((BLACK))
credits = pygame.image.load("credits.png")
credits.set_colorkey((BLACK))
#variables:-----------------------------------------------------------
clock = pygame.time.Clock()
done = False
text = pygame.font.Font(None,25)
display_instructions = True
instruction_page = 1
start_font = pygame.font.Font("C:\Windows\Fonts\BAUHS93.TTF", 35)
instruction_font = pygame.font.Font(None, 17)
win_lose_font = pygame.font.Font("C:\Windows\Fonts\BAUHS93.TTF",50)
score = pygame.font.Font(None, 100)
bounce = pygame.mixer.Sound("bounce.wav")
playerOne_score = 0
playerTwo_score = 0
playerOne = ""
playerTwo = ""
x = 350
y = 300
ball_rect = pygame.Rect(x,y,10,10)
paddleOne_rect = pygame.Rect(10, 250, 20, 60)
paddleTwo_rect = pygame.Rect(670, 250, 20, 60)
x_speed = random.randrange(5, 10)
y_speed = random.randrange(5,10)
def draw_background(screen, pic, x,y):
screen.blit(pic, (x,y))
#main loop
#INPUT v ---------------------------------------------------------
#Start Page
while not done and display_instructions:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == pygame.MOUSEBUTTONDOWN:
instruction_page += 1
if instruction_page == 2:
display_instructions = False
#Shows the start of the page
if instruction_page == 1:
draw_background(screen, logo, 100,-150)
draw_background(screen, credits, 100,50)
instruction_text = instruction_font.render("How to Play. The objective to this game is to score the ball on the other side before the opponent can.", False, WHITE)
instruction_text_three = instruction_font.render("First Player to get 10 points wins, Have Fun and Good Luck!", False, WHITE)
instruction_text_two = instruction_font.render("For Player One, use the a and the z keys to move up and down, For Player Two, use the k and m keys.", False, WHITE)
continue_text= start_font.render("Click to Play...",True, WHITE)
screen.blit(continue_text, [200, 400])
screen.blit(instruction_text, [0,500])
screen.blit(instruction_text_three, [0,532])
screen.blit(instruction_text_two,[0,516])
if instruction_page == 2:
display_instructions = False
clock.tick(60)
pygame.display.flip()
while not done:
click = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.MOUSEBUTTONDOWN:
click = True
#INPUT ^ =========================================================
#PROCESS v -------------------------------------------------------
str(playerOne_score)
str(playerTwo_score)
scoreOne = text.render("Player One:" + str(playerOne_score), False, WHITE)
scoreTwo = text.render("Player Two:" + str(playerTwo_score), False, WHITE)
#moves paddles with keys on keyboar
key = pygame.key.get_pressed()
if key[pygame.K_a]: paddleOne_rect.move_ip(0, -10)
if key[pygame.K_z]: paddleOne_rect.move_ip(0, 10)
if key[pygame.K_k]: paddleTwo_rect.move_ip(0, -10)
if key[pygame.K_m]: paddleTwo_rect.move_ip(0, 10)
#makes sure paddles stay on screen
paddleOne_rect.clamp_ip(screen_rect)
paddleTwo_rect.clamp_ip(screen_rect)
ball_rect.move_ip(x_speed, y_speed)
if ball_rect.y + ball_rect.height> screen_rect.height or ball_rect.y < 0:
y_speed = y_speed * -1
bounce.play()
if ball_rect.collidelist([paddleOne_rect, paddleTwo_rect]) > -1:
x_speed = -x_speed
R = random.randrange(1,255)
B = random.randrange(1,255)
G = random.randrange(1,255)
bounce.play()
if ball_rect.x >= 700:
x_speed * -1
playerOne_score += 1
pygame.display.flip
if ball_rect.x <= 0:
x_speed * -1
playerTwo_score += 1
#PROCESS ^ =======================================================
#DRAWING GOES BELOW HERE v ------------------------------------
draw_background(screen, background, 0,0)
screen.blit(scoreOne, (0,0))
screen.blit(scoreTwo, (500,0))
pygame.draw.ellipse(screen, WHITE,ball_rect )
pygame.draw.rect(screen,RANDOM_COLOR, paddleOne_rect)
pygame.draw.rect(screen,RANDOM_COLOR, paddleTwo_rect)
pygame.draw.line(screen, WHITE, (350,0),(350,700), 1)
#DRAWING GOES ABOVE HERE ^ ------------------------------------
pygame.display.flip()
clock.tick(60)
pygame.quit()
What I am currently having problems with at the moment is when the ball goes off the screen, I want it to go back to the middle again as someone has scored a point. But I'm a bit stuck on what to do.
If you guys can help me out, that would be amazing!!
There is a lot of code here, so this does not follow specific variables you used, but I hope this helps.
1) Find the width of you screen
2) Take the x and y coordinates that you use to know where to draw the ball
3) Make an if statement that essentially says
(pseudocode)
if x > 1000
score1 += 1
x = 500
if x < 0
score2 += 1
x = 500
``
I hope this can set you on the right track, and I suggest checking out the pygame docs.
Cheers!
I'm trying to make a animation of projection movement but it does't work.
Just a black window appear.
import math
import time
import pygame
V0 = int(input("please enter initial speed(m/s)"))
angle = int(input("please enter throwing angle"))
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
pygame.init()
screen = pygame.display.set_mode((400, 300))
done = False
clock = pygame.time.Clock()
while not done:
T = time.clock()
x = int(math.cos(angle)*V0*T)
y = int((math.sin(angle)*V0*T)-1/2*(9.8*T*T))
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
screen.fill(BLACK)
pygame.draw.circle(screen, WHITE, (x, y), 5, 0)
pygame.display.flip()
clock.tick(10)
pygame.quit()
I think the problem is my formula statement, but I don't know how to fix it.
Read the comments. I've changed the way you calculated time and angle.
import math
import time
import pygame
V0 = int(input("please enter initial speed(m/s)"))
angle = int(input("please enter throwing angle"))
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
pygame.init()
screen = pygame.display.set_mode((400, 300))
done = False
clock = pygame.time.Clock()
T = 0 #initialize
while not done:
#T = time.clock() #don't use
x = int(math.cos(math.radians(angle))*V0*T) #use math.radians(degree). Don't just provide degrees. cos() and sin() needs input in radians
y = 300 - int((math.sin(math.radians(angle))*V0*T)-(0.5*9.8*T*T)) #looks better. projectile starts from the ground.
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
screen.fill(BLACK)
pygame.draw.circle(screen, WHITE, (x,y), 5, 0)
milliseconds = clock.tick(60) #try this. count ms. add to s. calculate total time passed.
seconds = milliseconds / 1000.0
T += seconds
pygame.display.flip()
pygame.quit()
After a few hours of looking for code to reference. I failed i tried to re-write the collision code but it failed. Now my Question is
How can i fix my code to make it delete the Enemy ship when the bullet hits him
Note: Im not asking for you to do it, i just need it further explained what the problem or where im making a mistake
The Code Segment
for bullet in Bullets:
Hit_list = pygame.sprite.Group()
if pygame.sprite.collide_rect(bullet, Enemy_list):
Hit_list.add(hit)
for hit in Hit_list:
Bullets.remove(bullet)
All.remove(bullet)
All.remove(hit)
Enemy_list.remove(hit)
# If the bullet goes off the screen it deletes
if bullet.rect.y < 0:
Bullets.remove(bullet)
All.remove(bullet)
The Error
Traceback (most recent call last):
File "C:\Users\jb127996\Desktop\Invaders in Space\Space Shooter.py", line 92, in <module>
if pygame.sprite.collide_rect(bullet, Enemy_list):
File "C:\Python32\lib\site-packages\pygame\sprite.py", line 1290, in collide_rect
return left.rect.colliderect(right.rect)
AttributeError: 'Group' object has no attribute 'rect'
Entire Code
import pygame
import Player_func
import AI
from pygame.locals import *
#Background
Background = pygame.image.load('Tempback.png')
Background_size = Background.get_size()
Background_rect = Background.get_rect()
# Screens Resoultion
Width = 640
Height = 480
Scr = pygame.display.set_mode((Width,Height))
# Fps Clock Vars( Clock.tick(FPS) )
Clock = pygame.time.Clock()
FPS = 60
# Colors
White = (255, 255, 255)
Black = (0, 0, 0)
Green = (0, 255, 0)
Red = (255, 0, 0)
Blue = (0, 0, 255)
Orange = (255, 140, 0)
Default = White
# Sprite Lists
Bullets = pygame.sprite.Group()
Enemy_list = pygame.sprite.Group()
All = pygame.sprite.Group()
# Shorting the Class files
AI = AI.Enemy()
Ply = Player_func.Player()
# CORDS for Player
AI.rect.x, AI.rect.y = 100, 50
AI_pos = (AI.rect.x, AI.rect.y)
Ply.rect.x, Ply.rect.y = 580, 425
P_pos = (Ply.rect.x, Ply.rect.y)
# True false statements and Vars
running = True
Gun_Overload = 0
Fire = 20
while running:
Enemy_list.add(AI)
All.add(AI)
All.add(Ply)
# Collision Detection for walls on the spaceship
if Ply.rect.x <= 0:
Ply.rect.x += 5.5
elif Ply.rect.x >= 590:
Ply.rect.x -= 5.5
# Events
for event in pygame.event.get():
if event.type == QUIT:
running = False
elif event.type == KEYDOWN:
if event.key == K_SPACE and Gun_Overload == Fire:
bullet = Player_func.Bullet()
bullet.rect.x = (Ply.rect.x +15)
bullet.rect.y = Ply.rect.y
Bullets.add(bullet)
All.add(bullet)
Gun_Overload = 0
#Cool Down
if Gun_Overload < Fire:
Gun_Overload += 1
AI.movement()
Ply.Controls()
# Updates the Sprite lists so they can all be drawn
All.update()
# Checks if a bullet hits the enemy on the list
for bullet in Bullets:
Hit_list = pygame.sprite.Group()
if pygame.sprite.collide_rect(bullet, Enemy_list):
Hit_list.add(hit)
for hit in Hit_list:
Bullets.remove(bullet)
All.remove(bullet)
All.remove(hit)
Enemy_list.remove(hit)
# If the bullet goes off the screen it deletes
if bullet.rect.y < 0:
Bullets.remove(bullet)
All.remove(bullet)
Scr.blit(Background, Background_rect)
All.draw(Scr)
pygame.display.flip()
# FPS Clock Loaded in
Clock.tick(FPS)
pygame.quit()
Your If condition uses collide_rect:
pygame.sprite.collide_rect()
Collision detection between two sprites, using rects.
collide_rect(left, right) -> bool
You pass 2 parameters - a Bullet, and a SpriteGroup. The error is telling you that a SpriteGroup does not have a Rect attribute.
I think you wanted to use:
pygame.sprite.spritecollide()
Find sprites in a group that intersect another sprite.
spritecollide(sprite, group, dokill, collided = None) -> Sprite_list
Apart from this, I would change all the variable names to lowercase. I have also noticed that your if bullet.rect.y < 0: is under the collide test. I think you want to remove a Bullet from the screen even if there is no collision.
I am doing a clone of pong. It is just a barebone version of pong. And It would be nice if you guys could help me refine it. I am mainly doing it as a learning exercise, So i have just kept it to a basic functions.
import time
import pygame
done = False
pygame.init()
myfont = pygame.font.SysFont("monospace", 15)
screen_size = [320,240]
white = [255,255,255]
black = [0,0,0]
gutter = 10
score_1 = 0
score_2 = 0
ball_pos = [160,120]
ball_vel = [1,1]
paddle_1 = [0,0]
paddle_2 = [screen_size[0]-5,0]
vel_1 = [0,0]
vel_2 = [0,0]
P1 = False
P2 = False
screen = pygame.display.set_mode(screen_size)
pygame.display.set_caption("mygame")
while not done:
time.sleep(0.02)
screen.fill(black)
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == pygame.KEYDOWN:
if pygame.key.get_pressed()[pygame.K_DOWN]:
vel_2[1] += 2
P1 = True
if pygame.key.get_pressed()[pygame.K_UP]:
P1 = True
vel_2[1] -= 2
if pygame.key.get_pressed()[pygame.K_s]:
P2 = True
vel_1[1] += 2
if pygame.key.get_pressed()[pygame.K_w]:
P2 = True
vel_1[1] -= 2
if event.type == pygame.KEYUP:
if(P1):
vel_2 = [0,0]
P1 = False
if (P2):
vel_1 = [0,0]
P2 = False
if ball_pos[1] in range(paddle_1[1],paddle_1[1]+30) and ball_pos[0] in range(0,gutter+10) :
ball_vel[0] *= -1
if ball_pos[1] in range(paddle_2[1],paddle_2[1]+30) and ball_pos[0] in range(310,320):
ball_vel[0] *= -1
if ball_pos[0] > 320:
score_1 += 1
ball_pos = [160,120]
if ball_pos[0] < 5:
score_2 += 1
ball_pos = [160,120]
if ball_pos[1] > 230 or ball_pos[1] < 5:
ball_vel[1] *= -1
paddle_1[0] += vel_1[0]
paddle_1[1] += vel_1[1]
paddle_2[0] += vel_2[0]
paddle_2[1] += vel_2[1]
ball_pos[0] += ball_vel[0]
ball_pos[1] += ball_vel[1]
## pygame.draw.line(screen,white,(gutter,0),(gutter,screen_size[1]))
## pygame.draw.line(screen,white,(screen_size[0]-gutter,0),(screen_size[0]-gutter,screen_size[1]))
pygame.draw.line(screen,white,(screen_size[0]/2,0),(screen_size[0]/2,screen_size[1]),1)
pygame.draw.circle(screen,white,ball_pos,10,0)
pygame.draw.line(screen,white,[paddle_1[0]+5,paddle_1[1]],[paddle_1[0]+5,paddle_1[1]+50],gutter)
pygame.draw.line(screen,white,paddle_2,[paddle_2[0],paddle_2[1]+50],gutter)
label_1 = myfont.render(str(score_1), 1, (255,255,0))
label_2 = myfont.render(str(score_2), 1, (255,255,0))
screen.blit(label_1, (100, 100))
screen.blit(label_2, (220, 100))
pygame.display.flip()
pygame.quit()
There are a few things that you should improve in your code:
1) Constants vs Variables
When you define
white = [255,255,255]
black = [0,0,0]
you should instead do:
WHITE = (255,255,255)
BLACK = ( 0, 0, 0)
Constants should usually be created as tuples so that you do not mistakenly change their values. Also, since you only ever read a constant and never change its value a tuple is more appropriate. It also runs slightly faster
2) Creating Classes
Whenever you make a game, it is recommended that you create the objects as classes. In this case, you would have classes such as Player and Ball. In these classes you can define functions such as update and draw. This will allow you to easily draw an object or update its location, speed etc by a single line of code. Eg:
player.update()
player.draw()
ball.draw()
3) Time vs Timer
Instead of using import time, I recommend that you use the pygame built-in Timer option for controlling the FPS of the game. Here's an example:
timer = pygame.time.Clock()
then at the start of your while loop, you can simply do:
timer.tick(60) #if you want 60 to be the number of frames per second
I know it is a lot to take in but in the end the effort will be more than worth it and it will make future game making with pygame much cleaner.
GREAT RESOURCE BOOK
HAPPY PYGAMING!
Try to encapsulate the ball and the paddles in proper Ball and Paddle classes. This way, you make your code cleaner and more reusable, since both paddles will share the same code.
I am trying to make a very simple game, here is my full code:
import pygame
from pygame.locals import *
pygame.init()
#define variables
width, height = 940, 780
screen = pygame.display.set_mode((width, height))
grey = 87, 87, 87
white = 255, 255, 255
player = pygame.image.load("Pics\goodcar.jpeg")
keys = [False, False, False, False]
playerpos = [0,40]
green = 0,255,0
red = 255,0,0
color = red
x1 = 0
x2 = 40
y1 = 940
y2 = 100
#main program
while 1:
screen.fill(0)
road = pygame.draw.rect(screen, grey, (x1,x2,y1,y2), 0)
traffic_light = pygame.draw.circle(screen, white, (640,90), 40, 1)
screen.blit(player, playerpos)
car_rect = player.get_rect()
if traffic_light.colliderect(car_rect):
print("Its working")
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
exit(0)
if event.type == pygame.KEYDOWN:
if event.key==K_RIGHT:
keys[0]=True
elif event.key==K_LEFT:
keys[1]=True
elif event.key==K_DOWN:
keys[2]=True
elif event.key==K_UP:
keys[3]=True
if event.type == pygame.KEYUP:
if event.key==pygame.K_RIGHT:
keys[0]=False
elif event.key==pygame.K_LEFT:
keys[1]=False
elif event.key==pygame.K_DOWN:
keys[2]=False
elif event.key==pygame.K_UP:
keys[3]=False
if keys[0]==True:
playerpos[0]+=3
elif keys[1]==True:
playerpos[0]-=3
elif keys[2]==True:
playerpos[1]+=3
elif keys[3]==True:
playerpos[1]-=3
pygame.display.update()
at the part where it checks if the car collided with the traffic light, it doesn't do anything.
Iv'e tried using a try statement, still doesn't work
Look at the documentation what Surface.get_rect() does:
Returns a new rectangle covering the entire surface. This rectangle will always start at 0, 0 with a width. and height the same size as the image.
So the Rects never collide, since the Rect for the car always starts at 0, 0. An easy fix is to simply set the starting position (top and left) of the car Rect while calling get_rect().
Change
car_rect = player.get_rect()
to:
car_rect = player.get_rect(left=playerpos[0], top=playerpos[1])
(Another way is to use the Sprite class, which basically combines a Surface and a Rect.)