Permalänk
Medlem

Python - problem med if sats.

Hej!
Efter några år utan dator och kodande lyckades jag komma igång igen här i jul. Problemet är en if-sats just nu iaf. Jag pillar på en pongklon, hela koden är längst ner och if-satsen är i fetstil. Jag har klippt ut själva if-satsen nedan. Jag använder mig av VS-Code och har lagt till pygame.

Det jag vill är att för alla bollar som finns på spelplanen försvinner tills det bara finns minst en kvar. Hamnar en boll bakom en spelare blir det poäng och extra bollar försvinner. Jag tycker jag har provat varianter med parenteser, AND OR, flera if-satser. Tills jag hittade nedan lösning, den fungerade så jag provade ändra värden då slutade den fungera. Ändrade tillbaka och då fungerade det inte längre. Möjligheterna till att jag snurrat till det är oändliga.

Senast jag pillade var längesedan, enligt github 5 år sedan.

balls: Håller informationen om alla bollar. När spelaren trycker på högerknappen läggs en boll till i list balls.
ball.rect[0]: innehåller X positionen för bollen.

for ball in balls: if 20 > ball.rect[0] < 750 and len(balls) > 1: #if ball.rect[0] <= 20 and len(balls) > 1: print(ball) balls.remove(ball) ball.draw() ball.move(players) #ball.draw()

Klicka för mer information

#!/usr/bin/env python3 """ Pong Clone made by sjoinnzeem with pygame""" import pygame import random from random import randint class Field: """Holds the size and position of the field""" #Maybe it should be a function instead def __init__(self, gameDisplay, fieldXPos, fieldYPos, fieldWidth, fieldHeight, fieldBorderSize): self.fieldXPos = fieldXPos self.fieldYPos = fieldYPos self.fieldWidth = fieldWidth self.fieldHeight = fieldHeight self.fieldBorderSize = fieldBorderSize self.gameDisplay = gameDisplay def draw(self): """Draws the field to the gameDisplay""" pygame.draw.rect(self.gameDisplay, (0, 0, 255), [self.fieldXPos, self.fieldYPos, self.fieldWidth, self.fieldHeight], self.fieldBorderSize) def score(self, player1Score, player2Score): """Handels the score of the players""" self.player1Score = player1Score self.player2Score = player2Score def addScore(self, ballPosition): """Add a score to the current standing in the match""" if ballPosition >= 775: self.player1Score += 1 elif ballPosition <= 15: self.player2Score += 1 def drawScore(self): """Draws the score to the screen to the field""" font=pygame.font.Font(None, 100) scoretext=font.render(str(self.player1Score) + ' : ' + str(self.player2Score), 1, (255, 255, 255)) self.gameDisplay.blit(scoretext, (350, 20)) class Paddle(object): """Holds size and position of the paddle also moves and draws it to the display""" def __init__(self, gameDisplay, paddleXPos, paddleYPos, paddleWidth, paddleHeight): self.paddleXPos = paddleXPos self.paddleYPos = paddleYPos self.gameDisplay = gameDisplay self.paddleWidth = paddleWidth self.paddleHeight = paddleHeight self.direction = 0 def draw(self): """Draws the paddle to the display""" self.move(self.direction) pygame.draw.rect(self.gameDisplay, (255, 0, 0), [self.paddleXPos, self.paddleYPos, self.paddleWidth, self.paddleHeight]) def move(self, direction): """Moves the paddle according to direction""" self.direction = direction self.paddleYPos += self.direction if self.paddleYPos <= 100: self.paddleYPos = 100 self.direction = 0 if self.paddleYPos >= 490: self.paddleYPos = 488 self.direction = 0 @property def rect(self): return pygame.Rect(self.paddleXPos, self.paddleYPos, self.paddleWidth, self.paddleHeight) class Ball(object): """Holds size and position""" def __init__(self, gameDisplay, ballXPos, ballYPos, xDirection, yDirection): self.ballXPos = self.ballStartXPos = ballXPos self.ballYPos = self.ballStartYPos = ballYPos self.gameDisplay = gameDisplay self.xDirection = xDirection self.yDirection = yDirection self.xSpeed = 5 self.ySpeed = 5 def draw(self): """Draws the ball to the screen""" pygame.draw.rect(self.gameDisplay, (255, 0, 0), [self.ballXPos, self.ballYPos, 10, 10]) def move(self, obstacles): """Direction and speed of the ball""" self.ballXPos = self.ballXPos + (self.xSpeed * self.xDirection) self.ballYPos = self.ballYPos + (self.ySpeed * self.yDirection) if self.ballXPos >= 780: print('xPos= ' + str(self.ballXPos)) self.xDirection = -self.xDirection self.reset() elif self.ballXPos <= 10: print('xPos= ' + str(self.ballXPos)) self.xDirection = -self.xDirection self.reset() if self.ballYPos >= 580: self.yDirection = -self.yDirection elif self.ballYPos <= 100: self.yDirection = -self.yDirection if self.rect.collidelist(obstacles) != -1: """collition between ball and paddle""" if self.ballXPos <= 50 or self.ballXPos >= 750: self.xDirection = self.xDirection self.yDirection = -self.yDirection elif self.ballXPos >= 51 or self.ballXPos <=751: self.xDirection = -self.xDirection def reset(self): """Resets the ball to start position""" self.ballXPos = self.ballStartXPos self.ballYPos = self.ballStartYPos @property def rect(self): return pygame.Rect(self.ballXPos, self.ballYPos, 10, 10) def windowSetup(): """Setting all initial variables and functions for start up""" pygame.display.set_caption('Pong Clone') windowWidth = 800 windowHeight = 600 def texts(gameDisplay, score): font=pygame.font.Font(None,30) scoretext=font.render("Score:"+str(score), 1,(255,255,255)) gameDisplay.blit(scoretext, (500, 457)) def main(): """Pong Clone that uses pygame""" pygame.init() windowSetup() clock = pygame.time.Clock() gameExit = False gameDisplay = pygame.display.set_mode((800, 600)) paddleWidth = 10 paddleHeight = 100 xPos = 400 yPos = 300 court = Field(gameDisplay, 8,98, 782, 492, 2) court.score(0, 0) player1 = Paddle(gameDisplay, 50, 250, paddleWidth, paddleHeight) player2 = Paddle(gameDisplay, 750, 250, paddleWidth, paddleHeight) ball0 = Ball(gameDisplay, 400, 295, 1, 1) players = [player1, player2] balls = [ball0] player1.draw() player2.draw() ball0.draw() print(randint(0, 10)) while not gameExit: #Main game loop for event in pygame.event.get(): #Event handler if event.type == pygame.QUIT: gameExit = True if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: gameExit = True elif event.key == pygame.K_LEFT: xPos -= 5 print(len(balls)) elif event.key == pygame.K_RIGHT: xPos += 5 balls.append(Ball(gameDisplay, 400, 295, 1, 1)) elif event.key == pygame.K_UP: yPos -= 5 player1.move(-5) player2.move(-5) elif event.key == pygame.K_DOWN: yPos += 5 player1.move(5) player2.move(5) if event.type == pygame.KEYUP: if event.key == pygame.K_UP: yPos -= 5 player1.move(0) player2.move(0) elif event.key == pygame.K_DOWN: yPos += 5 player1.move(0) player2.move(0) gameDisplay.fill((0, 0, 0)) court.draw() court.drawScore() pygame.draw.rect(gameDisplay, (255, 0, 0), [xPos, yPos, 10, 10], 2) for player in players: player.draw() for ball in balls: if 20 > ball.rect[0] < 750 and len(balls) > 1: #if ball.rect[0] <= 20 and len(balls) > 1: print(ball) balls.remove(ball) ball.draw() ball.move(players) #ball.draw() court.addScore(ball.rect[0]) pygame.display.update() clock.tick(30) pygame.quit() quit() if __name__ == "__main__": main()

Visa mer
Visa signatur

Laptop: HP Elitebook 640 G9
Server: HP Microserver N54L, 8 GB ram, 8 TB hd.

Permalänk

Tror det kan handla om att du försöker ta bort element i en lista(?) du använder i en loop. En lösning är att du sparar de bollar du vill ha kvar i en ny lista. Sen är 20 > ball.rect[0] < 750 == 20 > ball.rect[0]

Permalänk
Medlem

Skulle tro att du har flera logiska del i den fetmarkerade delen:

if 20 > ball.rect[0] < 750 and len(balls) > 1:

Till att börja med så gissar jag att du har ett teckenfel på din första jämförelse. Utan att ha läst resten av koden så gissar jag att det du vill göra är att kolla om ball.rect[0] ligger mellan 20 och 750, men du har använt ett "större än" (>) tecken där det i sådana fall borde varit ett "mindre än" (<) tecken.

Men även med denna ändring så känns inte detta som giltig kod, eller åtminstone så gör den nog inte alls vad du förväntar dig. Har inte kollat vad som gäller specifikt för Python men det brukar inte gå att göra flera numeriska jämförelser i ett uttryck. Jag skulle gissa att den vänstra jämförelsen att utföras först, och sedan kommer resultatet av denna att matas in i nästa jämförelse. Dvs det värde som går in i den andra jämförelsen på vänstersidan är inte ball.rect[0], utan kommer vara True eller False (som då bör behandlas som 1 eller 0 vilka bägge alltid är mindre 750).

Börja med att dela upp uttrycket i två jämförelser och se hur koden beter sig:

if 20 < ball.rect[0] and ball.rect[0] < 750 and len(balls) > 1:

Visa signatur

Mostly Harmless

Permalänk
Medlem
Skrivet av Mayhem SWE:

Har inte kollat vad som gäller specifikt för Python men det brukar inte gå att göra flera numeriska jämförelser i ett uttryck.

Python hanterar faktiskt t.ex. x < y < z som man förväntar sig matematiskt (se dokumentationen), till skillnad från många andra språk. Så att bara vända på den första jämförelsen borde vara tillräckligt för att det ska fungera i Python.

Permalänk
Medlem

Hej!

Tack för alla era svar. Provat så ögonen blöder, vända tecken och olika ordningar men blir inte klok på det! Jag läser och läser och det borde gå med x < y < z men jag får det inte att fungera. Jag fick följande att fungera iaf så som jag tänkte mig det hela. Kommer säkert på något listigt så jag får ändra det.

for ball in balls: if ball.rect[0] < 20 or ball.rect[0] > 770: court.addScore(ball.rect[0]) if len(balls) > 1: balls.remove(ball) ball.draw() ball.move(players)

Ändå så gnager det varför det inte fungerar men som sagt har jag tagit upp kodning i 3dagar efter ett långt uppehåll.
OS Windows 11
Python 3.10.9 via microsoft store
pygame installerat med pip
VS Code
Version: 1.74.2 (user setup)
Commit: e8a3071ea4344d9d48ef8a4df2c097372b0c5161
Date: 2022-12-20T10:29:14.590Z
Electron: 19.1.8
Chromium: 102.0.5005.167
Node.js: 16.14.2
V8: 10.2.154.15-electron.0
OS: Windows_NT x64 10.0.22621
Sandboxed: No

Visa signatur

Laptop: HP Elitebook 640 G9
Server: HP Microserver N54L, 8 GB ram, 8 TB hd.

Permalänk
Medlem
Skrivet av zeem:

Hej!

Tack för alla era svar. Provat så ögonen blöder, vända tecken och olika ordningar men blir inte klok på det! Jag läser och läser och det borde gå med x < y < z men jag får det inte att fungera. Jag fick följande att fungera iaf så som jag tänkte mig det hela. Kommer säkert på något listigt så jag får ändra det.

for ball in balls: if ball.rect[0] < 20 or ball.rect[0] > 770: court.addScore(ball.rect[0]) if len(balls) > 1: balls.remove(ball) ball.draw() ball.move(players)

Ändå så gnager det varför det inte fungerar men som sagt har jag tagit upp kodning i 3dagar efter ett långt uppehåll.
OS Windows 11
Python 3.10.9 via microsoft store
pygame installerat med pip
VS Code
Version: 1.74.2 (user setup)
Commit: e8a3071ea4344d9d48ef8a4df2c097372b0c5161
Date: 2022-12-20T10:29:14.590Z
Electron: 19.1.8
Chromium: 102.0.5005.167
Node.js: 16.14.2
V8: 10.2.154.15-electron.0
OS: Windows_NT x64 10.0.22621
Sandboxed: No

Borde ju vara rätt, du ska ju inte ha ett värde in between så att säga (x < v < y). Den ska räkna poäng ifall rect är under 20 eller över 770 (v < x or v > y).

Visa signatur

AMD 7800X3D | ASUS TUF X670E-PLUS | Corsair Vengeance DDR5 32GB EXPO | ASUS TUF 4090 OC 24GB |
Noctua NH-U12A | Corsair 4000D | Corsair AX1200W | Steelseries Apex 7 | Steelseries Sensei Ten | ASUS VG35VQ

https://github.com/Mariusz89B