Skip to content

Instantly share code, notes, and snippets.

@stmobo
Created February 21, 2018 18:16
Show Gist options
  • Save stmobo/b9e9e444bfcad7a4cf396b63e4bcce7f to your computer and use it in GitHub Desktop.
Save stmobo/b9e9e444bfcad7a4cf396b63e4bcce7f to your computer and use it in GitHub Desktop.
import pygame
import numpy as np
import math
import sys
import random
pygame.init()
bullets = pygame.sprite.Group()
player_group = pygame.sprite.Group()
init_pos = (400, 700)
screen_dims = (800, 800)
screen = pygame.display.set_mode(screen_dims)
clk = pygame.time.Clock()
class Bullet(pygame.sprite.Sprite):
def __init__(self, x, y, rot):
pygame.sprite.Sprite.__init__(self)
self.base_image = pygame.Surface([20, 20])
self.base_image.fill((0, 0, 255))
#pygame.draw.circle(self.base_image, (255, 0, 0), (10, 10), 10)
self.position = np.array((x, y), dtype=np.float64)
self.rotation = rot
self.acc = np.zeros(2, dtype=np.float64)
self.vel = np.zeros(2, dtype=np.float64)
self.image = self.base_image
self.rect = self.base_image.get_rect()
def accelerate_to(self, target, magnitude, x_only=False):
disp_vec = target - self.position
dist = np.sqrt(np.sum(disp_vec ** 2))
unit_disp_vec = disp_vec / dist
self.acc = unit_disp_vec * magnitude
if x_only:
self.acc[1] = 0
def update(self, dt):
if self.target is not None and self.target_acc is not None:
self.accelerate_to(self.target, self.target_acc, True)
self.vel[0] = self.vel[0] + (self.acc[0] * dt)
self.vel[1] = self.vel[1] + (self.acc[1] * dt)
self.position[0] = self.position[0] + (self.vel[0] * dt)
self.position[1] = self.position[1] + (self.vel[1] * dt)
self.image = pygame.transform.rotate(self.base_image, self.rotation)
self.rect = self.image.get_rect()
self.rect.x = self.position[0]
self.rect.y = self.position[1]
class Player(pygame.sprite.Sprite):
def __init__(self, pos):
pygame.sprite.Sprite.__init__(self)
self.pos = np.array(pos, dtype=np.float64)
self.vel = np.zeros(2)
self.movement_magnitude = 300
self.image = pygame.Surface([10, 10])
self.image.fill((255, 0, 0))
self.rect = self.image.get_rect()
def update(self, dt):
self.pos[0] = self.pos[0] + (self.vel[0] * dt)
self.pos[1] = self.pos[1] + (self.vel[1] * dt)
self.rect.x = self.pos[0]
self.rect.y = self.pos[1]
if self.pos[0] < 0:
self.pos[0] = 0
elif self.pos[0] > screen_dims[0]:
self.pos[0] = screen_dims[0]
if self.pos[1] < 0:
self.pos[1] = 0
elif self.pos[1] > screen_dims[1]:
self.pos[1] = screen_dims[1]
def update_movement(self, ev_type, keycode):
if ev_type == pygame.KEYDOWN:
if keycode == pygame.K_LEFT:
self.vel[0] = self.vel[0] - self.movement_magnitude
elif keycode == pygame.K_RIGHT:
self.vel[0] = self.vel[0] + self.movement_magnitude
elif keycode == pygame.K_UP:
self.vel[1] = self.vel[1] - self.movement_magnitude
elif keycode == pygame.K_DOWN:
self.vel[1] = self.vel[1] + self.movement_magnitude
elif keycode == pygame.K_LSHIFT or keycode == pygame.K_RSHIFT:
self.movement_magnitude = 150
elif ev_type == pygame.KEYUP:
if keycode == pygame.K_LEFT:
self.vel[0] = self.vel[0] + self.movement_magnitude
elif keycode == pygame.K_RIGHT:
self.vel[0] = self.vel[0] - self.movement_magnitude
elif keycode == pygame.K_UP:
self.vel[1] = self.vel[1] + self.movement_magnitude
elif keycode == pygame.K_DOWN:
self.vel[1] = self.vel[1] - self.movement_magnitude
elif keycode == pygame.K_LSHIFT or keycode == pygame.K_RSHIFT:
self.movement_magnitude = 300
player = Player(init_pos)
player_group.add(player)
pygame.time.set_timer(pygame.USEREVENT+1, 25)
t = 0
while True:
dt = clk.tick(60) / 1000
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN or event.type == pygame.KEYUP:
player.update_movement(event.type, event.key)
elif event.type == pygame.USEREVENT+1 and len(bullets.sprites()) < 100:
new_sprite = Bullet(400, 100, 180)
new_sprite.vel = np.array([0, 0])
x_vel = random.uniform(-200, 200)
y_vel = random.uniform(-50, 200)
new_sprite.vel[0] = x_vel
new_sprite.vel[1] = y_vel
new_sprite.target = (400, 700)
new_sprite.target_acc = 60
bullets.add(new_sprite)
bullets.update(dt)
player_group.update(dt)
for sprite in bullets.sprites():
if (
sprite.position[0] < 0 or sprite.position[0] > screen_dims[0]
or sprite.position[1] < 0 or sprite.position[1] > screen_dims[1]
):
sprite.kill()
sprite.target = player.pos
screen.fill((255, 255, 255))
bullets.draw(screen)
player_group.draw(screen)
pygame.display.flip()
if pygame.sprite.spritecollide(player, bullets, False):
print("Time: {:.3f}".format(t))
bullets.empty()
player.pos = np.array(init_pos)
t = 0
else:
t += dt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment