Pong Game From Python for absolute beginners - python

i am running into two error going two routes the ball is find works great but the score text wont work, every time i implement it it throws the two errors.
from superwires import games, color
from random import *
"""Main application file"""
#the screen width and height
SCREEN_WIDTH = 640
SCREEN_HEIGHT = 480
points = 0
score = 0
"""Paddle object that is controlled by the player. Moves up and down. Collides with the ball. Points are added when ball is collided with"""
class Paddle(games.Sprite):
HEIGHT = 480/20
paddle_image = games.load_image('paddle.png', transparent=True)
def __init__(self):
super(Paddle, self).__init__(image = Paddle.paddle_image,
x = 40,
y = 50,
is_collideable=True)
self.score = games.Text(value = 0,
size = 30,
color = color.green,
x = SCREEN_WIDTH - 25,
y = SCREEN_HEIGHT - 431)
games.screen.add(self.score)
games.screen.mainloop()
""" updates Position based on mouse Position"""
def update(self):
self.y = games.mouse.y
self.Check_Collision()
def Check_Collision(self):
for PongBall in self.overlapping_sprites:
PongBall.handle_collide()
"""actual ball in play """
class PongBall(games.Sprite):
#velocity variables
vel_x = 5
vel_y = 0
#pos of boundry to ball pos
lower_bounds_check = 0
upper_bounds_check = 0
#checks if paddle gets collided with
def handle_collide(self):
if((SCREEN_WIDTH/2) < self.x):
PongBall.vel_x = randint(-10,-5)
PongBall.vel_y = randint(-10,-5)
elif((SCREEN_WIDTH/2) > self.x):
PongBall.vel_x = randint(5,10)
PongBall.vel_y = randint(5,10)
#checks if it hit the bottom; bool function
def check_boundry_lower(self):
PongBall.lower_bounds_check = (SCREEN_HEIGHT/2)
return ((self.y - PongBall.upper_bounds_check) > PongBall.lower_bounds_check)
#checks if it hits the top; bool function
def check_boundry_upper(self):
PongBall.upper_bounds_check = (SCREEN_HEIGHT/2)
return ((self.y + PongBall.upper_bounds_check) < PongBall.upper_bounds_check)
#Resets the velocity based on boundry collision
def boundry_update(self):
if(self.check_boundry_upper()):
PongBall.vel_y = randint(5,10)
return
elif(self.check_boundry_lower()):
PongBall.vel_y = randint(-10,-5)
return
def update(self):
self.boundry_update()
self.x += PongBall.vel_x
self.y += PongBall.vel_y
"""
Entry point Function
"""
# Create background, paddle, and ball. Then call the game mainloop.
# crate the window
games.init(SCREEN_WIDTH, SCREEN_HEIGHT, 50, virtual = False)
#sets/loads background
background = games.load_image(f"background.png", transparent=True)
games.screen.background = background
# paddle image
paddle_image = games.load_image(f"paddle.png", transparent = True)
#PingPong ball
PingPongBall = games.load_image(f"Ball.png", transparent = True)
#paddle Right and left
paddle_1 = Paddle()
paddle_2 = Paddle()
#pingball ball instance
ball = PongBall(image = PingPongBall, x = 150, y = 250, is_collideable=True)
#adding all three sprites to screen
games.screen.add(ball)
games.screen.add(paddle_1)
games.screen.add(paddle_2)
#each instance update function
ball.update()
paddle_1.update()
paddle_2.update()
#adding text
#main loop
games.screen.mainloop()
i get this error;
Traceback (most recent call last):
File "C:\Users\gamer\Desktop\PingPong\main.py", line 15, in <module>
class Paddle(games.Sprite):
File "C:\Users\gamer\Desktop\PingPong\main.py", line 17, in Paddle
paddle_image = games.load_image('paddle.png', transparent=True)
File "C:\Users\gamer\AppData\Local\Programs\Python\Python310\lib\site-packages\superwires\games.py", line 836, in load_image
if not screen.virtual:
AttributeError: 'NoneType' object has no attribute 'virtual'
Please help i cant seem to escape the error even if i dont pass through the constructor i get text object doesnt not have handle_collide() attribute
-Thanks guys
new error:
Traceback (most recent call last):
File "C:\Users\gamer\Desktop\PingPong\main.py", line 153, in <module>
games.screen.mainloop()
File "C:\Users\gamer\AppData\Local\Programs\Python\Python310\lib\site-packages\superwires\games.py", line 783, in mainloop
sprite._process_sprite()
File "C:\Users\gamer\AppData\Local\Programs\Python\Python310\lib\site-packages\superwires\games.py", line 440, in _process_sprite
self.update()
File "C:\Users\gamer\Desktop\PingPong\main.py", line 40, in update
self.Check_Collision()
File "C:\Users\gamer\Desktop\PingPong\main.py", line 36, in Check_Collision
PongBall.handle_collide()
AttributeError: 'Text' object has no attribute 'handle_collide'

You need to have the games.load in the __init__ function so as not to call it before the environment is set up.
Replace this:
class Paddle(games.Sprite):
HEIGHT = 480/20
paddle_image = games.load_image('paddle.png', transparent=True)
def __init__(self):
super(Paddle, self).__init__(image = Paddle.paddle_image,
x = 40,
y = 50,
is_collideable=True)
with this:
class Paddle(games.Sprite):
HEIGHT = 480/20
def __init__(self):
self.paddle_image = games.load_image('paddle.png', transparent=True)
super(Paddle, self).__init__(image = self.paddle_image,
x = 40,
y = 50,
is_collideable=True)

Related

Because of this error, the 'NoneType' object is not iterable, nothing works for me

I wanted to add a gun for the player so that he could shoot at enemies. However, because of this, the game refuses to work. Nothing is displayed. Only a black screen for a few seconds.
About this error:
'NoneType' object is not iterable
I've heard, but I don't know exactly how to write it correctly so that everything is displayed.
The code looks fine, but it still doesn't work.
Can you tell me why this is happening and how to change it?
from sprite_object import *
class Weapon(AnimatedSprite):
def __init__(self, game, path='resources/sprites/weapon/shotgun/0.png', scale=0.4, animation_time=90):
super().__init__(game=game, path=path, scale=scale, animation_time=animation_time)
self.images = deque(
[pg.transform.smoothscale(img, (self.image.get_width() * scale, self.image.get_height() * scale))
for img in self.images])
self.weapon_pos = (HALF_WIDTH - self.images[0].get_width() // 2, HEIGHT - self.images[0].get_height())
self.reloading = False
self.num_images = len(self.images)
self.frame_counter = 0
self.damage = 50
def animate_shot(self):
if self.reloading:
self.game.player.shot = False
if self.animation_trigger:
self.images.rotate(-1)
self.image = self.images[0]
self.frame_counter += 1
if self.frame_counter == self.num_images:
self.reloading = False
self.frame_counter = 0
def draw(self):
self.game.screen.blit(self.images[0], self.weapon_pos)
def update(self):
self.check_animation_time()
self.animate_shot()
File "C:\Users\79853\pythonProject1\Doom\main.py", line 72, in <module>
game = Game()
^^^^^^
File "C:\Users\79853\pythonProject1\Doom\main.py", line 25, in __init__
self.new_game()
File "C:\Users\79853\pythonProject1\Doom\main.py", line 33, in new_game
self.weapon = Weapon(self)
^^^^^^^^^^^^
File "C:\Users\79853\pythonProject1\Doom\weapon.py", line 8, in __init__
[pg.transform.smoothscale(img, (self.image.get_width() * scale, self.image.get_height() * scale))
TypeError: 'NoneType' object is not iterable

AttributeError: 'ballcl' object has no attribute 'ballX'

I'm creating a Pong game as a fun project to learn python and pygame. I am currently having an issue, mentioned above. Please ignore my slop that is code lol. The relevant code:
ballVelX = 5
ballVelY = 5
ballWidth = 15
ballHeight = 15
ballX = 450
ballY = 300
class ballcl:
def __init(self, ballX, ballY, ballVelX, ballVelY, ballWidth, ballHeight):
self.ballX = ballX
self.ballY = ballY
self.ballVelX = ballVelX
self.ballVelY = ballVelY
self.ballWidth = ballWidth
self.ballHeight = ballHeight
def ball(self):
ball = pygame.draw.rect(screen, white, [self.ballX, self.ballY, self.ballWidth, self.ballHeight])
ball
#ball movement
self.ballX += self.ballVelX
ballOb = ballcl()
gameRunning = True
while gameRunning:
ballOb.ball()
The error i receive is:
Traceback (most recent call last):
File "d:/Ping/Main.py", line 67, in <module>
ballOb.ball()
File "d:/Ping/Main.py", line 49, in ball
ball = pygame.draw.rect(screen, white, [self.ballX, self.ballY, self.ballWidth, self.ballHeight])
AttributeError: 'ballcl' object has no attribute 'ballX'
See Classes. The name of the constructor of a class is __init__ rather than __init:
class ballcl:
def __init__(self, ballX, ballY, ballVelX, ballVelY, ballWidth, ballHeight):
# [...]

Object Following X Coords of Mouse Position Tkinter

I am trying to make pong, I want my paddle to follow the x position of the mouse. I just had the x position of the mouse assigned to a variable and it would add to itself every time I moved the mouse then just go off the screen. I now changed it a little bit but I just cannot get it to work
ERRORS:
Traceback (most recent call last):
File "Tkinter.py", line 1536, in __call__
return self.func(*args)
File "animationTest.py", line 51, in motion
self.diff = self.x - canvas.coords(self.paddle)
TypeError: unsupported operand type(s) for -: 'int' and 'list'
CODE:
from Tkinter import *
import time
HEIGHT = 500
WIDTH = 800
COLOR = 'blue'
SIZE = 50
root = Tk()
canvas = Canvas(root, width=WIDTH, height=HEIGHT, bg=COLOR)
canvas.pack()
class Ball:
def __init__(self, canvas):
self.ball = canvas.create_oval(0, 0, SIZE, SIZE, fill='black')
self.speedx = 6
self.speedy = 6
self.active = True
self.move_active()
def ball_update(self):
canvas.move(self.ball, self.speedx, self.speedy)
pos = canvas.coords(self.ball)
if pos[2] >= WIDTH or pos[0] <= 0:
self.speedx *= -1
if pos[3] >= HEIGHT or pos[1] <= 0:
self.speedy *= -1
def move_active(self):
if self.active:
self.ball_update()
root.after(1, self.move_active)
class Paddle:
def __init__(self, canvas):
self.paddle = canvas.create_rectangle(0,0,100,10, fill='red')
canvas.bind('<Motion>', self.motion)
self.active = True
self.move_active
def motion(self, event):
self.x = event.x
self.diff = self.x - canvas.coords(self.paddle)
print('the diff is:' ,self.diff)
print('the click is at: {}'.format(self.x))
def move_active(self):
if self.active:
self.motion()
root.after(1, self.move_active)
run = Ball(canvas)
run2 = Paddle(canvas)
root.mainloop()
There's no reason to read the current coordinates. You can use the event.x to calculate the new coordinates without knowing what the current coordinates are.
def motion(self, event):
'''update paddle coordinates using current mouse position'''
canvas.coords(self.paddle, event.x-50, 0, event.x+50, 10)
This simply overrides the coordinates 0,0,100,10 that you set in the __init__ method with new ones based on the mouse position.

TypeError: 'int' object has no attribute '__getitem__'

I'm trying to make a play surface out of rects in pygame. I'm not sure what the problem is exactly but I believe it has something to do with the actual iteration of the list when creating the rects. Sorry, noob here. :)
import pygame
w = 800
h = 600
board_pos = 0, 0
tile = 27
playfield = 0
class Board(object):
def __init__(self, surface, pos, tile_size):
self.surface = surface
self.x, self.y = pos
self.tsize = tile_size
self.color = 50, 50, 50
playfield = [list(None for i in xrange(22)) for i in xrange(10)]
def draw(self):
for i in xrange(10):
for j in xrange(22):
playfield[i][j] = pygame.draw.rect(self.surface, self.color,
(self.x + (i * self.tsize),
self.y + (j * self.tsize),
self.tsize, self.tsize))
pygame.display.init()
screen = pygame.display.set_mode((w, h))
board = Board(screen, board_pos, tile)
board.draw()
while __name__ == '__main__':
pygame.display.flip()
I keep getting this error:
Traceback (most recent call last):
File "C:\Documents and Settings\Administrator\My
Documents\Dropbox\Programming\DeathTris
\test2.py", line 30, in <module>
board.draw()
File "C:\Documents and Settings\Administrator\My
Documents\Dropbox\Programming\DeathTris
\test2.py", line 24, in draw
self.tsize, self.tsize))
TypeError: 'int' object has no attribute '__getitem__'
Any help would be appreciated. Thanks!
Your line playfield = [list(None for i in xrange(22)) for i in xrange(10)] creates a local variable inside the __init__ function. That variable disappears after the __init__ function returns. Later in draw when you do playfield[i][j], you are accessing the global value of playfield, which is still 0 (since you initialized it to 0 at the beginning).
If you want to overwrite the global playfield from inside your __init__, you need to do global playfield before you assign to it. (But. . . why are you using a global variable for this anyway?)

Debugging a simple pygame game

When I run this, it executes to an error in one of the imports. I posted the error at tend end of the code. The program essentially doesn't run, I can't tell what errors are occurring from the tracebacks. Any insight would be appreciated.
from livewires import games, color
import random
games.init (screen_width = 640, screen_height = 480, fps = 50)
class Pizza (games.Sprite):
def __init__(self, screen, x, y, image):
self.pizzaimage = games.load_image ("pizza.bmp", transparent = True)
self.init_sprite (screen = screen,
x = x,
y = 90,
image = self.pizzaimage,
dy = 1)
def moved (self):
if self.bottom > 480:
self.game_over()
def handle_caught (self):
self.destroy()
def game_over(self):
games.Message(value = "Game Over",
size = 90,
color = color.red,
x = 320,
y = 240,
lifetime = 250,
after_death = games.screen.quit())
class Pan (games.Sprite):
def __init__(self, screen, x, image ):
self.panimage = games.load_image ("pan.bmp", transparent = True)
self.init_sprite (screen = screen,
x = games.mouse.x,
image = self.panimage)
self.score_value = 0
self.score_text = games.Text (value = "Score"+str(self.score_value),
size = 20,
color = color.black,
x = 500,
y = 20)
def update (self):
self.x = games.mouse.x
#When it reaches end, return value to corner. Example:
if self.left < 0:
self.left = 0
if self.right > 640:
self.right = 640
def handling_pizzas (self):
for Pizza in self.overlapping_sprites:
self.score_value += 10
Pizza.handle_caught()
class Chef (games.Sprite):
def __init__(self, screen, x, y, image, dx, dy,):
self.chefimage = games.load_image ("chef.bmp", transparent = True)
self.timer = 80
self.init_sprite (screen = screen,
x = random.randrange(640),
y = y,
dx = 20,
dy = 0)
def update (self):
if self.left < 0:
self.dx = -self.dx
if self.right > 640:
self.dx = -self.dx
elif random.randrange (10) == 5:
self.dx = -self.dx
def add_teh_pizzas (self):
if self.timer > 80:
self.timer = self.timer - 1
else:
new_pizza = Pizza (x = self.x)
games.screen.add (new_pizza)
self.timer = 80
#main
def main ():
backgroundwall = games.load_image ("wall.jpg", transparent = False)
games.screen.background = backgroundwall
le_chef = Chef = ()
games.screen.add(le_chef)
le_pan = Pan = ()
games.screen.add (le_pan)
games.mouse.is_visible = False
games.screen.event_grab = False
games.screen.mainloop()
main()
ERRORS REPORT:
Traceback (most recent call last):
File "C:\Users\COMPAQ\My Documents\Aptana Studio Workspace\Pythonic Things\PizzaPanicAttempt\PizzaPanicAttempt1.py", line 98, in <module>
main()
File "C:\Users\COMPAQ\My Documents\Aptana Studio Workspace\Pythonic Things\PizzaPanicAttempt\PizzaPanicAttempt1.py", line 96, in main
games.screen.mainloop()
File "C:\Python27\lib\site-packages\livewires\games.py", line 303, in mainloop
object._erase()
AttributeError: 'tuple' object has no attribute '_erase'
Don't know anything about livewires, but the following looks suspicious:
le_chef = Chef = ()
games.screen.add(le_chef)
le_pan = Pan = ()
games.screen.add (le_pan)
You have classes called Chef, and Pan, but you're not doing anything with these - just assigning these things an empty tuple, and then adding them to games.screen. Were they supposed to be initialized instead?
eg.
le_chef = Chef(<some args>)
le_pan = Pan(<some args>)

Categories