Un piccolo progetto che ho creato nel tempo libero qualche mese fa, Primitive Shooter è uno shooter semplice creato con Python e Pygame.
Buongiorno a tutti, qualche mese fa ho voluto provare un po' le mie (scarse) competenze di programmazione in Python e Pygame scrivendo un piccolo shooter senza grafiche sfavillanti o effetti speciali (tutti gli elementi sono rettangoli!): grezzo, primitivo e rude; proprio come me.
Il gioco è completamente contenuto in 269 righe di codice, contenute a loro volta in un solo file.
I moduli principali sono:
Modulo | Descrizione |
---|---|
Classe Player() | Una semplice classe che rappresenta il giocatore |
Classe Enemy() | Un semplice nemico, rappresentato da un quadrato rosso |
Classe Bullet() | Un semplice proiettile |
Classe PowerUp() | Un semplice quadratino azzurro che rappresenta un potenziatore |
Classe PowerBullet() | Un Proiettile Più potente |
Funzione Shoot() | Controlla il cannone e la sua potenza |
Funzione Level() | Gestisce la generazione dei livelli |
Le caratteristiche supportate dal gioco sono altamente all'avanguardia:
- Movimento della nave e dei nemici
- Grafica dignitosamente quadrettosa
- Supporto per le vite
- Supporto per i Powerup
- Schermata finale di Game Over
Se volete provare il gioco è sufficiente scaricare il codice sorgente, presente qui sotto e avviarlo con il comando:
python shooter.py
Primitive Shooter è, diversamente dagli altri pezzi di codice contenuti nel blog, distribuito con la sola clausola di "Attribuzione", il programma potrà tranquillamente essere modificato e rivenduto, purchè venga citato il nome dell'autore.
Ecco il codice sorgente del programma:
#!/usr/bin/env python
import pygame
from pygame import *
from sys import exit
from random import randint
import Vector
from math import floor, ceil
from Vector import *
render_list=pygame.sprite.Group()
score=0
empower=False
tp=0
kills=0
killlevel=0
lv=1
empow=0
shlvl=1
lives=3
class Player(pygame.sprite.Sprite):
move_x=0
move_y=0
def __init__(self,x,y):
pygame.sprite.Sprite.__init__(self)
self.image=pygame.Surface((20,20))
self.image.fill((255,255,255))
self.rect=self.image.get_rect()
self.rect.x=x
self.rect.y=y
render_list.add(self)
def update(self):
if self.rect.x+self.move_x < 620 and self.rect.x+self.move_x >0:
self.rect.x+=self.move_x
if self.rect.y+self.move_y < 460 and self.rect.y+self.move_y >0:
self.rect.y+=self.move_y
collision=pygame.sprite.spritecollide(self,enemy_list,True)
if collision:
global lives
lives-=1
global kills
kills+=1
pow_list=pygame.sprite.Group()
enemy_list=pygame.sprite.Group()
class Powerup(pygame.sprite.Sprite):
def __init__(self,x,y):
pygame.sprite.Sprite.__init__(self)
self.image=pygame.Surface((15,15))
self.image.fill((73,255,234))
self.rect=self.image.get_rect()
self.rect.x=x
self.rect.y=y
render_list.add(self)
pow_list.add(self)
def update(self):
self.rect.y+=2
if self.rect.y>=480:
self.kill()
collide=pygame.sprite.spritecollide(player,pow_list,True)
if collide:
global shlvl
shlvl+=1
self.kill()
class Enemy(pygame.sprite.Sprite):
destination=0
def __init__(self,x,y):
pygame.sprite.Sprite.__init__(self)
self.image=pygame.Surface((20,20))
self.image.fill((255,0,0))
self.rect=self.image.get_rect()
self.rect.x=x
self.rect.y=y
enemy_list.add(self)
render_list.add(self)
self.destination=randint(0,620)
def update(self):
self.rect.y+=3
if self.rect.y>=0:
if self.rect.x>self.destination:
self.rect.x-=randint(1,5)
elif self.rect.x < self.destination:
self.rect.x+=randint(1,5)
if self.rect.y>480:
self.kill()
global kills
kills+=1
bullets=pygame.sprite.Group()
class PowerBullet(pygame.sprite.Sprite):
speed=10
def __init__(self,x,y):
pygame.sprite.Sprite.__init__(self)
self.image=pygame.Surface((4,10))
self.image.fill((17,128,255))
self.rect=self.image.get_rect()
self.rect.x=x
self.rect.y=y
bullets.add(self)
render_list.add(self)
def update(self):
self.rect.y-=self.speed
if self.rect.y<=-5:
self.kill()
collide=pygame.sprite.spritecollide(self,enemy_list,True)
if collide:
global score
global kills
score+=20
kills+=1
n=randint(0,2)
if n==1:
Powerup(320,0)
global score
score+=10
class Bullet(pygame.sprite.Sprite):
speed=300
direction=Vector()
heading=Vector()
move_x=0
def __init__(self,x,y,dirx):
pygame.sprite.Sprite.__init__(self)
self.image=pygame.Surface((2,5))
self.image.fill((255,128,12))
self.rect=self.image.get_rect()
self.rect.x=x
self.rect.y=y
bullets.add(self)
render_list.add(self)
self.direction=Vector.FromPoints((x,y),(x+dirx,-20))
self.direction.normalize()
self.move_x=(tp/1000.)*self.speed*self.direction.to_tuple()[0]
if self.move_x<0:
self.move_x=floor(self.move_x)
elif self.move_x>0:
self.move_x=ceil(self.move_x)
def update(self):
self.rect.x+=self.move_x
self.rect.y+=(tp/1000.)*self.speed*self.direction.to_tuple()[1]
if self.rect.y<=-5:
self.kill()
collide=pygame.sprite.spritecollide(self,enemy_list,True)
if collide:
self.kill()
global score
score+=20
global kills
kills+=1
n=randint(0,15)
if n==1:
Powerup(320,0)
global score
score+=10
def Shoot():
if shlvl==1:
Bullet(player.rect.x+(player.rect.width/2),player.rect.y,0)
elif shlvl==2:
Bullet(player.rect.x,player.rect.y,0)
Bullet(player.rect.x+player.rect.width,player.rect.y,0)
elif shlvl==3:
Bullet(player.rect.x+(player.rect.width/2),player.rect.y-10,0)
Bullet(player.rect.x,player.rect.y,0)
Bullet(player.rect.x+player.rect.width,player.rect.y,0)
elif shlvl==4:
Bullet(player.rect.x+(player.rect.width/2),player.rect.y-10,0)
Bullet(player.rect.x,player.rect.y,-5)
Bullet(player.rect.x+player.rect.width,player.rect.y,5)
elif shlvl==5:
Bullet(player.rect.x+(3*player.rect.width/4),player.rect.y-10,0)
Bullet(player.rect.x,player.rect.y,-5)
Bullet(player.rect.x+(player.rect.width/4),player.rect.y-10,0)
Bullet(player.rect.x+player.rect.width,player.rect.y,5)
elif shlvl==6:
Bullet(player.rect.x+(3*player.rect.width/4),player.rect.y-10,0)
Bullet(player.rect.x,player.rect.y,-5)
Bullet(player.rect.x,player.rect.y+10,-7)
Bullet(player.rect.x+player.rect.width,player.rect.y+10,7)
Bullet(player.rect.x+(player.rect.width/4),player.rect.y-10,0)
Bullet(player.rect.x+player.rect.width,player.rect.y,5)
elif shlvl==7:
Bullet(player.rect.x+(3*player.rect.width/4),player.rect.y-10,0)
Bullet(player.rect.x,player.rect.y,-5)
Bullet(player.rect.x+(player.rect.width/4),player.rect.y-10,0)
Bullet(player.rect.x+player.rect.width,player.rect.y,5)
Bullet(player.rect.x,player.rect.y+5,-200)
Bullet(player.rect.x+player.rect.width,player.rect.y+5,200)
elif shlvl>7:
global shlvl
shlvl=7
player=Player(320,440)
pygame.init()
screen=pygame.display.set_mode((640,480),0,32)
pygame.display.set_caption("Primitive Shooter!!")
clock=pygame.time.Clock()
f=pygame.font.SysFont("Arial",12)
g=pygame.font.SysFont("Arial",30,True,True)
gtext=g.render("Game Over",True,(255,0,0),None)
def Level():
global killlevel
killlevel=lv*20
for n in range(20*lv):
x=randint(0,640)
y=randint(-5000,-100)
Enemy(x,y)
Level()
while True:
for event in pygame.event.get():
if event.type==QUIT:
exit()
if event.type==KEYDOWN:
if event.key==K_LEFT:
player.move_x=-7
if event.key==K_RIGHT:
player.move_x=7
if event.key==K_UP:
player.move_y=-7
if event.key==K_DOWN:
player.move_y=7
if event.key==K_z:
if not empower:
Shoot()
else:
PowerBullet(player.rect.x+(player.rect.width/2),player.rect.y)
if event.type==KEYUP:
if event.key==K_LEFT:
player.move_x=0
if event.key==K_RIGHT:
player.move_x=0
if event.key==K_UP:
player.move_y=0
if event.key==K_DOWN:
player.move_y=0
if event.key==K_e:
empow=1
if event.key==K_m and empow==1:
empow=2
if event.key==K_p and empow==2:
empow=3
if event.key==K_o and empow==3:
empow=4
if event.key==K_w and empow==4:
empower=True
player.image.fill((255,12,128))
player.update()
for bullet in bullets:
bullet.update()
screen.fill((0,0,0))
render_list.draw(screen)
s=f.render(str(score),True,(255,255,255),None)
l=f.render("Level "+str(lv),True,(255,255,255),None)
live=f.render("Lives: " +str(lives),True,(255,255,255),None)
screen.blit(live,(400,460))
screen.blit(l,(400,10))
screen.blit(s,(10,10))
for enemy in enemy_list:
enemy.update()
global kills
for powerup in pow_list:
powerup.update()
if kills==killlevel:
score+=1000
lv+=1
kills=0
Level()
if lives<=0:
player.kill()
for enemy in enemy_list:
enemy.kill()
screen.blit(gtext,(240,200))
pygame.display.flip()
global tp
tp=clock.tick(60)
Questo è quanto!
Buona programmazione!
Penaz.