I'm here to ask what is the problem with my code? I'm making a game engine, and I thought the easiest way to sort player types would be putting them into a different script and using them there. However, I am having a slight issue doing that, and have no clue how to fix it.
Here is the error I'm getting:
Traceback (most recent call last): File "C:\Users\Harry Court\AppData\Local\Programs\Python\Python36-32\projects\Game Engine\main.py", line 48, in <module> topDownPlayerControls() NameError: name 'topDownPlayerControls' is not defined
P.S: If there is an easier way to do this, please tell me!
main.py
import pygame
from playerSelection import *
import ctypes
from ctypes.wintypes import HWND, LPWSTR, UINT
# Window Size
display_w = 1366
display_h = 768
# Initialize and Set Display
pygame.init()
gameDisplay = pygame.display.set_mode((display_w, display_h))
pygame.display.set_caption("The Joker Engine (Version Undecided) - By Harrison Court")
clock = pygame.time.Clock()
# Ctypes ID's
IDYES = 6
IDNO = 7
x = (display_w * 0.45)
y = (display_h * 0.8)
# Colours
black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)
running = True
gameDisplay.fill(white)
while running:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
# Misc.
if event.key == pygame.K_ESCAPE:
quitWindow = ctypes.windll.user32.MessageBoxW(0, "Are you sure you want to quit?", "Warning!", 4)
# Confirm they want to leave.
if quitWindow == IDYES:
quit()
topDownPlayerControls()
pygame.display.update()
clock.tick(60)
pygame.quit()
quit()
playerSelection.py:
import pygame
from tkinter import Tk, Frame, Menu
import ctypes
from ctypes.wintypes import HWND, LPWSTR, UINT
x = (300)
y = (300)
playerImg = pygame.image.load('Player.png')
class playerMovement():
def player(x,y):
gameDisplay.blit(playerImg, (x,y))
def topDownPlayerControls():
if event.type == pygame.KEYDOWN:
# Left & Right
if event.key == pygame.K_LEFT:
x_change = -5
print("Left")
elif event.key == pygame.K_RIGHT:
x_change = 5
print("Right")
# Up & Down
if event.key == pygame.K_DOWN:
y_change = 5
print("Down")
elif event.key == pygame.K_UP:
y_change = -5
print("Up")
# If no keys are pressed, do this...
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x_change = 0
if event.key == pygame.K_DOWN or event.key == pygame.K_UP:
y_change = 0
# Player Movement
x += x_change
y += y_change
Updated Script:
main.py:
import pygame
from playerSelection import *
from gui import *
from tkinter import *
import ctypes
from ctypes.wintypes import HWND, LPWSTR, UINT
# Define stuff
player = playerMovement()
# Window Size
display_w = 1366
display_h = 768
# Initialize and Set Display
pygame.init()
gameDisplay = pygame.display.set_mode((display_w, display_h))
pygame.display.set_caption("The Joker Engine (Version Undecided) - By Harrison Court")
clock = pygame.time.Clock()
# Ctypes ID's
IDYES = 6
IDNO = 7
x = (display_w * 0.45)
y = (display_h * 0.8)
# Colours
black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)
running = True
gameDisplay.fill(white)
# Make sure the game isn't dying on us.
while running:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
# Misc.
if event.key == pygame.K_ESCAPE:
quitWindow = ctypes.windll.user32.MessageBoxW(0, "Are you sure you want to quit?", "Warning!", 4)
# Confirm they want to leave.
if quitWindow == IDYES:
quit()
player.displayPlayer(x,y)
player.topDownPlayerControls
pygame.display.update()
clock.tick(60)
pygame.quit()
quit()
playerSelection.py:
import pygame
from tkinter import Tk, Frame, Menu
import ctypes
from ctypes.wintypes import HWND, LPWSTR, UINT
x = (300)
y = (300)
display_w = 1366
display_h = 768
gameDisplay = pygame.display.set_mode((display_w, display_h))
playerImg = pygame.image.load('Player.png')
class playerMovement():
def displayPlayer(self,x,y):
gameDisplay.blit(playerImg, (x,y))
def topDownPlayerControls(self):
if event.type == pygame.KEYDOWN:
# Left & Right
if event.key == pygame.K_LEFT:
x_change = -5
print("Left")
elif event.key == pygame.K_RIGHT:
x_change = 5
print("Right")
# Up & Down
if event.key == pygame.K_DOWN:
y_change = 5
print("Down")
elif event.key == pygame.K_UP:
y_change = -5
print("Up")
# If no keys are pressed, do this...
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x_change = 0
if event.key == pygame.K_DOWN or event.key == pygame.K_UP:
y_change = 0
# Player Movement
x += x_change
y += y_change
Your error message is saying that the function topDownPlayerControls is not defined. This is because you are trying to call it as a free function. However, this function is defined within the playerMovement class. So, you would first need to create a playerMovement object, and then call the topDownPlayerControls function on that object. It would look something like this:
player = playerMovement()
player.topDownPlayerControls()
It looks like you will have a number of other fails after that, but I'll leave that as an exercise :)
Related
The code is isn't running, it is a Pygame code for a race game, everytime I try to run it, it says ImportError: No module named Pygame. I don't have any idea if this code has any other problems, so as far as I know it is only the Import Error. Can you help me solve the Import Error and any other problems that occur?
import pygame
import time
pygame.init()
display_width = 800
display_height = 600
black = (0,0,0)
white = (255,255,255)
red = (255,0,0)
car_width = 73
gameDisplay = pygame.display.set_mode((display_width,display_height ))
pygame.display.set_caption('A bit Racey 3')
clock = pygame.time.Clock()
def carImg():
pygame.image.load('racecar.png')
def car(x,y):
gameDisplay.blit(carImg,(x,y))
def game_loop():
x = (display_width * 0.45)
y = (display_height * 0.8)
x_change = 0
gameExit = False
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = -5
elif event.key == pygame.K_RIGHT:
x_change = 5
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x_change = 0
x += x_change
gameDisplay.fill(white)
car(x, y)
if x > display_width - car_width or x < 0:
gameExit = True
pygame.display.update()
clock.tick(60)
game_loop()
pygame.quit()
quit()
pygame.image.load() loads an image and returns the a Surface object. Your surface goes to nowhere:
def carImg():
pygame.image.load('racecar.png')
carImg has to be a variable rather then a function. Assign the Surface object to carImg:
carImg = pygame.image.load('racecar.png')
I'm just messing around with Pygame and I can't see what I'm doing incorrectly to make the red circle move with the arrow keys. I can't tell if it's in my main loop. I also haven't been able to find very many tutorials on sprite or looping animations with Pygame. If I for example wanted to make a square oscillate for example like a moving platform how would I do that?
import pygame
import time
## event handling varibles
player_x = 0
player_y = 0
x = 250
y = 250
## screen display
display_width = 500
display_height = 500
pygame.init()
game_screen = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption("test")
# player
def player():
pygame.draw.circle(game_screen,red,(x,y),15)
# colors
white = (255,255,255)
red = (255,0,0)
black = (0,0,0)
### main loop
dead = False
while dead != True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
dead = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
player_x = -1
elif event.key == pygame.K_RIGHT:
player_x = +1
if event.key == pygame.K_UP:
player_y = +1
elif event.key == pygame.K_DOWN:
player_y = -1
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or pygame.K_RIGHT:
player_x = 0
if event.key == pygame.K_UP or pygame.K_DOWN:
player_y = 0
game_screen.fill(black)
player()
pygame.display.update()
x -= player_x
y -= player_y
pygame.quit()
quit()
Your indendation is all messed up.
Your code won't do anything unless the event is QUIT... which then makes it quit.
Your boolean logic is wrong.
This is not proper syntax event.key == pygame.K_UP or pygame.K_DOWN. The order of precedence here is as follows (event.key == pygame.K_UP) or (K_DOWN). Since K_DOWN is truthy, it is always true and thus this entire statement is always true.
I think you mean: event.key == pygame.K_UP or event.key == pygame.K_DOWN
Lastly, it wont' keep moving as you say you want.
It will only move when there is an event in the queue. You can make it keep moving by generating events. Perhaps with an event timer.
Here is a fixed version, hope this helps:
import pygame
import time
## event handling varibles
player_x = 0
player_y = 0
x = 250
y = 250
## screen display
display_width = 500
display_height = 500
pygame.init()
game_screen = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption("test")
# player
def player(game_screen, red, point): # Use parameters not globals
pygame.draw.circle(game_screen, red, point, 15)
# colors
white = (255,255,255)
red = (255,0,0)
black = (0,0,0)
### main loop
pygame.time.set_timer(pygame.USEREVENT, 1) # 1 per second
dead = False
while not dead:
for event in pygame.event.get():
if event.type == pygame.QUIT:
dead = True
elif event.type == pygame.USEREVENT:
pygame.time.set_timer(pygame.USEREVENT, 1) # Set another timer for another 1 second
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
player_x = +10
elif event.key == pygame.K_RIGHT:
player_x = -10
elif event.key == pygame.K_UP:
player_y = +10
elif event.key == pygame.K_DOWN:
player_y = -10
elif event.type == pygame.KEYUP:
if event.key in [pygame.K_LEFT, pygame.K_RIGHT]:
player_x = 0
elif event.key in [pygame.K_UP, pygame.K_DOWN]:
player_y = 0
game_screen.fill(black)
player(game_screen,red,(x,y))
pygame.display.update()
x -= player_x
y -= player_y
pygame.quit()
I am moving a sprite on the x-axis. It is properly moving left and right. When I press both LEFT and RIGHT at the same time it stop moving properly.
I am trying to make it when a user presses both keys and then lets go of one, for it to continue moving in the direction still pressed.
Weirdly it works while I holding right and letting go of left. It continues moving right.
When I hold left and tap right it stops moving until I press right again.
I commented out some ideas I had to make this work, but they failed me.
I am sure its a simple fix or a logic failure on my part.
I have worked a couple hours on this.
Thanks for responses ahead of time.
import pygame
import time
import random
import sys
import math
pygame.init()
displayWidth = 1200
displayHeight = 800
white = (255,255,255)
black = (0,0,0)
gameDisplay = pygame.display.set_mode((displayWidth, displayHeight))
pygame.display.set_caption('Game 3')
clock = pygame.time.Clock()
class firstSquare:
def __init__(self,player_x,player_y):
self.x = player_x
self.y = player_y
self.width = 100
self.height = 100
def render(self):
pygame.draw.rect(gameDisplay, white,(self.x, self.y, self.width, self.height))
class secondSquare:
def __init__(self,cpu_x,cpu_y):
self.x = cpu_x
self.y = cpu_y
self.width = 100
self.height = 100
def render(self):
pygame.draw.rect(gameDisplay, white,(self.x, self.y, self.width, self.height))
player = firstSquare(300,300)
cpu = secondSquare(100,100)
def gameLoop():
### variables##
player_x = 100
player_y = 100
x = 100
y = 100
movement_x = 0
movement_y = 0
frame_rate = 0
frame_table = 0
inGame = True
while inGame:
for event in pygame.event.get():
if event.type == pygame.QUIT:
inGame = False
pygame.quit()
sys.exit()
keyPressed= pygame.key.get_pressed()
#### this is moving the player on x-axis##
if keyPressed[pygame.K_LEFT]:
movement_x = -5
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
movement_x = 0
if keyPressed[pygame.K_RIGHT]:
movement_x = 5
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
movement_x = 0
### two keys at once won't move the player###
if keyPressed[pygame.K_LEFT] and keyPressed[pygame.K_RIGHT]:
movement_x = 0
### pressing one key and letting go the other will continue movement
## if keyPressed[pygame.K_LEFT] and keyPressed[pygame.K_RIGHT]:
## if event.type == pygame.KEYUP:
## if event.key == pygame.K_LEFT:
## movement_x = 5
## print("left dropped")
## if keyPressed[pygame.K_RIGHT] and keyPressed[pygame.K_LEFT]:
## if event.type == pygame.KEYUP:
## if event.key == pygame.K_RIGHT:
## movement_x = -5
## print("Right dropped")
gameDisplay.fill(black)
player.render()
cpu.render()
player.x += movement_x
pygame.display.update()
clock.tick(60)
gameLoop()
pygame.quit()
quit()
I think what you need is this:
if keyPressed[pygame.K_LEFT]:
movement_x = -5
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT and movement_x < 0:
movement_x = 0
if keyPressed[pygame.K_RIGHT]:
movement_x = 5
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT and movement_x > 0:
movement_x = 0
And that would be it... Hope it helps.
Try to use the following code in your movement:
if keyPressed[pygame.K_LEFT]:
movement_x = -5
elif keyPressed[pygame.K_RIGHT]:
movement_x = +5
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
movement_x = 0
elif event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
movement_x = 0
I am kinda stuck with a supposed to be simple code to check if the user has pressed "w" or "s".
Below you can see my code:
import pygame
pygame.init()
while True:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN and event.key == pygame.K_w:
print('Forward')
elif event.type == pygame.KEYDOWN and event.key == pygame.K_s:
print('Backward')
Am I forgetting something here?
Thanks!
A window needs to be created to receive key presses, the following works.
import pygame
import sys
pygame.init()
pygame.display.set_mode((100, 100))
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
print('Forward')
elif event.key == pygame.K_s:
print('Backward')
This is what seems to me the most simple and understandable way to do it:
import pygame
pygame.init()
pygame.display.set_mode((300, 300))
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
print('Forward')
elif event.key == pygame.K_s:
print('Backward')
Instead of using the sys.exit() method I prefer to just use pygame.quit()
it is no good to ask the gamer to keep hitting w to get the response. If you want to read the "pressed" state. You could consider the followings:
from pygame import *
import time
flag = False # The flag is essential.
DONE = False
screen = display.set_mode((500,500)) # 1180, 216
count=0
while not DONE:
event.pump() # process event queue
keys = key.get_pressed() # It gets the states of all keyboard keys.
#print("%d"%count,keys)
count+=1
if keys[ord('w')]: # And if the key is K_DOWN:
print("%d w down"%count)
if keys[ord('s')]: # And if the key is K_DOWN:
print("%d s down"%count)
time.sleep(0.1)
Try this:
import pygame
pygame.init()
key = pygame.key.get_pressed()
while True:
for event in pygame.event.get():
if event.type == KEYDOWN and event.key == pygame.K_w:
print('Forward')
elif event.type == KEYDOWN and event.key == pygame.K_s:
print('Backward')
Sample code to understand how key press events work.
import pygame
from pygame.locals import *
def main():
pygame.init()
pygame.display.set_caption("Move Box With Arrow Keys")
wndsize = (320, 240)
display = pygame.display.set_mode(wndsize)
x = 5
y = 5
black = (0, 0, 0)
white = (255, 255, 255)
rectpos = (x, y)
rectdim = (50, 50)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
x += 5
print("K_RIGHT")
if event.key == pygame.K_LEFT:
x -= 5
print("K_LEFT")
if event.key == pygame.K_UP:
y -= 5
print("K_UP")
if event.key == pygame.K_DOWN:
y += 5
print("K_DOWN")
# Don't allow coords below 0
if 0 > x:
x = 5
if 0 > y:
y = 5
# Don't allow overflow
if x + rectdim[0] > wndsize[0]:
x = wndsize[0] - rectdim[0] - 5
if y + rectdim[1] > wndsize[1]:
y = wndsize[1] - rectdim[1] - 5
rectpos = (x, y)
display.fill(white)
rect = pygame.draw.rect(display, black, ((rectpos), (rectdim)))
pygame.display.update()
main()
This might work:
from pygame import *
init()
if key.get_pressed()[K_w] == True:
print('Forwards')
if key.get_pressed()[K_s] == True:
print('Backwards')`
This is the code I used.
import pygame, sys
from pygame.locals import *
pygame.init()
def game():
width, height = 1000, 600
screen = pygame.display.set_mode((width,height))
pygame.display.set_caption('My game far now :P') #This command allows you make a title.
background=pygame.image.load('AE.jpg')
background = pygame.transform.scale(background, (width,height))
screen.blit(background, (0,0))
#Load target image and player
player = pygame.image.load('little.png')
player = pygame.transform.scale(player, (40,40))
px,py = width/2,height/2
screen.blit(player, (px,py))
movex = movey = 0
#Running of the game loop
while True:
screen.blit(background, (0,0))
#screen.blit(target,targetpos)
screen.blit(player, (px,py))
pygame.display.update()
#keyboard an/or mouse movements
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
elif event.type == pygame.KEYDOWN:
if event.key == K_RIGHT:
movex = 2
if event.key == K_LEFT:
movex = -2
if event.key == K_UP:
movey = -2
if event.key == K_DOWN:
movey = 2
elif event.type == pygame.KEYUP:
if event.key == K_RIGHT:
movex = 0
if event.key == K_LEFT:
movex = 0
if event.key == K_UP:
movey = 0
if event.key == K_DOWN:
movey = 0
px = px + movex
py = py + movey
#Python 's way of running the main routine
if __name__=='__main__':
game()
When I run the program it all starts right, the screen opens with background and player spawning in the middle of the screen, but when I try to move nothing happends, no errors nothing.
Would apriciate any help I can get :)
Thx for taking time to help me.
You seem to have code indentation problem in last two lines which may be causing the bug.
Your curent code is equivalent to this if code block:
elif event.type == pygame.KEYUP:
if event.key == K_RIGHT:
movex = 0
if event.key == K_LEFT:
movex = 0
if event.key == K_UP:
movey = 0
if event.key == K_DOWN # IF BLOCK STARTS
movey = 0
px = px + movex # THIS FALLS IN THE PREVIOUS IF BLOCK
py = py + movey
Correct code would be :
elif event.type == pygame.KEYUP:
if event.key == K_RIGHT:
movex = 0
if event.key == K_LEFT:
movex = 0
if event.key == K_UP:
movey = 0
if event.key == K_DOWN # IF BLOCK STARTS
movey = 0 #IF BLOCK ENDS
px = px + movex # NOW THIS IS OUT OF THE IF BLOCK
py = py + movey
Take this code, the movement is optimized. Useles code removed.
I hope you understand it ;)
import pygame, sys
from pygame.locals import *
pygame.init()
width, height = 1000, 600
screen = pygame.display.set_mode((width,height))
pygame.display.set_caption('My game far now :P')
background=pygame.image.load('AE.png')
background = pygame.transform.scale(background, (width,height))
player = pygame.image.load('little.png')
player = pygame.transform.scale(player, (40,40))
px,py = width/2,height/2
movex = movey = 0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]: px -= 2
if keys[pygame.K_RIGHT]: px += 2
if keys[pygame.K_UP]: py -= 2
if keys[pygame.K_DOWN]: py += 2
screen.blit(background, (0,0))
screen.blit(player, (px,py))
pygame.display.update()
Two problems.
You don't render in your loop
You are updating the location only in the if statement.
fixed:
while True:
# input
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
elif event.type == pygame.KEYDOWN:
# ...snip...
# physics
px += movex
py += movey
# drawing
screen.blit(background, (0,0))
screen.blit(player, (px,py))
pygame.display.update()