How to move Sprite image with cursor movement in pygame? - python

Now below what i did is simply created a sprite as shown..
futher to do something interesting,thought of threading i added a thread which will check the cursor position, hence update global x & y resulting in change of sprite position that is trigered by display.update
I am newbie so i might me wrong in many ways ...so please bear me....
a lot thanks in advance
from pygame import *
from main import *
import threading
import sys
#lets add our sprites
(x,y) = (0, 0)
class threading1(threading.Thread):
def run(self):
global x,y
clockobj1 = pygame.time.Clock()
while (True):
clockobj1.tick(6)
(x,y)=pygame.mouse.get_pos()
display.update()
class sprites(pygame.sprite.Sprite ):
def __init__(self,color= redd, width=120, height=120):
super(sprites,self).__init__()
self.image = pygame.Surface((width,height))
self.image.fill(color)
self.rect=self.image.get_rect()
self.rect.move_ip(x,y)
display.update()
if __name__ == '__main__':
clockobj = pygame.time.Clock()
init()
mainwin = pygame.display.set_mode((720,640))
sprite1 = sprites()
spritegrp = pygame.sprite.Group()
spritegrp.add(sprite1)
spritegrp.update()
mainwin.fill(blue)
spritegrp.draw(mainwin)
threadingobj = threading1()
threadingobj.start()
x = True
while(x):
display.update()
for evt in event.get() :
if (evt.type == QUIT) :
quit()
x=False
clockobj.tick(40)
***BELOW IS MY LATEST CODE----------UPDATED AS PER ANSWERS***PLEASE CHECK
import pygame
from main import *
import threading
import sys
# lets add our sprites
class Sprites(pygame.sprite.Sprite ):
def __init__(self, color=redd, width=120, height=120):
super().__init__()
self.image = pygame.Surface((width, height))
self.image.fill(color)
self.rect = self.image.get_rect()
def updaterect(self):
print("i m in updatereact")
print(pygame.mouse.get_pos())
self.rect.center= pygame.mouse.get_pos()
pygame.display.update()
if __name__ == '__main__':
clockobj = pygame.time.Clock()
pygame.init()
mainwin = pygame.display.set_mode((720,640))
sprite1 = Sprites()
sprite1.updaterect()
spritegrp = pygame.sprite.Group()
spritegrp.add(sprite1)
spritegrp.update()
mainwin.fill(blue)
spritegrp.draw(mainwin)
x = True
while x:
sprite1.updaterect()
pygame.display.update()
for evt in pygame.event.get() :
if evt.type == pygame.QUIT :
quit()
x=False

Threading will only just complicate things. Get rid of it, and take self.rect.move_ip(x,y) and display.update() out of the __init__ for the class. Make a function in the class called update(). This function will move the rect just by saying. self.rect.center = pygame.mouse.get_pos(). Then in the main game loop, put sprite1.update() in there or update it by using the group name instead (as you did with spritegrp.update() ) and then call display.update() there too instead of in the function.
Other things:
super().__init__() doesn't need any args
if and while loops don't need parentheses
you don't need to import main (I may be wrong about this but I don't think so)
from module import * is a bad practice in general, but if you are going to do it (I don't recommend it), you can't put module.method anywhere. You did from pygame import *, but still put pygame.mouse and others like that. Maybe you meant from pygame.locals import * ?
colons don't have a space in between them and the word, i.e. for evt in event.get() : is bad
Indentation should also be the length of a tab, or four spaces. (What IDE are you using? Most do it automatically.)
variables assignments should have spaces: x = False

Related

algorithm writer of tkinter

I'm writing an algorithm that provides a tkinter program as output (I hope I explained myself) the program works by dragging the combobox, the text ... into a space and memorizing the coordinates.
I decided to do it with pygame, (I took the skeleton of the program from the internet and then modified it).
I have encountered several problems:
I have a problem inserting multiple images (for now I have only
inserted one),
I can't memorize the coordinates, I tried with print (event) but it doesn't work,
I can not insert the image in a specific point of the root.
here is my code:
import os,sys
import pygame as pg
pg.init()
a=0
b=0
c=200
d=200
event = pg.event.poll()
Sfondo = pg.image.load("Sfondo.jpg")
def DisegnaBackground (a,b):
Screen.blit(Sfondo,(a,b))
class Character:
def __init__(self,rect):
self.rect = pg.Rect(rect)
self.click = False
self.image = pg.image.load("ComboBox.png").convert()
Screen.blit(self.image, (c,d))
def update(self,surface):
if self.click:
self.rect.center = pg.mouse.get_pos()
surface.blit(self.image,self.rect)
def main(Surface,Player):
game_event_loop(Player)
DisegnaBackground (a,b)
Player.update(Surface)
def game_event_loop(Player):
for event in pg.event.get():
if event.type == pg.MOUSEBUTTONDOWN:
if Player.rect.collidepoint(event.pos):
Player.click = True
elif event.type == pg.MOUSEBUTTONUP:
Player.click = False
elif event.type == pg.QUIT:
pg.quit(); sys.exit()
if __name__ == "__main__":
os.environ['SDL_VIDEO_CENTERED'] = '1'
pg.init()
Screen = pg.display.set_mode((1500,800))
MyClock = pg.time.Clock()
MyPlayer = Character((0,0,200,24))
MyPlayer.rect.center = Screen.get_rect().center
while 1:
main(Screen,MyPlayer)
pg.display.update()
MyClock.tick(60)
print(event)
There are a number of problems. First, try to make sure not to mix global and local variables. Try re-writing the function like this:
def DisegnaBackground (surface, a, b):
surface.blit(Sfondo, (a, b))
For this to work, you have to update your main too:
def main(Surface,Player):
game_event_loop(Player)
DisegnaBackground (Surface, a, b)
Player.update(Surface)
Finally, you do not need to display your character immediately after the creation, so you can leave the init function as
def __init__(self,rect):
self.rect = pg.Rect(rect)
self.click = False
self.image = pg.image.load("ComboBox.png").convert()
I hope it helps.

Pygame - can't draw image to screen: TypeError: draw() missing 1 required positional argument: 'surface'

I want to draw a box to my screen, however when I call the function to do so it says I'm missing the argument for "surface"
As seen in the code below, the function is in a class. The function contains two parameters: "self" and "surface", and I'm passing the variable "screen" in place of "surface" so I can draw the box:
import pygame
import time
pygame.init()
(width, height) = (600, 400)
bg_colour = (100, 20, 156)
class infoBox(object):
def __init__(self, surface):
self.box = pygame.draw.rect(surface, (255,255,255),(0,400,400,100),2)
def draw(self, surface):
surface.blit(self.box)
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("battle EduGame")
clock = pygame.time.Clock()
pygame.display.flip()
gameRun = True
while gameRun:
event = pygame.event.poll()
if event.type == pygame.QUIT: #if the "x" is pressed
pygame.quit() #quit game
gameRun = False #break the loop.
quit()
screen.fill(bg_colour)
infoBox.draw(screen)
pygame.display.update()
clock.tick(60)
I've done things exactly like this in previous codes however it's choosing not to work here.
Note your calling technique:
class infoBox(object):
def draw(self, surface):
surface.blit(self.box)
...
infoBox.draw(screen)
draw is an instance method, but you've invoked it as a class method. Therefore, you have only one argument, screen. You haven't provided the required self instance ... which will be needed immediately.
You need to create the object and use that to invoke the routine, something like
game_box = InfoBox(screen)
...
game_box.draw(screen)

python/pygame image cant be found the the same folder

hello im new to python/pygame and tried to make a basic project. it did not turn out as planned as i don't understand this error if you can tell my why my image is not loading it will very much appreciated. Traceback (most recent call last):
File "C:\Users\Nicolas\Desktop\template\templat.py", line 15, in <module>
screen.fill(background_colour)
NameError: name 'background_colour' is not defined
this is the error i was speaking of however i have fixed now. how ever now the screen opens displayes the background and crashes.
import pygame, sys
pygame.init()
def game():
background_colour = (255,255,255)
(width, height) = (800, 600)
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption('Tutorial 1')
pygame.display.set_icon(pygame.image.load('baller.jpg'))
background=pygame.image.load('path.png')
target = pygame.image.load('Player.png')
targetpos =target.get_rect()
screen.blit(target,targetpos)
screen.blit(background,(0,0))
pygame.display.update()
while True:
screen.blit(background,(0,0))
screen.blit(target,targetpos)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if__name__==('__main__')
game()
You missed the __init__ definition!
While your code does run, it is not what you want. There's an infinite loop inside the definition of the class, which means, however you are running this, there's something missing. You should put this code (most of it at least) inside the __init__ function, and then create an instance of the class.
This is what I assume you want:
import pygame, sys
class game():
width, height = 600,400
def __init__(self):
ball_filename = "Ball.png"
path_filename = "path.png"
self.screen = pygame.display.set_mode((self.width, self.height))
pygame.display.set_caption('Star catcher')
self.background = pygame.image.load(path_filename)
self.screen.blit(self.background,(0,0))
self.target = pygame.image.load(ball_filename)
def run(self):
while True:
self.screen.blit(self.background, (0,0))
targetpos = self.target.get_rect()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
if __name__ == "__main__":
# To run this
pygame.init()
g = game()
g.run()
UPDATE:
I made more modifications than what you must do, but they could be useful. I did not test this, but it should be fine.
The error of width and height not being defined is because they are not local/global variables, but bound to the class and/or the instance of the class, therefore in their namespace. So you need to access these either via game.width (per class) or self.width (per instance, only inside a method defined in the class) or g.width (per instance, if you are outside the class definition and g is an instance of game class).
I hope I'm clear. :)

How do you make a sprite appear in pygame/python?

I'm trying to make a basic (Mario style) game but my sprite(plumber) doesn't appear, it could be hidden behind background? i'm not exactly sure, i am not getting any errors either.
import pygame
import sys
import itertools
import pygame
from pygame.sprite import Sprite
cloud_background = pygame.image.load('clouds.bmp')
brick_tile = pygame.image.load('brick_tile.png')
pink = (255, 64, 64)
w = 640
h = 480
screen = pygame.display.set_mode((w, h))
running = 1
def setup_background():
screen.fill((pink))
screen.blit(cloud_background,(0,0))
brick_width, brick_height = brick_tile.get_width(), brick_tile.get_height()
for x,y in itertools.product(range(0,640,brick_width),
range(390,480,brick_height)):
# print(x,y)
screen.blit(brick_tile, (x, y))
pygame.display.flip()
while running:
setup_background()
event = pygame.event.poll()
if event.type == pygame.QUIT: sys.exit()
class plumber(sprite):
def __init__(
self, screen, img_filename, init_position,
init_direction, speed):
Sprite.__init__(self)
self.screen = screen
self.speed = speed
self.base_image = pygame.image.load(Mario_sideways_sprite_2xL.png).convert_alpha()
self.image = self.base_image
self.pos = 50,50
First problem found is that you must modify
pygame.image.load(Mario_sideways_sprite_2xL.png)
with something like.
pygame.image.load("Mario_sideways_sprite_2xL.png")
Besides this, the code has many problems that impedes it to work. For example,
you do not instantiate your plumber class.
class plumber(sprite) should be plumber(Sprite) (still better Plumber(Sprite))
You need something like:
myplumber = Plumber()
allsprites = pygame.sprite.RenderPlain((myplumber, ....))
clock = pygame.time.Clock()
You could see here the main parts of a simple program like yours.

Pygame Inquiry- Generating Multiple Sprites in Same Class

Unimportant Preamble:
Hello, I'm using Python and Pygame to create a game. This is for the purpose of improving my programming skills rather than a serious attempt at game creation. I've taken a break from Python lately for Objective C, but I'm now returning to it. This is a problem that I was having before I took a brief break, and I've returned to a question that was originally puzzling me. I've spent quite a while researching it, and I have a suspicion I've come across the solution and merely failed to understand it. I apologize for some of the bad naming conventions/lack of comments. I'm working on improving that.
Substance of Question:
Anyway, I've attached the four images I'm using. The program uses a simple function to position various Tiles on the screen. The mouse cursor is a sword. It is the entire image, but I'll be changing that later. I've made the program type "blue" in the shell whenever the cursor collides with a Tile. My goal is to have this happen when it collides with "ANY" tile of that color.
Long-term, I want to be able to modify the properties of these tile sprites. Various game-pieces would interact, and I would need to save the state of each sprite. I'd also be setting interactions for the other sprites.
Right now the sprites are all generating images, but my collision rectangle for the Tile is simply moving after each image is generated. I suppose that makes sense given the code, but I need a way to multiple sprites, each with a rectangle for collision.
Thanks
EDIT: I was unable to add images due to a new-user restriction. They are available enter link description here I think I read somewhere that people can (and do) edit posts here. So if anyone who the ability to move the images into this thread is welcome to do so.
import random,math,sys,os
import pygame
from pygame.locals import *
pygame.init() #Initializing Pygame
#Colors
black=(0,0,0)
#Screen
screen=pygame.display.set_mode((1200,800),0,0)
pygame.display.set_caption("Nero's Sandbox")
pygame.mouse.set_visible(False)
clock=pygame.time.Clock()
fps=40
#Game Functions:
def terminate():
pygame.quit()
sys.exit()
def numgen(x,y):
return random.randint(x,y)
#Loop Variables
tri=2
#Groups:
allsprites = pygame.sprite.Group()
alltiles = pygame.sprite.Group()
allmice = pygame.sprite.Group()
#Mouse Classes
class Pointy(pygame.sprite.DirtySprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load('redsword.png').convert() #31x32 image
self.image.set_colorkey(black)
self.rect=self.image.get_rect()
self.set=pygame.sprite.Group()
self.add(allmice, allsprites, self.set)
pygame.sprite.RenderPlain((self.set,allmice,allsprites))
def update(self):
screen.fill(black)
alltiles.draw(screen)
if event.type == pygame.MOUSEMOTION:
pos = pygame.mouse.get_pos()
self.rect.topright = pos
self.set.draw(screen)
#Tile Sprites - only one rect is being recognized.
class Tile(pygame.sprite.Sprite):
def __init__(self, graphic):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(graphic).convert()
self.image = pygame.transform.scale((self.image),(50,50))
self.rect=self.image.get_rect()
self.add(alltiles, allsprites)
self.set=pygame.sprite.RenderPlain((self))
def update(self, x, y):
pos = (x,y)
self.rect.topleft = pos
#Micers
pointy1=Pointy()
#Game Loops
while True: #Ensures all loops within program are constantly called when conditions are met.
screen.fill(black)
while tri==2:
for event in pygame.event.get():
if event.type == QUIT:
terminate()
pygame.display.flip()
x = 0
y = 50
w = 0
while x!=600:
x=x+50
w = w+1
if w%2==0:
purpletile1=Tile('purplesquare.png')
purpletile1.set.update(x,y)
purpletile1.set.draw(screen)
else:
c=numgen(1,2)
if c==1:
bluetile1=Tile('lightbluesquare.png')
bluetile1.set.update(x,y)
bluetile1.set.draw(screen)
if c==2:
redtile1=Tile('redsquare.png')
redtile1.set.update(x,y)
redtile1.set.draw(screen)
if x>=600 and y!=450:
if y<450:
x = 0
y = y+50
w=w-1
if y>=450:
tri=3
while tri==3:
for event in pygame.event.get():
if event.type == QUIT:
terminate()
alltiles.draw(screen)
pointy1.set.update()
pointy1.set.draw(screen)
pygame.display.flip()
clock.tick(fps)
if pygame.sprite.collide_rect(pointy1,bluetile1):
print('blue')
I had this same problem myself! I did some debugging, and it appeared that all instances of my class shared the same instance of pygame.Rect()
You may want to change the line:
pygame.sprite.Sprite.__init__(self)
to
super.__init__(self)
This way, pygame.sprite.Sprite's init will set attributes to your tile. I could be wrong, I'm not entirely familiar with python's inheritance syntax, but that is the way I do it.
I could also be the get_rect that is causing the same rectangle to be used for all classes, but that doesn't seem to be likely.
I hope that I was some help, and just remember that pygame.Rect is an object, so somehow you are instantiating only once.

Categories

Resources