Pong Game: Paddle Won't Move with Input (Python) - python

I am a novice to Python trying to make the game Pong. I have created a Paddle class with the Turtle Graphics module, but I can't get the paddle to move. I just want to start with one direction and then down shouldn't be too hard from there. Can anyone see what I am doing wrong with my method?
from turtle import Turtle
COORDINATES = [(350, 20), (350, 0), (350, -20)]
X_COORDINATES = [350, 350, 350]
Y_COORDINATES = [20, 0, -20]
class Paddle(Turtle):
def __init__(self):
super().__init__()
self.paddle = []
self.create_paddles()
self.coordinate_number = 0
def create_paddles(self):
for coordinates in COORDINATES:
self.paddle_block = Turtle(shape='square')
self.paddle_block.goto(coordinates)
self.paddle_block.color('white')
self.paddle.append(self.paddle_block)
def w(self):
global Y_COORDINATES
Y_COORDINATES = [coordinate + 100 for coordinate in Y_COORDINATES]
for self.paddle_block in self.paddle:
self.paddle_block.goto(X_COORDINATES[self.coordinate_number], Y_COORDINATES[self.coordinate_number])
self.coordinate_number += 1
self.coordinate_number = 0
I tried to iterate through the y-coordinates and add to each of them with my function. From there, I tried to iterate through each paddle block and move it's current location to a new one, taking in the newly updated y coordinate. I expect movement, but I am not seeing any movement whatsoever.

This isn't the usual approach to this problem, but I can see why it might be advantageous. Your primary issue seems to be not being able to determine what should be global, what should be local, and what should be a property. Let's make this work to demonstrate the use of all three:
from turtle import Screen, Turtle
COORDINATES = [(350, 20), (350, 0), (350, -20)]
class Paddle(Turtle):
def __init__(self):
super().__init__()
self.paddle = []
self.coordinates = list(COORDINATES) # make copy
self.create_paddles()
def create_paddles(self):
for coordinate in self.coordinates:
paddle_block = Turtle(shape='square', visible=False)
paddle_block.penup()
paddle_block.color('white')
paddle_block.goto(coordinate)
paddle_block.showturtle()
self.paddle.append(paddle_block)
def move_up(self):
self.coordinates = [(x, y + 10) for x, y in self.coordinates]
for coordinate_number, paddle_block in enumerate(self.paddle):
paddle_block.goto(self.coordinates[coordinate_number])
def move_down(self):
self.coordinates = [(x, y - 10) for x, y in self.coordinates]
for coordinate_number, paddle_block in enumerate(self.paddle):
paddle_block.goto(self.coordinates[coordinate_number])
screen = Screen()
screen.bgcolor('black')
paddle_1 = Paddle()
screen.onkey(paddle_1.move_up, 'w')
screen.onkey(paddle_1.move_down, 's')
screen.listen()
screen.mainloop()

Related

how to make lined circle with turtle in python

How to make draw like this with turtle?
right now my code looks like that:
class OperationsOnSets():
def __init__(self):
self.font_style = ("Times New Roman", 40, "bold")
def move_turtle_pos(self, x, y, turtle):
turtle.up()
turtle.setpos(x, y)
turtle.down()
def set_d(self):
turtle = Turtle()
turtle.pensize(2)
turtle.speed(2)
self.move_turtle_pos(-100, -50, turtle)
turtle.circle(200)
self.move_turtle_pos(100, -50, turtle)
turtle.circle(200)
sleep(5)
turtle.mainloop()
example = OperationsOnSets()
example.set_d()
and here is result
I though about pasting image, or make algorithm that would draw a lines, but I don`t know how to realize it. So I hope that someobody of you will help me with it...
My philosophy of turtles, is avoid the math by getting the turtle to do the hard work for you. Not quite perfect, but pretty close:
from turtle import Screen, Turtle
RADIUS = 200
NUMBER_LINES = 14
class OperationsOnSets():
def __init__(self):
self.turtle = Turtle()
self.turtle.pensize(2)
self.turtle.fillcolor(screen.bgcolor())
def move_turtle_pos(self, x, y):
self.turtle.penup()
self.turtle.setpos(x, y)
self.turtle.pendown()
def set_d(self):
self.move_turtle_pos(-RADIUS/2, -RADIUS)
points = []
for _ in range(NUMBER_LINES):
self.turtle.circle(RADIUS, 180 / NUMBER_LINES)
points.append(self.turtle.position())
for _ in range(NUMBER_LINES):
self.turtle.circle(RADIUS, 180 / NUMBER_LINES)
position = self.turtle.position()
self.turtle.goto(points.pop())
self.turtle.goto(position)
self.move_turtle_pos(RADIUS/2, -RADIUS)
self.turtle.begin_fill()
self.turtle.circle(RADIUS)
self.turtle.end_fill()
self.move_turtle_pos(-RADIUS/2, -RADIUS)
self.turtle.circle(RADIUS, 180)
self.turtle.hideturtle()
screen = Screen()
example = OperationsOnSets()
example.set_d()
screen.mainloop()
We make the turtle stop along its way around the circle to record points we'll need to finish the drawing.

Trouble with rendering background boxes class from a 2d list in pygame

I am trying to make a background of boxes for a simple snake game by iterating through a 2d array and drawing boxes which I've stored as instances of a class BackgroundCube in each part of the array. When I run the program there are no errors, but nothing shows up on the pygame screen.
I've printed the length of each sublist which shows a length of 20, my desired grid size. I've also just printed the entire array which shows what I believe to be instances of the class, something like this: <main.BackgroundCube object at 0x11186e090> would be one entry in the list. So I believe the problem lies in how I'm drawing the rectangles.
python
WIDTH = 400
HEIGHT = 420
screen = pygame.display.set_mode((WIDTH, HEIGHT))
class BackgroundCube:
def __init__(self, x, y, width, height, color):
self.x = x
self.y = y
self.width = width
self.height = height
self.color = color
def draw(self, screen):
pygame.draw.rect(screen, self.color, (self.x, self.y, self.width, self.height), 2)
def redrawGameWindow():
for x in range(20):
for y in range(20):
cube2 = background_cube_list[x][y]
cube2.draw(screen)
run = True
background_cube_list = [[0 for x in range(int(WIDTH/20))] for x in range(int((HEIGHT-20)/20))]
while run:
for cube in range(int(WIDTH / 20)):
for cube1 in range(int((HEIGHT - 20) / 20)):
background_cube_list[cube][cube1] = BackgroundCube(cube * 20, cube1 * 20, 20, 20, (144, 144, 144))
clock.tick(30)
redrawGameWindow()
Again, no errors, just a blank white window. Thank you.
You forgot to add
pygame.display.update()
in your main loop. Add it just after redrawGameWindow().
You also need to define clock, which I guess is clock = pygame.time.Clock(). Add it before the main loop.

How to get object to move in a random pattern in pygame?

I have been working on an "Asteroids" remake. However I can not get the objects to move in a random motion. I'm sure this evolves using vectors, however I do not know how to randomly generate a vector for each individual asteroid.
I am looking for a motion similar to this motion shown in this asteroid game, however I have no idea how to even start. This is my code so far:
import pygame as game
import random as r
import math
game.init()
game.display.set_caption("Asteroids")
screen = game.display.set_mode([800,600])
time=0
gameon=True
bgcolor = game.color.Color("#f6cb39")
black=game.color.Color("black")
badguy = game.image.load("asteroid.png")
badguy = game.transform.scale(badguy, (50, 50))
badguys=[]
SPAWNENEMY=10
CLOCK=11
game.time.set_timer(SPAWNENEMY,800)
game.time.set_timer(CLOCK,1000)
font=game.font.Font(None,20)
timetext=font.render("Time: 0", 0, black)
while gameon:
screen.fill(bgcolor)
event=game.event.poll()
if event.type==SPAWNENEMY:
bgbox = game.Rect(badguy.get_rect())
bgbox.x = r.randint(50,800)
bgbox.y = r.randint(50,600)
badguys.append(bgbox)
if event.type==game.QUIT:
gameon=False;
for bg in badguys:
'''
This is where I tried to put the mocment code,
but I was unableto get randmom movments,
only for asteroids to randomly appear or consistently
move in one direction something like "bg.x+=2"
'''
for bg in badguys:
screen.blit(badguy,(bg.x,bg.y))
game.display.flip()
I apologize if its a little long, I don't know what else I can cut out to create an MCV.
Here's how to do it using vectors. Each item in the badguy list is now a pair of items, its current position and an associated speed vector. Note that the position itself is also a vector (aka a "position vector").
Updating the current position is accomplished by simply adding each badguy's speed vector to its current position. i.e. bg[0] += bg[1].
import pygame as game
import pygame.math as math
from pygame.time import Clock
import random as r
game.init()
game.display.set_caption("Asteroids")
screen = game.display.set_mode([800, 600])
time = 0
gameon = True
bgcolor = game.color.Color("#f6cb39")
black = game.color.Color("black")
clock = Clock()
badguy = game.image.load("asteroid.png")
badguy = game.transform.scale(badguy, (50, 50))
badguys = []
SPAWNENEMY = 10
CLOCK = 11
game.time.set_timer(SPAWNENEMY, 800)
game.time.set_timer(CLOCK, 1000)
font=game.font.Font(None,20)
timetext=font.render("Time: 0", 0, black)
while gameon:
screen.fill(bgcolor)
event = game.event.poll()
if event.type == SPAWNENEMY:
# Select a random initial position vector.
posn = math.Vector2(r.randint(50, 800), r.randint(50, 600))
# Create a random speed vector.
speed = r.randint(1, 10)
dx = r.random()*speed * r.choice((-1, 1))
dy = r.random()*speed * r.choice((-1, 1))
vector = math.Vector2(dx, dy)
# Each badguy item is a [position, speed vector].
badguys.append([posn, vector])
if event.type == game.QUIT:
gameon = False;
for bg in badguys:
# Update positions.
bg[0] += bg[1] # Update position using speed vector.
for bg in badguys:
screen.blit(badguy, bg[0])
clock.tick(60)
game.display.flip()
So each asteroid in your game is represented by a Rect, stored in badguys.
With a Rect, you're able to store a postion and a size (since a Rect has the attributes x, y, width and height).
Now, you want to store additional information/state for each asteroid, so only using a Rect is not enough. You need a different data structure that holds more fields.
Since you use python, the fitting data structure is a class that is able to hold the random vector.
But let's think a little bit further. Since you use pygame, pygame already offers a class for represting your game objects, and that class is called Sprite.
So here we go (note the comments in the code):
import pygame
import random
screen = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
class Asteroid(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
# let's create an image of an asteroid by drawing some lines
self.image = pygame.Surface((50, 50))
self.image.set_colorkey((11, 12, 13))
self.image.fill((11, 12, 13))
pygame.draw.polygon(self.image, pygame.Color('grey'), [(0, 11), (20, 0), (50, 10), (15, 22), (27, 36), (10, 50), (0, 11)], 1)
# Let's store a copy of that image to we can easily rotate the image
self.org_image = self.image.copy()
# The rect is used to store the position of the Sprite
# this is required by pygame
self.rect = self.image.get_rect(topleft=(x, y))
# Let's create a random vector for the asteroid
self.direction = pygame.Vector2(0, 0)
while self.direction.length() == 0:
self.direction = pygame.Vector2(random.uniform(-1, 2), random.uniform(-1, 2))
# Also we want a constant, random speed
self.direction.normalize_ip()
self.speed = random.uniform(0.1, 0.3)
# we additionaly store the position in a vector, so the math is easy
self.pos = pygame.Vector2(self.rect.center)
# Aaaaaaaaaand a random rotation, because why not
self.rotation = random.uniform(-0.3, 0.3)
self.angle = 0
def update(self, dt):
# movement is easy, just add the position and direction vector
self.pos += self.direction * self.speed * dt
self.angle += self.rotation * dt
self.image = pygame.transform.rotate(self.org_image, self.angle)
# update the rect, because that's how pygame knows where to draw the sprite
self.rect = self.image.get_rect(center=self.pos)
SPAWNENEMY = pygame.USEREVENT + 1
pygame.time.set_timer(SPAWNENEMY, 800)
asteroids = pygame.sprite.Group()
dt = 0
while True:
for e in pygame.event.get():
if e.type == pygame.QUIT:
quit()
if e.type == SPAWNENEMY:
asteroids.add(Asteroid(random.randint(50, 200), random.randint(50, 200)))
screen.fill(pygame.Color('black'))
asteroids.draw(screen)
asteroids.update(dt)
pygame.display.flip()
dt = clock.tick(60)

Turn-based game map in python

I am making a turn-based game in python and I have some problems with game map.
This is the code:
import pygame, sys
from pygame.locals import *
pygame.init()
class Map(object):
def __init__(self, x, y, SURF):
self.x = x
self.y = y
self.SURF = SURF
def createNewMap(self, D1, D2):
create a D1xD2 map
self.Map = []
self.D1 = D1
self.D2 = D2
for n in range(self.D1):
current = ['']*self.D2
self.Map.append(current)
return self.Map
def drawMap(self):
draw the D1xD2 map from (x,y) position. grass.gif represent 1 grass box. the map contain D1xD2 grass boxes.
imgObj = pygame.image.load('images\\textures\grass.gif')
imgObj = pygame.transform.scale(imgObj, (40, 40))
xc = self.x
yc = self.y
for itemY in self.Map:
for itemX in self.Map[self.Map.index(itemY)]:
self.SURF.blit(imgObj, (xc, yc))
xc += 40
yc += 40
xc = self.x
i want when the mouse is above a box, i want to changes it with another texture box(grass1.gif). how can i do this?
You can do that by getting the current mouse position and then checking whether that is in the bounds of the box. Here is an unrelated example:
mouse_pos = pygame.mouse.get_pos()
for rectange in my_objects_list:
if rectangle.collidepoint(mouse_pos):
#do something ...

Debugging simple Ping-Pong game?

I've been programming a simple ping-pong game using Python's Pygame as run through Livewires. I've posted the question and a similar sample game code that runs perfectly as not everyone here will be versed in livewires and/or pygame.
Here's the code that has bugs on it. What happens is the window opens, and the "Ball" object works well and falls of the screen (as it should, it's incomplete), and the "Slab" object is gets stuck to wherever the mouse initially is. Here it is:
from livewires import games, color
games.init (screen_width = 640, screen_height = 480, fps = 50)
class Ball (games.Sprite):
def iMove (self):
self.dx = -self.dx
self.dy = -self.dy
class Slab (games.Sprite):
def mouse_moves (self):
self.x = games.mouse.x
self.y = games.mouse.y
self.iCollide()
def iCollide (self):
for Ball in overlapping_sprites:
Ball.iMove()
def main():
#Backgrounds
pingpongbackground = games.load_image ("pingpongbackground.jpg", transparent = False)
games.screen.background = pingpongbackground
#Ball: Initializing object and setting speed.
ballimage = games.load_image ("pingpongball.jpg")
theball = Ball (image = ballimage,
x = 320,
y = 240,
dx = 2,
dy = 2)
games.screen.add(theball)
#Paddle: Initializing ping pong object and setting initial poisition to the initial mouse position
slabimage = games.load_image ("pingpongpaddle.jpg")
theslab = Slab (image = slabimage,
x = games.mouse.x,
y = games.mouse.y)
games.screen.add(theslab)
games.mouse.is_visible = False
games.screen.event_grab = True
games.screen.mainloop()
main ()
And here's a piece of similar, functioning code:
# Slippery Pizza Program
# Demonstrates testing for sprite collisions
from livewires import games
import random
games.init(screen_width = 640, screen_height = 480, fps = 50)
class Pan(games.Sprite):
"""" A pan controlled by the mouse. """
def update(self):
""" Move to mouse position. """
self.x = games.mouse.x
self.y = games.mouse.y
self.check_collide()
def check_collide(self):
""" Check for collision with pizza. """
for pizza in self.overlapping_sprites:
pizza.handle_collide()
class Pizza(games.Sprite):
"""" A slippery pizza. """
def handle_collide(self):
""" Move to a random screen location. """
self.x = random.randrange(games.screen.width)
self.y = random.randrange(games.screen.height)
def main():
wall_image = games.load_image("wall.jpg", transparent = False)
games.screen.background = wall_image
pizza_image = games.load_image("pizza.bmp")
pizza_x = random.randrange(games.screen.width)
pizza_y = random.randrange(games.screen.height)
the_pizza = Pizza(image = pizza_image, x = pizza_x, y = pizza_y)
games.screen.add(the_pizza)
pan_image = games.load_image("pan.bmp")
the_pan = Pan(image = pan_image,
x = games.mouse.x,
y = games.mouse.y)
games.screen.add(the_pan)
games.mouse.is_visible = False
games.screen.event_grab = True
games.screen.mainloop()
# kick it off!
main()
Any insight at all would be greatly appreciated!
I don't know your framework, but to keep the slab from "getting stuck" you need to update its location when the mouse is moved.
Here you initialize it:
theslab = Slab (image = slabimage,
x = games.mouse.x,
y = games.mouse.y)
Then here you add it to the game:
games.screen.add(theslab)
Presumably, the game would then call this function whenever the mouse moves:
def mouse_moves (self):
self.x = games.mouse.x
self.y = games.mouse.y
self.iCollide()
But that is either not happening, or the screen is not getting updated.
So you should find out, by doing this:
def mouse_moves (self):
print "mouse_moves: ", str(games.mouse.x), str(games.mouse.y)
self.x = games.mouse.x
self.y = games.mouse.y
self.iCollide()
If you see the output of the print statement happening when the mouse moves, you're probably not updating the screen, you'll need to check the framework docs. But I don't think that's the case. I think you are not updating the game when the mouse moves. I would imagine the framework has some sort of onMouseMove type event that you need to hook into, to allow you to update the game state (i.e. call mouse_moves()) when mouse movement occurs. Then, the next time the screen is updated, you should check for changes (invalidate the objects, mark them as dirty) and if they are dirty, update their part of the screen then mark them clean again.
Just put this update method in the slab class:
def update(self):
self.x=games.mouse.x
self.y=games.mouse.y
It will automatically run once every fiftieth of a second (your update speed). Currently, you just start the slab at the position of the mouse, and leave it there.

Categories

Resources