Skip to content

Instantly share code, notes, and snippets.

@f0ursqu4r3
Last active November 24, 2021 02:43
Show Gist options
  • Save f0ursqu4r3/63244f2370d35482b465aebdbd38c4c9 to your computer and use it in GitHub Desktop.
Save f0ursqu4r3/63244f2370d35482b465aebdbd38c4c9 to your computer and use it in GitHub Desktop.
python pygame bullet test playground
import time
import math
import pygame
import random
from pygame import Vector2
pygame.init()
class Game:
def __init__(self):
self.window_size = Vector2(512)
self.window = pygame.display.set_mode(self.window_size, pygame.DOUBLEBUF)
pygame.display.set_caption('playground')
self.screen_scale = 3
self.screen = pygame.Surface(self.window_size/self.screen_scale)
self.screen_size = Vector2(self.screen.get_size())
self.clock = pygame.time.Clock()
self.mpos = Vector2(pygame.mouse.get_pos()) / self.screen_scale
self.p_pos = self.screen_size / 2
self.p_vel = Vector2()
self.bullets = []
self.shells = []
self.cam_offset = Vector2()
self.time_scale = 1
self.shot_timer = 0
self.fire_rate = 1/20
def run(self):
while 1:
self.process_events()
self.update()
self.draw()
def process_events(self):
for event in pygame.event.get():
if (event.type == pygame.QUIT or
(event.type == pygame.KEYDOWN and
event.key == pygame.K_ESCAPE)):
pygame.quit()
quit()
self.p_vel = Vector2()
pressed = pygame.key.get_pressed()
if pressed[pygame.K_w]:
self.p_vel.y -= 80
if pressed[pygame.K_s]:
self.p_vel.y += 80
if pressed[pygame.K_a]:
self.p_vel.x -= 80
if pressed[pygame.K_d]:
self.p_vel.x += 80
if pygame.mouse.get_pressed()[0] and not self.shot_timer:
mpos = Vector2(pygame.mouse.get_pos()) / self.screen_scale
vec = (mpos - self.p_pos).normalize()
self.bullets.append(Bullet(self.p_pos + vec * 15, vec))
eject_vec = Vector2(-vec.y, vec.x)
self.bullets.append(Shell(self.p_pos + (vec * 4) + (eject_vec * 4), eject_vec))
shake = vec * -(random.random() * 4 + 4)
self.cam_offset = shake
self.p_vel = shake * 50
self.shot_timer = self.fire_rate
self.time_scale = 0.2
def update(self):
tdt = self.clock.tick(60) * 0.001
self.time_scale = min(1, self.time_scale + tdt * 4)
dt = tdt * self.time_scale
self.shot_timer = max(0, self.shot_timer - dt)
self.cam_offset *= .8
self.p_pos += self.p_vel * dt
if self.p_pos.x < 0:
self.p_pos.x = 0
elif self.p_pos.x > self.screen_size.x:
self.p_pos.x = self.screen_size.x
if self.p_pos.y < 0:
self.p_pos.y = 0
elif self.p_pos.y > self.screen_size.y:
self.p_pos.y = self.screen_size.y
for bullet in self.bullets[:]:
bullet.update(dt)
if bullet.life < 0:
self.bullets.remove(bullet)
continue
if not (0 < bullet.pos.x < self.screen_size.x):
if bullet.pos.x < 0:
bullet.pos.x = 0
else:
bullet.pos.x = self.screen_size.x
bullet.vel.x *= -1
if not (0 < bullet.pos.y < self.screen_size.y):
if bullet.pos.y < 0:
bullet.pos.y = 0
else:
bullet.pos.y = self.screen_size.y
bullet.vel.y *= -1
for shell in self.shells[:]:
shell.update(dt)
if shell.life < 0:
self.shells.remove(shell)
continue
if not (0 < shell.pos.x < self.screen_size.x):
if shell.pos.x < 0:
shell.pos.x = 0
else:
shell.pos.x = self.screen_size.x
shell.vel.x *= -1
if not (0 < shell.pos.y < self.screen_size.y):
if shell.pos.y < 0:
shell.pos.y = 0
else:
shell.pos.y = self.screen_size.y
shell.vel.y *= -1
def draw(self):
self.screen.fill((60,50,60))
layer = pygame.Surface(self.screen.get_size(), pygame.SRCALPHA)
for bullet in self.bullets:
layer.blit(bullet.surf, bullet.pos - Vector2(bullet.surf.get_size())/2)
for shell in self.shells:
layer.blit(shell.surf, shell.pos - Vector2(shell.surf.get_size())/2)
mpos = Vector2(pygame.mouse.get_pos()) / self.screen_scale
vec = (mpos - self.p_pos).normalize()
degrees = math.degrees(math.atan2(vec.y, vec.x))
angle = (360 + degrees) % 360
pygame.draw.line(layer, (0,200,0), self.p_pos, self.p_pos + vec * 10, 1)
pygame.draw.circle(layer, (0,200,0), self.p_pos, 2)
self.mpos = mpos
self.screen.blit(layer, self.cam_offset)
pygame.transform.scale(self.screen, self.window_size, self.window)
pygame.display.flip()
class Bullet:
__slots__ = [
'pos', 'vel', 'speed', '_speed',
'_surf', 'life', 'rot_speed'
]
def __init__(self, pos, vel):
self.pos = Vector2(pos)
self.vel = Vector2(vel)
self.speed = 100
self._speed = 100
surf = pygame.Surface(Vector2(8, 4))
pygame.draw.rect(surf, (100, 100, 100), (0,0,6,4))
pygame.draw.circle(surf, (100, 100, 100), (6,2), 2)
self._surf = surf
self.life = 5
def update(self, dt):
self.pos += self.vel * self.speed * dt
self.life -= dt
@property
def surf(self):
if not self.vel:
return self._surf
vel = self.vel.normalize()
degrees = math.degrees(math.atan2(vel.y, vel.x))
angle = (360 + degrees) % 360
return pygame.transform.rotozoom(self._surf, -angle, self.life / 5)
class Shell(Bullet):
def __init__(self, pos, vel):
super().__init__(pos, vel)
surf = pygame.Surface(Vector2(8, 4))
pygame.draw.rect(surf, (200, 200, 0), (0, 0, 2, 4))
pygame.draw.rect(surf, (200, 0, 0), (2, 0, 6, 4))
self._surf = surf
self.speed = random.randint(80, 100)
self._speed = int(self.speed)
self.rot_speed = random.random()
def update(self, dt):
super().update(dt)
self.speed *= 1 - dt * 1.8
@property
def surf(self):
if not self.vel:
return self._surf
vel = self.vel.normalize()
degrees = math.degrees(math.atan2(vel.y, vel.x))
angle = (360 + degrees - 90 - (360 * ((self.speed/self._speed)*self.rot_speed))) % 360
return pygame.transform.rotozoom(self._surf, -angle, self.life / 5)
Game().run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment