]> Skullheadx's Git Forge - fruit-ninja.git/commitdiff
fixed performance on checking if split is good
authorSkullheadx <94652084+Skullheadx@users.noreply.github.com>
Tue, 4 Jul 2023 21:18:10 +0000 (17:18 -0400)
committerSkullheadx <94652084+Skullheadx@users.noreply.github.com>
Tue, 4 Jul 2023 21:18:10 +0000 (17:18 -0400)
13 files changed:
README.md
assets/bomb.png
assets/knife.png [new file with mode: 0644]
bomb.py
effect.py
fruit.py
game.py
high_score.txt
image.png [deleted file]
main.py
menu.py
player.py
setup.py

index a9bee68a751335c7befdb995aa7a68b3e267ec43..7db37d0374d0057ac5be653e10fd381cfab8653d 100644 (file)
--- a/README.md
+++ b/README.md
@@ -22,4 +22,8 @@ https://pixabay.com/sound-effects/sub-bass-4-secondsssss-6241/
 
 ## Game background image made with help from https://www.deviantart.com/sadfacerl/art/WoodTexture-748548579
 
-## Blood Splatter Effect https://bluerosesonata.itch.io/free-blood-splatter-cgsfx
\ No newline at end of file
+## Blood Splatter Effect https://bluerosesonata.itch.io/free-blood-splatter-cgsfx
+
+
+Bomb https://www.rawpixel.com/image/6287121/png-public-domain-black
+Knife https://wandering-ghost.itch.io/horror-knifes-sprites
\ No newline at end of file
index 5418bee0e590c0c97b23511dd4f30ad7a3d8fc41..5d873bbbe5a9e360c7102f30134330a37cb1da32 100644 (file)
Binary files a/assets/bomb.png and b/assets/bomb.png differ
diff --git a/assets/knife.png b/assets/knife.png
new file mode 100644 (file)
index 0000000..832c934
Binary files /dev/null and b/assets/knife.png differ
diff --git a/bomb.py b/bomb.py
index 9fae48f5ec21cd33c748a317895e14b887318220..133934e7eb5ac8c3ad31af0611b505edeb39ccdd 100644 (file)
--- a/bomb.py
+++ b/bomb.py
@@ -1,5 +1,4 @@
 from fruit import Fruit
-from effect import SplitEffect
 from setup import *
 
 
@@ -12,6 +11,8 @@ class Bomb(Fruit):
     BOMB_IMAGE = pygame.image.load("assets/bomb.png").convert_alpha()
     BOMB_TXT = Texture.from_surface(renderer, BOMB_IMAGE)
 
+    RADIUS_FACTOR = 1.75
+
     EXPLOSIONS = [
         [
             Texture.from_surface(renderer, pygame.image.load(f"assets/explosion/Punch1/File1.png")),
@@ -57,6 +58,10 @@ class Bomb(Fruit):
 
         self.explosion_txt = random.choice(self.EXPLOSIONS)
 
+        circle = pygame.Surface((self.radius * 2, self.radius * 2), pygame.SRCALPHA)
+        pygame.draw.circle(circle, (255, 255, 255, 255), (self.radius, self.radius), self.radius)
+        self.circle = Texture.from_surface(renderer, circle)
+
     def update(self, delta):
         super().update(delta)
         if self.exploded:
@@ -93,7 +98,11 @@ class Bomb(Fruit):
                                                                             self.EXPLOSION_RADIUS * 2,
                                                                             self.EXPLOSION_RADIUS * 2))
         else:
-            if self.position.y - self.radius <= HEIGHT:
-                self.BOMB_TXT.draw(None, pygame.Rect(self.position.x - self.radius, self.position.y - self.radius,
-                                                     self.radius * 2, self.radius * 2), self.angle,
-                                   (self.radius, self.radius))
+            # self.circle.draw(None, pygame.Rect(self.position.x - self.RADIUS, self.position.y - self.RADIUS,
+            #                                    self.RADIUS * 2, self.RADIUS * 2))
+
+            self.BOMB_TXT.draw(None, pygame.Rect(self.position.x - self.radius * self.RADIUS_FACTOR,
+                                                 self.position.y - self.radius * self.RADIUS_FACTOR,
+                                                 self.radius * 2 * self.RADIUS_FACTOR,
+                                                 self.radius * 2 * self.RADIUS_FACTOR),
+                               self.angle, (self.radius * self.RADIUS_FACTOR, self.radius * self.RADIUS_FACTOR))
index 4b6462e35cf46ba6c0cb141698395dc0236ab05c..368e90b0951f5e409c8db6ca52404b10f6657d2d 100644 (file)
--- a/effect.py
+++ b/effect.py
@@ -119,11 +119,12 @@ class SplitEffect:
                                                               random.random()) / 100 + pygame.Vector2(normal_velocity)
         self.acceleration = pygame.Vector2(0, self.gravity)
 
-        self.angle = 0
+        self.angle = frame.angle
         self.direction = random.choice([-1, 1])
 
-        self.frame = Texture.from_surface(renderer, frame)
-        self.width, self.height = self.frame.width, self.frame.height
+
+        self.frame = frame
+        self.width, self.height = self.frame.get_rect().width, self.frame.get_rect().height
 
     def update(self, delta):
         self.velocity += self.acceleration * delta / 1000
@@ -135,83 +136,95 @@ class SplitEffect:
             return True
 
     def draw(self):
+        self.frame.angle = self.angle
+        # print(self.position)
         self.frame.draw(None, pygame.Rect(self.position.x - self.width / 2,
                                           self.position.y - self.height / 2,
-                                          self.width, self.height),
-                        self.angle, origin=(self.width / 2, self.height / 2))
-        self.width, self.height = self.frame.width, self.frame.height
+                                          self.width, self.height))
+        self.width, self.height = self.frame.get_rect().width, self.frame.get_rect().height
 
     @staticmethod
     def find_normals(v):
         return pygame.Vector2(-v.y, v.x), pygame.Vector2(v.y, -v.x)
 
     @staticmethod
-    def should_split(image, angle, image_position, mouse_position, mouse_direction, radius):
-        img, img_pos = rotate_center(pygame.transform.scale(image.copy(), (radius * 2, radius * 2)), angle,
-                                     image_position)
-        img_pos += pygame.Vector2(img.get_size()) / 2
+    def should_split(texture, angle, image_position, mouse_position, mouse_direction, radius):
         if mouse_direction.x == 0:
             mouse_direction.x += 0.0001
+
         a = math.degrees(math.atan(mouse_direction.y / mouse_direction.x))
-        img = rotate_center(img, a, pygame.Vector2(0, 0))[0]
+        diagonal = math.sqrt(2 * ((radius * 2) ** 2))
+        txt = Texture(renderer, (diagonal, diagonal), target=True)
+        txt.blend_mode = pygame.BLEND_ADD
+        renderer.target = txt
+        texture.draw(None, pygame.Rect((diagonal - radius * 2) / 2, (diagonal - radius * 2) / 2, radius * 2,
+                                       radius * 2), angle - a, origin=(radius, radius))
+        renderer.target = None
+
+        img_size = pygame.Vector2(diagonal, diagonal)
+        center = img_size / 2
+
+        # finding end and start points of the splitting line
+        # [x,y] = mouse_position + t * mouse_direction # vector equation
+        # x = mouse_position.x + t * mouse_direction.x
+        # y = mouse_position.y + t * mouse_direction.y
 
-        top_left = pygame.Vector2(image_position) - pygame.Vector2(img.get_width() / 2, img.get_height() / 2)
-        rot_center = pygame.Vector2(image_position) - top_left
-        mp = mouse_position - top_left
+        mp = mouse_position - image_position + center
 
         t1 = (- mp.x) / mouse_direction.x
         p1 = mp + t1 * mouse_direction
 
-        p3 = (p1 - rot_center).rotate(-a) + rot_center
+        p3 = (p1 - center).rotate(-a) + center
 
         MIN_SPLIT = 0.25
-        slice_percent = clamp(p3.y, 0, img.get_height()) / img.get_height()
+        slice_percent = clamp(p3.y, 0, img_size.y) / img_size.y
         if MIN_SPLIT < slice_percent < 1 - MIN_SPLIT:
             return True
         return False
 
     @staticmethod
-    def split_image(image, angle, image_position, mouse_position, mouse_direction, radius):
-        img, img_pos = rotate_center(pygame.transform.scale(image.copy(), (radius * 2, radius * 2)), angle,
-                                     image_position)
-
-
-        img_pos += pygame.Vector2(img.get_size()) / 2
+    def split_image(texture, angle, image_position, mouse_position, mouse_direction, radius):
         if mouse_direction.x == 0:
             mouse_direction.x += 0.0001
 
         a = math.degrees(math.atan(mouse_direction.y / mouse_direction.x))
-        img = rotate_center(img, a, pygame.Vector2(0, 0))[0]
+        diagonal = math.sqrt(2 * ((radius * 2) ** 2))
+        txt = Texture(renderer, (diagonal, diagonal), target=True)
+        txt.blend_mode = pygame.BLEND_ADD
+        renderer.target = txt
+        texture.draw(None, pygame.Rect((diagonal - radius * 2) / 2, (diagonal - radius * 2) / 2, radius * 2,
+                                       radius * 2), angle - a, origin=(radius, radius))
+        renderer.target = None
 
-        top_left = pygame.Vector2(img_pos) - pygame.Vector2(img.get_width() / 2, img.get_height() / 2)
-        rot_center = pygame.Vector2(img_pos) - top_left
+        img_size = pygame.Vector2(diagonal, diagonal)
+        center = img_size / 2
 
         # finding end and start points of the splitting line
         # [x,y] = mouse_position + t * mouse_direction # vector equation
         # x = mouse_position.x + t * mouse_direction.x
         # y = mouse_position.y + t * mouse_direction.y
 
-        mp = mouse_position - top_left
+        mp = mouse_position - image_position + center
 
         t1 = (- mp.x) / mouse_direction.x
         p1 = mp + t1 * mouse_direction
 
-        p3 = (p1 - rot_center).rotate(-a) + rot_center
+        p3 = (p1 - center).rotate(-a) + center
 
-        half1 = img.subsurface(pygame.Rect(0, 0, img.get_width(), clamp(p3.y, 0, img.get_height())))
-        half2 = img.subsurface(pygame.Rect(0, clamp(p3.y, 0, img.get_height()), img.get_width(),
-                                           clamp(img.get_height() - p3.y, 0, img.get_height())))
+        half1 = Image(txt, pygame.Rect(0, 0, img_size.x, clamp(p3.y, 0, img_size.y)))
+        half2 = Image(txt,
+                      pygame.Rect(0, clamp(p3.y, 0, img_size.y), img_size.x, clamp(img_size.y - p3.y, 0, img_size.y)))
 
-        p5 = half1.get_rect().center - rot_center
-        pos1 = p5.rotate(a) + img_pos
+        p5 = half1.get_rect().center - center
+        pos1 = p5.rotate(a) + image_position
 
-        p6 = half2.get_rect().center - rot_center + pygame.Vector2(0, clamp(p3.y, 0, img.get_height()))
-        pos2 = p6.rotate(a) + img_pos
+        p6 = half2.get_rect().center - center
+        pos2 = p6.rotate(a) + image_position
 
-        r_half1 = pygame.transform.rotate(half1, -a)
-        r_half2 = pygame.transform.rotate(half2, -a)
+        half1.angle = a
+        half2.angle = a
 
-        return r_half1, r_half2, pos1, pos2
+        return half1, half2, pos1, pos2
 
 
 class SlashEffect:
index aed62a362b68e97a27b7c621c4c4d1b4d6454db2..37a9df3711f494d2bc80a88cb741e4545ece7264 100644 (file)
--- a/fruit.py
+++ b/fruit.py
@@ -50,4 +50,4 @@ class Fruit:
         if self.position.y - self.radius <= HEIGHT:
             self.fruit_txt.draw(None, pygame.Rect(self.position - pygame.Vector2(self.radius, self.radius),
                                                   (self.radius * 2, self.radius * 2)),
-                                angle=-self.angle, origin=(self.radius, self.radius))
+                                angle=self.angle, origin=(self.radius, self.radius))
diff --git a/game.py b/game.py
index 9680b400d5b1249f84a7575a9ad3122997505db6..d86359881e1db744617a0879fe8fc5c34d1454ea 100644 (file)
--- a/game.py
+++ b/game.py
@@ -8,7 +8,7 @@ from setup import *
 
 
 class Game:
-    BOMB_CHANCE = 0
+    BOMB_CHANCE = 0.1
 
     COMBO_TIME = 250
     GAME_OVER_TIME = 2000
@@ -59,7 +59,7 @@ class Game:
         self.time_since_last_hit = 0
         self.current_combo = 0
 
-        self.wave = 100
+        self.wave = 1
         self.cleared_wave = True
         self.wave_cooldown_timer = 0
 
@@ -83,7 +83,7 @@ class Game:
         self.score_surf = font.render(f"SCORE {self.score}", True, WHITE)
         self.score_txt = Texture.from_surface(renderer, self.score_surf)
 
-        self.combo_surf = font.render(f"COMBO x{self.current_combo}", True, WHITE)
+        self.combo_surf = font.render(f"COMBO x{max(1,self.current_combo)}", True, WHITE)
         self.combo_txt = Texture.from_surface(renderer, self.combo_surf)
 
         self.high_score_surf = font.render(f"BEST {self.high_score}", True, WHITE)
@@ -139,7 +139,7 @@ class Game:
             fruit.update(delta)
 
             hit_status = self.player.hits(fruit)
-            if hit_status and SplitEffect.should_split(fruit.image, fruit.angle, fruit.position,
+            if hit_status and SplitEffect.should_split(fruit.fruit_txt, fruit.angle, fruit.position,
                                                        self.player.previous_mouse_pos,
                                                        self.player.mouse_direction, fruit.radius):
                 hits.append((fruit, self.player.mouse_direction, self.player.previous_mouse_pos))
@@ -159,7 +159,7 @@ class Game:
             self.high_score_txt = Texture.from_surface(renderer, self.high_score_surf)
         else:
             self.current_combo = 0
-            self.combo_surf = font.render(f"COMBO x{self.current_combo}", True, WHITE)
+            self.combo_surf = font.render(f"COMBO x{max(1,self.current_combo)}", True, WHITE)
             self.combo_txt = Texture.from_surface(renderer, self.combo_surf)
 
         for hit, mouse_direction, mouse_position in hits:
@@ -169,7 +169,7 @@ class Game:
                                                  color))
             self.effects[1].append(BloodEffect(hit.position, hit.radius, lighten(color, 0.15)))
 
-            half1, half2, pos1, pos2 = SplitEffect.split_image(hit.image, hit.angle, hit.position, mouse_position,
+            half1, half2, pos1, pos2 = SplitEffect.split_image(hit.fruit_txt, hit.angle, hit.position, mouse_position,
                                                                mouse_direction, hit.radius)
 
             n1, n2 = SplitEffect.find_normals(mouse_direction.normalize() * 5)
@@ -186,7 +186,7 @@ class Game:
 
             if self.time_since_last_hit < self.COMBO_TIME:
                 self.current_combo += 1
-                self.combo_surf = font.render(f"COMBO x{self.current_combo}", True, WHITE)
+                self.combo_surf = font.render(f"COMBO x{max(1,self.current_combo)}", True, WHITE)
                 self.combo_txt = Texture.from_surface(renderer, self.combo_surf)
             if self.current_combo > 1:
                 self.combo_counters.append(ComboCounter(hit.position, self.current_combo + 1))
@@ -218,7 +218,7 @@ class Game:
                 self.bombs.remove(bomb)
                 continue
             if (((not -bomb.radius * 2 < bomb.position.x < WIDTH + bomb.radius * 2) or
-                 bomb.position.y - bomb.radius * 2 > HEIGHT) and bomb.velocity.y > 0):
+                 bomb.position.y - bomb.radius * 2 * bomb.RADIUS_FACTOR > HEIGHT) and bomb.velocity.y > 0):
                 self.bombs.remove(bomb)
 
         if len(self.fruits) == 0 and len(self.bombs) == 0 and not self.game_over:
@@ -269,7 +269,6 @@ class Game:
             effect.draw()
         for combo in self.combo_counters:
             combo.draw()
-        self.player.draw()
         for effect in self.effects[4]:
             effect.draw()
 
@@ -278,3 +277,4 @@ class Game:
             self.r2.draw()
             self.game_over_txt.draw(None, (
                 WIDTH / 2 - self.game_over_txt.width / 2, HEIGHT / 2 - self.game_over_txt.height / 2))
+        self.player.draw()
index d23ee5cc64b4226586574e99789b195b3c4da139..c227083464fb9af8955c90d2924774ee50abb547 100644 (file)
@@ -1 +1 @@
-3850
\ No newline at end of file
+0
\ No newline at end of file
diff --git a/image.png b/image.png
deleted file mode 100644 (file)
index 73e6ada..0000000
Binary files a/image.png and /dev/null differ
diff --git a/main.py b/main.py
index b3d22bee94e79808ee5aa1a167c345e8a1ecb27e..2053bfe5167b889899f2a259eb0663e79b5ca79a 100644 (file)
--- a/main.py
+++ b/main.py
@@ -15,9 +15,9 @@ while is_running:
     status = scene.update(delta)
     scene.draw()
 
-    fps_text = font_small.render(f"FPS: {clock.get_fps():.0f}", True, DARK_GRAY)
-    fps_txt = Texture.from_surface(renderer, fps_text)
-    fps_txt.draw(None, pygame.Vector2(10, 75))
+    fps_text = font_small.render(f"FPS: {clock.get_fps():.0f}", True, DARK_GRAY)
+    fps_txt = Texture.from_surface(renderer, fps_text)
+    fps_txt.draw(None, pygame.Vector2(10, 75))
 
     renderer.present()
 
diff --git a/menu.py b/menu.py
index 2dcf1bf82e4950d77ccfafe876cd8bc485482b62..21ac97bd3c49785191b6a76079222d44d30831f1 100644 (file)
--- a/menu.py
+++ b/menu.py
@@ -88,7 +88,7 @@ class Menu:
         if not self.blacked_out:
             hit_status = self.player.hits(self.fruit)  # Check if player hits fruit
             # Check if fruit should split
-            if hit_status and SplitEffect.should_split(self.fruit.image, self.fruit.angle, self.fruit.position,
+            if hit_status and SplitEffect.should_split(self.fruit.fruit_txt, self.fruit.angle, self.fruit.position,
                                                        self.player.previous_mouse_pos, self.player.mouse_direction,
                                                        self.fruit.radius):
                 # Split fruit
@@ -100,7 +100,7 @@ class Menu:
                                                                   self.fruit.position + self.player.mouse_direction),
                                                   color))
                 self.effects.append(BloodEffect(self.fruit.position, self.fruit.radius, lighten(color, 0.15)))
-                half1, half2, pos1, pos2 = SplitEffect.split_image(self.fruit.image, self.fruit.angle,
+                half1, half2, pos1, pos2 = SplitEffect.split_image(self.fruit.fruit_txt, self.fruit.angle,
                                                                    self.fruit.position, self.player.previous_mouse_pos,
                                                                    self.player.mouse_direction, self.fruit.radius)
 
@@ -143,7 +143,7 @@ class Menu:
         self.controls_txt.draw(None, self.controls_surface.get_rect(bottomleft=(10, HEIGHT - 10)))
         self.credit_txt.draw(None, self.credit_surface.get_rect(bottomright=(WIDTH - 10, HEIGHT - 10)))
 
-        self.player.draw()
 
         for effect in self.effects:
             effect.draw()
+        self.player.draw()
index fe66ea81f61088f52811a7669fa073533f147d93..ba3f230b186929f6473dbfba57d142a8a994d0ef 100644 (file)
--- a/player.py
+++ b/player.py
@@ -1,11 +1,15 @@
+import pygame.mouse
+
 from setup import *
 
 
 class Player:
     LIFE_TIME = 100
-    INFLATE_SCALE = 20
 
-    IMAGE = pygame.image.load("assets/effects/sword_slashes/White_Slash_Thin/File2.png").convert_alpha()
+    image = pygame.image.load("assets/knife.png").convert_alpha()
+    txt = Texture.from_surface(renderer, image)
+
+    SIZE = pygame.Vector2(50* SCALE, 50* SCALE)
 
     def __init__(self):
         self.sliced_points = []
@@ -13,10 +17,9 @@ class Player:
 
         self.previous_mouse_pos = pygame.Vector2(pygame.mouse.get_pos())
         self.mouse_direction = pygame.Vector2(0, 0)
-        self.angle = 0
         self.slicing = False
-        self.display_image = self.IMAGE.copy()
-        self.position = pygame.Vector2(0, 0)
+
+        self.angle = 0
 
     def update(self, delta):
         pressed = pygame.mouse.get_pressed()
@@ -25,21 +28,13 @@ class Player:
             self.sliced_points.append((pygame.Vector2(pos), pygame.time.get_ticks()))
             self.mouse_direction = pygame.Vector2(pos) - self.previous_mouse_pos
             self.previous_mouse_pos = pygame.Vector2(pos)
-            if self.mouse_direction.x == 0:
-                x_direction = self.mouse_direction.x + 0.0001
-            else:
-                x_direction = self.mouse_direction.x
-            self.angle = math.degrees(math.atan(self.mouse_direction.y / x_direction))
-            self.display_image, self.position = rotate_center(self.IMAGE, self.angle,
-                                                              pygame.Vector2(pos) + pygame.Vector2(
-                                                                  self.IMAGE.get_width() / 2, 0))
             self.slicing = True
         else:
             self.mouse_direction = pygame.Vector2(0, 0)
             self.previous_mouse_pos = pygame.Vector2(pygame.mouse.get_pos())
-            self.angle = 0
             self.slicing = False
 
+
         self.lines.clear()
         if len(self.sliced_points) > 1:
             for i in range(len(self.sliced_points) - 1):
@@ -78,3 +73,5 @@ class Player:
             for i in range(len(self.sliced_points) - 1):
                 renderer.draw_line(self.sliced_points[i][0], self.sliced_points[i + 1][0])
         renderer.draw_line(self.previous_mouse_pos, self.previous_mouse_pos - self.mouse_direction)
+        self.txt.draw(None, pygame.Rect(pygame.mouse.get_pos(), self.SIZE))
+
index 7897215acd918734c8bb96ca28a3f9d75624ffb3..08ad0f103b7f39b5a8283bad4e3979b9d8213f54 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -1,5 +1,5 @@
 import pygame
-from pygame._sdl2 import Window, Renderer, Texture
+from pygame._sdl2 import Window, Renderer, Texture, Image
 import random
 import os
 import math
@@ -10,6 +10,7 @@ WIDTH, HEIGHT = pygame.display.Info().current_w, pygame.display.Info().current_h
 display = pygame.display.set_mode((WIDTH, HEIGHT))
 window = Window.from_display_module()
 renderer = Renderer(window)
+pygame.mouse.set_visible(False)
 
 SCALE = pygame.Vector2(WIDTH / 1536, HEIGHT / 864)
 
@@ -93,19 +94,6 @@ def lerp(start, end, weight):
 def clamp(value, minimum, maximum):
     return min(maximum, max(minimum, value))
 
-
-@cache
-def rotate(image, angle):
-    return pygame.transform.rotate(image, angle)
-
-
-def rotate_center(image, angle, position):
-    rotated_image = rotate(image, round(angle))
-    new_rect = rotated_image.get_rect(center=image.get_rect(topleft=(position.x - image.get_rect().width / 2,
-                                                                     position.y - image.get_rect().height / 2)).center)
-    return rotated_image, new_rect.topleft
-
-
 def determine_angle(pos1, pos2):
     pos1 = pygame.Vector2(pos1)
     pos2 = pygame.Vector2(pos2)