moving object drawing every frame over background

  • (2 Pages)
  • +
  • 1
  • 2

21 Replies - 1701 Views - Last Post: 07 August 2015 - 04:34 PM Rate Topic: -----

#1 sigint-ninja   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 148
  • Joined: 05-June 15

moving object drawing every frame over background

Posted 06 August 2015 - 08:29 AM

hi guys,

trying to get an object moving with the keyboard on pygame.

well i have...it works perfectly on a white background,but when applied to my background it looks like every frame
is being drawn...i know there is a line in the tutorial that fills the background white at the end of the event loop.

i tried doing a screen refresh but that didnt work...

so how would i delete the previous value for the movement of the object...any ideas appreciated

Is This A Good Question/Topic? 0
  • +

Replies To: moving object drawing every frame over background

#2 DK3250   User is offline

  • Pythonian
  • member icon

Reputation: 561
  • View blog
  • Posts: 1,794
  • Joined: 27-December 13

Re: moving object drawing every frame over background

Posted 06 August 2015 - 08:53 AM

If you background is a pygame surface, it should be ok to blit in onto the screen in each pass of the game-loop.

More complicated: You can save the part of the background where you want to place the sprite in a temporary surface, and then blit it back in the next game-loop. You can save pixel by pixel with pygame.Surface.get_at(). I'm not sure (never tried it myself) if a subsurface can do the trick.

Please provide the relevant code. It is much easier and more precise to comment on.
Was This Post Helpful? 0
  • +
  • -

#3 DK3250   User is offline

  • Pythonian
  • member icon

Reputation: 561
  • View blog
  • Posts: 1,794
  • Joined: 27-December 13

Re: moving object drawing every frame over background

Posted 06 August 2015 - 08:59 AM

Oh, - one more thing:
I guess your background is imported like:
picture = pygame.image.load("pic.png")


You should always add the convert() option:
picture = pygame.image.load("pic.png").convert()

This will speed-up all subsequent manipulations of your picture.

But again, - let's see the code.
Was This Post Helpful? 0
  • +
  • -

#4 sigint-ninja   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 148
  • Joined: 05-June 15

Re: moving object drawing every frame over background

Posted 06 August 2015 - 09:31 AM

Hey DK,

im prob going to get in trouble for coding during work hours!!! LOL...

im so close just cant get the updating right...

before i give you the code i have one quick question.

i found a really good tutorial on python programming .net

i watched the tutorial then copied the code and applied it to my existing code then tailored it
to my requirements...is it ok to learn things doing it this way...or am i better coding from scratch?

i do see how the majority of the code works,but would have a few questions on a line/statement or two.
is it ok to learn this way? let me know...

regards
ninja

###invader 5-7-2015
###main file
import pygame
import sys
import time
pygame.init()

#draws the title screen background
screen = pygame.display.set_mode((800, 600))
#changes caption on main window
pygame.display.set_caption('Invader')
#loads the title screen image
title_screen = pygame.image.load("titlescreen.jpg")
#draws the jpg to the surface
screen.blit (title_screen,(0,0))
#adds wbrandt2015 to titlescreen
wb2015 = pygame.image.load('wb2015.png')
screen.blit(wb2015,(625,575))
#updates the surface
pygame.display.update()
#adds music to the title screen
file = 'titletheme.mp3'
pygame.mixer.init()
pygame.mixer.music.load(file)
pygame.mixer.music.play()
#adds start game to title screen
#time.sleep(3)
Button = pygame.image.load('startgame.png')
screen.blit(Button,(320,210))
pygame.display.update()
buttonloop=0
while buttonloop < 1:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.quit()
        if event.type == pygame.MOUSEBUTTONDOWN:
           if Button.get_rect(topleft=(320, 210)).collidepoint(pygame.mouse.get_pos()):
              button_pressed = pygame.image.load('button_pressed.png')
              screen.blit(button_pressed,(320,210))
              pygame.display.update()
              pygame.mixer.music.stop()
              file = 'ngsound.mp3'
              pygame.mixer.init()
              pygame.mixer.music.load(file)
              pygame.mixer.music.play()
              #time.sleep(3)
              buttonloop=+1

### end of title screen
              
#draws the main screen background
screen = pygame.display.set_mode((800, 600))
#loads the 1st background image
bground1 = pygame.image.load("arrival.jpg").convert()
#draws the jpg to the surface
screen.blit (bground1,(0,0))
#updates the surface
pygame.display.update()
#this section draws and arranges the flying UFO and controls

display_width = 800
display_height = 600

clock = pygame.time.Clock()
crashed = False
ufoImg = pygame.image.load('ufoImg.png')

def ufo(x,y):
    bground1.blit(ufoImg, (x,y))

x =  (display_width * 0.45)
y = (display_height * 0.05)
x_change = 0
y_change = 0
ufo_speed = 0

while not crashed:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            crashed = True

#horizontal control      
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                x_change = -2
            elif event.key == pygame.K_RIGHT:
                x_change = 2
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                x_change = 0

#vertical control
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                y_change = -2
            elif event.key == pygame.K_DOWN:
                y_change = 2
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                y_change = 0
                            
    x += x_change
    y += y_change
      
    ufo(x,y)
    screen.blit (bground1,(0,0))

    pygame.display.update()
    clock.tick(60)

pygame.quit()
quit()

Was This Post Helpful? 0
  • +
  • -

#5 DK3250   User is offline

  • Pythonian
  • member icon

Reputation: 561
  • View blog
  • Posts: 1,794
  • Joined: 27-December 13

Re: moving object drawing every frame over background

Posted 06 August 2015 - 09:45 AM

You should use the convert() on the ufo also.

Don't blit the ufo to the bground1, but to the screen. Otherwise the background is 'ruined' for good.

In each loop you should have two blit:

while loop:
    # other code lines, event handling, etc.
    screen.blit(bground1, (0,0))
    screen.blit(ufoImg, (x, y))
    pygame.display.update()


Your learning method is just fine - actually any method that makes sense to yourself is ok.
Feel free to revert if this answer is too short.

This post has been edited by DK3250: 06 August 2015 - 09:48 AM

Was This Post Helpful? 0
  • +
  • -

#6 sigint-ninja   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 148
  • Joined: 05-June 15

Re: moving object drawing every frame over background

Posted 06 August 2015 - 01:44 PM

Hi DK,

i made the changes you suggested...
its got better...still a trail but only as long as i hold the button down...when i release the trail disappears
looks very cool...was even considering keeping the effect...but no...not at this stage lol

as far as convert goes...i converted the png background
but not the ufo as it seemed to draw a strange background to the picture...but i did read that i will have to
maybe upload and download the file through a converter (png warning was going off in my console,and i googled it)
dont know if that has something to do with it..

i also have the ufo blitting to the screen now...not the image,,,

heres my updated code: if you have any further suggestions im all eyes!!!
as i am out of solutions

as always...much appreciation this side

def ufo(x,y):
    screen.blit(ufoImg, (x,y))

x =  (display_width * 0.45)
y = (display_height * 0.05)
x_change = 0
y_change = 0
ufo_speed = 0

while not crashed:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            crashed = True

#horizontal control      
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                x_change = -2
                screen.blit(bground1, (0,0))
                screen.blit(ufoImg, (x, y))
                pygame.display.update()

            elif event.key == pygame.K_RIGHT:
                x_change = 2
                screen.blit(bground1, (0,0))
                screen.blit(ufoImg, (x, y))
                pygame.display.update()
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                x_change = 0
                screen.blit(bground1, (0,0))
                screen.blit(ufoImg, (x, y))
                pygame.display.update()

#vertical control
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                y_change = -2
                screen.blit(bground1, (0,0))
                screen.blit(ufoImg, (x, y))
                pygame.display.update()
            elif event.key == pygame.K_DOWN:
                y_change = 2
                screen.blit(bground1, (0,0))
                screen.blit(ufoImg, (x, y))
                pygame.display.update()
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                y_change = 0
                screen.blit(bground1, (0,0))
                screen.blit(ufoImg, (x, y))
                pygame.display.update()
                
    x += x_change
    y += y_change
      
    ufo(x,y)
    screen.blit (screen,(0,0))

Was This Post Helpful? 0
  • +
  • -

#7 DK3250   User is offline

  • Pythonian
  • member icon

Reputation: 561
  • View blog
  • Posts: 1,794
  • Joined: 27-December 13

Re: moving object drawing every frame over background

Posted 06 August 2015 - 02:00 PM

Hi Ninja,

EDIT : This comment refers to the first version of your code

Found some time to look a little more detailed on your code. I'll just comment from top referring to line numbers in you code here (neglecting that the first four lines are outside code tags).
Line 6, 10, 21, 32 and 60, you should add the convert() option. I prefer to load all images as a block in the top of the code rather than spread throughout the code.
Line 16 and 37, you don't need the mixer.init() - it is done by the generel pygame.init()
Line 21, variable names should start with lower case letters; Button >> button
Line 29: sys.quit() should be sys.exit()
Line 46 is redundant from line 2
The two variables in line 55 and 56 could be declared before line 2 and used in the pygame.display.set_mode() call.
Line 62, 63, this small function is not necessary as mentioned in earlier reply
Line 69, ufo_speed is not used in later code
Line 99 and 100 I have commented upon in earlier reply
Line 106; I don't think Python support quit() in this way, better use sys.exit()

Many small issues, you are still on a good track for your game. :-O

This post has been edited by DK3250: 06 August 2015 - 02:05 PM

Was This Post Helpful? 1
  • +
  • -

#8 DK3250   User is offline

  • Pythonian
  • member icon

Reputation: 561
  • View blog
  • Posts: 1,794
  • Joined: 27-December 13

Re: moving object drawing every frame over background

Posted 06 August 2015 - 02:22 PM

Hi Ninja,
In your second code (DIC #7) you don't follow my advice from DIC #5
In order to avoid the 'tail' of ufo pictures, you need to do two updates in every pass of the loop:
1. Update the background - this wipes everything away and provides a fresh start. This is equal to screen.fill(color), only you fill the screen with your background picture instead.
2. Update the ufo position

So, your function in line 1, 2 of latest code snip is unnecessary. Line 57, 58 must be modified (look at line 3,4 in my earlier reply)

EDIT: Oh, I am blind. Did not see all the extra (and unnecessary) blitting in line 19, 20, 25, 26, ..
Only one blitting is needed (line 57, 58)

This post has been edited by DK3250: 06 August 2015 - 02:26 PM

Was This Post Helpful? 0
  • +
  • -

#9 sigint-ninja   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 148
  • Joined: 05-June 15

Re: moving object drawing every frame over background

Posted 06 August 2015 - 02:49 PM

Hey DK you always seem to be at it!!!

thanks for your input on the code...good to get into good habits early!!!
as far as loading images in the beginning...so if an image is loaded in the first line of your program it will be available throughout the whole program?

im going to stop thanking you for your help...as im sure its getting annoying...but thanks again!!!

This post has been edited by sigint-ninja: 06 August 2015 - 02:50 PM

Was This Post Helpful? 0
  • +
  • -

#10 DK3250   User is offline

  • Pythonian
  • member icon

Reputation: 561
  • View blog
  • Posts: 1,794
  • Joined: 27-December 13

Re: moving object drawing every frame over background

Posted 06 August 2015 - 03:00 PM

If you assign a variable to the loaded image, it will be available all the time.
<name> = pygame.image.load("pic.png").convert()

Then <name> will be available.

Hope you have seen the EDIT in my last post.
Was This Post Helpful? 0
  • +
  • -

#11 DK3250   User is offline

  • Pythonian
  • member icon

Reputation: 561
  • View blog
  • Posts: 1,794
  • Joined: 27-December 13

Re: moving object drawing every frame over background

Posted 06 August 2015 - 03:15 PM

It's late over here, so I'll be AFK next 8-10 hours.
Just to give you something to continue on, I'll give you the game loop as I think it should be (at this stage of game development):
while not crashed:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            crashed = True

#horizontal control      
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                x_change = -2
            elif event.key == pygame.K_RIGHT:
                x_change = 2
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                x_change = 0

#vertical control
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                y_change = -2
            elif event.key == pygame.K_DOWN:
                y_change = 2
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                y_change = 0
                            
    x += x_change
    y += y_change
      
    screen.blit (bground1, (0,0))
    screen.blit(ufoImg, (x, y))

    pygame.display.update()
    clock.tick(60)


Was This Post Helpful? 0
  • +
  • -

#12 sigint-ninja   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 148
  • Joined: 05-June 15

Re: moving object drawing every frame over background

Posted 07 August 2015 - 01:01 AM

Hey DK the code works perfect...but it looks less than what we discussed previously...is it ok if i do a report over the weekend line by line to explain what i think is going on and then also ask a few questions at the end? I think it would be good as i dont und3rstand 100 percent whats going on.
Was This Post Helpful? 1
  • +
  • -

#13 DK3250   User is offline

  • Pythonian
  • member icon

Reputation: 561
  • View blog
  • Posts: 1,794
  • Joined: 27-December 13

Re: moving object drawing every frame over background

Posted 07 August 2015 - 01:43 AM

Hi Ninja,
You are more than welcome. Please observe that I cannot run your code as I don't have the image files - all my input is based on reading the code.

Let me push you a bit more: Time for the first major refactoring. You should re-write your game loop to look something like this:
while not crashed:
    clock.tick(60)
    event_handling()
    move_player()
    draw_all()
Nothing more! This requires three new functions, but most of the code is re-use of existing lines.
I hope you see the idea behind this - in the end you will end up with a loop like this depending of the game:
while not crashed:
    clock.tick(60)
    event_handling()
    move_player()
    move_enemy()
    move_shot()
    check_for_collision()
    check_for_hit()
    draw_all()
This makes the code really easy to read and maintain, almost no need for comments.
You will need arguments and return values to pass data between the functions; for a first try you can even use globals. Later we make another refactoring introducing class objects and simplify this (but first things first). Give it a try and feel free to ask.

The functions may themselves have a similar structure, for instance:
def draw_all():
    draw_background()
    draw_player()
    draw_enemy()
    draw_shot()


Ninja, I am inspired by your open attitude; even to the point where I have taken up one of my own old projects that was stuck. Helping you have helped me moving this old project near completion. So this time it's me thanking you.

This post has been edited by DK3250: 07 August 2015 - 01:46 AM

Was This Post Helpful? 0
  • +
  • -

#14 sigint-ninja   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 148
  • Joined: 05-June 15

Re: moving object drawing every frame over background

Posted 07 August 2015 - 04:07 AM

Good to hear DK!!!

I will do a summary on the loop to move my ufo then i will arrange the code the way you have suggested...

speak soon

ninja

ps"whats the easiest way to export a pygame project into an all in one .exe file?...was looking at pygame2exe but it looked rather cumbersome...is there an easier way...also can you export to android? im sure you can,but you would obviously need to add touch screen controls."

This post has been edited by sigint-ninja: 07 August 2015 - 04:13 AM

Was This Post Helpful? 0
  • +
  • -

#15 DK3250   User is offline

  • Pythonian
  • member icon

Reputation: 561
  • View blog
  • Posts: 1,794
  • Joined: 27-December 13

Re: moving object drawing every frame over background

Posted 07 August 2015 - 05:30 AM

You want to move your Python/Pygame project into an .exe file. So would I. Fact is that it is not easy if at all possible. No matter where I have Googled or asked, no-one have provided a clear answer.

I did run py2exe succesfull on a old python 2.5 project. But you don't get one single file; rather you get a collection of 20-30 files that are all necessary for the .exe to run. I tried to zip the files into a self-extracting folder, but in the end it would only run on some computers and not on others. Furthermore py2exe has some severe limitations if pygame Fonts are used.

I have discussed this with many skilled programmers, but current buttomline is that I have no solution. Sic. If other readers here on DIC have a better answer, I would be happy to hear about it.

Quite recently I've heard about Brython that makes Python programs run in an HTML environment. It looks really exciting. It will not, however, run pygame imports. Graphics in Brython is shown by HTML canvas. It is my plan to convert a small pygame program to Brython, hopefully I'll find the time in near future.
Was This Post Helpful? 1
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2