Sign in to follow this  
EducationalGamesCreator

Python, Pygame, Require help with my code.

Recommended Posts

Hi, I'm new here, and I'm a beginner programmer.

I'm working with python and pygame library.

-Attached picture

 

For some reason When I try to post my prntscrn picture on paint, it doesn't show the arrow flying and the dog disappearing while the arrow still is in the air. (this happens when I click my left mouse button).

 

Now I want the arrow to hit the moving dog and if it hits it, let both of them disappear, how do I do that?

My problem now is that when I shoot (left mouse button), the entire game waits for the attack loop to end, and the dog disappears of screen. 

 

I've been working on this problem a couple of months back, and now returned to try for hours with no result.

Here is my code:

 

import pygame
import random

# Define some colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)

pygame.init()

# Set the width and height of the screen [width, height]
screen_width = 1280
screen_height = 800
screen = pygame.display.set_mode([screen_width, screen_height])

pygame.display.set_caption("Hunter")

# Loop until the user clicks the close button.
done = False

# Used to manage how fast the screen updates
clock = pygame.time.Clock()

background_image = pygame.image.load("backgroundImage.png").convert()
characterImage = pygame.image.load("Player1.png").convert()
characterImage1 = pygame.image.load("Player2.png").convert()
click_sound = pygame.mixer.Sound("shoot.ogg")
arrow = pygame.image.load("arrow.png").convert()
dog = pygame.image.load("dog.png").convert()
characterImage.set_colorkey(WHITE)
arrow.set_colorkey(WHITE)
dog.set_colorkey(WHITE)
pygame.mouse.set_visible(False)



dogX = 1200
dogY = 655
# -------- Main Program Loop -----------
while not done:
# --- Main event loop
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
#attack animation
if event.type==pygame.MOUSEBUTTONDOWN:
click_sound.play()
arrowX = charPos[0]+20
arrowY = charPos[1]+20
for arrowPixel in range(800):
charPos = pygame.mouse.get_pos()
charX = charPos[0]
charY = charPos[1]
screen.blit(characterImage, [charX-32, charY-35])
screen.blit(background_image, [0,0])
screen.blit(characterImage1, [charPos[0], charPos[1]])
screen.blit(arrow, [arrowX, arrowY])
arrowX += 1
pygame.display.flip()




###################################################### --- Game logic should go here

###################################################### --- Drawing code should go here

screen.blit(background_image, [0,0])

# player movement
charPos = pygame.mouse.get_pos()
charX = charPos[0]
charY = charPos[1]
screen.blit(characterImage, [charX-32, charY-35])


#monsters
screen.blit(dog, [dogX, dogY])
dogX -= 1


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

pygame.quit()

 

For some reason the code posted here without indentations, if I can fix this tell me and I will.

 

Edited by EducationalGamesCreator

Share this post


Link to post
Share on other sites
It is because you are updating the position of the arrow entirely within one game loop iteration.

In order to fix this, you'll need to incrementally update the position of the arrow each iteration of the game loop (no separate for loop to update the arrow position arrowX += 1). Instead you might only add 1 to arrowX for each iteration of the main loop. In reality, you would want to calculate how far the arrow moved each frame based on the arrow's desired speed and how much time has passed since the last loop iteration.

I am on my phone, otherwise I could get into greater detail. Sorry!

Share this post


Link to post
Share on other sites

It is because you are updating the position of the arrow entirely within one game loop iteration.

In order to fix this, you'll need to incrementally update the position of the arrow each iteration of the game loop (no separate for loop to update the arrow position arrowX += 1). Instead you might only add 1 to arrowX for each iteration of the main loop. In reality, you would want to calculate how far the arrow moved each frame based on the arrow's desired speed and how much time has passed since the last loop iteration.

I am on my phone, otherwise I could get into greater detail. Sorry!

 

Problem still persists. While I think I understand what you're saying, I don't know how to proceed now.

Share this post


Link to post
Share on other sites

I was thinking github that way you could share the images too.

I don't know how to use it, but basically what happens is:

 

LMOUSEBUTTON>arrow shoots from character position>while arrow is going to the right side of the screen, the dog disappears and continues from same place when the arrow is disappeared.  Since the entire game waits for the arrow loop to finish (That's my problem..)

Share this post


Link to post
Share on other sites
Ah, I see.

You have a separate loop for the arrow movement. Don't do that. You should have one place where you draw every character (the player, the dog, the arrow, and anything else that may appear).
After drawing, update the position of every character (the player, the dog, the arrow, and other things that appeared).

So in a sense, the arrow is always there, considered to be drawn and moved, but some times (most times probably), you skip drawing and moving it.
When the player fires the arrow, you switch its display on, set it at the start position, and enable its movement. From then on it's just one more thing that changes position every flip(). When it hits the target, or reaches the end of the screen, you switch the arrow off again, so it is not drawn and moved again. Edited by Alberth

Share this post


Link to post
Share on other sites

Ah, I see.

You have a separate loop for the arrow movement. Don't do that. You should have one place where you draw every character (the player, the dog, the arrow, and anything else that may appear).
After drawing, update the position of every character (the player, the dog, the arrow, and other things that appeared).

So in a sense, the arrow is always there, considered to be drawn and moved, but some times (most times probably), you skip drawing and moving it.
When the player fires the arrow, you switch its display on, set it at the start position, and enable its movement. From then on it's just one more thing that changes position every flip(). When it hits the target, or reaches the end of the screen, you switch the arrow off again, so it is not drawn and moved again.

but how to do that in code?

Share this post


Link to post
Share on other sites

Below shows the global idea. I just copied a few key-lines from your code, hopefully to get the idea across.

I would suggest you try to grasp my idea, and then modify your own code (make a copy first!), instead of taking my copied code, as that may miss some lines that you need.

 

Basically, it starts with initialization, then has a function to draw everything, and a function to move everything one step.

Then comes the main "while not done" loop, that loops around, continually drawing, receiving input, and moving everything.

# NOTE: This code is incomplete, and will likely not even run.

# Intitialize
pygame.init()

screen_width = 1280
screen_height = 800
screen = pygame.display.set_mode([screen_width, screen_height])

# x/y position of the character (not sure about the initial position)
charX = 20
charY = 655

# x/y position of the dog
dogX = 1200
dogY = 655

# x/y position of the arrow
arrowX = None
arrowY = None  # Use 'None' to indicate here is no arrow.

def draw_everything(screen):
    """
    Draw the screen with everything on it that currently exists
    """
    screen.blit(background_image, [0,0])
    screen.blit(characterImage1, [charX, charY])
    screen.blit(dog, [dogX, dogY])

    if arrowX is not None:
        # If we have an arrow, draw it
        screen.blit(arrow, [arrowX, arrowY])

def move_everything():
    """
    Move everything
    """
    dogX -= 1

    if arrowX is not None:
        arrowX += 1
        if arrowX >= screen_width:
            # It left the screen, disable the arrow again
            arrowX = None
            arrowY = None

    # Could not find whether the character moves too. If it does it should be done here

done = False
while not done:
    draw_everything(screen)
    pygame.display.flip()

    # Process input of the user
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
            break # Don't bother doing further event processing

        if event.type == pygame.MOUSEBUTTONDOWN:
            click_sound.play()
            # arrrow fired! set the intial arrow position in the screen.
            charPos = pygame.mouse.get_pos()
            arrowX = charPos[0] + 20
            arrowY = charPos[1] + 20

    move_everything()

    # Not sure this belongs here
    clock.tick(60)

pygame.quit()

Last but not least, you add code by pasting into the editor, with the code selected, click the "code" tool in the toolbar (the "<>" symbol). That will add a box around it. If you use spaces for indenting, code will look good.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this