Dateien nach "/" hochladen

This commit is contained in:
2026-09-10 13:57:49 +00:00
parent 49c80ef0ea
commit 11349988f7
3 changed files with 714 additions and 23 deletions
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 611 B

+27 -23
View File
@@ -14,9 +14,7 @@ class Kart:
self.position = [0, 0]
self.acceleration = acceleration
self.lastRam = 0
def __str__(self):
return "Das Kart heißt:" + self.name
self.knockback = [0, 0]
def acc(self, brk): #brk is true or false
if brk == False:
@@ -33,44 +31,50 @@ class Kart:
self.rotation += dir * self.handling
def pos(self):
# normale Eigenbewegung
self.position[0] += math.cos(math.radians(self.rotation)) * self.speed
self.position[1] += math.sin(math.radians(self.rotation)) * self.speed
# Bewegung durch Rammen
self.position[0] += self.knockback[0]
self.position[1] += self.knockback[1]
# Knockback langsam abbauen
self.knockback[0] *= 0.90
self.knockback[1] *= 0.90
if self.speed > 5:
self.speed *= 0.98
def ram(self, other):
current = time.time()
if current - self.lastRam < 1:
return
self.lastRam = current
dx = self.position[0] - other.position[0]
dy = self.position[1] - other.position[1]
dx = other.position[0] - self.position[0]
dy = other.position[1] - self.position[1]
distance = math.sqrt(dx**2 + dy**2)
if distance <= 200 and distance > 0:
if distance > 200 or distance == 0:
return
# Richtung vom anderen Kart zum eigenen Kart
direction_x = dx / distance
direction_y = dy / distance
self.lastRam = current
# Beide Karts bekommen eine schnelle Bewegung
# aufeinander zu bzw. vom Zusammenstoß weg.
ramSpeed = 12
# Richtung VOM eigenen Kart ZUM Gegner
direction_x = dx / distance
direction_y = dy / distance
self.position[0] += direction_x * ramSpeed
self.position[1] += direction_y * ramSpeed
# Das eigene Kart macht einen schnellen Satz zum Gegner
self.speed = 10
other.position[0] -= direction_x * ramSpeed
other.position[1] -= direction_y * ramSpeed
# Gegner fliegt in Bewegungsrichtung des Angreifers weg
knockbackSpeed = 18
# Zufällige Drehung wie vorher
randrot = random.randint(-20, 20)
self.rotation += randrot
other.rotation -= randrot
other.knockback[0] = direction_x * knockbackSpeed
other.knockback[1] = direction_y * knockbackSpeed
class Item:
+687
View File
@@ -0,0 +1,687 @@
import pygame
import random
import time
from kart import Kart, Item
# -------------------------
# Einstellungen
# -------------------------
WIDTH = 1000
HEIGHT = 700
FPS = 60
BACKGROUND = (40, 40, 40)
import pygame
import random
import time
from pathlib import Path
from kart import Kart, Item
# -------------------------
# Einstellungen
# -------------------------
WIDTH = 1000
HEIGHT = 700
FPS = 60
BACKGROUND = (40, 40, 40)
# Breite des Kart-Bildes auf dem Bildschirm.
# Die Höhe wird automatisch passend zum Seitenverhältnis berechnet.
KART_IMAGE_WIDTH = 60
# Falls die Vorderseite von car.jpg nicht nach rechts zeigt, kann dieser
# Wert angepasst werden, z. B. 90, -90 oder 180.
KART_IMAGE_ROTATION_OFFSET = 0
# Das Originalbild und bereits eingefärbte Varianten werden zwischengespeichert.
CAR_IMAGE = None
CAR_IMAGE_CACHE = {}
# -------------------------
# Hilfsfunktionen zum Zeichnen
# -------------------------
def load_car_image():
"""Lädt car.jpg aus demselben Ordner wie main.py."""
global CAR_IMAGE
image_path = Path(__file__).resolve().with_name("car.jpg")
image = pygame.image.load(str(image_path)).convert_alpha()
# Seitenverhältnis des Bildes beibehalten.
scale = KART_IMAGE_WIDTH / image.get_width()
new_height = max(1, round(image.get_height() * scale))
CAR_IMAGE = pygame.transform.smoothscale(
image,
(KART_IMAGE_WIDTH, new_height)
)
def get_colored_car_image(color):
"""
Gibt car.jpg in der gewünschten Kartfarbe zurück.
Reine Grautöne bleiben unverändert. Rote Bereiche werden durch die
gewünschte Farbe ersetzt. Ein kleiner Toleranzbereich sorgt dafür,
dass auch durch JPEG-Kompression veränderte rote Randpixel mitgefärbt
werden.
"""
color = tuple(color)
if color in CAR_IMAGE_CACHE:
return CAR_IMAGE_CACHE[color]
image = CAR_IMAGE.copy()
pixels = pygame.PixelArray(image)
for x in range(image.get_width()):
for y in range(image.get_height()):
pixel = image.unmap_rgb(pixels[x, y])
r, g, b = pixel.r, pixel.g, pixel.b
# Grautöne haben ungefähr r == g == b.
# Nur deutlich rotlastige Pixel werden eingefärbt.
gray = (g + b) / 2
redness = r - max(g, b)
if redness > 10:
# Stärke des roten Anteils.
# (255, 0, 0) -> 1.0, rote Übergangspixel entsprechend weniger.
strength = min(1.0, max(0.0, (r - gray) / 255.0))
new_r = round(gray + (color[0] - gray) * strength)
new_g = round(gray + (color[1] - gray) * strength)
new_b = round(gray + (color[2] - gray) * strength)
pixels[x, y] = (new_r, new_g, new_b)
del pixels
CAR_IMAGE_CACHE[color] = image
return image
def draw_kart(screen, kart, car_image, car_cache):
color_key = tuple(kart.color)
# Eingefärbtes Bild nur einmal pro Farbe erstellen
if color_key not in car_cache:
colored = colorize_car(car_image, kart.color)
# Vergrößern ohne Glättung -> Pixel-Look bleibt erhalten
scale = 4
new_size = (
colored.get_width() * scale,
colored.get_height() * scale
)
car_cache[color_key] = pygame.transform.scale(
colored,
new_size
)
surface = car_cache[color_key]
# Kart entsprechend seiner Rotation drehen
rotated = pygame.transform.rotate(surface, -kart.rotation)
rect = rotated.get_rect(
center=(int(kart.position[0]), int(kart.position[1]))
)
screen.blit(rotated, rect)
# -------------------------
# Pool zeichnen
# -------------------------
def draw_pool(screen, pool):
pygame.draw.ellipse(
screen,
pool.color,
(
int(pool.position[0] - pool.size),
int(pool.position[1] - pool.size / 2),
int(pool.size * 2),
int(pool.size)
)
)
def colorize_car(image, color):
colored = image.copy()
for x in range(colored.get_width()):
for y in range(colored.get_height()):
r, g, b, a = colored.get_at((x, y))
# Nur reines Rot wird durch die Kart-Farbe ersetzt
if (r, g, b) == (255, 0, 0):
colored.set_at((x, y), (*color, a))
return colored
# -------------------------
# Main
# -------------------------
def main():
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Kart Game")
# car.jpg erst nach dem Erzeugen des Fensters laden, damit convert_alpha()
# das Bild für die aktuelle Anzeige optimieren kann.
load_car_image()
clock = pygame.time.Clock()
car_image = pygame.image.load("car.png").convert_alpha()
car_cache = {}
# -------------------------
# Karts erzeugen
# -------------------------
kart1 = Kart(
"Player 1",
(255, 50, 50),
acceleration=0.2,
vMax=5,
handling=4
)
kart2 = Kart(
"Player 2",
(50, 100, 255),
acceleration=0.2,
vMax=5,
handling=4
)
# Startpositionen
kart1.position = [250, 350]
kart1.rotation = 0
kart2.position = [750, 350]
kart2.rotation = 180
# -------------------------
# Pool
# -------------------------
pool = None
# Zeitpunkt, wann der nächste Pool erscheint
nextPoolTime = time.time() + random.uniform(3, 8)
running = True
while running:
# -------------------------
# Events
# -------------------------
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# -------------------------
# Pool erzeugen / entfernen
# -------------------------
currentTime = time.time()
# Wenn momentan kein Pool existiert
# und die Wartezeit vorbei ist
if pool is None and currentTime >= nextPoolTime:
pool = Item("pool")
pool.typ()
# Zufällige Position
pool.position = [
random.randint(80, WIDTH - 80),
random.randint(80, HEIGHT - 80)
]
# Zufällige Größe
pool.size = random.randint(40, 80)
# Pool bleibt unterschiedlich lange sichtbar
poolEndTime = currentTime + random.uniform(3, 7)
# Pool verschwinden lassen
if pool is not None and currentTime >= poolEndTime:
pool = None
# Unregelmäßige Zeit bis zum nächsten Pool
nextPoolTime = currentTime + random.uniform(3, 10)
keys = pygame.key.get_pressed()
# -------------------------
# Kart 1
# WASD + E
# -------------------------
# W = Gas
if keys[pygame.K_w]:
kart1.acc(False)
# S = Rückwärts / Bremsen
elif keys[pygame.K_s]:
kart1.acc(True)
# Wenn kein Gas/Bremse -> langsam abbremsen
else:
kart1.speed *= 0.98
# A = links
if keys[pygame.K_a]:
kart1.turn(-1)
# D = rechts
if keys[pygame.K_d]:
kart1.turn(1)
# E = Rammen
if keys[pygame.K_e]:
kart1.ram(kart2)
# -------------------------
# Kart 2
# IJKL + O
# -------------------------
# I = Gas
if keys[pygame.K_i]:
kart2.acc(False)
# K = Rückwärts / Bremsen
elif keys[pygame.K_k]:
kart2.acc(True)
else:
kart2.speed *= 0.98
# J = links
if keys[pygame.K_j]:
kart2.turn(-1)
# L = rechts
if keys[pygame.K_l]:
kart2.turn(1)
# O = Rammen
if keys[pygame.K_o]:
kart2.ram(kart1)
# -------------------------
# Position aktualisieren
# -------------------------
kart1.pos()
kart2.pos()
# -------------------------
# Bildschirm verlassen?
# -> auf andere Seite wechseln
# -------------------------
# Abstand zum Bildschirmrand
border = 20
for kart in [kart1, kart2]:
# Linker Rand
if kart.position[0] < border:
kart.position[0] = border
# Rechter Rand
if kart.position[0] > WIDTH - border:
kart.position[0] = WIDTH - border
# Oberer Rand
if kart.position[1] < border:
kart.position[1] = border
# Unterer Rand
if kart.position[1] > HEIGHT - border:
kart.position[1] = HEIGHT - border
# -------------------------
# Zeichnen
# -------------------------
screen.fill(BACKGROUND)
# Pool zeichnen
if pool is not None:
draw_pool(screen, pool)
draw_kart(screen, kart1, car_image, car_cache)
draw_kart(screen, kart2, car_image, car_cache)
# Namen anzeigen
font = pygame.font.Font(None, 28)
text1 = font.render(
f"{kart1.name}: {kart1.speed:.1f}",
True,
kart1.color
)
text2 = font.render(
f"{kart2.name}: {kart2.speed:.1f}",
True,
kart2.color
)
screen.blit(text1, (20, 20))
screen.blit(text2, (20, 50))
pygame.display.flip()
# FPS
clock.tick(FPS)
pygame.quit()
if __name__ == "__main__":
main()
# -------------------------
# Hilfsfunktion zum Zeichnen
# -------------------------
def draw_kart(screen, kart):
# Kart als Rechteck
width = 40
height = 25
surface = pygame.Surface((width, height), pygame.SRCALPHA)
pygame.draw.rect(surface, kart.color, (0, 0, width, height))
# Richtung des Karts
rotated = pygame.transform.rotate(surface, -kart.rotation)
rect = rotated.get_rect(
center=(int(kart.position[0]), int(kart.position[1]))
)
screen.blit(rotated, rect)
# -------------------------
# Pool zeichnen
# -------------------------
def draw_pool(screen, pool):
pygame.draw.ellipse(
screen,
pool.color,
(
int(pool.position[0] - pool.size),
int(pool.position[1] - pool.size / 2),
int(pool.size * 2),
int(pool.size)
)
)
def apply_pool_slow(kart, pool):
if pool is None:
return
dx = kart.position[0] - pool.position[0]
dy = kart.position[1] - pool.position[1]
# Prüfen, ob das Kart innerhalb der Ellipse liegt
inside = (
(dx / pool.size) ** 2
+ (dy / (pool.size / 2)) ** 2
<= 1
)
if inside:
kart.speed *= 0.8
# -------------------------
# Main
# -------------------------
def main():
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Kart Game")
clock = pygame.time.Clock()
# -------------------------
# Karts erzeugen
# -------------------------
kart1 = Kart(
"Player 1",
(255, 50, 50),
acceleration=0.2,
vMax=5,
handling=4
)
kart2 = Kart(
"Player 2",
(50, 100, 255),
acceleration=0.2,
vMax=5,
handling=4
)
# Startpositionen
kart1.position = [250, 350]
kart1.rotation = 0
kart2.position = [750, 350]
kart2.rotation = 180
# -------------------------
# Pool
# -------------------------
pool = None
# Zeitpunkt, wann der nächste Pool erscheint
nextPoolTime = time.time() + random.uniform(3, 8)
running = True
while running:
# -------------------------
# Events
# -------------------------
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# -------------------------
# Pool erzeugen / entfernen
# -------------------------
currentTime = time.time()
# Wenn momentan kein Pool existiert
# und die Wartezeit vorbei ist
if pool is None and currentTime >= nextPoolTime:
pool = Item("pool")
pool.typ()
# Zufällige Position
pool.position = [
random.randint(80, WIDTH - 80),
random.randint(80, HEIGHT - 80)
]
# Zufällige Größe
pool.size = random.randint(40, 80)
# Pool bleibt unterschiedlich lange sichtbar
poolEndTime = currentTime + random.uniform(3, 7)
# Pool verschwinden lassen
if pool is not None and currentTime >= poolEndTime:
pool = None
# Unregelmäßige Zeit bis zum nächsten Pool
nextPoolTime = currentTime + random.uniform(3, 10)
keys = pygame.key.get_pressed()
# -------------------------
# Kart 1
# WASD + E
# -------------------------
# W = Gas
if keys[pygame.K_w]:
kart1.acc(False)
# S = Rückwärts / Bremsen
elif keys[pygame.K_s]:
kart1.acc(True)
# Wenn kein Gas/Bremse -> langsam abbremsen
else:
kart1.acc(None)
# A = links
if keys[pygame.K_a]:
kart1.turn(-1)
# D = rechts
if keys[pygame.K_d]:
kart1.turn(1)
# E = Rammen
if keys[pygame.K_e]:
kart1.ram(kart2)
# -------------------------
# Kart 2
# IJKL + O
# -------------------------
# I = Gas
if keys[pygame.K_i]:
kart2.acc(False)
# K = Rückwärts / Bremsen
elif keys[pygame.K_k]:
kart2.acc(True)
else:
kart1.acc(None)
# J = links
if keys[pygame.K_j]:
kart2.turn(-1)
# L = rechts
if keys[pygame.K_l]:
kart2.turn(1)
# O = Rammen
if keys[pygame.K_o]:
kart2.ram(kart1)
# -------------------------
# Position aktualisieren
# -------------------------
# Pool-Effekt
apply_pool_slow(kart1, pool)
apply_pool_slow(kart2, pool)
# Position aktualisieren
kart1.pos()
kart2.pos()
# -------------------------
# Bildschirm verlassen?
# -> auf andere Seite wechseln
# -------------------------
# Abstand zum Bildschirmrand
border = 20
for kart in [kart1, kart2]:
# Linker Rand
if kart.position[0] < border:
kart.position[0] = border
# Rechter Rand
if kart.position[0] > WIDTH - border:
kart.position[0] = WIDTH - border
# Oberer Rand
if kart.position[1] < border:
kart.position[1] = border
# Unterer Rand
if kart.position[1] > HEIGHT - border:
kart.position[1] = HEIGHT - border
# -------------------------
# Zeichnen
# -------------------------
screen.fill(BACKGROUND)
# Pool zeichnen
if pool is not None:
draw_pool(screen, pool)
draw_kart(screen, kart1)
draw_kart(screen, kart2)
# Namen anzeigen
font = pygame.font.Font(None, 28)
text1 = font.render(
f"{kart1.name}: {kart1.speed:.1f}",
True,
kart1.color
)
text2 = font.render(
f"{kart2.name}: {kart2.speed:.1f}",
True,
kart2.color
)
screen.blit(text1, (20, 20))
screen.blit(text2, (20, 50))
pygame.display.flip()
# FPS
clock.tick(FPS)
pygame.quit()
if __name__ == "__main__":
main()