I have decided to make my game in pygame instead, and here is what I have coded so far:
from typing import Tuple
import pygame
from PIL import ImageGrab
# finding the height of the screen by taking a screenshot.
img = ImageGrab.grab()
(WIDTH, HEIGHT) = (img.size)
x = WIDTH / 2 - 470
y = HEIGHT / 2 - 400
fistx1 = x - 80
fistx2 = fistx1;
fisty1 = y + 40
fisty2 = y - 50
pygame.init()
clock = pygame.time.Clock()
RESOLUTION = (WIDTH, HEIGHT)
BACKGROUND_COLOR: Tuple[int, int, int] = (79, 205, 109)
MOVESPEED = 5
# window stuff
window = pygame.display.set_mode(RESOLUTION, flags=pygame.RESIZABLE, depth=32)
pygame.display.set_caption("The Connection")
window.fill(BACKGROUND_COLOR)
running = True
# all images for the game here
player_image = pygame.image.load("Connector.png")
player_fist1_image = pygame.image.load("Connector_hand.png")
player_fist2_image = player_fist1_image
while running:
pressed = pygame.key.get_pressed()
clicked = pygame.mouse.get_pressed();
class Player():
def __init__(self, hp, image, fist1image, fist2image):
global fisty1, fistx1, fisty2
self.hp = hp
self.image = image
self.fist1image = fist1image
self.fist2image = fist2image
window.blit(self.image, (x, y))
window.blit(self.fist1image, (fistx1, fisty1))
window.blit(self.fist2image, (fistx2, fisty2))
def move(self, movespeed):
global x, y, fistx1, fisty1, fisty2
if pressed[pygame.K_a]:
x -= movespeed
fistx1 -= movespeed
elif pressed[pygame.K_d]:
x += movespeed
fistx1 += movespeed
elif pressed[pygame.K_w]:
y -= movespeed
fisty1 -= movespeed
fisty2 -= movespeed
elif pressed[pygame.K_s]:
y += movespeed
fisty1 += movespeed
fisty2 += movespeed
def deal_damage(self, damage):
global x, y, fistx1, fisty1
fistx1 -= 25
window.fill(BACKGROUND_COLOR);
window.blit(self.fist1image, (fistx1, fisty1));
pygame.display.flip();
# this is the function we use to actually call it. This is more helpful and less confusing for an idiot like me
def actual_deal():
main_player.deal_damage(25);
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
try:
pygame.quit()
except pygame.error:
pass
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
actual_deal();
window.fill(BACKGROUND_COLOR)
main_player = Player(100, player_image, fist1image=player_fist1_image, fist2image=player_fist2_image)
main_player.move(movespeed=MOVESPEED)
pygame.display.flip()
clock.tick(60);
For context, the fist's have to go forward and then backward. However, the fists aren't moving smoothly, which has two problems:
It doesn't look good. I want to show this to other people, so I want it to look good.
When I retract the fists, it doesn't look like they moved forward in the first place. I'd have to add time.sleep
in between, but I am not willing to do that.
Here is the output I am getting when I punch: Placed in a spoiler so it isn't intrusive
As you can see, it moves in a blocky fashion. If you want to see the output I desire, then move the character around with the WASD keys and see how smoothly the characters move. I want the same thing for the fists.
If it matters, I am using pycharm to code this, and I'm running it from Command Prompt. I also have Windows 10.
Lastly, I have tried changing the framerate by doing this:
Here are the questions I have already looked at:
clock.tick(360);
But to no avail.
I have looked at these questions:
https://gamedev.stackexchange.com/questions/48227/smooth-movement-pygame
Couple of this I can spot. Firstly, function and class definitions are supposed to be outside of main loop because defining the same thing over and over again in a loop doesn't make any sense. Second you are calling pygame.display.flip
twice, which is not needed. Flip should only be called once, otherwise it causes flickering. Third, you are drawing in __init__
method and creating a new instance every frame. Usually, an instance is only made once, and there are methods of that instance to do something with that instance. So, instead of drawing in the __init__
, make a new method called draw.
Now to answer your question, it moves in blocks becasue:
pygame.MOUSEBUTTONDOWN
. This function only returns once true per click. So if you hold down your mouse button, it wouldn't work because it returns True
in the first frame and None
after that. To continuously update the mouse state, you need to use pygame.mouse.get_pressed()
.New code with everything I mentioned above implemented (NOTE: I changed images to surfaces to make it work, so you might wanna change it to image again):
from typing import Tuple
import pygame
from PIL import ImageGrab
# finding the height of the screen by taking a screenshot.
img = ImageGrab.grab()
(WIDTH, HEIGHT) = (img.size)
x = WIDTH / 2 - 470
y = HEIGHT / 2 - 400
fistx1 = x - 80
fistx2 = fistx1;
fisty1 = y + 40
fisty2 = y - 50
pygame.init()
clock = pygame.time.Clock()
RESOLUTION = (WIDTH, HEIGHT)
BACKGROUND_COLOR: Tuple[int, int, int] = (79, 205, 109)
MOVESPEED = 5
# window stuff
window = pygame.display.set_mode(RESOLUTION, flags=pygame.RESIZABLE, depth=32)
pygame.display.set_caption("The Connection")
window.fill(BACKGROUND_COLOR)
running = True
# all images for the game here
player_image = pygame.Surface((50, 50)).convert()
player_fist1_image = pygame.Surface((10, 10)).convert()
player_fist2_image = player_fist1_image
class Player():
def __init__(self, hp, image, fist1image, fist2image):
global fisty1, fistx1, fisty2
self.hp = hp
self.image = image
self.fist1image = fist1image
self.fist2image = fist2image
def move(self, movespeed):
global x, y, fistx1, fisty1, fisty2
if pressed[pygame.K_a]:
x -= movespeed
fistx1 -= movespeed
elif pressed[pygame.K_d]:
x += movespeed
fistx1 += movespeed
elif pressed[pygame.K_w]:
y -= movespeed
fisty1 -= movespeed
fisty2 -= movespeed
elif pressed[pygame.K_s]:
y += movespeed
fisty1 += movespeed
fisty2 += movespeed
def draw(self):
window.blit(self.image, (x, y))
window.blit(self.fist1image, (fistx1, fisty1))
window.blit(self.fist2image, (fistx2, fisty2))
def deal_damage(self, damage):
global x, y, fistx1, fisty1
mousePressed = pygame.mouse.get_pressed()
if mousePressed[0]:
fistx1 -= 1
window.fill(BACKGROUND_COLOR);
window.blit(self.fist1image, (fistx1, fisty1));
#pygame.display.flip();
main_player = Player(100, player_image, fist1image=player_fist1_image, fist2image=player_fist2_image)
# this is the function we use to actually call it. This is more helpful and less confusing for an idiot like me
def actual_deal():
main_player.deal_damage(25);
while running:
pressed = pygame.key.get_pressed()
clicked = pygame.mouse.get_pressed();
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
try:
pygame.quit()
except pygame.error:
pass
window.fill(BACKGROUND_COLOR)
main_player.move(movespeed=MOVESPEED)
main_player.deal_damage(50)
main_player.draw()
pygame.display.flip()
clock.tick(60);
Edit: Forgot to mention this but you are taking damage
argument in deal_damage
method but not using it.