## 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
from fruit import Fruit
-from effect import SplitEffect
from setup import *
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")),
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:
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))
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
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:
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))
class Game:
- BOMB_CHANCE = 0
+ BOMB_CHANCE = 0.1
COMBO_TIME = 250
GAME_OVER_TIME = 2000
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
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)
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))
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:
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)
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))
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:
effect.draw()
for combo in self.combo_counters:
combo.draw()
- self.player.draw()
for effect in self.effects[4]:
effect.draw()
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()
-3850
\ No newline at end of file
+0
\ No newline at end of file
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()
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
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)
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()
+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 = []
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()
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):
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))
+
import pygame
-from pygame._sdl2 import Window, Renderer, Texture
+from pygame._sdl2 import Window, Renderer, Texture, Image
import random
import os
import math
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)
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)