Bildrotation und Verarbeitung von Tastaturbefehlen in Pygame
Verfasst: Dienstag 23. April 2013, 22:46
Hallo zusammen
Letztes Mal, als ich hier um Hilfe bitten wollte, fiel mir die Lösung während des Tippens des Posts ein, diesmal ist diese "Erleuchtung" leider ausgeblieben...
Ich poste zuerst den Code. Es ist ein Spiel, bei dem der Spieler eine Figur aus der Vogelperspektive lenkt. Später wird's drei verschiedene Modi, diverse Gegner und Waffen, sowie richtige Spielziele geben. Davon ist noch nicht viel implementiert.
Ich habe im Code selbst einiges an englischen Kommentaren, die ich gerne übersetzen könnte, sollte das gewünscht sein. Dazu hat es noch zwei Tags "PROBLEM XX" und einmal "FRAGE". Diese stehen nicht im Original-Code, sondern nur hier im Forum, um die problematischen Bereiche hervorzuheben.
Problem 1
An der markierten Stelle in der PlayerClass.update-Funktion sollte eigentlich das Bild um self.rad gedreht werden, was aber nicht geschieht. Zwar bewegt sich die Spielfigur in die neue Richtung, das Bild wird aber nicht gedreht, sondern starrt starr an den unteren Bildschirmrand. Ich sitze jetzt Stunden daran und finde wirklich nicht heraus, was ich da falsch überlegt habe :/
Frage 2
Was würde diese Stelle mit dem "if not hasattr..." und dem "continue" bewirken, wenn sie nicht auskommentiert wäre? Ich weiss aus der Dokumentation, dass die Bedingung ist, dass das Objekt "event" das Attribut "key" nicht haben darf, damit das "continue" ausgelöst wird. Nur verstehe ich die Verwendung im konkreten Zusammenhang nicht genau. Unter welchen Bedingungen trifft das hier zu (oder eben nicht...)? Wohin zielt das "continue"? Sprich: Wo fährt der Interpreter weiter, wenn das "if not" eintrifft? Und wo fährt er weiter, wenn es nicht eintrifft? Da wäre ich dankbar für eine Klärung
Problem 3
Im folgenden Block müssten eigentlich die Tastenbefehle an die PlayerClass.update-Funktion übergeben werden. Das Problem ist nun, dass ich die Bewegen-Taste (NUMPAD 8 oder 2) loslassen muss, damit eine Richtungstaste verwendet werden kann. Halte ich die Bewegungstaste gedrückt, geht die Figur stur geradeaus, auch wenn ich eine Richtungstaste (NUMPAD 4 oder 6) drücke. Lasse ich die Bewegentaste los, kann ich die Drehung vollziehen (Bild dreht eben nicht mit, wie bei Problem 1 beschrieben) und danach mit der Bewegen-Taste in die entsprechende Richtung gehen. Warum funktioniert das nicht, während ich die jeweilige Bewegentaste gedrückt halte?
Bitte geizt nicht mit Erklärungen und Verweisen
Ich möchte gerne möglichst viel aus meinen Fehlern lernen können 
Live long and prosper
Kensen
Letztes Mal, als ich hier um Hilfe bitten wollte, fiel mir die Lösung während des Tippens des Posts ein, diesmal ist diese "Erleuchtung" leider ausgeblieben...
Ich poste zuerst den Code. Es ist ein Spiel, bei dem der Spieler eine Figur aus der Vogelperspektive lenkt. Später wird's drei verschiedene Modi, diverse Gegner und Waffen, sowie richtige Spielziele geben. Davon ist noch nicht viel implementiert.
Ich habe im Code selbst einiges an englischen Kommentaren, die ich gerne übersetzen könnte, sollte das gewünscht sein. Dazu hat es noch zwei Tags "PROBLEM XX" und einmal "FRAGE". Diese stehen nicht im Original-Code, sondern nur hier im Forum, um die problematischen Bereiche hervorzuheben.
Code: Alles auswählen
import pygame
import random
import os
import sys
import math
###############################################################################
#-------------------------PROGRAM VARIABLES-----------------------------------#
###############################################################################
#all variables concerning the build-up of the game
global screen
width = 1024
height = 768
###############################################################################
#-------------------------GAME VARIABLES--------------------------------------#
###############################################################################
#all variables concerning the game progress
weapon = 0#chosen weapon (1=blaster (unlimited ammo),2=autoblaster,3=rockets)
level = 1 #game starts at level 1; there will be a load function ingame
gamemode = 2 #0 = spacebattle, 1 = jump'n'run, 2 = strategic
shooting = False #turned True by the space key, keeps auto blaster firing
kup = kdown = kright = kleft = False #key events are handled by these
keystate = 0 #for movement keys
speed = 0#applicable in all three modes, just handled and passed differently
turnspeed = 0#applicable in modes 0 and 2, otherwise not passed at all
direction = 0 #the direction in gamemodes 0 and 2
pygame.mixer.pre_init(44100, -16, 2, 2048)
pygame.init()
screen = pygame.display.set_mode((width, height))
clock = pygame.time.Clock() #fps will be limited to 60
###############################################################################
#-------------------------SOUNDS----------------------------------------------#
###############################################################################
#function to load the soundfiles
def soundload(folder, name):
fullname = os.path.join("data\\"+folder, name)
try:
sound = pygame.mixer.Sound(fullname)
except:
raise SystemExit, "Could not load or play soundfile: ", name
return sound
global shotsounds
shotsounds = [soundload("sounds", "shotsmall.ogg")
,soundload("sounds", "shotauto.ogg")
,soundload("sounds", "shotrocket.ogg")]
###############################################################################
#-------------------------IMAGES----------------------------------------------#
###############################################################################
#function to load image files with transparency
def imgload(folder, name):
fullname = os.path.join("data\\"+folder, name)
try:
image = pygame.image.load(fullname)
except pygame.error, message:
print "Image not found: ", name
raise SystemExit, message
image = image.convert_alpha()
return image
#function to load image files without transparency
def imgloadnoalpha(folder, name):
filename = os.path.join("data\\"+folder, name)
try:
image = pygame.image.load(filename)
except pygame.error, message:
print "Image not found: ", name
raise SystemExit, message
image = image.convert()
return image
#The images are loadid into tuples here
global plstrat #the images for the strategy view
plstrat = [imgload("player", "stratmove1.png")
, imgload("player", "stratstand.png")
, imgload("player", "stratmove2.png")]
class PlayerClass(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.x = (width / 2)
self.y = (height / 2)
self.rect = pygame.rect.Rect(self.x,self.y,64,96)
self.imgnr = 0
self.imgmod = 0.15
self.rad = 0
def update(self, speed, direction, keystate):
tempo = speed
heading = direction
keys = keystate
if keystate > 0:
self.rad = heading * math.pi / 180
self.x += tempo * math.sin(self.rad)
self.y += tempo * math.cos(self.rad)
self.imgnr += self.imgmod
if self.imgnr > 3:
self.imgmod = -0.15
self.inum = 2.5
elif self.imgnr < 1:
self.imgmod = 0.15
self.inum = 1
if gamemode == 0:
pass#replace by imgload
elif gamemode == 1:
pass#replace by imgload
elif gamemode == 2:
if keys <= 0:
bild = plstrat[1]
elif keys > 0:
bild = plstrat[int(round(self.imgnr - 1))]
rotatedimg = pygame.transform.rotate(bild, self.rad) #PROBLEM 1
rect = bild.get_rect()
rect.center = (self.x,self.y)
screen.blit(bild,rect)
Player = PlayerClass()
plgrp = pygame.sprite.RenderPlain(Player)
###############################################################################
#-------------------------WELCOME TO THE GAME---------------------------------#
###############################################################################
running = True
while running:
clock.tick(60)
if gamemode == 0:
turnspeed = 50
pygame.display.set_caption("Outer Space")
elif gamemode == 1:
pygame.display.set_caption("World")
elif gamemode == 2:
turnspeed = 50
pygame.display.set_caption("Strategic View")
Player.moving = False#TEST
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.quit()
sys.exit()
## if not hasattr(event, "key"): #FRAGE 2
## continue
[b]#PROBLEM 3[/b]
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_KP8:
kup = True
keystate += 1
if event.key == pygame.K_KP2:
kdown = True
keystate += 1
if event.key == pygame.K_KP4:
kleft = True
keystate += 1
if event.key == pygame.K_KP6:
kright = True
keystate += 1
if event.key == pygame.K_ESCAPE:
running = False
pygame.quit()
sys.exit()
elif event.type == pygame.KEYUP:
if event.key == pygame.K_KP8:
kup = False
keystate -= 1
elif event.key == pygame.K_KP2:
kdown = False
keystate -= 1
elif event.key == pygame.K_KP4:
kleft = False
keystate -= 1
elif event.key == pygame.K_KP6:
kright = False
keystate -= 1
if kup:
if gamemode == 0:
speed += 0.8
elif gamemode == 1:
speed = 1
elif gamemode == 2:
if speed < 0:
speed += 0.8
elif speed >= 0:
speed = 0.8
elif kdown:
if gamemode == 0:
speed -= 0.3
elif gamemode == 1:
speed = -1
elif gamemode == 2:
if speed > 0:
speed -= 0.8
elif speed <= 0:
speed = -0.8
elif kright:
if gamemode == 0 or gamemode == 2:
direction += turnspeed
elif gamemode == 1:
pass
elif kleft:
if gamemode == 0 or gamemode == 2:
direction += -turnspeed
elif gamemode == 1:
pass
if keystate < 0:
keystate = 0
elif keystate == 0:
speed = 0 #Note: all three game modes need the speed variable
screen.fill((0, 0, 0))
plgrp.update(speed, direction, keystate)
pygame.display.update()
An der markierten Stelle in der PlayerClass.update-Funktion sollte eigentlich das Bild um self.rad gedreht werden, was aber nicht geschieht. Zwar bewegt sich die Spielfigur in die neue Richtung, das Bild wird aber nicht gedreht, sondern starrt starr an den unteren Bildschirmrand. Ich sitze jetzt Stunden daran und finde wirklich nicht heraus, was ich da falsch überlegt habe :/
Frage 2
Was würde diese Stelle mit dem "if not hasattr..." und dem "continue" bewirken, wenn sie nicht auskommentiert wäre? Ich weiss aus der Dokumentation, dass die Bedingung ist, dass das Objekt "event" das Attribut "key" nicht haben darf, damit das "continue" ausgelöst wird. Nur verstehe ich die Verwendung im konkreten Zusammenhang nicht genau. Unter welchen Bedingungen trifft das hier zu (oder eben nicht...)? Wohin zielt das "continue"? Sprich: Wo fährt der Interpreter weiter, wenn das "if not" eintrifft? Und wo fährt er weiter, wenn es nicht eintrifft? Da wäre ich dankbar für eine Klärung

Problem 3
Im folgenden Block müssten eigentlich die Tastenbefehle an die PlayerClass.update-Funktion übergeben werden. Das Problem ist nun, dass ich die Bewegen-Taste (NUMPAD 8 oder 2) loslassen muss, damit eine Richtungstaste verwendet werden kann. Halte ich die Bewegungstaste gedrückt, geht die Figur stur geradeaus, auch wenn ich eine Richtungstaste (NUMPAD 4 oder 6) drücke. Lasse ich die Bewegentaste los, kann ich die Drehung vollziehen (Bild dreht eben nicht mit, wie bei Problem 1 beschrieben) und danach mit der Bewegen-Taste in die entsprechende Richtung gehen. Warum funktioniert das nicht, während ich die jeweilige Bewegentaste gedrückt halte?
Bitte geizt nicht mit Erklärungen und Verweisen


Live long and prosper
Kensen