2017-06-15 2 views
1

Ich mache das Pong-Spiel. Aber statt 2 Spielern mache ich es für 4 (eins auf jeder Seite des Bildschirms). Ich muss den Ball nach dem Zufallsprinzip "wählen", in welche Richtung er gehen muss.pygame: Zufällige Richtung eines Balles zu Beginn des Spiels

import pygame 
import random 

class Ball(object): 
    @classmethod 
    def init(cls, SCREEN_WIDTH, SCREEN_HEIGHT): 
     cls.radius = 20 
     cls.centerx = SCREEN_WIDTH*0.5 
     cls.centery = SCREEN_HEIGHT*0.5 

     cls.rect = pygame.Rect(cls.centerx - cls.radius, 
           cls.centery - cls.radius, 
           cls.radius * 2, 
           cls.radius * 2) 

    # x , y 
    cls.direction = [random.choice([1, -1]), random.choice([1, -1])] 
    cls.speed = [5, 8] # x, y 

    # left, right, top, bottom 
    cls.hit_edge = [False, False, False, False] 

    @classmethod 
    def update(cls, player1, player2, player3, player4, SCREEN_WIDTH, 
      SCREEN_HEIGHT): 
     cls.centerx += cls.direction[0] * cls.speed[0] 
     cls.centery += cls.direction[1] * cls.speed[1] 

     cls.rect.center = (cls.centerx, cls.centery) 

     #detects if someone losses 
     if cls.rect.left <= 0: 
      cls.hit_edge[0] = True 
     elif cls.rect.right >= SCREEN_WIDTH-1: 
      cls.hit_edge[1] = True 
     elif cls.rect.top <= 0: 
      cls.hit_edge[2] = True 
     elif cls.rect.bottom >= SCREEN_HEIGHT-1: 
      cls.hit_edge[3] = True 

     #detects collision between players & the ball 
     if cls.rect.colliderect(player1.rect): 
      cls.direction[0] = 1 
      cls.up_speed() 
     elif cls.rect.colliderect(player2.rect): 
      cls.direction[0] = -1 
      cls.up_speed() 
     elif cls.rect.colliderect(player3.rect): 
      cls.direction[1] = 1 
      cls.up_speed() 
     elif cls.rect.colliderect(player4.rect): 
      cls.direction[1] = -1 
      cls.up_speed() 

    @classmethod 
    def up_speed(cls): 
     cls.speed[0] += random.uniform(0, 0.25) 
     cls.speed[1] += random.uniform(0, 0.25) 

    @classmethod 
     def render(cls, SCREEN, color): 
     pygame.draw.circle(SCREEN, color, cls.rect.center, cls.radius, 0) 

Rechnung zu nehmen: Ich hatte die Idee, eine „0“ in jedem random.choice() hinzuzufügen, obwohl, wenn ich am Anfang dieses einzige Funktion zu tun, dann wird es nicht in der Lage sein, sich zu bewegen die Achse wo die "0" ist. Auch ich habe zwei Arten von Geschwindigkeiten in X und Y, könnte gelöst werden, indem Sie eine "0.1" in random.choice(), aber dies würde machen, wenn das Spiel beginnt der Ball geht sehr langsam. Wie wäre es, wenn der Ball in eine zufällige Richtung startet (unter Berücksichtigung, dass die Geschwindigkeit des Balls beim Start für alle Spieler gleich sein muss. Wenn der Ball am Anfang nach links geht und später (in einem anderen) Spiel) wenn es anfängt, aber der Ball steigt, muss er mit der gleichen Geschwindigkeit gehen)

+1

Es ist wirklich merkwürdig, dass Sie '@ classmethod' überall verwenden. Wo hast du das gelernt? Es hat einige spezielle Zwecke wie das Erstellen alternativer Konstruktoren, aber es sollte nicht für jede Methode einer Klasse verwendet werden. – skrx

Antwort

1

Das mag ein wenig überkomplizierende Dinge sein, aber wenn du die Geschwindigkeit kennst, die der Ball mit insgesamt beginnen soll, könntest du verwenden so etwas wie diese:

  1. generieren Zufallszahl zwischen 0-1
  2. angle = 360 * Zufallszahl
  3. xSpeed = startSpeed * sin (angle)
  4. ySpeed = startSpeed * cos (angle)

Dies bedeutet, dass der Ball immer mit der gleichen Geschwindigkeit reisen. Das einzige, was zufällig ist, ist die Richtung, in der es sich bewegt.

+0

Das ist der richtige Weg. Ein paar Tipps: 'random.uniform (0, 360)' gibt einen Gleitkommawert zwischen 0 und 360 zurück. Sie müssen den Winkel in Radianten umwandeln, bevor Sie ihn an sin und cos 'math.sin übergeben (math.radians (angle)) 'oder alternativ einfach einen Winkel in Radianten erzeugen' angle = random.uniform (0, 2 * math.pi) '. Du brauchst sin für die ySpeed ​​und cos für die xSpeed, aber das ist hier eigentlich egal. Und wenn Sie zu Vektoren wechseln, müssen Sie nicht einmal mehr die x- und y-Geschwindigkeit berechnen und den Vektor einfach drehen. – skrx

0

Ich empfehle Vektoren zu verwenden. Für die Geschwindigkeit können Sie einfach eine beliebige Startgeschwindigkeit wie (8, 0) wählen und dann den Vektor um einen zufälligen Winkel drehen.

position = pg.math.Vector2(100, 200) 
velocity = pg.math.Vector2(8, 0).rotate(random.randrange(360)) 

die Position zu aktualisieren:

position += velocity 

Hier ist ein Beispielprogramm, das Kugeln mit gelegentlicher Farbe und Geschwindigkeit laicht.

import sys 
import math 
from random import randrange 
import pygame as pg 


class Ball(pg.sprite.Sprite): 

    def __init__(self, pos, *groups): 
     super().__init__(groups) 
     self.image = pg.Surface((30, 30), pg.SRCALPHA) 
     col = randrange(256), randrange(256), randrange(256) 
     pg.draw.circle(self.image, col, (15, 15), 15) 
     self.rect = self.image.get_rect(center=pos) 
     self.vel = pg.math.Vector2(8, 0).rotate(randrange(360)) 
     self.pos = pg.math.Vector2(pos) 

    def update(self): 
     self.pos += self.vel 
     self.rect.center = self.pos 
     if self.rect.left < 0 or self.rect.right > 640: 
      self.vel.x *= -1 
     if self.rect.top < 0 or self.rect.bottom > 480: 
      self.vel.y *= -1 


def main(): 
    screen = pg.display.set_mode((640, 480)) 
    clock = pg.time.Clock() 
    sprite_group = pg.sprite.Group() 
    ball = Ball((320, 240), sprite_group) 

    done = False 

    while not done: 
     for event in pg.event.get(): 
      if event.type == pg.QUIT: 
       done = True 
      elif event.type == pg.MOUSEBUTTONDOWN: 
       sprite_group.add(Ball((320, 240))) 

     sprite_group.update() 
     screen.fill((30, 30, 30)) 
     sprite_group.draw(screen) 

     pg.display.flip() 
     clock.tick(30) 


if __name__ == '__main__': 
    pg.init() 
    main() 
    pg.quit() 
    sys.exit() 
+0

Wie Sie sehen, brauchen Sie nicht '@ classmethod' und können' self' anstelle von 'cls' verwenden, was auf die Instanz und nicht auf die Klasse verweist. – skrx

Verwandte Themen